From patchwork Wed Aug 7 08:21: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: 265393 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 59CD42C00DC for ; Wed, 7 Aug 2013 18:24:14 +1000 (EST) Received: from localhost ([::1]:33658 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V6z2S-0004lU-FF for incoming@patchwork.ozlabs.org; Wed, 07 Aug 2013 04:24:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59198) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V6z0h-0002aI-Bj for qemu-devel@nongnu.org; Wed, 07 Aug 2013 04:22:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V6z0b-0007U5-Fa for qemu-devel@nongnu.org; Wed, 07 Aug 2013 04:22:23 -0400 Received: from mail-pa0-f41.google.com ([209.85.220.41]:34438) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V6z0b-0007Tq-0Z for qemu-devel@nongnu.org; Wed, 07 Aug 2013 04:22:17 -0400 Received: by mail-pa0-f41.google.com with SMTP id bj1so1893807pad.0 for ; Wed, 07 Aug 2013 01:22:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hBMbYRUW87xdsu+U3dpbpdaLtZOFXyardn6dgXaSSO4=; b=k/r3qYCLqfp81tJN1oE0X80efRIrUDmpHSlnxrGiVeiGrgPG58DRs94RWt7eVPb03u kZHuibW6DiRs2V99XOhJ6hP5J914Poc6CcMwG5BcgdMAmAqYlxLfDMiZ+G88fBuavEi9 tMuUaHp3bju1G7vqya9V9K+43GZRG8lS9rh4/Lm/mfQxpxD2iO+ZwIcu8qeTXKawFQHz MLQKSqrnv3iY+zmjSQp9KjahwVdOHa2X610OFPMEjL3pfCsJwiixt20uyXgwMpQGEZNS KUSTXuuG2/V15VQ+PXutr9WecOmpq/OO8mzqqnwlKkXV44193trBYuYhy85jllqboFqd qwFg== X-Gm-Message-State: ALoCoQmgBr62aId/4Mg2FPE9R5V3QbHE2VGQR9flfRfUmuBebCoy+3/7ZxdFgWJi8hLkFaeTqlQr X-Received: by 10.68.227.4 with SMTP id rw4mr2300150pbc.182.1375863736323; Wed, 07 Aug 2013 01:22:16 -0700 (PDT) Received: from ka1.ozlabs.ibm.com (ibmaus65.lnk.telstra.net. [165.228.126.9]) by mx.google.com with ESMTPSA id 7sm8957160paf.22.2013.08.07.01.22.07 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 07 Aug 2013 01:22:11 -0700 (PDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Wed, 7 Aug 2013 18:21:28 +1000 Message-Id: <1375863692-12207-5-git-send-email-aik@ozlabs.ru> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1375863692-12207-1-git-send-email-aik@ozlabs.ru> References: <1375863692-12207-1-git-send-email-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.85.220.41 Cc: Anthony Liguori , "Michael S . Tsirkin" , aik@ozlabs.ru, Alexander Graf , Alex Williamson , qemu-ppc@nongnu.org, Paolo Bonzini , Paul Mackerras , David Gibson Subject: [Qemu-devel] [PATCH 4/8] 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 --- hw/misc/vfio.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index bcd67a0..e1ee56e 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; @@ -2609,10 +2610,33 @@ 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) @@ -2707,6 +2731,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); } @@ -2714,6 +2740,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); } } @@ -3085,6 +3113,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; @@ -3120,14 +3149,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_iommu_as(pdev) != &address_space_memory) { - error_report("vfio: DMA address space must be system memory"); - return -ENXIO; - } + space = vfio_get_address_space(pci_iommu_as(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; } @@ -3348,7 +3375,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); }