Commit fa7d0f83 authored by Xin Li (Intel)'s avatar Xin Li (Intel) Committed by Dave Hansen
Browse files

x86/traps: Initialize DR7 by writing its architectural reset value



Initialize DR7 by writing its architectural reset value to always set
bit 10, which is reserved to '1', when "clearing" DR7 so as not to
trigger unanticipated behavior if said bit is ever unreserved, e.g. as
a feature enabling flag with inverted polarity.

Signed-off-by: default avatarXin Li (Intel) <xin@zytor.com>
Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: default avatarH. Peter Anvin (Intel) <hpa@zytor.com>
Reviewed-by: default avatarSohil Mehta <sohil.mehta@intel.com>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: default avatarSean Christopherson <seanjc@google.com>
Tested-by: default avatarSohil Mehta <sohil.mehta@intel.com>
Cc:stable@vger.kernel.org
Link: https://lore.kernel.org/all/20250620231504.2676902-3-xin%40zytor.com
parent 5f465c14
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -9,6 +9,14 @@
#include <asm/cpufeature.h>
#include <asm/msr.h>

/*
 * Define bits that are always set to 1 in DR7, only bit 10 is
 * architecturally reserved to '1'.
 *
 * This is also the init/reset value for DR7.
 */
#define DR7_FIXED_1	0x00000400

DECLARE_PER_CPU(unsigned long, cpu_dr7);

#ifndef CONFIG_PARAVIRT_XXL
@@ -100,8 +108,8 @@ static __always_inline void native_set_debugreg(int regno, unsigned long value)

static inline void hw_breakpoint_disable(void)
{
	/* Zero the control register for HW Breakpoint */
	set_debugreg(0UL, 7);
	/* Reset the control register for HW Breakpoint */
	set_debugreg(DR7_FIXED_1, 7);

	/* Zero-out the individual HW breakpoint address registers */
	set_debugreg(0UL, 0);
@@ -125,9 +133,12 @@ static __always_inline unsigned long local_db_save(void)
		return 0;

	get_debugreg(dr7, 7);
	dr7 &= ~0x400; /* architecturally set bit */

	/* Architecturally set bit */
	dr7 &= ~DR7_FIXED_1;
	if (dr7)
		set_debugreg(0, 7);
		set_debugreg(DR7_FIXED_1, 7);

	/*
	 * Ensure the compiler doesn't lower the above statements into
	 * the critical section; disabling breakpoints late would not
+1 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@

#include <asm/apic.h>
#include <asm/pvclock-abi.h>
#include <asm/debugreg.h>
#include <asm/desc.h>
#include <asm/mtrr.h>
#include <asm/msr-index.h>
@@ -249,7 +250,6 @@ enum x86_intercept_stage;
#define DR7_BP_EN_MASK	0x000000ff
#define DR7_GE		(1 << 9)
#define DR7_GD		(1 << 13)
#define DR7_FIXED_1	0x00000400
#define DR7_VOLATILE	0xffff2bff

#define KVM_GUESTDBG_VALID_MASK \
+1 −1
Original line number Diff line number Diff line
@@ -2246,7 +2246,7 @@ EXPORT_PER_CPU_SYMBOL(__stack_chk_guard);
static void initialize_debug_regs(void)
{
	/* Control register first -- to make sure everything is disabled. */
	set_debugreg(0, 7);
	set_debugreg(DR7_FIXED_1, 7);
	set_debugreg(DR6_RESERVED, 6);
	/* dr5 and dr4 don't exist */
	set_debugreg(0, 3);
+1 −1
Original line number Diff line number Diff line
@@ -385,7 +385,7 @@ static void kgdb_disable_hw_debug(struct pt_regs *regs)
	struct perf_event *bp;

	/* Disable hardware debugging while we are in kgdb: */
	set_debugreg(0UL, 7);
	set_debugreg(DR7_FIXED_1, 7);
	for (i = 0; i < HBP_NUM; i++) {
		if (!breakinfo[i].enabled)
			continue;
+1 −1
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,

	/* Only print out debug registers if they are in their non-default state. */
	if ((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) &&
	    (d6 == DR6_RESERVED) && (d7 == 0x400))
	    (d6 == DR6_RESERVED) && (d7 == DR7_FIXED_1))
		return;

	printk("%sDR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
Loading