[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] x86/debug: Plumb pending_dbg through the monitor and devicemodel interfaces



Like %cr2 for pagefaults, %dr6 contains ancillary information for debug
exceptions, and needs similar handling.

For xendevicemodel_inject_event(), no ABI change is needed (although an API
one would be ideal).  Switch from 'cr2' to 'extra' in variable names which
don't constitute an API change, and update the documentation to match.

For the monitor interface, vm_event_debug needs extending with a pending_dbg
field.  Extend hvm_monitor_debug() and for now, always pass in 0 - this will
be fixed eventually, when other hypervisor bugfixes are complete.

While modifying hvm_monitor_debug(), take the opportunity to correct trap type
and instruction length from unsigned long to unsigned int, as they are both
tiny values.

Finally, adjust xen-access.c to the new expectations.  Introspection tools
intercepting debug exceptions should mirror the new pending_dbg field into
xendevicemodel_inject_event() for %dr6 to be processed correctly for the
guest.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx>
CC: Tamas K Lengyel <tamas@xxxxxxxxxxxxx>
CC: Alexandru Isaila <aisaila@xxxxxxxxxxxxxxx>
CC: Petre Pircalabu <ppircalabu@xxxxxxxxxxxxxxx>
CC: Ian Jackson <Ian.Jackson@xxxxxxxxxx>

I'm expecting to commit this alongside "x86/svm: Correct vm_event API for
descriptor accesses" which covers the bump of the VM_EVENT interface version.
---
 tools/libs/devicemodel/core.c                   | 4 ++--
 tools/libs/devicemodel/include/xendevicemodel.h | 4 ++--
 tools/tests/xen-access/xen-access.c             | 7 ++++---
 xen/arch/x86/hvm/monitor.c                      | 4 +++-
 xen/arch/x86/hvm/svm/svm.c                      | 4 ++--
 xen/arch/x86/hvm/vmx/vmx.c                      | 6 +++---
 xen/include/asm-x86/hvm/monitor.h               | 3 ++-
 xen/include/public/hvm/dm_op.h                  | 2 +-
 xen/include/public/vm_event.h                   | 1 +
 9 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c
index f76e3d305e..db501d9e80 100644
--- a/tools/libs/devicemodel/core.c
+++ b/tools/libs/devicemodel/core.c
@@ -536,7 +536,7 @@ int xendevicemodel_set_mem_type(
 
 int xendevicemodel_inject_event(
     xendevicemodel_handle *dmod, domid_t domid, int vcpu, uint8_t vector,
-    uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t cr2)
+    uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t extra)
 {
     struct xen_dm_op op;
     struct xen_dm_op_inject_event *data;
@@ -551,7 +551,7 @@ int xendevicemodel_inject_event(
     data->type = type;
     data->error_code = error_code;
     data->insn_len = insn_len;
-    data->cr2 = cr2;
+    data->cr2 = extra;
 
     return xendevicemodel_op(dmod, domid, 1, &op, sizeof(op));
 }
diff --git a/tools/libs/devicemodel/include/xendevicemodel.h 
b/tools/libs/devicemodel/include/xendevicemodel.h
index 08cb0d4374..e877f5c8a6 100644
--- a/tools/libs/devicemodel/include/xendevicemodel.h
+++ b/tools/libs/devicemodel/include/xendevicemodel.h
@@ -309,12 +309,12 @@ int xendevicemodel_set_mem_type(
  * @parm type the event type (see the definition of enum x86_event_type)
  * @parm error_code the error code or ~0 to skip
  * @parm insn_len the instruction length
- * @parm cr2 the value of CR2 for page faults
+ * @parm extra type-specific extra data (%cr2 for #PF, pending_dbg for #DB)
  * @return 0 on success, -1 on failure.
  */
 int xendevicemodel_inject_event(
     xendevicemodel_handle *dmod, domid_t domid, int vcpu, uint8_t vector,
-    uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t cr2);
+    uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t extra);
 
 /**
  * Shuts the domain down.
diff --git a/tools/tests/xen-access/xen-access.c 
b/tools/tests/xen-access/xen-access.c
index 6aaee16d67..044a3a3c57 100644
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -826,18 +826,19 @@ int main(int argc, char *argv[])
 
                 break;
             case VM_EVENT_REASON_DEBUG_EXCEPTION:
-                printf("Debug exception: rip=%016"PRIx64", vcpu %d. Type: %u. 
Length: %u\n",
+                printf("Debug exception: rip=%016"PRIx64", vcpu %d. Type: %u. 
Length: %u. Pending dbg %08"PRIx64"\n",
                        req.data.regs.x86.rip,
                        req.vcpu_id,
                        req.u.debug_exception.type,
-                       req.u.debug_exception.insn_length);
+                       req.u.debug_exception.insn_length,
+                       req.u.debug_exception.pending_dbg);
 
                 /* Reinject */
                 rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id,
                                         X86_TRAP_DEBUG,
                                         req.u.debug_exception.type, -1,
                                         req.u.debug_exception.insn_length,
-                                        req.data.regs.x86.cr2);
+                                        req.u.debug_exception.pending_dbg);
                 if (rc < 0)
                 {
                     ERROR("Error %d injecting breakpoint\n", rc);
diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c
index 7fb1e2c04e..e7fb9f4254 100644
--- a/xen/arch/x86/hvm/monitor.c
+++ b/xen/arch/x86/hvm/monitor.c
@@ -136,7 +136,8 @@ static inline unsigned long gfn_of_rip(unsigned long rip)
 }
 
 int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
