diff mbox series

[5/6] x86/pv: factor out single-step debug trap injection

Message ID 5c1cd2ca-880a-72d4-e586-3d0838adf8eb@gmail.com (mailing list archive)
State New, archived
Headers show
Series x86/debug: fix guest dr6 value for single stepping and HW breakpoints | expand

Commit Message

Jinoh Kang Aug. 18, 2023, 3:47 p.m. UTC
Add pv_inject_debug_exception() helper and use it wherever
applicable.

This helper corresponds to hvm_inject_debug_exception() in HVM.

Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
---
 xen/arch/x86/include/asm/domain.h | 12 ++++++++++++
 xen/arch/x86/pv/emulate.c         |  5 +----
 xen/arch/x86/pv/ro-page-fault.c   |  5 +----
 xen/arch/x86/pv/traps.c           | 10 ++++++++++
 4 files changed, 24 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/xen/arch/x86/include/asm/domain.h b/xen/arch/x86/include/asm/domain.h
index 0e445cff5c08..cfeb63da6cd6 100644
--- a/xen/arch/x86/include/asm/domain.h
+++ b/xen/arch/x86/include/asm/domain.h
@@ -741,6 +741,18 @@  static inline void pv_inject_page_fault(int errcode, unsigned long cr2)
     pv_inject_event(&event);
 }
 
+static inline void pv_inject_debug_exception(unsigned long pending_dbg)
+{
+    const struct x86_event event = {
+        .vector = X86_EXC_DB,
+        .type = X86_EVENTTYPE_HW_EXCEPTION,
+        .error_code = X86_EVENT_NO_EC,
+        .extra = pending_dbg,
+    };
+
+    pv_inject_event(&event);
+}
+
 static inline void pv_inject_sw_interrupt(unsigned int vector)
 {
     const struct x86_event event = {
diff --git a/xen/arch/x86/pv/emulate.c b/xen/arch/x86/pv/emulate.c
index e7a1c0a2cc4f..865b05337192 100644
--- a/xen/arch/x86/pv/emulate.c
+++ b/xen/arch/x86/pv/emulate.c
@@ -72,10 +72,7 @@  void pv_emul_instruction_done(struct cpu_user_regs *regs, unsigned long rip)
     regs->rip = rip;
     regs->eflags &= ~X86_EFLAGS_RF;
     if ( regs->eflags & X86_EFLAGS_TF )
-    {
-        current->arch.dr6 |= DR_STEP | DR_STATUS_RESERVED_ONE;
-        pv_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC);
-    }
+        pv_inject_debug_exception(DR_STEP);
 }
 
 uint64_t pv_get_reg(struct vcpu *v, unsigned int reg)
diff --git a/xen/arch/x86/pv/ro-page-fault.c b/xen/arch/x86/pv/ro-page-fault.c
index 238bfbeb4ac4..9c6042cab3b2 100644
--- a/xen/arch/x86/pv/ro-page-fault.c
+++ b/xen/arch/x86/pv/ro-page-fault.c
@@ -391,10 +391,7 @@  int pv_ro_page_fault(unsigned long addr, struct cpu_user_regs *regs)
         /* Fallthrough */
     case X86EMUL_OKAY:
         if ( ctxt.retire.singlestep )
-        {
-            current->arch.dr6 |= DR_STEP | DR_STATUS_RESERVED_ONE;
-            pv_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC);
-        }
+            pv_inject_debug_exception(DR_STEP);
 
         /* Fallthrough */
     case X86EMUL_RETRY:
diff --git a/xen/arch/x86/pv/traps.c b/xen/arch/x86/pv/traps.c
index e5c9734b8204..4cf31558ac2f 100644
--- a/xen/arch/x86/pv/traps.c
+++ b/xen/arch/x86/pv/traps.c
@@ -15,6 +15,7 @@ 
 #include <asm/pv/trace.h>
 #include <asm/shared.h>
 #include <asm/traps.h>
+#include <asm/debugreg.h>
 #include <irq_vectors.h>
 
 void pv_inject_event(const struct x86_event *event)
@@ -64,7 +65,16 @@  void pv_inject_event(const struct x86_event *event)
         trace_pv_page_fault(event->extra, error_code);
     }
     else
+    {
+        if ( event->type == X86_EVENTTYPE_HW_EXCEPTION &&
+             vector == X86_EXC_DB )
+        {
+            if ( event->extra )
+                curr->arch.dr6 |= event->extra | DR_STATUS_RESERVED_ONE;
+        }
+
         trace_pv_trap(vector, regs->rip, use_error_code, error_code);
+    }
 
     if ( use_error_code )
     {