]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86/traps: Initialize DR7 by writing its architectural reset value
authorXin Li (Intel) <xin@zytor.com>
Fri, 20 Jun 2025 23:15:04 +0000 (16:15 -0700)
committerDave Hansen <dave.hansen@linux.intel.com>
Tue, 24 Jun 2025 20:15:52 +0000 (13:15 -0700)
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: Xin Li (Intel) <xin@zytor.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Reviewed-by: Sohil Mehta <sohil.mehta@intel.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Sean Christopherson <seanjc@google.com>
Tested-by: Sohil Mehta <sohil.mehta@intel.com>
Cc:stable@vger.kernel.org
Link: https://lore.kernel.org/all/20250620231504.2676902-3-xin%40zytor.com
arch/x86/include/asm/debugreg.h
arch/x86/include/asm/kvm_host.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/kgdb.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kvm/x86.c

index 363110e6b2e33f7d2165e37560dd489ca2ca270b..a2c1f2d24b64561ae30fbb3d2911008030236624 100644 (file)
@@ -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
index b4a391929cdbaa9960e870ade649606bdcab2e9a..639d9bcee8424d1735a4899d9867ef9a9cb3099b 100644 (file)
@@ -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 \
index 0f6c280a94f0cae9d7449e2f99a2df907c9900ed..27125e009847c7395bb799685daf48b186034692 100644 (file)
@@ -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);
index 102641fd217284c0fbdfd8d06d53e00beebee8d1..8b1a9733d13e3f69a12a8cf4a9dcc2062cec3336 100644 (file)
@@ -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;
index a10e180cbf233db27d94c97bd22c3cb1924acd40..3ef15c2f152f7033970dd997265f16eeb176bfa2 100644 (file)
@@ -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",
index 8d6cf25127aab78ea201b5fc80082f6641805cdb..b972bf72fb8b6839c68b2d0c0f865f85dfcb5185 100644 (file)
@@ -133,7 +133,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))) {
                printk("%sDR0: %016lx DR1: %016lx DR2: %016lx\n",
                       log_lvl, d0, d1, d2);
                printk("%sDR3: %016lx DR6: %016lx DR7: %016lx\n",
index b58a74c1722de3f2d180cf8d6a3cf0ce9cf534fd..a9d992d5652fa0fa2cba6874eb64c7cc6356c1a8 100644 (file)
@@ -11035,7 +11035,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 
        if (unlikely(vcpu->arch.switch_db_regs &&
                     !(vcpu->arch.switch_db_regs & KVM_DEBUGREG_AUTO_SWITCH))) {
-               set_debugreg(0, 7);
+               set_debugreg(DR7_FIXED_1, 7);
                set_debugreg(vcpu->arch.eff_db[0], 0);
                set_debugreg(vcpu->arch.eff_db[1], 1);
                set_debugreg(vcpu->arch.eff_db[2], 2);
@@ -11044,7 +11044,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT))
                        kvm_x86_call(set_dr6)(vcpu, vcpu->arch.dr6);
        } else if (unlikely(hw_breakpoint_active())) {
-               set_debugreg(0, 7);
+               set_debugreg(DR7_FIXED_1, 7);
        }
 
        vcpu->arch.host_debugctl = get_debugctlmsr();