diff --git a/xen/arch/x86/hvm/vm_event.c b/xen/arch/x86/hvm/vm_event.c index 28d08a6..8e7c737 100644 --- a/xen/arch/x86/hvm/vm_event.c +++ b/xen/arch/x86/hvm/vm_event.c @@ -124,6 +124,8 @@ void hvm_vm_event_do_resume(struct vcpu *v) w->do_write.msr = 0; } + + v->arch.vm_event->intr_block = false; } /* diff --git a/xen/arch/x86/hvm/vmx/intr.c b/xen/arch/x86/hvm/vmx/intr.c index eb9b288..97cecbf 100644 --- a/xen/arch/x86/hvm/vmx/intr.c +++ b/xen/arch/x86/hvm/vmx/intr.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include /* * A few notes on virtual NMI and INTR delivery, and interactions with @@ -231,6 +233,11 @@ void vmx_intr_assist(void) enum hvm_intblk intblk; int pt_vector; + if ( unlikely(v->arch.vm_event) && + vm_event_check_ring(v->domain->vm_event_monitor) && + v->arch.vm_event->intr_block ) + return; + /* Block event injection when single step with MTF. */ if ( unlikely(v->arch.hvm_vcpu.single_step) ) { diff --git a/xen/common/monitor.c b/xen/common/monitor.c index c606683..4263929 100644 --- a/xen/common/monitor.c +++ b/xen/common/monitor.c @@ -113,6 +113,12 @@ int monitor_traps(struct vcpu *v, bool sync, vm_event_request_t *req) if ( sync ) { req->flags |= VM_EVENT_FLAG_VCPU_PAUSED; + /* + * It only makes sense to block interrupts for the duration of + * processing blocking vm_events, since that is the only case where + * emulating the current instruction really applies. + */ + v->arch.vm_event->intr_block = true; vm_event_vcpu_pause(v); rc = 1; } diff --git a/xen/include/asm-x86/vm_event.h b/xen/include/asm-x86/vm_event.h index 39e73c8..2b36614 100644 --- a/xen/include/asm-x86/vm_event.h +++ b/xen/include/asm-x86/vm_event.h @@ -34,6 +34,12 @@ struct arch_vm_event { struct monitor_write_data write_data; struct vm_event_regs_x86 gprs; bool set_gprs; + /* + * Block interrupts until this vm_event is done handling (after the + * fashion of single-step). Meant for the cases where the vm_event + * reply asks for emulation of the current instruction. + */ + bool intr_block; }; int vm_event_init_domain(struct domain *d);