From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57968) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b8jRe-0002Ok-KB for qemu-devel@nongnu.org; Fri, 03 Jun 2016 03:23:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b8jR5-0003AJ-0n for qemu-devel@nongnu.org; Fri, 03 Jun 2016 03:23:01 -0400 Date: Fri, 3 Jun 2016 17:23:59 +1000 From: David Gibson Message-ID: <20160603072358.GU1087@voom.fritz.box> References: <1464771463-37214-1-git-send-email-aik@ozlabs.ru> <201606010901.u518wwEL029369@mx0a-001b2d01.pphosted.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="ZsW/usBbx2ObC9TW" Content-Disposition: inline In-Reply-To: <201606010901.u518wwEL029369@mx0a-001b2d01.pphosted.com> Subject: Re: [Qemu-devel] [PATCH qemu v17 09/12] vfio: Add host side DMA window capabilities List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexey Kardashevskiy Cc: qemu-devel@nongnu.org, qemu-ppc@nongnu.org, Alexander Graf , Alex Williamson --ZsW/usBbx2ObC9TW Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Jun 01, 2016 at 06:57:40PM +1000, Alexey Kardashevskiy wrote: > There are going to be multiple IOMMUs per a container. This moves > the single host IOMMU parameter set to a list of VFIOHostDMAWindow. >=20 > This should cause no behavioral change and will be used later by > the SPAPR TCE IOMMU v2 which will also add a vfio_host_win_del() helper. >=20 > Signed-off-by: Alexey Kardashevskiy > Reviewed-by: David Gibson > --- > Changes: > v17: > * vfio_host_win_add() uses vfio_host_win_lookup() for overlap check and > aborts if any found instead of returning an error (as recovery is not > possible anyway) > * hw_error() when overlapped iommu is detected >=20 > v16: > * adjusted commit log with changes from v15 >=20 > v15: > * s/vfio_host_iommu_add/vfio_host_win_add/ > * s/VFIOHostIOMMU/VFIOHostDMAWindow/ > --- > hw/vfio/common.c | 59 +++++++++++++++++++++++++++++++------= ------ > include/hw/vfio/vfio-common.h | 9 +++++-- > 2 files changed, 50 insertions(+), 18 deletions(-) >=20 > diff --git a/hw/vfio/common.c b/hw/vfio/common.c > index 770f630..52b08fd 100644 > --- a/hw/vfio/common.c > +++ b/hw/vfio/common.c > @@ -29,6 +29,7 @@ > #include "exec/memory.h" > #include "hw/hw.h" > #include "qemu/error-report.h" > +#include "qemu/range.h" > #include "sysemu/kvm.h" > #ifdef CONFIG_KVM > #include "linux/kvm.h" > @@ -242,6 +243,38 @@ static int vfio_dma_map(VFIOContainer *container, hw= addr iova, > return -errno; > } > =20 > +static VFIOHostDMAWindow *vfio_host_win_lookup(VFIOContainer *container, > + hwaddr min_iova, hwaddr m= ax_iova) > +{ > + VFIOHostDMAWindow *hostwin; > + > + QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { > + if (hostwin->min_iova <=3D min_iova && max_iova <=3D hostwin->ma= x_iova) { This is not an overlaps test, but a strictly includes test.. > + return hostwin; > + } > + } > + > + return NULL; > +} > + > +static void vfio_host_win_add(VFIOContainer *container, > + hwaddr min_iova, hwaddr max_iova, > + uint64_t iova_pgsizes) > +{ > + VFIOHostDMAWindow *hostwin; > + > + if (vfio_host_win_lookup(container, min_iova, max_iova)) { =2E.which means this no longer catches (partially) overlapping regions. > + hw_error("%s: Overlapped IOMMU are not enabled", __func__); > + } > + > + hostwin =3D g_malloc0(sizeof(*hostwin)); > + > + hostwin->min_iova =3D min_iova; > + hostwin->max_iova =3D max_iova; > + hostwin->iova_pgsizes =3D iova_pgsizes; > + QLIST_INSERT_HEAD(&container->hostwin_list, hostwin, hostwin_next); > +} > + > static bool vfio_listener_skipped_section(MemoryRegionSection *section) > { > return (!memory_region_is_ram(section->mr) && > @@ -355,7 +388,7 @@ static void vfio_listener_region_add(MemoryListener *= listener, > } > end =3D int128_get64(int128_sub(llend, int128_one())); > =20 > - if ((iova < container->min_iova) || (end > container->max_iova)) { > + if (!vfio_host_win_lookup(container, iova, end)) { > error_report("vfio: IOMMU container %p can't map guest IOVA regi= on" > " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx, > container, iova, end); > @@ -370,10 +403,6 @@ static void vfio_listener_region_add(MemoryListener = *listener, > =20 > trace_vfio_listener_region_add_iommu(iova, end); > /* > - * FIXME: We should do some checking to see if the > - * capabilities of the host VFIO IOMMU are adequate to model > - * the guest IOMMU > - * > * FIXME: For VFIO iommu types which have KVM acceleration to > * avoid bouncing all map/unmaps through qemu this way, this > * would be the right place to wire that up (tell the KVM > @@ -880,17 +909,14 @@ static int vfio_connect_container(VFIOGroup *group,= AddressSpace *as) > * existing Type1 IOMMUs generally support any IOVA we're > * going to actually try in practice. > */ > - container->min_iova =3D 0; > - container->max_iova =3D (hwaddr)-1; > - > - /* Assume just 4K IOVA page size */ > - container->iova_pgsizes =3D 0x1000; > info.argsz =3D sizeof(info); > ret =3D ioctl(fd, VFIO_IOMMU_GET_INFO, &info); > /* Ignore errors */ > - if ((ret =3D=3D 0) && (info.flags & VFIO_IOMMU_INFO_PGSIZES)) { > - container->iova_pgsizes =3D info.iova_pgsizes; > + if (ret || !(info.flags & VFIO_IOMMU_INFO_PGSIZES)) { > + /* Assume 4k IOVA page size */ > + info.iova_pgsizes =3D 4096; > } > + vfio_host_win_add(container, 0, (hwaddr)-1, info.iova_pgsizes); > } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU) || > ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_v2_IOMMU))= { > struct vfio_iommu_spapr_tce_info info; > @@ -946,11 +972,12 @@ static int vfio_connect_container(VFIOGroup *group,= AddressSpace *as) > ret =3D -errno; > goto listener_release_exit; > } > - container->min_iova =3D info.dma32_window_start; > - container->max_iova =3D container->min_iova + info.dma32_window_= size - 1; > =20 > - /* Assume just 4K IOVA pages for now */ > - container->iova_pgsizes =3D 0x1000; > + /* The default table uses 4K pages */ > + vfio_host_win_add(container, info.dma32_window_start, > + info.dma32_window_start + > + info.dma32_window_size - 1, > + 0x1000); > } else { > error_report("vfio: No available IOMMU models"); > ret =3D -EINVAL; > diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h > index 405c3b2..c76ddc4 100644 > --- a/include/hw/vfio/vfio-common.h > +++ b/include/hw/vfio/vfio-common.h > @@ -82,9 +82,8 @@ typedef struct VFIOContainer { > * contiguous IOVA window. We may need to generalize that in > * future > */ > - hwaddr min_iova, max_iova; > - uint64_t iova_pgsizes; > QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; > + QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; > QLIST_HEAD(, VFIOGroup) group_list; > QLIST_ENTRY(VFIOContainer) next; > } VFIOContainer; > @@ -97,6 +96,12 @@ typedef struct VFIOGuestIOMMU { > QLIST_ENTRY(VFIOGuestIOMMU) giommu_next; > } VFIOGuestIOMMU; > =20 > +typedef struct VFIOHostDMAWindow { > + hwaddr min_iova, max_iova; > + uint64_t iova_pgsizes; > + QLIST_ENTRY(VFIOHostDMAWindow) hostwin_next; > +} VFIOHostDMAWindow; > + > typedef struct VFIODeviceOps VFIODeviceOps; > =20 > typedef struct VFIODevice { --=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 --ZsW/usBbx2ObC9TW Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJXUTCOAAoJEGw4ysog2bOSbpMQAMezFXeP6D9L0kwDXVcf0l+9 hGtkosoBAZ7t57xmnbyWrxR7yS+Nw0XSx2F01gNuQ8Hvu6IDvFDTRiePYxHaYU8A e//TBY8HenSWqs/b2D/qcU1SXpeoHcg1Wz6tuD9Ab2KcR5jinE3AyYECc85T1D0y JxjsMvnpQKgEzTL+FMD/uC6mQDbVlJ9vMpS2BHpmNfQk/Y54rqPXe3uleMXO43J4 Nov9JEiDWJo4WITSOyKS8W8hJSb9CszMTo4Oa3fvKYKRzj5NVLMR3oSLYKlAjoJG fMyijYlfxpVY1I6HOh5wvDz5248a9CEiEIZvdW7jN8W8SSUftWc+z+AFhJm7P3TK JOSFHBFk4TBxR4mYoWfWWCSgZPtn+2ch09sQuYnIS06+ZbRveDdbgns4XCweJnnB mUWTwZgUktUxbQUaiUlSHnsoLlhTWlxSqGSfqCg/WU4UQzop5pQT2QiglRZgg0Qx 7r82m+wsegO2cux9A7gwvavNjfa4VYSICX4ECLnfr7qn8FNbDepUhMW5/cqcAnTw 05bv7NKEB4mA4GQCqfLDc7KYPVD8Ne6gTch11rQLvWq//Nc3C1tajE1T+qIVBxud KutuWYcdcCvV1neHAr1H92+A2ya/6NoBOeYYLMOIjF/YbHKCCbeCcKVURKkDGi0H NAstIe5xNZ9XVv9i83/+ =PDMj -----END PGP SIGNATURE----- --ZsW/usBbx2ObC9TW--