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

[Xen-changelog] [xen master] x86/debug: Plumb pending_dbg through the monitor and devicemodel interfaces



commit 21867648033df025129eca9bbcfdbd0310d13562
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Thu May 31 18:50:50 2018 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Dec 27 16:37:42 2019 +0000

    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.  This shall behave like the VT-x PENDING_DBG control.  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>
    Acked-by: Tamas K Lengyel <tamas@xxxxxxxxxxxxx>
    Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Petre Pircalabu <ppircalabu@xxxxxxxxxxxxxxx>
---
 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..1ab4f6705f 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 0x%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 85996a3edd..f5d89e71d1 100644
--- a/xen/arch/x86/hvm/monitor.c
+++ b/xen/arch/x86/hvm/monitor.c
@@ -133,7 +133,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
@@ -178,6 +179,7 @@ int hvm_monitor_debug(unsigned long rip, enum 
hvm_monitor_debug_type type,
             return 0;
         req.reason = VM_EVENT_REASON_DEBUG_EXCEPTION;
         req.u.debug_exception.gfn = gfn_of_rip(rip);
+        req.u.debug_exception.pending_dbg = pending_dbg;
         req.u.debug_exception.type = trap_type;
         req.u.debug_exception.insn_length = insn_length;
         sync = !!ad->monitor.debug_exception_sync;
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index fb2677b9a6..b1c376d455 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -2644,7 +2644,7 @@ void svm_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 unexpected_exit_type;
             if ( !rc )
@@ -2673,7 +2673,7 @@ void svm_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 unexpected_exit_type;
            if ( !rc )
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 56733b72b5..f83f102638 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -3872,7 +3872,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;
@@ -3893,7 +3893,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;
@@ -4196,7 +4196,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 0ffec27d62..fdd3ad8a30 100644
--- a/xen/include/public/vm_event.h
+++ b/xen/include/public/vm_event.h
@@ -291,6 +291,7 @@ struct vm_event_fast_singlestep {
 
 struct vm_event_debug {
     uint64_t gfn;
+    uint64_t pending_dbg; /* Behaves like the VT-x PENDING_DBG field. */
     uint32_t insn_length;
     uint8_t type;        /* HVMOP_TRAP_* */
     uint8_t _pad[3];
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

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