From patchwork Fri Aug 30 10:15:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 271216 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C48C82C009D for ; Fri, 30 Aug 2013 20:16:59 +1000 (EST) Received: from localhost ([::1]:48598 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VFLlA-0005F5-Vk for incoming@patchwork.ozlabs.org; Fri, 30 Aug 2013 06:16:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34489) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VFLkT-0005DA-4b for qemu-devel@nongnu.org; Fri, 30 Aug 2013 06:16:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VFLkJ-0003VZ-CG for qemu-devel@nongnu.org; Fri, 30 Aug 2013 06:16:13 -0400 Received: from e23smtp08.au.ibm.com ([202.81.31.141]:33234) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VFLkI-0003UG-N4 for qemu-devel@nongnu.org; Fri, 30 Aug 2013 06:16:03 -0400 Received: from /spool/local by e23smtp08.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 30 Aug 2013 20:12:40 +1000 Received: from d23dlp02.au.ibm.com (202.81.31.213) by e23smtp08.au.ibm.com (202.81.31.205) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 30 Aug 2013 20:12:37 +1000 Received: from d23relay05.au.ibm.com (d23relay05.au.ibm.com [9.190.235.152]) by d23dlp02.au.ibm.com (Postfix) with ESMTP id 8CA292BB0053; Fri, 30 Aug 2013 20:15:54 +1000 (EST) Received: from d23av01.au.ibm.com (d23av01.au.ibm.com [9.190.234.96]) by d23relay05.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r7U9xQC052166906; Fri, 30 Aug 2013 19:59:37 +1000 Received: from d23av01.au.ibm.com (localhost [127.0.0.1]) by d23av01.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id r7UAFhAr010929; Fri, 30 Aug 2013 20:15:43 +1000 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.190.163.12]) by d23av01.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id r7UAFhDG010923; Fri, 30 Aug 2013 20:15:43 +1000 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.190.164.82]) by ozlabs.au.ibm.com (Postfix) with ESMTP id D7669A0147; Fri, 30 Aug 2013 20:15:42 +1000 (EST) Received: from ka1.ozlabs.ibm.com (ka1.ozlabs.ibm.com [10.61.145.11]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 2146D16ABB7; Fri, 30 Aug 2013 20:15:41 +1000 (EST) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 30 Aug 2013 20:15:28 +1000 Message-Id: <1377857738-14789-3-git-send-email-aik@ozlabs.ru> X-Mailer: git-send-email 1.8.4.rc4 In-Reply-To: <1377857738-14789-1-git-send-email-aik@ozlabs.ru> References: <1377857738-14789-1-git-send-email-aik@ozlabs.ru> X-TM-AS-MML: No X-Content-Scanned: Fidelis XPS MAILER x-cbid: 13083010-5140-0000-0000-000003C0DB5F X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 202.81.31.141 Cc: Alexey Kardashevskiy , Alexander Graf , Alex Williamson , qemu-ppc@nongnu.org, David Gibson Subject: [Qemu-devel] [PATCH v4 02/12] vfio: Create VFIOAddressSpace objects as needed X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- hw/misc/vfio.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index 93a316e..c16f41b 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -133,9 +133,10 @@ enum { typedef struct VFIOAddressSpace { AddressSpace *as; QLIST_HEAD(, VFIOContainer) containers; + QLIST_ENTRY(VFIOAddressSpace) list; } VFIOAddressSpace; -static VFIOAddressSpace vfio_address_space_memory; +QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces; struct VFIOGroup; @@ -2611,10 +2612,34 @@ static int vfio_load_rom(VFIODevice *vdev) return 0; } -static void vfio_address_space_init(VFIOAddressSpace *space, AddressSpace *as) +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, VFIOAddressSpace *space) @@ -2699,6 +2724,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); } @@ -2706,6 +2733,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); } } @@ -3076,6 +3105,7 @@ static int vfio_initfn(PCIDevice *pdev) { VFIODevice *pvdev, *vdev = DO_UPCAST(VFIODevice, pdev, pdev); VFIOGroup *group; + VFIOAddressSpace *space; char path[PATH_MAX], iommu_group_path[PATH_MAX], *group_name; ssize_t len; struct stat st; @@ -3111,14 +3141,12 @@ 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; - } + space = vfio_get_address_space(pci_device_iommu_address_space(pdev)); - group = vfio_get_group(groupid, &vfio_address_space_memory); + group = vfio_get_group(groupid, space); if (!group) { error_report("vfio: failed to get group %d", groupid); + vfio_put_address_space(space); return -ENOENT; } @@ -3339,7 +3367,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); }