-                      unsigned long trap_type, unsigned long insn_length)
+                      unsigned int trap_type, unsigned int insn_length,
+                      unsigned int pending_dbg)
 {
    /*
     * rc < 0 error in monitor/vm_event, crash
@@ -175,6 +176,7 @@ int hvm_monitor_debug(unsigned long rip, enum 
hvm_monitor_debug_type type,
         req.u.debug_exception.gfn = gfn_of_rip(rip);
         req.u.debug_exception.type = trap_type;
         req.u.debug_exception.insn_length = insn_length;
+        req.u.debug_exception.pending_dbg = pending_dbg;
         sync = !!ad->monitor.debug_exception_sync;
         break;
 
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 0fb1908c18..72b1dcbf54 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -2649,7 +2649,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
 
             rc = hvm_monitor_debug(regs->rip,
                                    HVM_MONITOR_DEBUG_EXCEPTION,
-                                   trap_type, inst_len);
+                                   trap_type, inst_len, 0);
             if ( rc < 0 )
                 goto unexpected_exit_type;
             if ( !rc )
@@ -2680,7 +2680,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
            rc = hvm_monitor_debug(regs->rip,
                                   HVM_MONITOR_SOFTWARE_BREAKPOINT,
                                   X86_EVENTTYPE_SW_EXCEPTION,
-                                  inst_len);
+                                  inst_len, 0);
            if ( rc < 0 )
                goto unexpected_exit_type;
            if ( !rc )
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 7450cbe40d..39efd91991 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -3834,7 +3834,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
 
                 rc = hvm_monitor_debug(regs->rip,
                                        HVM_MONITOR_DEBUG_EXCEPTION,
-                                       trap_type, insn_len);
+                                       trap_type, insn_len, 0);
 
                 if ( rc < 0 )
                     goto exit_and_crash;
@@ -3855,7 +3855,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
                 rc = hvm_monitor_debug(regs->rip,
                                        HVM_MONITOR_SOFTWARE_BREAKPOINT,
                                        X86_EVENTTYPE_SW_EXCEPTION,
-                                       insn_len);
+                                       insn_len, 0);
 
                 if ( rc < 0 )
                     goto exit_and_crash;
@@ -4157,7 +4157,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
         {
             hvm_monitor_debug(regs->rip,
                               HVM_MONITOR_SINGLESTEP_BREAKPOINT,
-                              0, 0);
+                              0, 0, 0);
 
             if ( v->domain->debugger_attached )
                 domain_pause_for_debugger();
diff --git a/xen/include/asm-x86/hvm/monitor.h 
b/xen/include/asm-x86/hvm/monitor.h
index 325b44674d..66de24cb75 100644
--- a/xen/include/asm-x86/hvm/monitor.h
+++ b/xen/include/asm-x86/hvm/monitor.h
@@ -42,7 +42,8 @@ void hvm_monitor_descriptor_access(uint64_t exit_info,
                                    uint64_t vmx_exit_qualification,
                                    uint8_t descriptor, bool is_write);
 int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
-                      unsigned long trap_type, unsigned long insn_length);
+                      unsigned int trap_type, unsigned int insn_length,
+                      unsigned int pending_dbg);
 int hvm_monitor_cpuid(unsigned long insn_length, unsigned int leaf,
                       unsigned int subleaf);
 void hvm_monitor_interrupt(unsigned int vector, unsigned int type,
diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h
index d3b554d019..fd00e9d761 100644
--- a/xen/include/public/hvm/dm_op.h
+++ b/xen/include/public/hvm/dm_op.h
@@ -324,7 +324,7 @@ struct xen_dm_op_inject_event {
     /* IN - error code (or ~0 to skip) */
     uint32_t error_code;
     uint32_t pad1;
-    /* IN - CR2 for page faults */
+    /* IN - type-specific extra data (%cr2 for #PF, pending_dbg for #DB) */
     uint64_aligned_t cr2;
 };
 
diff --git a/xen/include/public/vm_event.h b/xen/include/public/vm_event.h
index 959083d8c4..76676ff4c0 100644
--- a/xen/include/public/vm_event.h
+++ b/xen/include/public/vm_event.h
@@ -281,6 +281,7 @@ struct vm_event_debug {
     uint32_t insn_length;
     uint8_t type;        /* HVMOP_TRAP_* */
     uint8_t _pad[3];
+    uint64_t pending_dbg;
 };
 
 struct vm_event_mov_to_msr {
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.