From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:50934) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UcFtD-0006QU-Li for qemu-devel@nongnu.org; Tue, 14 May 2013 10:07:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UcFt7-0000Xx-4v for qemu-devel@nongnu.org; Tue, 14 May 2013 10:07:39 -0400 Date: Tue, 14 May 2013 23:57:07 +1000 From: David Gibson Message-ID: <20130514135707.GL14944@truffula.fritz.box> References: <1368522837-20747-1-git-send-email-david@gibson.dropbear.id.au> <1368522837-20747-12-git-send-email-david@gibson.dropbear.id.au> <5192087F.90601@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="keoAwTxaagou87Dg" Content-Disposition: inline In-Reply-To: <5192087F.90601@redhat.com> Subject: Re: [Qemu-devel] [Qemu-ppc] [PATCH 11/11] vfio: Add guest side IOMMU support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: alex.williamson@redhat.com, qemu-ppc@nongnu.org, qemu-devel@nongnu.org, mst@redhat.com --keoAwTxaagou87Dg Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, May 14, 2013 at 11:48:47AM +0200, Paolo Bonzini wrote: > Il 14/05/2013 11:13, David Gibson ha scritto: > > This patch uses the new IOMMU notifiers to allow VFIO pass through devi= ces > > to work with guest side IOMMUs, as long as the host-side VFIO iommu has > > sufficient capability and granularity to match the guest side. This wor= ks > > by tracking all map and unmap operations on the guest IOMMU using the > > notifiers, and mirroring them into VFIO. > >=20 > > There are a number of FIXMEs, and the scheme involves rather more notif= ier > > structures than I'd like, but it shuold make for a reasonable proof of > > concept. > >=20 > > Signed-off-by: David Gibson > > --- > > hw/misc/vfio.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++= ++------ > > 1 file changed, 126 insertions(+), 13 deletions(-) > >=20 > > diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c > > index f4e3792..62a83ca 100644 > > --- a/hw/misc/vfio.c > > +++ b/hw/misc/vfio.c > > @@ -133,10 +133,18 @@ typedef struct VFIOContainer { > > }; > > void (*release)(struct VFIOContainer *); > > } iommu_data; > > + QLIST_HEAD(, VFIOGuestIOMMU) guest_iommus; > > QLIST_HEAD(, VFIOGroup) group_list; > > QLIST_ENTRY(VFIOContainer) next; > > } VFIOContainer; > > =20 > > +typedef struct VFIOGuestIOMMU { > > + VFIOContainer *container; > > + MemoryRegion *iommu; > > + Notifier n; > > + QLIST_ENTRY(VFIOGuestIOMMU) list; > > +} VFIOGuestIOMMU; > > + > > /* Cache of MSI-X setup plus extra mmap and memory region for split BA= R map */ > > typedef struct VFIOMSIXInfo { > > uint8_t table_bar; > > @@ -1940,7 +1948,64 @@ static int vfio_dma_map(VFIOContainer *container= , hwaddr iova, > > =20 > > static bool vfio_listener_skipped_section(MemoryRegionSection *section) > > { > > - return !memory_region_is_ram(section->mr); > > + return !memory_region_is_ram(section->mr) && > > + !memory_region_is_iommu(section->mr); > > +} > > + > > +static void vfio_iommu_map_notify(Notifier *n, void *data) > > +{ > > + VFIOGuestIOMMU *giommu =3D container_of(n, VFIOGuestIOMMU, n); > > + MemoryRegion *iommu =3D giommu->iommu; > > + VFIOContainer *container =3D giommu->container; > > + IOMMUTLBEntry *iotlb =3D data; > > + MemoryRegionSection *mrs; > > + hwaddr xlat; > > + hwaddr len =3D iotlb->addr_mask + 1; > > + void *vaddr; > > + int ret; > > + > > + DPRINTF("iommu map @ %"HWADDR_PRIx" - %"HWADDR_PRIx"\n", > > + iotlb->iova, iotlb->iova + iotlb->address_mask); > > + > > + /* The IOMMU TLB entry we have just covers translation through > > + * this IOMMU to its immediate target. We need to translate > > + * it the rest of the way through to memory. */ > > + mrs =3D address_space_translate(iommu->iommu_target_as, > > + iotlb->translated_addr, > > + &xlat, &len, iotlb->perm[1]); > > + if (!memory_region_is_ram(mrs->mr)) { > > + DPRINTF("iommu map to non memory area %"HWADDR_PRIx"\n", > > + xlat); > > + return; > > + } > > + if (len & iotlb->addr_mask) { > > + DPRINTF("iommu has granularity incompatible with target AS\n"); > > + return; > > + } > > + > > + vaddr =3D memory_region_get_ram_ptr(mrs->mr) + > > + mrs->offset_within_region + > > + (xlat - mrs->offset_within_address_space); >=20 > Are you sure you need this translation? It's done already in > address_space_translate, so it should be just >=20 > vaddr =3D memory_region_get_ram_ptr(mrs->mr) + xlat; Ah, yes. I wasn't sure what xlat was relative to (the final address space, or the final memory region). Looking more carefully at the similar path in address_space_map(), I see that it's the memory region. I'll fix that up. --=20 David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson --keoAwTxaagou87Dg Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEARECAAYFAlGSQrMACgkQaILKxv3ab8YM1ACfXijFtoCmq30EQsDzbV6hfENP W+sAnj7oVNYolj0atS23LtUt4/m9CpE5 =zE1E -----END PGP SIGNATURE----- --keoAwTxaagou87Dg--