|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/hvm: simplify emulation triggered by vm_event response
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@xxxxxxxxxxxxxxx>
---
xen/arch/x86/hvm/hvm.c | 17 +++++++++++++++++
xen/arch/x86/mm/p2m.c | 34 ----------------------------------
xen/include/asm-x86/vm_event.h | 2 --
3 files changed, 17 insertions(+), 36 deletions(-)
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 35ec6c9..930d0e3 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -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);
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index a45ee35..47e7fad 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -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 )
diff --git a/xen/include/asm-x86/vm_event.h b/xen/include/asm-x86/vm_event.h
index 5aff834..fff8326 100644
--- a/xen/include/asm-x86/vm_event.h
+++ b/xen/include/asm-x86/vm_event.h
@@ -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;
};
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |