From patchwork Mon Sep 11 18:56:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 9947947 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 345EA603FB for ; Mon, 11 Sep 2017 18:37:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 319A228D11 for ; Mon, 11 Sep 2017 18:37:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2624728D0A; Mon, 11 Sep 2017 18:37:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8000528D05 for ; Mon, 11 Sep 2017 18:37:57 +0000 (UTC) Received: from localhost ([::1]:59926 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drTak-0001Rs-7I for patchwork-qemu-devel@patchwork.kernel.org; Mon, 11 Sep 2017 14:37:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42353) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drTZi-0001RP-6r for qemu-devel@nongnu.org; Mon, 11 Sep 2017 14:36:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drTZd-0005iv-Co for qemu-devel@nongnu.org; Mon, 11 Sep 2017 14:36:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33648) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drTZd-0005ih-4I for qemu-devel@nongnu.org; Mon, 11 Sep 2017 14:36:45 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2F897750EE for ; Mon, 11 Sep 2017 18:36:44 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2F897750EE Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=wexu@redhat.com Received: from Wei-Dev.nay.redhat.com (dhcp-15-231.nay.redhat.com [10.66.15.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id 841F2600C8; Mon, 11 Sep 2017 18:36:42 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 02:56:30 +0800 Message-Id: <1505156192-18994-2-git-send-email-wexu@redhat.com> In-Reply-To: <1505156192-18994-1-git-send-email-wexu@redhat.com> References: <1505156192-18994-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 11 Sep 2017 18:36:44 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [Patch 1/3] vfio: reusing address space for the same IOMMU group devices X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: marcel@redhat.com, jasowang@redhat.com, alex.williamson@redhat.com, Wei Xu Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Wei Xu Currently address space of a vfio device is selected by directly looking up pci device IOMMU address space during realizing, this usually works for most none separate address space targeted cases since they are using the system address space, i.e. a q35 machine without virtual IOMMU. Unfortunately, when it comes down to the case having a virtual IOMMU(x86 vtd in this case) and two vfio devices in the same IOMMU group, the virtual IOMMU(vtd) creates two separate address space for each device, this breaks the minimum granularity for vfio, and the device fails realizing by prompting 'group xxx used in multiple address spaces'. This patch is a helper looking up the same IOMMU device before invoking creating an new address space for a device, thus fixes the issue. As a side work for the all groups/devices loop, also it checks if the device has been assigned to the guest twice before creating an extra group and removing it later which is not necessary. Signed-off-by: Wei Xu --- hw/vfio/common.c | 28 ++++++++++++++++++++++++++++ include/hw/vfio/vfio-common.h | 1 + 2 files changed, 29 insertions(+) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 7b2924c..63c3609 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -35,6 +35,7 @@ #include "sysemu/kvm.h" #include "trace.h" #include "qapi/error.h" +#include "hw/vfio/pci.h" struct vfio_group_head vfio_group_list = QLIST_HEAD_INITIALIZER(vfio_group_list); @@ -1183,6 +1184,33 @@ static void vfio_disconnect_container(VFIOGroup *group) } } +AddressSpace *vfio_lookup_as(int groupid, PCIDevice *pdev, Error **errp) +{ + VFIOGroup *group; + VFIODevice *vbasedev_iter; + VFIOPCIDevice *vdev, *vd; + + vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); + QLIST_FOREACH(group, &vfio_group_list, next) { + QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { + if (strcmp(vbasedev_iter->name, vdev->vbasedev.name) == 0) { + error_setg(errp, "device is already attached"); + return 0; + } + + if (vbasedev_iter->group->groupid == groupid) { + vd = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev); + + if (vd->pdev.bus == pdev->bus) { + return vbasedev_iter->group->container->space->as; + } + } + } + } + + return pci_device_iommu_address_space(pdev); +} + VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp) { VFIOGroup *group; diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index f3a2ac9..5b4827b 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -157,6 +157,7 @@ void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled); void vfio_region_exit(VFIORegion *region); void vfio_region_finalize(VFIORegion *region); void vfio_reset_handler(void *opaque); +AddressSpace *vfio_lookup_as(int groupid, PCIDevice *pdev, Error **errp); VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp); void vfio_put_group(VFIOGroup *group); int vfio_get_device(VFIOGroup *group, const char *name,