From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38177) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WNc62-0002zX-HR for qemu-devel@nongnu.org; Wed, 12 Mar 2014 01:53:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WNc5r-0005I2-Cq for qemu-devel@nongnu.org; Wed, 12 Mar 2014 01:52:54 -0400 Received: from e23smtp06.au.ibm.com ([202.81.31.148]:43346) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WNc5q-0005H5-MF for qemu-devel@nongnu.org; Wed, 12 Mar 2014 01:52:43 -0400 Received: from /spool/local by e23smtp06.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 12 Mar 2014 15:52:39 +1000 From: Alexey Kardashevskiy Date: Wed, 12 Mar 2014 16:52:25 +1100 Message-Id: <1394603550-11556-7-git-send-email-aik@ozlabs.ru> In-Reply-To: <1394603550-11556-1-git-send-email-aik@ozlabs.ru> References: <1394603550-11556-1-git-send-email-aik@ozlabs.ru> Subject: [Qemu-devel] [PATCH v5 06/11] vfio: Create VFIOAddressSpace objects as needed List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alex Williamson Cc: Alexey Kardashevskiy , Alexander Graf , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson From: David Gibson So far, VFIO has a notion of different logical DMA address spaces, but only ever uses one (system memory). This patch extends this, creating new VFIOAddressSpace objects as necessary, according to the AddressSpace reported by the PCI subsystem for this device's DMAs. This isn't enough yet to support guest side IOMMUs with VFIO, but it does mean we could now support VFIO devices on, for example, a guest side PCI host bridge which maps system memory at somewhere other than 0 in PCI space. Signed-off-by: David Gibson Signed-off-by: Alexey Kardashevskiy --- Changes: v6: * vfio_get_address_space() moved to vfio_connect_container() v5: * vfio_get_group() now takes AddressSpace* instead of VFIOAddressSpace --- hw/misc/vfio.c | 58 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index c8236c3..038010b 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -141,14 +141,6 @@ typedef struct VFIOAddressSpace { QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces; -static VFIOAddressSpace vfio_address_space_memory; - -static void vfio_address_space_init(VFIOAddressSpace *space, AddressSpace *as) -{ - space->as = as; - QLIST_INIT(&space->containers); -} - struct VFIOGroup; typedef struct VFIOType1 { @@ -3294,13 +3286,43 @@ static void vfio_kvm_device_del_group(VFIOGroup *group) #endif } +static VFIOAddressSpace *vfio_get_address_space(AddressSpace *as) +{ + VFIOAddressSpace *space; + + QLIST_FOREACH(space, &vfio_address_spaces, list) { + if (space->as == as) { + return space; + } + } + + /* No suitable VFIOAddressSpace, create a new one */ + space = g_malloc0(sizeof(*space)); + space->as = as; + QLIST_INIT(&space->containers); + + QLIST_INSERT_HEAD(&vfio_address_spaces, space, list); + + return space; +} + +static void vfio_put_address_space(VFIOAddressSpace *space) +{ + if (!QLIST_EMPTY(&space->containers)) { + return; + } + + QLIST_REMOVE(space, list); + g_free(space); +} + static int vfio_connect_container(VFIOGroup *group, AddressSpace *as) { VFIOContainer *container; int ret, fd; VFIOAddressSpace *space; - space = &vfio_address_space_memory; + space = vfio_get_address_space(as); QLIST_FOREACH(container, &space->containers, next) { if (!ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) { @@ -3313,7 +3335,8 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as) fd = qemu_open("/dev/vfio/vfio", O_RDWR); if (fd < 0) { error_report("vfio: failed to open /dev/vfio/vfio: %m"); - return -errno; + ret = -errno; + goto put_space_exit; } ret = ioctl(fd, VFIO_GET_API_VERSION); @@ -3380,6 +3403,9 @@ free_container_exit: close_fd_exit: close(fd); +put_space_exit: + vfio_put_address_space(space); + return ret; } @@ -3396,6 +3422,8 @@ static void vfio_disconnect_container(VFIOGroup *group) group->container = NULL; if (QLIST_EMPTY(&container->group_list)) { + VFIOAddressSpace *space = container->space; + if (container->iommu_data.release) { container->iommu_data.release(container); } @@ -3403,6 +3431,8 @@ static void vfio_disconnect_container(VFIOGroup *group) DPRINTF("vfio_disconnect_container: close container->fd\n"); close(container->fd); g_free(container); + + vfio_put_address_space(space); } } @@ -3801,12 +3831,7 @@ static int vfio_initfn(PCIDevice *pdev) DPRINTF("%s(%04x:%02x:%02x.%x) group %d\n", __func__, vdev->host.domain, vdev->host.bus, vdev->host.slot, vdev->host.function, groupid); - if (pci_device_iommu_address_space(pdev) != &address_space_memory) { - error_report("vfio: DMA address space must be system memory"); - return -EINVAL; - } - - group = vfio_get_group(groupid, &address_space_memory); + group = vfio_get_group(groupid, pci_device_iommu_address_space(pdev)); if (!group) { error_report("vfio: failed to get group %d", groupid); return -ENOENT; @@ -4020,7 +4045,6 @@ static const TypeInfo vfio_pci_dev_info = { static void register_vfio_pci_dev_type(void) { - vfio_address_space_init(&vfio_address_space_memory, &address_space_memory); type_register_static(&vfio_pci_dev_info); } -- 1.8.4.rc4