[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/hvm: serialize trap injecting producer and consumer
commit 9b7c0ce58396a20f01e8db4494e967ca4cb55ed4 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Wed Jan 25 10:51:10 2017 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Wed Jan 25 10:51:10 2017 +0100 x86/hvm: serialize trap injecting producer and consumer Since injection works on a remote vCPU, and since there's no enforcement of the subject vCPU being paused, there's a potential race between the producing and consuming sides. Fix this by leveraging the vector field as synchronization variable. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> [re-based] Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- xen/arch/x86/hvm/dm.c | 5 ++++- xen/arch/x86/hvm/hvm.c | 10 ++++++---- xen/include/asm-x86/hvm/hvm.h | 3 +++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c index 0c013d6..6a722a5 100644 --- a/xen/arch/x86/hvm/dm.c +++ b/xen/arch/x86/hvm/dm.c @@ -255,13 +255,16 @@ static int inject_event(struct domain *d, if ( data->vcpuid >= d->max_vcpus || !(v = d->vcpu[data->vcpuid]) ) return -EINVAL; - if ( v->arch.hvm_vcpu.inject_event.vector != -1 ) + if ( cmpxchg(&v->arch.hvm_vcpu.inject_event.vector, + HVM_EVENT_VECTOR_UNSET, HVM_EVENT_VECTOR_UPDATING) != + HVM_EVENT_VECTOR_UNSET ) return -EBUSY; v->arch.hvm_vcpu.inject_event.type = data->type; v->arch.hvm_vcpu.inject_event.insn_len = data->insn_len; v->arch.hvm_vcpu.inject_event.error_code = data->error_code; v->arch.hvm_vcpu.inject_event.cr2 = data->cr2; + smp_wmb(); v->arch.hvm_vcpu.inject_event.vector = data->vector; return 0; diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 342df74..9ffc21b 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -542,13 +542,15 @@ void hvm_do_resume(struct vcpu *v) } } - /* Inject pending hw/sw trap */ - if ( v->arch.hvm_vcpu.inject_event.vector != -1 ) + /* Inject pending hw/sw event */ + if ( v->arch.hvm_vcpu.inject_event.vector >= 0 ) { + smp_rmb(); + if ( !hvm_event_pending(v) ) hvm_inject_event(&v->arch.hvm_vcpu.inject_event); - v->arch.hvm_vcpu.inject_event.vector = -1; + v->arch.hvm_vcpu.inject_event.vector = HVM_EVENT_VECTOR_UNSET; } if ( unlikely(v->arch.vm_event) && v->arch.monitor.next_interrupt_enabled ) @@ -1519,7 +1521,7 @@ int hvm_vcpu_initialise(struct vcpu *v) (void(*)(unsigned long))hvm_assert_evtchn_irq, (unsigned long)v); - v->arch.hvm_vcpu.inject_event.vector = -1; + v->arch.hvm_vcpu.inject_event.vector = HVM_EVENT_VECTOR_UNSET; if ( is_pvh_domain(d) ) { diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 329831c..87b203a 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -77,6 +77,9 @@ enum hvm_intblk { #define HVM_HAP_SUPERPAGE_2MB 0x00000001 #define HVM_HAP_SUPERPAGE_1GB 0x00000002 +#define HVM_EVENT_VECTOR_UNSET (-1) +#define HVM_EVENT_VECTOR_UPDATING (-2) + /* * The hardware virtual machine (HVM) interface abstracts away from the * x86/x86_64 CPU virtualization assist specifics. Currently this interface -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |