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

[Xen-changelog] [xen-unstable] mem_event: Allow memory access listener to perform single step execution.



# HG changeset patch
# User Aravindh Puthiyaparambil <aravindh@xxxxxxxxxxxx>
# Date 1306518266 -3600
# Node ID ef410f262299d45017c42f36194600a35263404a
# Parent  964b022e336dddf0e94cc05d84baa65c44d743cd
mem_event: Allow memory access listener to perform single step execution.

Add a new memory event that handles single step. This allows the
memory access listener to handle instructions that modify data within
the execution page.  This can be enabled in the listener by doing:
xc_set_hvm_param(xch, domain_id, HVM_PARAM_MEMORY_EVENT_SINGLE_STEP,
HVMPME_mode_sync)

Now the listener can start single stepping by:
xc_domain_debug_control(xch, domain_id,
XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON, vcpu_id)

And stop single stepping by: xc_domain_debug_control(xch, domain_id,
XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF, vcpu_id)

Signed-off-by: Aravindh Puthiyaparambil <aravindh@xxxxxxxxxxxx>
Acked-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
---


diff -r 964b022e336d -r ef410f262299 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri May 27 18:41:12 2011 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Fri May 27 18:44:26 2011 +0100
@@ -3510,7 +3510,8 @@
                     rc = -EPERM;
                 break;
             case HVM_PARAM_MEMORY_EVENT_INT3:
-                if ( d == current->domain ) 
+            case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP:
+                if ( d == current->domain )
                 {
                     rc = -EPERM;
                     break;
@@ -3543,6 +3544,7 @@
                 switch( a.index )
                 {
                 case HVM_PARAM_MEMORY_EVENT_INT3:
+                case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP:
                 {
                     domain_pause(d);
                     domain_unpause(d); /* Causes guest to latch new status */
@@ -4066,11 +4068,21 @@
             rc = -ENOSYS;
             if ( !cpu_has_monitor_trap_flag )
                 break;
-            rc = 0;
-            vcpu_pause(v);
+
+            rc = mem_event_check_ring(v->domain);
+            /* rc ==0 p2m_mem_access_check() has already paused the vcpu */
+            if ( rc < 0 )
+                vcpu_pause(v);
+
             v->arch.hvm_vcpu.single_step =
                 (op == XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON);
-            vcpu_unpause(v); /* guest will latch new state */
+
+            /* rc ==0 p2m_mem_access_resume() will unpause the vcpu */
+            if ( rc < 0 )
+            {
+                vcpu_unpause(v); /* guest will latch new state */
+                rc = 0;
+            }
             break;
         default:
             rc = -ENOSYS;
@@ -4159,6 +4171,18 @@
                                   MEM_EVENT_REASON_INT3,
                                   gfn, 0, 1, gla);
 }
+
+int hvm_memory_event_single_step(unsigned long gla)
+{
+    uint32_t pfec = PFEC_page_present;
+    unsigned long gfn;
+    gfn = paging_gva_to_gfn(current, gla, &pfec);
+
+    return hvm_memory_event_traps(current->domain->arch.hvm_domain
+            .params[HVM_PARAM_MEMORY_EVENT_SINGLE_STEP],
+            MEM_EVENT_REASON_SINGLESTEP,
+            gfn, 0, 1, gla);
+}
 #endif /* __x86_64__ */
 
 int nhvm_vcpu_hostrestore(struct vcpu *v, struct cpu_user_regs *regs)
diff -r 964b022e336d -r ef410f262299 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Fri May 27 18:41:12 2011 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Fri May 27 18:44:26 2011 +0100
@@ -1081,8 +1081,9 @@
         hvm_asid_flush_vcpu(v);
     }
 
