From patchwork Fri Nov 24 08:52:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Liu, Yi L" X-Patchwork-Id: 840997 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yjrBT4Njsz9sQl for ; Fri, 24 Nov 2017 20:15:12 +1100 (AEDT) Received: from localhost ([::1]:48123 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eIA4j-0008W1-Pu for incoming@patchwork.ozlabs.org; Fri, 24 Nov 2017 04:15:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48510) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eI9zQ-00049e-VZ for qemu-devel@nongnu.org; Fri, 24 Nov 2017 04:09:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eI9zO-0000L1-JX for qemu-devel@nongnu.org; Fri, 24 Nov 2017 04:09:40 -0500 Received: from mga09.intel.com ([134.134.136.24]:49873) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eI9zO-0000JB-8r for qemu-devel@nongnu.org; Fri, 24 Nov 2017 04:09:38 -0500 Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 24 Nov 2017 01:09:38 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,446,1505804400"; d="scan'208";a="177227773" Received: from sky-dev.bj.intel.com ([10.238.144.127]) by orsmga005.jf.intel.com with ESMTP; 24 Nov 2017 01:09:35 -0800 From: "Liu, Yi L" To: qemu-devel@nongnu.org, mst@redhat.com, david@gibson.dropbear.id.au Date: Fri, 24 Nov 2017 16:52:39 +0800 Message-Id: <1511513560-28611-7-git-send-email-yi.l.liu@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1511513560-28611-1-git-send-email-yi.l.liu@linux.intel.com> References: <1511513560-28611-1-git-send-email-yi.l.liu@linux.intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.24 Subject: [Qemu-devel] [PATCH v2 6/7] vfio/pci: add notify framework based on IOMMUObject 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: tianyu.lan@intel.com, "Liu, Yi L" , kevin.tian@intel.com, yi.l.liu@intel.com, jasowang@redhat.com, peterx@redhat.com, alex.williamson@redhat.com, pbonzini@redhat.com, eric.auger.pro@gmail.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch introduce a notify framework for IOMMUObject.iommu_notifiers. Introduce VFIOGuestIOMMUObject is to link VFIO Container and the new IOMMUObject notififiers. VFIOGuestIOMMUObject instance is allocated when device is assigned and meanwhile vIOMMU is exposed to guest. If there is IOMMUObject behind the device AddressSpace(a.ka vIOMMU exposed). The VFIOGuestIOMMUObject instance would be allocated and inserted to the VFIOContainer.giommu_object_list. Signed-off-by: Liu, Yi L --- hw/vfio/common.c | 1 + hw/vfio/pci.c | 39 ++++++++++++++++++++++++++++++++++++++- include/hw/vfio/vfio-common.h | 9 +++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 3d40bec..9d53e1a 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -990,6 +990,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, container = g_malloc0(sizeof(*container)); container->space = space; container->fd = fd; + QLIST_INIT(&container->giommu_object_list); if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU) || ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU)) { bool v2 = !!ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU); diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index c977ee3..5b77c7e 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -2642,6 +2642,8 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); VFIODevice *vbasedev_iter; VFIOGroup *group; + AddressSpace *as; + IOMMUObject *iommu; char *tmp, group_path[PATH_MAX], *group_name; Error *err = NULL; ssize_t len; @@ -2694,7 +2696,8 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) trace_vfio_realize(vdev->vbasedev.name, groupid); - group = vfio_get_group(groupid, pci_device_iommu_address_space(pdev), errp); + as = pci_device_iommu_address_space(pdev); + group = vfio_get_group(groupid, as, errp); if (!group) { goto error; } @@ -2877,6 +2880,17 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) vfio_register_req_notifier(vdev); vfio_setup_resetfn_quirk(vdev); + iommu = address_space_iommu_get(as); + if (iommu != NULL) { + VFIOGuestIOMMUObject *giommu; + giommu = g_malloc0(sizeof(*giommu)); + giommu->iommu = iommu; + giommu->container = group->container; + QLIST_INSERT_HEAD(&group->container->giommu_object_list, + giommu, + giommu_next); + } + return; out_teardown: @@ -2907,6 +2921,28 @@ static void vfio_instance_finalize(Object *obj) vfio_put_group(group); } +static void vfio_release_iommu_object(PCIDevice *pdev) +{ + VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); + AddressSpace *as; + IOMMUObject *iommu; + + as = pci_device_iommu_address_space(pdev); + iommu = address_space_iommu_get(as); + if (iommu != NULL) { + VFIOGuestIOMMUObject *giommu, *tmp; + VFIOGroup *group; + group = vdev->vbasedev.group; + + QLIST_FOREACH_SAFE(giommu, + &group->container->giommu_object_list, + giommu_next, tmp) { + QLIST_REMOVE(giommu, giommu_next); + g_free(giommu); + } + } + return; +} static void vfio_exitfn(PCIDevice *pdev) { VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); @@ -2915,6 +2951,7 @@ static void vfio_exitfn(PCIDevice *pdev) vfio_unregister_err_notifier(vdev); pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); vfio_disable_interrupts(vdev); + vfio_release_iommu_object(pdev); if (vdev->intx.mmap_timer) { timer_free(vdev->intx.mmap_timer); } diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index 702a085..77075d5 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -29,6 +29,7 @@ #ifdef CONFIG_LINUX #include #endif +#include "hw/core/iommu.h" #define ERR_PREFIX "vfio error: %s: " #define WARN_PREFIX "vfio warning: %s: " @@ -88,6 +89,7 @@ typedef struct VFIOContainer { * future */ QLIST_HEAD(, VFIOGuestIOMMUMR) giommu_mr_list; + QLIST_HEAD(, VFIOGuestIOMMUObject) giommu_object_list; QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; QLIST_HEAD(, VFIOGroup) group_list; QLIST_ENTRY(VFIOContainer) next; @@ -101,6 +103,13 @@ typedef struct VFIOGuestIOMMUMR { QLIST_ENTRY(VFIOGuestIOMMUMR) giommu_next; } VFIOGuestIOMMUMR; +typedef struct VFIOGuestIOMMUObject { + VFIOContainer *container; + IOMMUObject *iommu; + IOMMUNotifier n; + QLIST_ENTRY(VFIOGuestIOMMUObject) giommu_next; +} VFIOGuestIOMMUObject; + typedef struct VFIOHostDMAWindow { hwaddr min_iova; hwaddr max_iova;