From mboxrd@z Thu Jan 1 00:00:00 1970 From: Razvan Cojocaru Subject: [PATCH] x86/hvm: simplify emulation triggered by vm_event response Date: Thu, 4 Feb 2016 14:27:32 +0200 Message-ID: <1454588852-5389-1-git-send-email-rcojocaru@bitdefender.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: george.dunlap@eu.citrix.com, andrew.cooper3@citrix.com, keir@xen.org, Razvan Cojocaru , jbeulich@suse.com List-Id: xen-devel@lists.xenproject.org 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 --- 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