-    debug_state = v->domain->debugger_attached 
-                  || 
v->domain->arch.hvm_domain.params[HVM_PARAM_MEMORY_EVENT_INT3];
+    debug_state = v->domain->debugger_attached
+                  || 
v->domain->arch.hvm_domain.params[HVM_PARAM_MEMORY_EVENT_INT3]
+                  || 
v->domain->arch.hvm_domain.params[HVM_PARAM_MEMORY_EVENT_SINGLE_STEP];
 
     if ( unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) )
     {
diff -r 964b022e336d -r ef410f262299 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Fri May 27 18:41:12 2011 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri May 27 18:44:26 2011 +0100
@@ -2494,8 +2494,12 @@
     case EXIT_REASON_MONITOR_TRAP_FLAG:
         v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG;
         vmx_update_cpu_exec_control(v);
-        if ( v->domain->debugger_attached && v->arch.hvm_vcpu.single_step )
-            domain_pause_for_debugger();
+        if ( v->arch.hvm_vcpu.single_step ) {
+          hvm_memory_event_single_step(regs->eip);
+          if ( v->domain->debugger_attached )
+              domain_pause_for_debugger();
+        }
+
         break;
 
     case EXIT_REASON_PAUSE_INSTRUCTION:
diff -r 964b022e336d -r ef410f262299 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Fri May 27 18:41:12 2011 +0100
+++ b/xen/include/asm-x86/hvm/hvm.h     Fri May 27 18:44:26 2011 +0100
@@ -414,6 +414,10 @@
 void hvm_memory_event_cr4(unsigned long value, unsigned long old);
 /* Called for current VCPU on int3: returns -1 if no listener */
 int hvm_memory_event_int3(unsigned long gla);
+
+/* Called for current VCPU on single step: returns -1 if no listener */
+int hvm_memory_event_single_step(unsigned long gla);
+
 #else
 static inline void hvm_memory_event_cr0(unsigned long value, unsigned long old)
 { }
@@ -423,6 +427,8 @@
 { }
 static inline int hvm_memory_event_int3(unsigned long gla)
 { return 0; }
+static inline int hvm_memory_event_single_step(unsigned long gla)
+{ return 0; }
 #endif
 
 /*
diff -r 964b022e336d -r ef410f262299 xen/include/public/hvm/params.h
--- a/xen/include/public/hvm/params.h   Fri May 27 18:41:12 2011 +0100
+++ b/xen/include/public/hvm/params.h   Fri May 27 18:44:26 2011 +0100
@@ -126,10 +126,11 @@
 
 /* Enable blocking memory events, async or sync (pause vcpu until response) 
  * onchangeonly indicates messages only on a change of value */
-#define HVM_PARAM_MEMORY_EVENT_CR0   20
-#define HVM_PARAM_MEMORY_EVENT_CR3   21
-#define HVM_PARAM_MEMORY_EVENT_CR4   22
-#define HVM_PARAM_MEMORY_EVENT_INT3  23
+#define HVM_PARAM_MEMORY_EVENT_CR0          20
+#define HVM_PARAM_MEMORY_EVENT_CR3          21
+#define HVM_PARAM_MEMORY_EVENT_CR4          22
+#define HVM_PARAM_MEMORY_EVENT_INT3         23
+#define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP  25
 
 #define HVMPME_MODE_MASK       (3 << 0)
 #define HVMPME_mode_disabled   0
@@ -140,6 +141,6 @@
 /* Boolean: Enable nestedhvm (hvm only) */
 #define HVM_PARAM_NESTEDHVM    24
 
-#define HVM_NR_PARAMS          25
+#define HVM_NR_PARAMS          26
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
diff -r 964b022e336d -r ef410f262299 xen/include/public/mem_event.h
--- a/xen/include/public/mem_event.h    Fri May 27 18:41:12 2011 +0100
+++ b/xen/include/public/mem_event.h    Fri May 27 18:44:26 2011 +0100
@@ -46,6 +46,7 @@
 #define MEM_EVENT_REASON_CR3         3    /* CR3 was hit: gfn is CR3 value */
 #define MEM_EVENT_REASON_CR4         4    /* CR4 was hit: gfn is CR4 value */
 #define MEM_EVENT_REASON_INT3        5    /* int3 was hit: gla/gfn are RIP */
+#define MEM_EVENT_REASON_SINGLESTEP  6    /* single step was invoked: gla/gfn 
are RIP */
 
 typedef struct mem_event_shared_page {
     uint32_t port;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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