From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: [PATCH 4/4] x86/vMSI-X: use generic intercept handler in place of MMIO one Date: Wed, 08 Jun 2016 06:54:47 -0600 Message-ID: <575831B702000078000F30AE@prv-mh.provo.novell.com> References: <5758302D02000078000F3087@prv-mh.provo.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__PartF5C3F787.1__=" Return-path: Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bAd0W-0007kK-Ii for xen-devel@lists.xenproject.org; Wed, 08 Jun 2016 12:54:52 +0000 In-Reply-To: <5758302D02000078000F3087@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: Andrew Cooper , Paul Durrant 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. --=__PartF5C3F787.1__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline This allows us to see the full ioreq without having to peek into state which is supposedly private to the emulation framework. Suggested-by: Paul Durrant Signed-off-by: Jan Beulich --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -199,9 +199,8 @@ static struct msi_desc *msixtbl_addr_to_ return NULL; } =20 -static int msixtbl_read( - struct vcpu *v, unsigned long address, - unsigned int len, unsigned long *pval) +static int msixtbl_read(const struct hvm_io_handler *handler, + uint64_t address, uint32_t len, uint64_t *pval) { unsigned long offset; struct msixtbl_entry *entry; @@ -213,7 +212,7 @@ static int msixtbl_read( =20 rcu_read_lock(&msixtbl_rcu_lock); =20 - entry =3D msixtbl_find_entry(v, address); + entry =3D msixtbl_find_entry(current, address); if ( !entry ) goto out; offset =3D address & (PCI_MSIX_ENTRY_SIZE - 1); @@ -333,23 +332,29 @@ out: return r; } =20 -static int msixtbl_range(struct vcpu *v, unsigned long addr) +static int _msixtbl_write(const struct hvm_io_handler *handler, + uint64_t address, uint32_t len, uint64_t val) { + return msixtbl_write(current, address, len, val); +} + +static bool_t msixtbl_range(const struct hvm_io_handler *handler, + const ioreq_t *r) +{ + struct vcpu *curr =3D current; + unsigned long addr =3D r->addr; const struct msi_desc *desc; - const ioreq_t *r; + + ASSERT(r->type =3D=3D IOREQ_TYPE_COPY); =20 rcu_read_lock(&msixtbl_rcu_lock); - desc =3D msixtbl_addr_to_desc(msixtbl_find_entry(v, addr), addr); + desc =3D msixtbl_addr_to_desc(msixtbl_find_entry(curr, addr), addr); rcu_read_unlock(&msixtbl_rcu_lock); =20 if ( desc ) return 1; =20 - r =3D &v->arch.hvm_vcpu.hvm_io.io_req; - if ( r->state !=3D STATE_IOREQ_READY || r->addr !=3D addr ) - return 0; - ASSERT(r->type =3D=3D IOREQ_TYPE_COPY); - if ( r->dir =3D=3D IOREQ_WRITE ) + if ( r->state =3D=3D STATE_IOREQ_READY && r->dir =3D=3D IOREQ_WRITE ) { unsigned int size =3D r->size; =20 @@ -368,8 +373,8 @@ static int msixtbl_range(struct vcpu *v, PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET) && !(data & PCI_MSIX_VECTOR_BITMASK) ) { - v->arch.hvm_vcpu.hvm_io.msix_snoop_address =3D addr; - v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa =3D 0; + curr->arch.hvm_vcpu.hvm_io.msix_snoop_address =3D addr; + curr->arch.hvm_vcpu.hvm_io.msix_snoop_gpa =3D 0; } } else if ( (size =3D=3D 4 || size =3D=3D 8) && @@ -386,9 +391,9 @@ static int msixtbl_range(struct vcpu *v, BUILD_BUG_ON((PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET + 4) & (PCI_MSIX_ENTRY_SIZE - 1)); =20 - v->arch.hvm_vcpu.hvm_io.msix_snoop_address =3D + curr->arch.hvm_vcpu.hvm_io.msix_snoop_address =3D addr + size * r->count - 4; - v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa =3D + curr->arch.hvm_vcpu.hvm_io.msix_snoop_gpa =3D r->data + size * r->count - 4; } } @@ -396,10 +401,10 @@ static int msixtbl_range(struct vcpu *v, return 0; } =20 -static const struct hvm_mmio_ops msixtbl_mmio_ops =3D { - .check =3D msixtbl_range, +static const struct hvm_io_ops msixtbl_mmio_ops =3D { + .accept =3D msixtbl_range, .read =3D msixtbl_read, - .write =3D msixtbl_write + .write =3D _msixtbl_write }; =20 static void add_msixtbl_entry(struct domain *d, @@ -544,13 +549,20 @@ found: =20 void msixtbl_init(struct domain *d) { + struct hvm_io_handler *handler; + if ( !has_hvm_container_domain(d) || !has_vlapic(d) || d->arch.hvm_domain.msixtbl_list.next ) return; =20 INIT_LIST_HEAD(&d->arch.hvm_domain.msixtbl_list); =20 - register_mmio_handler(d, &msixtbl_mmio_ops); + handler =3D hvm_next_io_handler(d); + if ( handler ) + { + handler->type =3D IOREQ_TYPE_COPY; + handler->ops =3D &msixtbl_mmio_ops; + } } =20 void msixtbl_pt_cleanup(struct domain *d) --=__PartF5C3F787.1__= Content-Type: text/plain; name="x86-vMSI-X-distinct-handler.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="x86-vMSI-X-distinct-handler.patch" x86/vMSI-X: use generic intercept handler in place of MMIO one=0A=0AThis = allows us to see the full ioreq without having to peek into state=0Awhich = is supposedly private to the emulation framework.=0A=0ASuggested-by: Paul = Durrant =0ASigned-off-by: Jan Beulich =0A=0A--- a/xen/arch/x86/hvm/vmsi.c=0A+++ b/xen/arch/x86/hvm/vmsi.c= =0A@@ -199,9 +199,8 @@ static struct msi_desc *msixtbl_addr_to_=0A = return NULL;=0A }=0A =0A-static int msixtbl_read(=0A- struct vcpu *v, = unsigned long address,=0A- unsigned int len, unsigned long *pval)=0A+sta= tic int msixtbl_read(const struct hvm_io_handler *handler,=0A+ = uint64_t address, uint32_t len, uint64_t *pval)=0A {=0A = unsigned long offset;=0A struct msixtbl_entry *entry;=0A@@ -213,7 = +212,7 @@ static int msixtbl_read(=0A =0A rcu_read_lock(&msixtbl_rcu_lo= ck);=0A =0A- entry =3D msixtbl_find_entry(v, address);=0A+ entry =3D = msixtbl_find_entry(current, address);=0A if ( !entry )=0A goto = out;=0A offset =3D address & (PCI_MSIX_ENTRY_SIZE - 1);=0A@@ -333,23 = +332,29 @@ out:=0A return r;=0A }=0A =0A-static int msixtbl_range(struc= t vcpu *v, unsigned long addr)=0A+static int _msixtbl_write(const struct = hvm_io_handler *handler,=0A+ uint64_t address, = uint32_t len, uint64_t val)=0A {=0A+ return msixtbl_write(current, = address, len, val);=0A+}=0A+=0A+static bool_t msixtbl_range(const struct = hvm_io_handler *handler,=0A+ const ioreq_t = *r)=0A+{=0A+ struct vcpu *curr =3D current;=0A+ unsigned long addr = =3D r->addr;=0A const struct msi_desc *desc;=0A- const ioreq_t = *r;=0A+=0A+ ASSERT(r->type =3D=3D IOREQ_TYPE_COPY);=0A =0A = rcu_read_lock(&msixtbl_rcu_lock);=0A- desc =3D msixtbl_addr_to_desc(msix= tbl_find_entry(v, addr), addr);=0A+ desc =3D msixtbl_addr_to_desc(msixtb= l_find_entry(curr, addr), addr);=0A rcu_read_unlock(&msixtbl_rcu_lock);= =0A =0A if ( desc )=0A return 1;=0A =0A- r =3D &v->arch.hvm_= vcpu.hvm_io.io_req;=0A- if ( r->state !=3D STATE_IOREQ_READY || r->addr = !=3D addr )=0A- return 0;=0A- ASSERT(r->type =3D=3D IOREQ_TYPE_CO= PY);=0A- if ( r->dir =3D=3D IOREQ_WRITE )=0A+ if ( r->state =3D=3D = STATE_IOREQ_READY && r->dir =3D=3D IOREQ_WRITE )=0A {=0A = unsigned int size =3D r->size;=0A =0A@@ -368,8 +373,8 @@ static int = msixtbl_range(struct vcpu *v,=0A PCI_MSIX_ENTRY_VECTOR_CT= RL_OFFSET) &&=0A !(data & PCI_MSIX_VECTOR_BITMASK) )=0A = {=0A- v->arch.hvm_vcpu.hvm_io.msix_snoop_address = =3D addr;=0A- v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa =3D = 0;=0A+ curr->arch.hvm_vcpu.hvm_io.msix_snoop_address =3D = addr;=0A+ curr->arch.hvm_vcpu.hvm_io.msix_snoop_gpa =3D = 0;=0A }=0A }=0A else if ( (size =3D=3D 4 || = size =3D=3D 8) &&=0A@@ -386,9 +391,9 @@ static int msixtbl_range(struct = vcpu *v,=0A BUILD_BUG_ON((PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET + = 4) &=0A (PCI_MSIX_ENTRY_SIZE - 1));=0A =0A- = v->arch.hvm_vcpu.hvm_io.msix_snoop_address =3D=0A+ = curr->arch.hvm_vcpu.hvm_io.msix_snoop_address =3D=0A addr = + size * r->count - 4;=0A- v->arch.hvm_vcpu.hvm_io.msix_snoop_gp= a =3D=0A+ curr->arch.hvm_vcpu.hvm_io.msix_snoop_gpa =3D=0A = r->data + size * r->count - 4;=0A }=0A }=0A@@ = -396,10 +401,10 @@ static int msixtbl_range(struct vcpu *v,=0A return = 0;=0A }=0A =0A-static const struct hvm_mmio_ops msixtbl_mmio_ops =3D {=0A- = .check =3D msixtbl_range,=0A+static const struct hvm_io_ops msixtbl_mmio= _ops =3D {=0A+ .accept =3D msixtbl_range,=0A .read =3D msixtbl_read,= =0A- .write =3D msixtbl_write=0A+ .write =3D _msixtbl_write=0A };=0A = =0A static void add_msixtbl_entry(struct domain *d,=0A@@ -544,13 +549,20 = @@ found:=0A =0A void msixtbl_init(struct domain *d)=0A {=0A+ struct = hvm_io_handler *handler;=0A+=0A if ( !has_hvm_container_domain(d) || = !has_vlapic(d) ||=0A d->arch.hvm_domain.msixtbl_list.next )=0A = return;=0A =0A INIT_LIST_HEAD(&d->arch.hvm_domain.msixtbl_list);= =0A =0A- register_mmio_handler(d, &msixtbl_mmio_ops);=0A+ handler = =3D hvm_next_io_handler(d);=0A+ if ( handler )=0A+ {=0A+ = handler->type =3D IOREQ_TYPE_COPY;=0A+ handler->ops =3D &msixtbl_mmi= o_ops;=0A+ }=0A }=0A =0A void msixtbl_pt_cleanup(struct domain *d)=0A --=__PartF5C3F787.1__= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KWGVuLWRldmVs IG1haWxpbmcgbGlzdApYZW4tZGV2ZWxAbGlzdHMueGVuLm9yZwpodHRwOi8vbGlzdHMueGVuLm9y Zy94ZW4tZGV2ZWwK --=__PartF5C3F787.1__=--