Skip to content

Commit 1df2902

Browse files
author
Maxim Levitsky
committed
x86/traps: Initialize DR7 by writing its architectural reset value
JIRA: https://issues.redhat.com/browse/RHEL-120168 commit fa7d0f8 Author: Xin Li (Intel) <xin@zytor.com> Date: Fri Jun 20 16:15:04 2025 -0700 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: 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 Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
1 parent 2419efd commit 1df2902

File tree

7 files changed

+22
-11
lines changed

7 files changed

+22
-11
lines changed

arch/x86/include/asm/debugreg.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
#include <asm/cpufeature.h>
1010
#include <asm/msr.h>
1111

12+
/*
13+
* Define bits that are always set to 1 in DR7, only bit 10 is
14+
* architecturally reserved to '1'.
15+
*
16+
* This is also the init/reset value for DR7.
17+
*/
18+
#define DR7_FIXED_1 0x00000400
19+
1220
DECLARE_PER_CPU(unsigned long, cpu_dr7);
1321

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

101109
static inline void hw_breakpoint_disable(void)
102110
{
103-
/* Zero the control register for HW Breakpoint */
104-
set_debugreg(0UL, 7);
111+
/* Reset the control register for HW Breakpoint */
112+
set_debugreg(DR7_FIXED_1, 7);
105113

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

127135
get_debugreg(dr7, 7);
128-
dr7 &= ~0x400; /* architecturally set bit */
136+
137+
/* Architecturally set bit */
138+
dr7 &= ~DR7_FIXED_1;
129139
if (dr7)
130-
set_debugreg(0, 7);
140+
set_debugreg(DR7_FIXED_1, 7);
141+
131142
/*
132143
* Ensure the compiler doesn't lower the above statements into
133144
* the critical section; disabling breakpoints late would not

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include <asm/apic.h>
3333
#include <asm/pvclock-abi.h>
34+
#include <asm/debugreg.h>
3435
#include <asm/desc.h>
3536
#include <asm/mtrr.h>
3637
#include <asm/msr-index.h>
@@ -248,7 +249,6 @@ enum x86_intercept_stage;
248249
#define DR7_BP_EN_MASK 0x000000ff
249250
#define DR7_GE (1 << 9)
250251
#define DR7_GD (1 << 13)
251-
#define DR7_FIXED_1 0x00000400
252252
#define DR7_VOLATILE 0xffff2bff
253253

254254
#define KVM_GUESTDBG_VALID_MASK \

arch/x86/kernel/cpu/common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2188,7 +2188,7 @@ EXPORT_PER_CPU_SYMBOL(__stack_chk_guard);
21882188
static void initialize_debug_regs(void)
21892189
{
21902190
/* Control register first -- to make sure everything is disabled. */
2191-
set_debugreg(0, 7);
2191+
set_debugreg(DR7_FIXED_1, 7);
21922192
set_debugreg(DR6_RESERVED, 6);
21932193
/* dr5 and dr4 don't exist */
21942194
set_debugreg(0, 3);

arch/x86/kernel/kgdb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ static void kgdb_disable_hw_debug(struct pt_regs *regs)
385385
struct perf_event *bp;
386386

387387
/* Disable hardware debugging while we are in kgdb: */
388-
set_debugreg(0UL, 7);
388+
set_debugreg(DR7_FIXED_1, 7);
389389
for (i = 0; i < HBP_NUM; i++) {
390390
if (!breakinfo[i].enabled)
391391
continue;

arch/x86/kernel/process_32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
9393

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

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

arch/x86/kernel/process_64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
132132

133133
/* Only print out debug registers if they are in their non-default state. */
134134
if (!((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) &&
135-
(d6 == DR6_RESERVED) && (d7 == 0x400))) {
135+
(d6 == DR6_RESERVED) && (d7 == DR7_FIXED_1))) {
136136
printk("%sDR0: %016lx DR1: %016lx DR2: %016lx\n",
137137
log_lvl, d0, d1, d2);
138138
printk("%sDR3: %016lx DR6: %016lx DR7: %016lx\n",

arch/x86/kvm/x86.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11045,7 +11045,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
1104511045

1104611046
if (unlikely(vcpu->arch.switch_db_regs &&
1104711047
!(vcpu->arch.switch_db_regs & KVM_DEBUGREG_AUTO_SWITCH))) {
11048-
set_debugreg(0, 7);
11048+
set_debugreg(DR7_FIXED_1, 7);
1104911049
set_debugreg(vcpu->arch.eff_db[0], 0);
1105011050
set_debugreg(vcpu->arch.eff_db[1], 1);
1105111051
set_debugreg(vcpu->arch.eff_db[2], 2);
@@ -11054,7 +11054,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
1105411054
if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT))
1105511055
run_flags |= KVM_RUN_LOAD_GUEST_DR6;
1105611056
} else if (unlikely(hw_breakpoint_active())) {
11057-
set_debugreg(0, 7);
11057+
set_debugreg(DR7_FIXED_1, 7);
1105811058
}
1105911059

1106011060
/*

0 commit comments

Comments
 (0)