]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/xen.git/commitdiff
x86/hvm: simplify emulation triggered by vm_event response
authorRazvan Cojocaru <rcojocaru@bitdefender.com>
Tue, 9 Feb 2016 12:20:49 +0000 (13:20 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 9 Feb 2016 12:20:49 +0000 (13:20 +0100)
Currently, after receiving a vm_event reply requesting emulation,
the actual emulation is triggered in p2m_mem_access_check(),
which means that we're waiting for the page fault to occur again
before emulating. Aside from the performance impact, this
complicates the code since between hvm_do_resume() and the second
page fault it is possible that the latter becomes a completely
new page fault - hence checking that EIP and the GPA match with
the ones in the original page fault. If they don't, duplicate
EPT fault vm_events will occur, of which a monitoring application
needs to be aware.
This patch makes struct arch_vm_event smaller (since we no longer
need to track eip and gpa), removes the checking code from
p2m_mem_access_check(), and moves the emulation in hvm_do_resume().

Signed-off-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Tamas K Lengyel <tamas@tklengyel.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/mm/p2m.c
xen/include/asm-x86/vm_event.h

index 35ec6c95e7926cf6ff2bf988a289aa8d52df6507..930d0e3431e4c551db00a72f3bcd295f7b19f38f 100644 (file)
@@ -552,6 +552,23 @@ void hvm_do_resume(struct vcpu *v)
     {
         struct monitor_write_data *w = &v->arch.vm_event->write_data;
 
+        if ( v->arch.vm_event->emulate_flags )
+        {
+            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;
+
+            hvm_mem_access_emulate_one(kind, TRAP_invalid_op,
+                                       HVM_DELIVER_NO_ERROR_CODE);
+
+            v->arch.vm_event->emulate_flags = 0;
+        }
+
         if ( w->do_write.msr )
         {
             hvm_msr_write_intercept(w->msr, w->value, 0);
index a45ee3535005c24588c9b6f4098836e0fca435c1..47e7fadb513f95e03ab66054bff59c1cf0944e16 100644 (file)
@@ -1639,7 +1639,6 @@ bool_t p2m_mem_access_check(paddr_t gpa, unsigned long gla,
     p2m_access_t p2ma;
     vm_event_request_t *req;
     int rc;
-    unsigned long eip = guest_cpu_user_regs()->eip;
 
     if ( altp2m_active(d) )
         p2m = p2m_get_altp2m(v);
@@ -1698,39 +1697,6 @@ bool_t p2m_mem_access_check(paddr_t gpa, unsigned long gla,
         }
     }
 
-    /* The previous vm_event reply does not match the current state. */
-    if ( unlikely(v->arch.vm_event) &&
-         (v->arch.vm_event->gpa != gpa || v->arch.vm_event->eip != eip) )
-    {
-        /* Don't emulate the current instruction, send a new vm_event. */
-        v->arch.vm_event->emulate_flags = 0;
-
-        /*
-         * Make sure to mark the current state to match it again against
-         * the new vm_event about to be sent.
-         */
-        v->arch.vm_event->gpa = gpa;
-        v->arch.vm_event->eip = eip;
-    }
-
-    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_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);
-
-        v->arch.vm_event->emulate_flags = 0;
-        return 1;
-    }
-
     *req_ptr = NULL;
     req = xzalloc(vm_event_request_t);
     if ( req )
index 5aff834aa4a7fdb2995a51e2517fa1465cb57aae..fff8326444ced83311e5e21999fd5fa5b3cbf972 100644 (file)
@@ -28,8 +28,6 @@
  */
 struct arch_vm_event {
     uint32_t emulate_flags;
-    unsigned long gpa;
-    unsigned long eip;
     struct vm_event_emul_read_data emul_read_data;
     struct monitor_write_data write_data;
 };