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

[Xen-devel] [PATCH 2/2] xen: Introduce VM_EVENT_FLAG_SET_EIP



A previous version of this patch dealing with support for skipping
the current instruction when a vm_event response requested it
computed the instruction length in the hypervisor, adding non-trivial
code dependencies. This patch allows a userspace vm_event client to
simply request that the guest's EIP is set to an arbitary value,
computed by the introspection application.

Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx>
---
 xen/arch/x86/mm/p2m.c          |   25 ++++++++++++++++---------
 xen/include/asm-x86/vm_event.h |    1 +
 xen/include/public/vm_event.h  |    5 +++++
 3 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index c4329d2..ef45b15 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1596,6 +1596,8 @@ void p2m_mem_access_emulate_check(struct vcpu *v,
 
         if ( (rsp->flags & VM_EVENT_FLAG_SET_EMUL_READ_DATA) )
             v->arch.vm_event->emul_read_data = rsp->data.emul_read_data;
+        else if ( (rsp->flags & VM_EVENT_FLAG_SET_EIP) )
+            v->arch.vm_event->set_eip = rsp->data.regs.x86.rip;
     }
 }
 
@@ -1694,17 +1696,22 @@ bool_t p2m_mem_access_check(paddr_t gpa, unsigned long 
gla,
 
     if ( unlikely(v->arch.vm_event) && v->arch.vm_event->emulate_flags )
     {
-        enum emul_kind kind = EMUL_KIND_NORMAL;
+        if ( v->arch.vm_event->emulate_flags & VM_EVENT_FLAG_SET_EIP )
+            guest_cpu_user_regs()->eip = v->arch.vm_event->set_eip;
+        else
+        {
+            enum emul_kind kind = EMUL_KIND_NORMAL;
 
-        if ( v->arch.vm_event->emulate_flags &
-             VM_EVENT_FLAG_SET_EMUL_READ_DATA )
-            kind = EMUL_KIND_SET_CONTEXT;
-        else if ( v->arch.vm_event->emulate_flags &
-                  VM_EVENT_FLAG_EMULATE_NOWRITE )
-            kind = EMUL_KIND_NOWRITE;
+            if ( v->arch.vm_event->emulate_flags &
+                 VM_EVENT_FLAG_SET_EMUL_READ_DATA )
+                kind = EMUL_KIND_SET_CONTEXT;
+            else if ( v->arch.vm_event->emulate_flags &
+                      VM_EVENT_FLAG_EMULATE_NOWRITE )
+                kind = EMUL_KIND_NOWRITE;
 
-        hvm_mem_access_emulate_one(kind, TRAP_invalid_op,
-                                   HVM_DELIVER_NO_ERROR_CODE);
+            hvm_mem_access_emulate_one(kind, TRAP_invalid_op,
+                                       HVM_DELIVER_NO_ERROR_CODE);
+        }
 
         v->arch.vm_event->emulate_flags = 0;
         return 1;
diff --git a/xen/include/asm-x86/vm_event.h b/xen/include/asm-x86/vm_event.h
index 2ff2cab..310fc5a 100644
--- a/xen/include/asm-x86/vm_event.h
+++ b/xen/include/asm-x86/vm_event.h
@@ -30,6 +30,7 @@ struct arch_vm_event {
     uint32_t emulate_flags;
     unsigned long gpa;
     unsigned long eip;
+    unsigned long set_eip;
     struct vm_event_emul_read_data emul_read_data;
     struct monitor_write_data write_data;
 };
diff --git a/xen/include/public/vm_event.h b/xen/include/public/vm_event.h
index ff2f217..0109bdf 100644
--- a/xen/include/public/vm_event.h
+++ b/xen/include/public/vm_event.h
@@ -89,6 +89,11 @@
  * by the altp2m_idx response field if possible.
  */
 #define VM_EVENT_FLAG_ALTERNATE_P2M      (1 << 7)
+/*
+ * Move the guest's instruction pointer to data.regs.x86.rip from the vm_event
+ * response.
+ */
+#define VM_EVENT_FLAG_SET_EIP            (1 << 8)
 
 /*
  * Reasons for the vm event request
-- 
1.7.9.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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