[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86/vm_event: block interrupt injection for sync vm_events
commit ff9b9d540f1bddab278daa103291a217270cc587 Author: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx> AuthorDate: Mon Jan 21 12:13:22 2019 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Mon Jan 21 12:13:22 2019 +0100 x86/vm_event: block interrupt injection for sync vm_events Block interrupts (in vmx_intr_assist()) for the duration of processing a sync vm_event (similarly to the strategy currently used for single-stepping). Otherwise, attempting to emulate an instruction when requested by a vm_event reply may legitimately need to call e.g. hvm_inject_page_fault(), which then overwrites the active interrupt in the VMCS. The sync vm_event handling path on x86/VMX is (roughly): monitor_traps() -> process vm_event -> vmx_intr_assist() (possibly writing VM_ENTRY_INTR_INFO) -> hvm_vm_event_do_resume() -> hvm_emulate_one_vm_event() (possibly overwriting the VM_ENTRY_INTR_INFO value). This patch may also be helpful for the future removal of may_defer in hvm_set_cr{0,3,4} and hvm_set_msr(). Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx> Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx> Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> Acked-by: Tamas K Lengyel <tamas@xxxxxxxxxxxxx> Release-acked-by: Juergen Gross <jgross@xxxxxxxx> --- xen/arch/x86/hvm/svm/intr.c | 5 +++++ xen/arch/x86/hvm/vm_event.c | 2 ++ xen/arch/x86/hvm/vmx/intr.c | 5 +++++ xen/arch/x86/vm_event.c | 5 +++++ xen/common/monitor.c | 1 + xen/include/asm-arm/vm_event.h | 6 ++++++ xen/include/asm-x86/vm_event.h | 4 ++++ 7 files changed, 28 insertions(+) diff --git a/xen/arch/x86/hvm/svm/intr.c b/xen/arch/x86/hvm/svm/intr.c index 79673535d1..ff755165cd 100644 --- a/xen/arch/x86/hvm/svm/intr.c +++ b/xen/arch/x86/hvm/svm/intr.c @@ -32,6 +32,7 @@ #include <asm/hvm/svm/svm.h> #include <asm/hvm/svm/intr.h> #include <asm/hvm/nestedhvm.h> /* for nestedhvm_vcpu_in_guestmode */ +#include <asm/vm_event.h> #include <xen/event.h> #include <xen/kernel.h> #include <public/hvm/ioreq.h> @@ -137,6 +138,10 @@ void svm_intr_assist(void) struct hvm_intack intack; enum hvm_intblk intblk; + /* Block event injection while handling a sync vm_event. */ + if ( unlikely(v->arch.vm_event) && v->arch.vm_event->sync_event ) + return; + /* Crank the handle on interrupt state. */ pt_update_irq(v); diff --git a/xen/arch/x86/hvm/vm_event.c b/xen/arch/x86/hvm/vm_event.c index 0df8ab40e6..121de23071 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; } + + vm_event_sync_event(v, false); } /* diff --git a/xen/arch/x86/hvm/vmx/intr.c b/xen/arch/x86/hvm/vmx/intr.c index 5e8cbd4b4a..0d097cf1f2 100644 --- a/xen/arch/x86/hvm/vmx/intr.c +++ b/xen/arch/x86/hvm/vmx/intr.c @@ -37,6 +37,7 @@ #include <asm/hvm/nestedhvm.h> #include <public/hvm/ioreq.h> #include <asm/hvm/trace.h> +#include <asm/vm_event.h> /* * A few notes on virtual NMI and INTR delivery, and interactions with @@ -239,6 +240,10 @@ void vmx_intr_assist(void) return; } + /* Block event injection while handling a sync vm_event. */ + if ( unlikely(v->arch.vm_event) && v->arch.vm_event->sync_event ) + return; + /* Crank the handle on interrupt state. */ pt_vector = pt_update_irq(v); diff --git a/xen/arch/x86/vm_event.c b/xen/arch/x86/vm_event.c index 713e684abe..51c3493b1d 100644 --- a/xen/arch/x86/vm_event.c +++ b/xen/arch/x86/vm_event.c @@ -122,6 +122,11 @@ void vm_event_monitor_next_interrupt(struct vcpu *v) v->arch.monitor.next_interrupt_enabled = true; } +void vm_event_sync_event(struct vcpu *v, bool value) +{ + v->arch.vm_event->sync_event = value; +} + #ifdef CONFIG_HVM static void vm_event_pack_segment_register(enum x86_segment segment, struct vm_event_regs_x86 *reg) diff --git a/xen/common/monitor.c b/xen/common/monitor.c index c6066830e3..cb5f37fdb2 100644 --- a/xen/common/monitor.c +++ b/xen/common/monitor.c @@ -113,6 +113,7 @@ int monitor_traps(struct vcpu *v, bool sync, vm_event_request_t *req) if ( sync ) { req->flags |= VM_EVENT_FLAG_VCPU_PAUSED; + vm_event_sync_event(v, true); vm_event_vcpu_pause(v); rc = 1; } diff --git a/xen/include/asm-arm/vm_event.h b/xen/include/asm-arm/vm_event.h index 66f2474fe1..14d1d341cc 100644 --- a/xen/include/asm-arm/vm_event.h +++ b/xen/include/asm-arm/vm_event.h @@ -52,4 +52,10 @@ void vm_event_emulate_check(struct vcpu *v, vm_event_response_t *rsp) /* Not supported on ARM. */ } +static inline +void vm_event_sync_event(struct vcpu *v, bool value) +{ + /* Not supported on ARM. */ +} + #endif /* __ASM_ARM_VM_EVENT_H__ */ diff --git a/xen/include/asm-x86/vm_event.h b/xen/include/asm-x86/vm_event.h index 39e73c83ca..23e655710b 100644 --- a/xen/include/asm-x86/vm_event.h +++ b/xen/include/asm-x86/vm_event.h @@ -34,6 +34,8 @@ struct arch_vm_event { struct monitor_write_data write_data; struct vm_event_regs_x86 gprs; bool set_gprs; + /* A sync vm_event has been sent and we're not done handling it. */ + bool sync_event; }; int vm_event_init_domain(struct domain *d); @@ -47,4 +49,6 @@ void vm_event_register_write_resume(struct vcpu *v, vm_event_response_t *rsp); void vm_event_emulate_check(struct vcpu *v, vm_event_response_t *rsp); +void vm_event_sync_event(struct vcpu *v, bool value); + #endif /* __ASM_X86_VM_EVENT_H__ */ -- generated by git-patchbot for /home/xen/git/xen.git#staging _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |