From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: [PATCH v2 11/11] x86/HVM: serialize trap injecting producer and consumer Date: Fri, 24 Jun 2016 04:34:33 -0600 Message-ID: <576D28D902000078000F879D@prv-mh.provo.novell.com> References: <576D25DA02000078000F86C2@prv-mh.provo.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__PartF7C1C0A9.3__=" Return-path: Received: from mail6.bemta6.messagelabs.com ([85.158.143.247]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bGORZ-0004kY-KN for xen-devel@lists.xenproject.org; Fri, 24 Jun 2016 10:34:37 +0000 In-Reply-To: <576D25DA02000078000F86C2@prv-mh.provo.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" To: xen-devel Cc: Stefano Stabellini , Wei Liu , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , dgdegra@tycho.nsa.gov List-Id: xen-devel@lists.xenproject.org This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__PartF7C1C0A9.3__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline 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 Reviewed-by: Andrew Cooper --- a/xen/arch/x86/hvm/control.c +++ b/xen/arch/x86/hvm/control.c @@ -215,14 +215,16 @@ static int inject_trap(struct domain *d, if ( op->vcpuid >=3D d->max_vcpus || (v =3D d->vcpu[op->vcpuid]) = =3D=3D NULL ) return -ENOENT; =20 - if ( v->arch.hvm_vcpu.inject_trap.vector !=3D -1 ) + if ( cmpxchg(&v->arch.hvm_vcpu.inject_trap.vector, HVM_TRAP_VECTOR_UNS= ET, + HVM_TRAP_VECTOR_UPDATING) !=3D HVM_TRAP_VECTOR_UNSET ) return -EBUSY; =20 - v->arch.hvm_vcpu.inject_trap.vector =3D op->vector; v->arch.hvm_vcpu.inject_trap.type =3D op->type; v->arch.hvm_vcpu.inject_trap.error_code =3D op->error_code; v->arch.hvm_vcpu.inject_trap.insn_len =3D op->insn_len; v->arch.hvm_vcpu.inject_trap.cr2 =3D op->cr2; + smp_wmb(); + v->arch.hvm_vcpu.inject_trap.vector =3D op->vector; =20 return 0; } --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -510,10 +510,11 @@ void hvm_do_resume(struct vcpu *v) } =20 /* Inject pending hw/sw trap */ - if ( v->arch.hvm_vcpu.inject_trap.vector !=3D -1 ) + if ( v->arch.hvm_vcpu.inject_trap.vector >=3D 0 ) { + smp_rmb(); hvm_inject_trap(&v->arch.hvm_vcpu.inject_trap); - v->arch.hvm_vcpu.inject_trap.vector =3D -1; + v->arch.hvm_vcpu.inject_trap.vector =3D HVM_TRAP_VECTOR_UNSET; } } =20 @@ -1508,7 +1509,7 @@ int hvm_vcpu_initialise(struct vcpu *v) (void(*)(unsigned long))hvm_assert_evtchn_irq, (unsigned long)v); =20 - v->arch.hvm_vcpu.inject_trap.vector =3D -1; + v->arch.hvm_vcpu.inject_trap.vector =3D HVM_TRAP_VECTOR_UNSET; =20 if ( is_pvh_domain(d) ) { --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -78,6 +78,8 @@ enum hvm_intblk { #define HVM_HAP_SUPERPAGE_1GB 0x00000002 =20 struct hvm_trap { +#define HVM_TRAP_VECTOR_UNSET (-1) +#define HVM_TRAP_VECTOR_UPDATING (-2) int16_t vector; uint8_t type; /* X86_EVENTTYPE_* */ uint8_t insn_len; /* Instruction length */ --=__PartF7C1C0A9.3__= Content-Type: text/plain; name="x86-HVM-inject-trap-serialize.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="x86-HVM-inject-trap-serialize.patch" x86/HVM: serialize trap injecting producer and consumer=0A=0ASince = injection works on a remote vCPU, and since there's no=0Aenforcement of = the subject vCPU being paused, there's a potential race=0Abetween the = producing and consuming sides. Fix this by leveraging the=0Avector field = as synchronization variable.=0A=0ASigned-off-by: Jan Beulich =0AReviewed-by: Andrew Cooper =0A=0A--- = a/xen/arch/x86/hvm/control.c=0A+++ b/xen/arch/x86/hvm/control.c=0A@@ = -215,14 +215,16 @@ static int inject_trap(struct domain *d,=0A if ( = op->vcpuid >=3D d->max_vcpus || (v =3D d->vcpu[op->vcpuid]) =3D=3D NULL = )=0A return -ENOENT;=0A =0A- if ( v->arch.hvm_vcpu.inject_trap.v= ector !=3D -1 )=0A+ if ( cmpxchg(&v->arch.hvm_vcpu.inject_trap.vector, = HVM_TRAP_VECTOR_UNSET,=0A+ HVM_TRAP_VECTOR_UPDATING) !=3D = HVM_TRAP_VECTOR_UNSET )=0A return -EBUSY;=0A =0A- v->arch.hvm_vc= pu.inject_trap.vector =3D op->vector;=0A v->arch.hvm_vcpu.inject_tr= ap.type =3D op->type;=0A v->arch.hvm_vcpu.inject_trap.error_code = =3D op->error_code;=0A v->arch.hvm_vcpu.inject_trap.insn_len =3D = op->insn_len;=0A v->arch.hvm_vcpu.inject_trap.cr2 =3D = op->cr2;=0A+ smp_wmb();=0A+ v->arch.hvm_vcpu.inject_trap.vector = =3D op->vector;=0A =0A return 0;=0A }=0A--- a/xen/arch/x86/hvm/hvm.c=0A= +++ b/xen/arch/x86/hvm/hvm.c=0A@@ -510,10 +510,11 @@ void hvm_do_resume(str= uct vcpu *v)=0A }=0A =0A /* Inject pending hw/sw trap */=0A- if = ( v->arch.hvm_vcpu.inject_trap.vector !=3D -1 )=0A+ if ( v->arch.hvm_vcp= u.inject_trap.vector >=3D 0 )=0A {=0A+ smp_rmb();=0A = hvm_inject_trap(&v->arch.hvm_vcpu.inject_trap);=0A- v->arch.hvm_vcpu= .inject_trap.vector =3D -1;=0A+ v->arch.hvm_vcpu.inject_trap.vector = =3D HVM_TRAP_VECTOR_UNSET;=0A }=0A }=0A =0A@@ -1508,7 +1509,7 @@ int = hvm_vcpu_initialise(struct vcpu *v)=0A (void(*)(unsigned long))hvm_= assert_evtchn_irq,=0A (unsigned long)v);=0A =0A- v->arch.hvm_vcp= u.inject_trap.vector =3D -1;=0A+ v->arch.hvm_vcpu.inject_trap.vector = =3D HVM_TRAP_VECTOR_UNSET;=0A =0A if ( is_pvh_domain(d) )=0A = {=0A--- a/xen/include/asm-x86/hvm/hvm.h=0A+++ b/xen/include/asm-x86/hvm/hvm= .h=0A@@ -78,6 +78,8 @@ enum hvm_intblk {=0A #define HVM_HAP_SUPERPAGE_1GB = 0x00000002=0A =0A struct hvm_trap {=0A+#define HVM_TRAP_VECTOR_UNSET = (-1)=0A+#define HVM_TRAP_VECTOR_UPDATING (-2)=0A int16_t = vector;=0A uint8_t type; /* X86_EVENTTYPE_* */=0A = uint8_t insn_len; /* Instruction length */=0A --=__PartF7C1C0A9.3__= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KWGVuLWRldmVs IG1haWxpbmcgbGlzdApYZW4tZGV2ZWxAbGlzdHMueGVuLm9yZwpodHRwOi8vbGlzdHMueGVuLm9y Zy94ZW4tZGV2ZWwK --=__PartF7C1C0A9.3__=--