public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH] x86/debug: Fix macro definitions for DR7 local/global enable bits
@ 2025-11-26 19:17 Sean Christopherson
  2025-12-11 16:41 ` Sean Christopherson
  0 siblings, 1 reply; 2+ messages in thread
From: Sean Christopherson @ 2025-11-26 19:17 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson

Fix the shifts for the DR7 local/global enable bits.  As called out by the
comment, the local/global enable bits have a stride of 2, i.e. use every
other bit.

Use DR2 instead of DR0 in the debug test to create a data breakpoint to
demonstrate that using something other than DR0 actually works.

Fixes: f1dcfd54 ("x86: Overhaul definitions for DR6 and DR7 bits")
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 lib/x86/asm/debugreg.h |  5 +++--
 x86/debug.c            | 22 +++++++++++++---------
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/lib/x86/asm/debugreg.h b/lib/x86/asm/debugreg.h
index a30f9493..47c90ebf 100644
--- a/lib/x86/asm/debugreg.h
+++ b/lib/x86/asm/debugreg.h
@@ -37,8 +37,9 @@
  * by the CPU on task switch), bits 1, 3, 5, and 7 are global enable bits
  * (never cleared by the CPU).
  */
-#define DR7_LOCAL_ENABLE_DRx(x)		(BIT(0) << (x))
-#define DR7_GLOBAL_ENABLE_DRx(x)	(BIT(1) << (x))
+#define DR7_LOCAL_ENABLE_DRx(x)		(BIT(0) << ((x) * 2))
+#define DR7_GLOBAL_ENABLE_DRx(x)	(BIT(1) << ((x) * 2))
+
 #define DR7_ENABLE_DRx(x) \
 	(DR7_LOCAL_ENABLE_DRx(x) | DR7_GLOBAL_ENABLE_DRx(x))
 
diff --git a/x86/debug.c b/x86/debug.c
index 09f06ef5..1a4ee5c8 100644
--- a/x86/debug.c
+++ b/x86/debug.c
@@ -38,7 +38,7 @@ static void handle_db(struct ex_regs *regs)
 	db_addr[n] = regs->rip;
 	dr6[n] = read_dr6();
 
-	if (dr6[n] & 0x1)
+	if (dr6[n] & DR6_TRAP2)
 		regs->rflags |= X86_EFLAGS_RF;
 
 	if (++n >= 10) {
@@ -488,29 +488,33 @@ int main(int ac, char **av)
 	 * The CPU sets/clears bits 0-3 (trap bits for DR0-3) on #DB based on
 	 * whether or not the corresponding DR0-3 got a match.  All other bits
 	 * in DR6 are set if and only if their associated breakpoint condition
-	 * is active, and are never cleared by the CPU.  Verify a match on DR0
+	 * is active, and are never cleared by the CPU.  Verify a match on DR2
 	 * is reported correctly, and that DR6.BS is not set when single-step
 	 * breakpoints are disabled, but is left set (if set by software).
 	 */
 	n = 0;
 	extern unsigned char hw_bp1;
-	write_dr0(&hw_bp1);
-	write_dr7(DR7_FIXED_1 | DR7_GLOBAL_ENABLE_DR0);
+	write_dr2(&hw_bp1);
+	write_dr7(DR7_FIXED_1 | DR7_GLOBAL_ENABLE_DR2);
 	asm volatile("hw_bp1: nop");
 	report(n == 1 &&
 	       db_addr[0] == ((unsigned long)&hw_bp1) &&
-	       dr6[0] == (DR6_ACTIVE_LOW | DR6_TRAP0),
-	       "hw breakpoint (test that dr6.BS is not set)");
+	       dr6[0] == (DR6_ACTIVE_LOW | DR6_TRAP2),
+	       "Wanted #DB on 0x%lx w/ DR6 = 0x%lx, got %u #DBs, addr[0] = 0x%lx, DR6 = 0x%lx",
+	       ((unsigned long)&hw_bp1), DR6_ACTIVE_LOW | DR6_TRAP2,
+	       n, db_addr[0], dr6[0]);
 
 	n = 0;
 	extern unsigned char hw_bp2;
-	write_dr0(&hw_bp2);
+	write_dr2(&hw_bp2);
 	write_dr6(DR6_BS | DR6_TRAP1);
 	asm volatile("hw_bp2: nop");
 	report(n == 1 &&
 	       db_addr[0] == ((unsigned long)&hw_bp2) &&
-	       dr6[0] == (DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP0),
-	       "hw breakpoint (test that dr6.BS is not cleared)");
+	       dr6[0] == (DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP2),
+	       "Wanted #DB on 0x%lx w/ DR6 = 0x%lx, got %u #DBs, addr[0] = 0x%lx, DR6 = 0x%lx",
+	       ((unsigned long)&hw_bp1), DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP2,
+	       n, db_addr[0], dr6[0]);
 
 	run_ss_db_test(singlestep_basic);
 	run_ss_db_test(singlestep_emulated_instructions);

base-commit: d2dc9294e25a34110feffb497a29c10f7e2a8ceb
-- 
2.52.0.487.g5c8c507ade-goog


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [kvm-unit-tests PATCH] x86/debug: Fix macro definitions for DR7 local/global enable bits
  2025-11-26 19:17 [kvm-unit-tests PATCH] x86/debug: Fix macro definitions for DR7 local/global enable bits Sean Christopherson
@ 2025-12-11 16:41 ` Sean Christopherson
  0 siblings, 0 replies; 2+ messages in thread
From: Sean Christopherson @ 2025-12-11 16:41 UTC (permalink / raw)
  To: Paolo Bonzini, kvm

On Wed, Nov 26, 2025, Sean Christopherson wrote:
>  	n = 0;
>  	extern unsigned char hw_bp2;
> -	write_dr0(&hw_bp2);
> +	write_dr2(&hw_bp2);
>  	write_dr6(DR6_BS | DR6_TRAP1);
>  	asm volatile("hw_bp2: nop");
>  	report(n == 1 &&
>  	       db_addr[0] == ((unsigned long)&hw_bp2) &&
> -	       dr6[0] == (DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP0),
> -	       "hw breakpoint (test that dr6.BS is not cleared)");
> +	       dr6[0] == (DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP2),
> +	       "Wanted #DB on 0x%lx w/ DR6 = 0x%lx, got %u #DBs, addr[0] = 0x%lx, DR6 = 0x%lx",
> +	       ((unsigned long)&hw_bp1), DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP2,

Copy+paste fail, this should be hw_bp2.

> +	       n, db_addr[0], dr6[0]);
>  
>  	run_ss_db_test(singlestep_basic);
>  	run_ss_db_test(singlestep_emulated_instructions);
> 
> base-commit: d2dc9294e25a34110feffb497a29c10f7e2a8ceb
> -- 
> 2.52.0.487.g5c8c507ade-goog
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-12-11 16:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-26 19:17 [kvm-unit-tests PATCH] x86/debug: Fix macro definitions for DR7 local/global enable bits Sean Christopherson
2025-12-11 16:41 ` Sean Christopherson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox