From patchwork Thu Aug 26 13:34:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459829 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66457C432BE for ; Thu, 26 Aug 2021 13:37:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 47DEC60EE5 for ; Thu, 26 Aug 2021 13:37:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242620AbhHZNh4 (ORCPT ); Thu, 26 Aug 2021 09:37:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47912 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242595AbhHZNhz (ORCPT ); Thu, 26 Aug 2021 09:37:55 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E22AC061757 for ; Thu, 26 Aug 2021 06:37:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=1gugMjOVOb4yD2aeD89cStVf3/Wj6V9yXQoQv9yuzW8=; b=r5bYXt3ni+WUd3PLPLb8Ymrqry 5UGt1hPGjDttag2QxeY03hLbzMtu/OfbYihrG+X2jhkftOzABeoloYJrW8PbMSLoOCdYLqVOFZZno adYk+QXu3tLwYjsH7tp0z87reaq76fQzVpvYUvWnm2eTwvDJTHEeKmF/KsjcjZN382LXNzwJ2Da7/ XVQqWKYIoad80lwEJ2Vd5M7On2f1aqq0kBarwy7SdlKdBWnsYUeJEUe9OuCHMY3XcplbL4joyRkwl 813qZKS0m7g1kBaLIVOVMEdFLHXdb1TjTwjD0lF7iw93oUlTaQSHcnPFeJeh99SlVSkIM+DMXsomK 8aKqjhTg==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFXY-00DKxJ-3V; Thu, 26 Aug 2021 13:35:41 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe Subject: [PATCH 01/14] vfio: Move vfio_iommu_group_get() to vfio_register_group_dev() Date: Thu, 26 Aug 2021 15:34:11 +0200 Message-Id: <20210826133424.3362-2-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Jason Gunthorpe We don't need to hold a reference to the group in the driver as well as obtain a reference to the same group as the first thing vfio_register_group_dev() does. Since the drivers never use the group move this all into the core code. Signed-off-by: Jason Gunthorpe Signed-off-by: Christoph Hellwig Reviewed-by: Kevin Tian --- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 17 ++------- drivers/vfio/pci/vfio_pci_core.c | 13 ++----- drivers/vfio/platform/vfio_platform_common.c | 13 +------ drivers/vfio/vfio.c | 36 ++++++++------------ include/linux/vfio.h | 3 -- 5 files changed, 19 insertions(+), 63 deletions(-) diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index 0ead91bfa83867..9e838fed560339 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -505,22 +505,13 @@ static void vfio_fsl_uninit_device(struct vfio_fsl_mc_device *vdev) static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) { - struct iommu_group *group; struct vfio_fsl_mc_device *vdev; struct device *dev = &mc_dev->dev; int ret; - group = vfio_iommu_group_get(dev); - if (!group) { - dev_err(dev, "VFIO_FSL_MC: No IOMMU group\n"); - return -EINVAL; - } - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); - if (!vdev) { - ret = -ENOMEM; - goto out_group_put; - } + if (!vdev) + return -ENOMEM; vfio_init_group_dev(&vdev->vdev, dev, &vfio_fsl_mc_ops); vdev->mc_dev = mc_dev; @@ -556,8 +547,6 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) out_uninit: vfio_uninit_group_dev(&vdev->vdev); kfree(vdev); -out_group_put: - vfio_iommu_group_put(group, dev); return ret; } @@ -574,8 +563,6 @@ static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev) vfio_uninit_group_dev(&vdev->vdev); kfree(vdev); - vfio_iommu_group_put(mc_dev->dev.iommu_group, dev); - return 0; } diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index c67751948504af..4134dceab3f73b 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -1807,7 +1807,6 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_uninit_device); int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) { struct pci_dev *pdev = vdev->pdev; - struct iommu_group *group; int ret; if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) @@ -1826,10 +1825,6 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) return -EBUSY; } - group = vfio_iommu_group_get(&pdev->dev); - if (!group) - return -EINVAL; - if (pci_is_root_bus(pdev->bus)) { ret = vfio_assign_device_set(&vdev->vdev, vdev); } else if (!pci_probe_reset_slot(pdev->slot)) { @@ -1843,10 +1838,10 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) } if (ret) - goto out_group_put; + return ret; ret = vfio_pci_vf_init(vdev); if (ret) - goto out_group_put; + return ret; ret = vfio_pci_vga_init(vdev); if (ret) goto out_vf; @@ -1877,8 +1872,6 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) vfio_pci_set_power_state(vdev, PCI_D0); out_vf: vfio_pci_vf_uninit(vdev); -out_group_put: - vfio_iommu_group_put(group, &pdev->dev); return ret; } EXPORT_SYMBOL_GPL(vfio_pci_core_register_device); @@ -1894,8 +1887,6 @@ void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev) vfio_pci_vf_uninit(vdev); vfio_pci_vga_uninit(vdev); - vfio_iommu_group_put(pdev->dev.iommu_group, &pdev->dev); - if (!disable_idle_d3) vfio_pci_set_power_state(vdev, PCI_D0); } diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index 6af7ce7d619c25..256f55b84e70a0 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -642,7 +642,6 @@ static int vfio_platform_of_probe(struct vfio_platform_device *vdev, int vfio_platform_probe_common(struct vfio_platform_device *vdev, struct device *dev) { - struct iommu_group *group; int ret; vfio_init_group_dev(&vdev->vdev, dev, &vfio_platform_ops); @@ -663,24 +662,15 @@ int vfio_platform_probe_common(struct vfio_platform_device *vdev, goto out_uninit; } - group = vfio_iommu_group_get(dev); - if (!group) { - dev_err(dev, "No IOMMU group for device %s\n", vdev->name); - ret = -EINVAL; - goto put_reset; - } - ret = vfio_register_group_dev(&vdev->vdev); if (ret) - goto put_iommu; + goto put_reset; mutex_init(&vdev->igate); pm_runtime_enable(dev); return 0; -put_iommu: - vfio_iommu_group_put(group, dev); put_reset: vfio_platform_put_reset(vdev); out_uninit: @@ -696,7 +686,6 @@ void vfio_platform_remove_common(struct vfio_platform_device *vdev) pm_runtime_disable(vdev->device); vfio_platform_put_reset(vdev); vfio_uninit_group_dev(&vdev->vdev); - vfio_iommu_group_put(vdev->vdev.dev->iommu_group, vdev->vdev.dev); } EXPORT_SYMBOL_GPL(vfio_platform_remove_common); diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 3c034fe14ccb03..b39da9b90c95bc 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -169,15 +169,7 @@ static void vfio_release_device_set(struct vfio_device *device) xa_unlock(&vfio_device_set_xa); } -/* - * vfio_iommu_group_{get,put} are only intended for VFIO bus driver probe - * and remove functions, any use cases other than acquiring the first - * reference for the purpose of calling vfio_register_group_dev() or removing - * that symmetric reference after vfio_unregister_group_dev() should use the raw - * iommu_group_{get,put} functions. In particular, vfio_iommu_group_put() - * removes the device from the dummy group and cannot be nested. - */ -struct iommu_group *vfio_iommu_group_get(struct device *dev) +static struct iommu_group *vfio_iommu_group_get(struct device *dev) { struct iommu_group *group; int __maybe_unused ret; @@ -220,18 +212,6 @@ struct iommu_group *vfio_iommu_group_get(struct device *dev) return group; } -EXPORT_SYMBOL_GPL(vfio_iommu_group_get); - -void vfio_iommu_group_put(struct iommu_group *group, struct device *dev) -{ -#ifdef CONFIG_VFIO_NOIOMMU - if (iommu_group_get_iommudata(group) == &noiommu) - iommu_group_remove_device(dev); -#endif - - iommu_group_put(group); -} -EXPORT_SYMBOL_GPL(vfio_iommu_group_put); #ifdef CONFIG_VFIO_NOIOMMU static void *vfio_noiommu_open(unsigned long arg) @@ -841,7 +821,7 @@ int vfio_register_group_dev(struct vfio_device *device) if (!device->dev_set) vfio_assign_device_set(device, device); - iommu_group = iommu_group_get(device->dev); + iommu_group = vfio_iommu_group_get(device->dev); if (!iommu_group) return -EINVAL; @@ -849,6 +829,10 @@ int vfio_register_group_dev(struct vfio_device *device) if (!group) { group = vfio_create_group(iommu_group); if (IS_ERR(group)) { +#ifdef CONFIG_VFIO_NOIOMMU + if (iommu_group_get_iommudata(iommu_group) == &noiommu) + iommu_group_remove_device(device->dev); +#endif iommu_group_put(iommu_group); return PTR_ERR(group); } @@ -865,6 +849,10 @@ int vfio_register_group_dev(struct vfio_device *device) dev_WARN(device->dev, "Device already exists on group %d\n", iommu_group_id(iommu_group)); vfio_device_put(existing_device); +#ifdef CONFIG_VFIO_NOIOMMU + if (iommu_group_get_iommudata(iommu_group) == &noiommu) + iommu_group_remove_device(device->dev); +#endif vfio_group_put(group); return -EBUSY; } @@ -1010,6 +998,10 @@ void vfio_unregister_group_dev(struct vfio_device *device) if (list_empty(&group->device_list)) wait_event(group->container_q, !group->container); +#ifdef CONFIG_VFIO_NOIOMMU + if (iommu_group_get_iommudata(group) == &noiommu) + iommu_group_remove_device(dev); +#endif /* Matches the get in vfio_register_group_dev() */ vfio_group_put(group); } diff --git a/include/linux/vfio.h b/include/linux/vfio.h index b53a9557884ada..f7083c2fd0d099 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -71,9 +71,6 @@ struct vfio_device_ops { int (*match)(struct vfio_device *vdev, char *buf); }; -extern struct iommu_group *vfio_iommu_group_get(struct device *dev); -extern void vfio_iommu_group_put(struct iommu_group *group, struct device *dev); - void vfio_init_group_dev(struct vfio_device *device, struct device *dev, const struct vfio_device_ops *ops); void vfio_uninit_group_dev(struct vfio_device *device); From patchwork Thu Aug 26 13:34:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459831 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C2A1C432BE for ; Thu, 26 Aug 2021 13:37:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 311DD60EE5 for ; Thu, 26 Aug 2021 13:37:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242691AbhHZNi2 (ORCPT ); Thu, 26 Aug 2021 09:38:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48028 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241385AbhHZNiX (ORCPT ); Thu, 26 Aug 2021 09:38:23 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E756C061757 for ; Thu, 26 Aug 2021 06:37:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=vweiZh77d6HbzrcxiqPv9iaxIdW7lH4OOzT9ZJhkw1U=; b=rhBpAY+6d4GbzCnyIUYINvPnSV HPfUgQ+hCDPCRU9swdkVRnAMapzUDMQOoSjGzorwXx4mD+NCTqaG0MI+qHHMT+swJQHYWDNADzQYn TS7QtuL2YNtnFDOZm+RjgCbsn4V9+944IFg5Yp1nV1n+xgZvWfxu8LKHr9SCSBtLwcKQGz7F0Ob3Q /w+95c1Q/sKNfRBmszxfhC6/mqMASVFzZUfldMHGRr6chxAg7hUcqVrCSLS65DSMjRb3aDCYmCIEO Y1zdjO84l7rxwZLzgJqqOGP8FiGIePgMxTOHtHi1ZVZZWMuWKxU0A22rwjT/XvMz4bz8P5WOY/3AI Kkg7b5YA==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFY5-00DKzG-Sc; Thu, 26 Aug 2021 13:36:35 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe , Kevin Tian Subject: [PATCH 02/14] vfio: factor out a vfio_iommu_driver_allowed helper Date: Thu, 26 Aug 2021 15:34:12 +0200 Message-Id: <20210826133424.3362-3-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Factor out a little helper to make the checks for the noiommu driver less ugly. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/vfio/vfio.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index b39da9b90c95bc..e53756743f1b6a 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -257,8 +257,23 @@ static const struct vfio_iommu_driver_ops vfio_noiommu_ops = { .attach_group = vfio_noiommu_attach_group, .detach_group = vfio_noiommu_detach_group, }; -#endif +/* + * Only noiommu containers can use vfio-noiommu and noiommu containers can only + * use vfio-noiommu. + */ +static inline bool vfio_iommu_driver_allowed(struct vfio_container *container, + const struct vfio_iommu_driver *driver) +{ + return container->noiommu == (driver->ops == &vfio_noiommu_ops); +} +#else +static inline bool vfio_iommu_driver_allowed(struct vfio_container *container, + const struct vfio_iommu_driver *driver) +{ + return true; +} +#endif /* CONFIG_VFIO_NOIOMMU */ /** * IOMMU driver registration @@ -1034,13 +1049,10 @@ static long vfio_ioctl_check_extension(struct vfio_container *container, list_for_each_entry(driver, &vfio.iommu_drivers_list, vfio_next) { -#ifdef CONFIG_VFIO_NOIOMMU if (!list_empty(&container->group_list) && - (container->noiommu != - (driver->ops == &vfio_noiommu_ops))) + !vfio_iommu_driver_allowed(container, + driver)) continue; -#endif - if (!try_module_get(driver->ops->owner)) continue; @@ -1112,15 +1124,8 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container, list_for_each_entry(driver, &vfio.iommu_drivers_list, vfio_next) { void *data; -#ifdef CONFIG_VFIO_NOIOMMU - /* - * Only noiommu containers can use vfio-noiommu and noiommu - * containers can only use vfio-noiommu. - */ - if (container->noiommu != (driver->ops == &vfio_noiommu_ops)) + if (!vfio_iommu_driver_allowed(container, driver)) continue; -#endif - if (!try_module_get(driver->ops->owner)) continue; From patchwork Thu Aug 26 13:34:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459833 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5EBABC432BE for ; Thu, 26 Aug 2021 13:39:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3A65560F14 for ; Thu, 26 Aug 2021 13:39:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241040AbhHZNkB (ORCPT ); Thu, 26 Aug 2021 09:40:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231371AbhHZNjz (ORCPT ); Thu, 26 Aug 2021 09:39:55 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5CB99C061757 for ; Thu, 26 Aug 2021 06:39:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=eN/+KvzSZNvHy0+wq4CetUXHeTpEHLZMtI58VYyqtpM=; b=mXDTBFE2TFsD6Dxe1nuyiAoRim Nsu2dyPR9gYmoFGrb4UjrPm/T3hE9PGVbIL9BQBf3jbLWPS0sF3lCV3jtnZRAvnR/pSYKAkqRaE6M Si8pIV24ykwwlw1s0cOur4JKZdP7qhVGKWZq5U9fIuOuiyYDSh4k4uK8z6onzKv7blgEh2i5I2pHd GUld4qQlbdgFyfogeghAJEfVc8VIT7cEYA5D2DGeXLLsT/JoTp8Otfj1NKqjlQIJbAx7sp5fjfmsG Gf7U/htQX2ED/2lFODP0FXqlPutR85Nh7pFJ0iZcjy5317vhHwgjnu/xy0y1XTtR+VqkiRNM2TbjZ sUxSSD5Q==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFZ0-00DL3L-RK; Thu, 26 Aug 2021 13:37:15 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe , Kevin Tian Subject: [PATCH 03/14] vfio: remove the iommudata check in vfio_noiommu_attach_group Date: Thu, 26 Aug 2021 15:34:13 +0200 Message-Id: <20210826133424.3362-4-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org vfio_noiommu_attach_group has two callers: 1) __vfio_container_attach_groups is called by vfio_ioctl_set_iommu, which just called vfio_iommu_driver_allowed 2) vfio_group_set_container requires already checks ->noiommu on the vfio_group, which is propagated from the iommudata in vfio_create_group so this check is entirely superflous and can be removed. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/vfio/vfio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index e53756743f1b6a..18e4c7906d1b3f 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -240,7 +240,7 @@ static long vfio_noiommu_ioctl(void *iommu_data, static int vfio_noiommu_attach_group(void *iommu_data, struct iommu_group *iommu_group) { - return iommu_group_get_iommudata(iommu_group) == &noiommu ? 0 : -EINVAL; + return 0; } static void vfio_noiommu_detach_group(void *iommu_data, From patchwork Thu Aug 26 13:34:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459867 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A01AEC432BE for ; Thu, 26 Aug 2021 13:40:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 77B8760F14 for ; Thu, 26 Aug 2021 13:40:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242746AbhHZNlI (ORCPT ); Thu, 26 Aug 2021 09:41:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48662 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242681AbhHZNlH (ORCPT ); Thu, 26 Aug 2021 09:41:07 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8C606C0613C1 for ; Thu, 26 Aug 2021 06:40:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=wbQ0tQTp/hqLaCjQ4F1Xqzgarh8YawHi7exDeqiqN/Y=; b=Gphhx/dzw2vWPDCDL1J27iLHdY J0IUl2uyFLr3qBdiaJ15cATH8jVyhZfIKed3xXjy5fnOpFbuEUNMbw2G6PeQeTGh4fusjfGgUz3xb VlYNIvaow/AQKQEnOw2Wjg+gLB68iOPaq9rshH7h/Kmd1HKZpHTM30Ls0Iyc/Rsw5gT9PBy+KPuOt 8PKe295zeT8zs/lwS0lk9XMIXszfWxMk+kb9QBNwg1x70jJpvk8Yq/LksbdQystOe3XY7+Gt1lqMJ 9z4S2D7HxUm2Yf/HhzY8to6qOS+70slJUrhJ1+hhJrdiRBCGVOijvVU2w81zO/TRvL/LclCPH5/be QoS8Gb2Q==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFa6-00DL5a-DL; Thu, 26 Aug 2021 13:38:40 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe Subject: [PATCH 04/14] vfio: factor out a vfio_group_find_or_alloc helper Date: Thu, 26 Aug 2021 15:34:14 +0200 Message-Id: <20210826133424.3362-5-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Factor out a helper to find or allocate the vfio_group to reduce the spagetthi code in vfio_register_group_dev a little. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe --- drivers/vfio/vfio.c | 59 ++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 18e4c7906d1b3f..852fe22125520d 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -823,10 +823,38 @@ void vfio_uninit_group_dev(struct vfio_device *device) } EXPORT_SYMBOL_GPL(vfio_uninit_group_dev); +struct vfio_group *vfio_group_find_or_alloc(struct device *dev) +{ + struct iommu_group *iommu_group; + struct vfio_group *group; + + iommu_group = vfio_iommu_group_get(dev); + if (!iommu_group) + return ERR_PTR(-EINVAL); + + /* a found vfio_group already holds a reference to the iommu_group */ + group = vfio_group_get_from_iommu(iommu_group); + if (group) + goto out_put; + + /* a newly created vfio_group keeps the reference. */ + group = vfio_create_group(iommu_group); + if (IS_ERR(group)) + goto out_put; + return group; + +out_put: +#ifdef CONFIG_VFIO_NOIOMMU + if (iommu_group_get_iommudata(iommu_group) == &noiommu) + iommu_group_remove_device(dev); +#endif + iommu_group_put(iommu_group); + return group; +} + int vfio_register_group_dev(struct vfio_device *device) { struct vfio_device *existing_device; - struct iommu_group *iommu_group; struct vfio_group *group; /* @@ -836,36 +864,17 @@ int vfio_register_group_dev(struct vfio_device *device) if (!device->dev_set) vfio_assign_device_set(device, device); - iommu_group = vfio_iommu_group_get(device->dev); - if (!iommu_group) - return -EINVAL; - - group = vfio_group_get_from_iommu(iommu_group); - if (!group) { - group = vfio_create_group(iommu_group); - if (IS_ERR(group)) { -#ifdef CONFIG_VFIO_NOIOMMU - if (iommu_group_get_iommudata(iommu_group) == &noiommu) - iommu_group_remove_device(device->dev); -#endif - iommu_group_put(iommu_group); - return PTR_ERR(group); - } - } else { - /* - * A found vfio_group already holds a reference to the - * iommu_group. A created vfio_group keeps the reference. - */ - iommu_group_put(iommu_group); - } + group = vfio_group_find_or_alloc(device->dev); + if (IS_ERR(group)) + return PTR_ERR(group); existing_device = vfio_group_get_device(group, device->dev); if (existing_device) { dev_WARN(device->dev, "Device already exists on group %d\n", - iommu_group_id(iommu_group)); + iommu_group_id(group->iommu_group)); vfio_device_put(existing_device); #ifdef CONFIG_VFIO_NOIOMMU - if (iommu_group_get_iommudata(iommu_group) == &noiommu) + if (iommu_group_get_iommudata(group->iommu_group) == &noiommu) iommu_group_remove_device(device->dev); #endif vfio_group_put(group); From patchwork Thu Aug 26 13:34:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459869 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 99E07C432BE for ; Thu, 26 Aug 2021 13:41:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7B91060E73 for ; Thu, 26 Aug 2021 13:41:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242745AbhHZNm1 (ORCPT ); Thu, 26 Aug 2021 09:42:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242712AbhHZNm1 (ORCPT ); Thu, 26 Aug 2021 09:42:27 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D4BA1C061757 for ; Thu, 26 Aug 2021 06:41:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=+5pcR9shTFpIoryoVzMQ1haWJAZEzLk7xrUKnLWneaU=; b=mx48KhCIa67B1IjB+6Du85ZJeE 6xCadWsnGdUXzQOr1RqHCYQh1cFJ2U4FL/VfQtQhb+d0vw5EzvfghZDEigWUiALMInsdqypmUJJWX tCUJlxTGFLYYRsIwJuovv87vPAp5y+ncP4CWH0SylN5PdxJ4/AJqTrOmGf6gcT2+UEr4s1ZPrFrxg oCC7KffVcgnrpJyb9VXsYww2/7iNXrRp3bZLcJQDCz8fVfh+6syJ3XYaYRCMjahCBffdIcf+FDxCF 73iiQcJ7s8svW69PNc8NpMdLuLSz+CJowS1hcCUlYJ51nadDIPbDLC/TpoKcyu65+QWGgZisOyq8t 1tN1GSWw==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFbG-00DL87-Rg; Thu, 26 Aug 2021 13:39:53 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe Subject: [PATCH 05/14] vfio: refactor noiommu group creation Date: Thu, 26 Aug 2021 15:34:15 +0200 Message-Id: <20210826133424.3362-6-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Split the actual noiommu group creation from vfio_iommu_group_get into a new helper, and open code the rest of vfio_iommu_group_get in its only caller. This creates an entirely separate and clear code path for the noiommu group creation. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe --- drivers/vfio/vfio.c | 101 ++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 852fe22125520d..109d3ef57665b0 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -169,50 +169,6 @@ static void vfio_release_device_set(struct vfio_device *device) xa_unlock(&vfio_device_set_xa); } -static struct iommu_group *vfio_iommu_group_get(struct device *dev) -{ - struct iommu_group *group; - int __maybe_unused ret; - - group = iommu_group_get(dev); - -#ifdef CONFIG_VFIO_NOIOMMU - /* - * With noiommu enabled, an IOMMU group will be created for a device - * that doesn't already have one and doesn't have an iommu_ops on their - * bus. We set iommudata simply to be able to identify these groups - * as special use and for reclamation later. - */ - if (group || !noiommu || iommu_present(dev->bus)) - return group; - - group = iommu_group_alloc(); - if (IS_ERR(group)) - return NULL; - - iommu_group_set_name(group, "vfio-noiommu"); - iommu_group_set_iommudata(group, &noiommu, NULL); - ret = iommu_group_add_device(group, dev); - if (ret) { - iommu_group_put(group); - return NULL; - } - - /* - * Where to taint? At this point we've added an IOMMU group for a - * device that is not backed by iommu_ops, therefore any iommu_ - * callback using iommu_ops can legitimately Oops. So, while we may - * be about to give a DMA capable device to a user without IOMMU - * protection, which is clearly taint-worthy, let's go ahead and do - * it here. - */ - add_taint(TAINT_USER, LOCKDEP_STILL_OK); - dev_warn(dev, "Adding kernel taint for vfio-noiommu group on device\n"); -#endif - - return group; -} - #ifdef CONFIG_VFIO_NOIOMMU static void *vfio_noiommu_open(unsigned long arg) { @@ -823,12 +779,61 @@ void vfio_uninit_group_dev(struct vfio_device *device) } EXPORT_SYMBOL_GPL(vfio_uninit_group_dev); -struct vfio_group *vfio_group_find_or_alloc(struct device *dev) +#ifdef CONFIG_VFIO_NOIOMMU +static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev) { struct iommu_group *iommu_group; struct vfio_group *group; + int ret; + + iommu_group = iommu_group_alloc(); + if (IS_ERR(iommu_group)) + return ERR_CAST(iommu_group); - iommu_group = vfio_iommu_group_get(dev); + iommu_group_set_name(iommu_group, "vfio-noiommu"); + iommu_group_set_iommudata(iommu_group, &noiommu, NULL); + ret = iommu_group_add_device(iommu_group, dev); + if (ret) + goto out_put_group; + + group = vfio_create_group(iommu_group); + if (IS_ERR(group)) { + ret = PTR_ERR(group); + goto out_remove_device; + } + + return group; + +out_remove_device: + iommu_group_remove_device(dev); +out_put_group: + iommu_group_put(iommu_group); + return ERR_PTR(ret); +} +#endif + +static struct vfio_group *vfio_group_find_or_alloc(struct device *dev) +{ + struct iommu_group *iommu_group; + struct vfio_group *group; + + iommu_group = iommu_group_get(dev); +#ifdef CONFIG_VFIO_NOIOMMU + if (!iommu_group && noiommu && !iommu_present(dev->bus)) { + /* + * With noiommu enabled, create an IOMMU group for devices that + * don't already have one and don't have an iommu_ops on their + * bus. Taint the kernel because we're about to give a DMA + * capable device to a user without IOMMU protection. + */ + group = vfio_noiommu_group_alloc(dev); + if (group) { + add_taint(TAINT_USER, LOCKDEP_STILL_OK); + dev_warn(dev, "Adding kernel taint for vfio-noiommu group on device\n"); + } + return group; + } +#endif if (!iommu_group) return ERR_PTR(-EINVAL); @@ -844,10 +849,6 @@ struct vfio_group *vfio_group_find_or_alloc(struct device *dev) return group; out_put: -#ifdef CONFIG_VFIO_NOIOMMU - if (iommu_group_get_iommudata(iommu_group) == &noiommu) - iommu_group_remove_device(dev); -#endif iommu_group_put(iommu_group); return group; } From patchwork Thu Aug 26 13:34:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459871 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9F66C4320A for ; Thu, 26 Aug 2021 13:42:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7E0DB60F14 for ; Thu, 26 Aug 2021 13:42:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242681AbhHZNnf (ORCPT ); Thu, 26 Aug 2021 09:43:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242505AbhHZNnd (ORCPT ); Thu, 26 Aug 2021 09:43:33 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A928FC061757 for ; Thu, 26 Aug 2021 06:42:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=o2yq1I0CE2cySW6RIxK8EwSBq7/HAENLE5xnuyoKIt8=; b=u34HgMb+nH1wQSUqYuOiivTMH1 lkKmMVbVmo4pCNTWDNX/0qJtr3q4k/20eg/MyL4QR7LIJ+IQ9jrHsD/kbOlfisG2zv8WiPIJ/qvc0 dTCPNPp65tqosoJ9vdJeLYPYNxhTYYI2j04aO0fhDl3Il4fqsJDBNx8e+gP54otg+HvEr0JFdiVKB afjllwD/lZhsABxVvX7UQQ+p9zguOF9UBGgccO9He8YT+ZwCyurhgEPu+zE77D0M9sGKwGM0BatBl /YkVU+RedOY0r6WzNGMZOlA4DbdtcbmZb3a8LB9SHj9NuJawM3ZvK6jTulOYT+NeHn+dit9Pb0YmV 04sYjTqQ==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFcl-00DLFS-GL; Thu, 26 Aug 2021 13:41:16 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe , Kevin Tian Subject: [PATCH 06/14] vfio: remove the iommudata hack for noiommu groups Date: Thu, 26 Aug 2021 15:34:16 +0200 Message-Id: <20210826133424.3362-7-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Just pass a noiommu argument to vfio_create_group and set up the ->noiommu flag directly, and remove the now superflous vfio_iommu_group_put helper. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/vfio/vfio.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 109d3ef57665b0..94c5e18a05e0d0 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -335,7 +335,8 @@ static void vfio_group_unlock_and_free(struct vfio_group *group) /** * Group objects - create, release, get, put, search */ -static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) +static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group, + bool noiommu) { struct vfio_group *group, *tmp; struct device *dev; @@ -354,9 +355,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) atomic_set(&group->opened, 0); init_waitqueue_head(&group->container_q); group->iommu_group = iommu_group; -#ifdef CONFIG_VFIO_NOIOMMU - group->noiommu = (iommu_group_get_iommudata(iommu_group) == &noiommu); -#endif + group->noiommu = noiommu; BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier); group->nb.notifier_call = vfio_iommu_group_notifier; @@ -791,12 +790,11 @@ static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev) return ERR_CAST(iommu_group); iommu_group_set_name(iommu_group, "vfio-noiommu"); - iommu_group_set_iommudata(iommu_group, &noiommu, NULL); ret = iommu_group_add_device(iommu_group, dev); if (ret) goto out_put_group; - group = vfio_create_group(iommu_group); + group = vfio_create_group(iommu_group, true); if (IS_ERR(group)) { ret = PTR_ERR(group); goto out_remove_device; @@ -843,7 +841,7 @@ static struct vfio_group *vfio_group_find_or_alloc(struct device *dev) goto out_put; /* a newly created vfio_group keeps the reference. */ - group = vfio_create_group(iommu_group); + group = vfio_create_group(iommu_group, false); if (IS_ERR(group)) goto out_put; return group; @@ -874,10 +872,8 @@ int vfio_register_group_dev(struct vfio_device *device) dev_WARN(device->dev, "Device already exists on group %d\n", iommu_group_id(group->iommu_group)); vfio_device_put(existing_device); -#ifdef CONFIG_VFIO_NOIOMMU - if (iommu_group_get_iommudata(group->iommu_group) == &noiommu) + if (group->noiommu) iommu_group_remove_device(device->dev); -#endif vfio_group_put(group); return -EBUSY; } @@ -1023,10 +1019,9 @@ void vfio_unregister_group_dev(struct vfio_device *device) if (list_empty(&group->device_list)) wait_event(group->container_q, !group->container); -#ifdef CONFIG_VFIO_NOIOMMU - if (iommu_group_get_iommudata(group) == &noiommu) - iommu_group_remove_device(dev); -#endif + if (group->noiommu) + iommu_group_remove_device(device->dev); + /* Matches the get in vfio_register_group_dev() */ vfio_group_put(group); } From patchwork Thu Aug 26 13:34:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459873 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D88FC4320E for ; Thu, 26 Aug 2021 13:43:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 26E1660F14 for ; Thu, 26 Aug 2021 13:43:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242710AbhHZNo2 (ORCPT ); Thu, 26 Aug 2021 09:44:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242049AbhHZNo1 (ORCPT ); Thu, 26 Aug 2021 09:44:27 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 792D6C061757 for ; Thu, 26 Aug 2021 06:43:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=M3SN9rMK+D3E6Ah6OxIQn6DJhsA+5sCWJQ0ClGk+71Y=; b=oYhT5H42nQyCURDyPc8dRtNPrv eFw8jdbxiMxclq0RaHrLabhh7zJiBOnOYZtyo6dGQt0Z4jqEYTjWvNBBD8CTNoVr4QG0WSUa/dqdm GrQyxN86tLfnUJSRnobnbM4AqDjuezQ1NhyJG8m9YdR6LJtxHS0byjVIIc5hqP5wH5+SGmMfKoVWk t4rt1SDdcfT2B7aSjGdL/qFNyzjDx7prFqTJD6yQcPmNtoOVa2gwC7n5tC+Cr31pLKUxL+rVKOnd4 /cv9S0IG6xCsD5AfwzQCossU4ZoVUoeiqCYQY959t7W3aPKUsd5hxuhVLDpUIONUlddcrfHbL0z79 0DvApjOw==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFe3-00DLNA-Gf; Thu, 26 Aug 2021 13:42:28 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe Subject: [PATCH 07/14] vfio: simplify iommu group allocation for mediated devices Date: Thu, 26 Aug 2021 15:34:17 +0200 Message-Id: <20210826133424.3362-8-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Reuse the logic in vfio_noiommu_group_alloc to allocate a fake single-device iommu group for mediated devices. A new function is exposed to create vfio_device for this emulated case and the noiommu boolean field in struct vfio_group is replaced with a set of flags so that devices with an emulated IOMMU can be distinguished from those with no IOMMU at all. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe --- drivers/vfio/mdev/mdev_driver.c | 46 ++---------------- drivers/vfio/mdev/vfio_mdev.c | 2 +- drivers/vfio/vfio.c | 82 ++++++++++++++++++++++----------- include/linux/vfio.h | 1 + samples/vfio-mdev/mbochs.c | 2 +- samples/vfio-mdev/mdpy.c | 2 +- samples/vfio-mdev/mtty.c | 2 +- 7 files changed, 65 insertions(+), 72 deletions(-) diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c index c368ec824e2b5c..14b9ab17426838 100644 --- a/drivers/vfio/mdev/mdev_driver.c +++ b/drivers/vfio/mdev/mdev_driver.c @@ -13,61 +13,23 @@ #include "mdev_private.h" -static int mdev_attach_iommu(struct mdev_device *mdev) -{ - int ret; - struct iommu_group *group; - - group = iommu_group_alloc(); - if (IS_ERR(group)) - return PTR_ERR(group); - - ret = iommu_group_add_device(group, &mdev->dev); - if (!ret) - dev_info(&mdev->dev, "MDEV: group_id = %d\n", - iommu_group_id(group)); - - iommu_group_put(group); - return ret; -} - -static void mdev_detach_iommu(struct mdev_device *mdev) -{ - iommu_group_remove_device(&mdev->dev); - dev_info(&mdev->dev, "MDEV: detaching iommu\n"); -} - static int mdev_probe(struct device *dev) { struct mdev_driver *drv = container_of(dev->driver, struct mdev_driver, driver); - struct mdev_device *mdev = to_mdev_device(dev); - int ret; - - ret = mdev_attach_iommu(mdev); - if (ret) - return ret; - if (drv->probe) { - ret = drv->probe(mdev); - if (ret) - mdev_detach_iommu(mdev); - } - - return ret; + if (!drv->probe) + return 0; + return drv->probe(to_mdev_device(dev)); } static int mdev_remove(struct device *dev) { struct mdev_driver *drv = container_of(dev->driver, struct mdev_driver, driver); - struct mdev_device *mdev = to_mdev_device(dev); if (drv->remove) - drv->remove(mdev); - - mdev_detach_iommu(mdev); - + drv->remove(to_mdev_device(dev)); return 0; } diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c index 7a9883048216e7..a90e24b0c851d3 100644 --- a/drivers/vfio/mdev/vfio_mdev.c +++ b/drivers/vfio/mdev/vfio_mdev.c @@ -119,7 +119,7 @@ static int vfio_mdev_probe(struct mdev_device *mdev) return -ENOMEM; vfio_init_group_dev(vdev, &mdev->dev, &vfio_mdev_dev_ops); - ret = vfio_register_group_dev(vdev); + ret = vfio_register_emulated_iommu_dev(vdev); if (ret) goto out_uninit; diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 94c5e18a05e0d0..467432379b91ef 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -67,6 +67,21 @@ struct vfio_unbound_dev { struct list_head unbound_next; }; +/* + * Virtual device without IOMMU backing. The VFIO core fakes up an iommu_group + * as the iommu_group sysfs interface is part of the userspace ABI. The user + * of these devices must not be able to directly trigger unmediated DMA. + */ +#define VFIO_EMULATED_IOMMU (1 << 0) + +/* + * Physical device without IOMMU backing. The VFIO core fakes up an iommu_group + * as the iommu_group sysfs interface is part of the userspace ABI. Users can + * trigger unmediated DMA by the device, usage is highly dangerous, requires + * an explicit opt-in and will taint the kernel. + */ +#define VFIO_NO_IOMMU (1 << 1) + struct vfio_group { struct kref kref; int minor; @@ -83,7 +98,7 @@ struct vfio_group { struct mutex unbound_lock; atomic_t opened; wait_queue_head_t container_q; - bool noiommu; + unsigned int flags; unsigned int dev_counter; struct kvm *kvm; struct blocking_notifier_head notifier; @@ -336,7 +351,7 @@ static void vfio_group_unlock_and_free(struct vfio_group *group) * Group objects - create, release, get, put, search */ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group, - bool noiommu) + unsigned int flags) { struct vfio_group *group, *tmp; struct device *dev; @@ -355,7 +370,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group, atomic_set(&group->opened, 0); init_waitqueue_head(&group->container_q); group->iommu_group = iommu_group; - group->noiommu = noiommu; + group->flags = flags; BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier); group->nb.notifier_call = vfio_iommu_group_notifier; @@ -391,8 +406,8 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group, } dev = device_create(vfio.class, NULL, - MKDEV(MAJOR(vfio.group_devt), minor), - group, "%s%d", group->noiommu ? "noiommu-" : "", + MKDEV(MAJOR(vfio.group_devt), minor), group, "%s%d", + (group->flags & VFIO_NO_IOMMU) ? "noiommu-" : "", iommu_group_id(iommu_group)); if (IS_ERR(dev)) { vfio_free_group_minor(minor); @@ -778,8 +793,8 @@ void vfio_uninit_group_dev(struct vfio_device *device) } EXPORT_SYMBOL_GPL(vfio_uninit_group_dev); -#ifdef CONFIG_VFIO_NOIOMMU -static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev) +static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev, + unsigned int flags) { struct iommu_group *iommu_group; struct vfio_group *group; @@ -794,7 +809,7 @@ static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev) if (ret) goto out_put_group; - group = vfio_create_group(iommu_group, true); + group = vfio_create_group(iommu_group, flags); if (IS_ERR(group)) { ret = PTR_ERR(group); goto out_remove_device; @@ -808,7 +823,6 @@ static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev) iommu_group_put(iommu_group); return ERR_PTR(ret); } -#endif static struct vfio_group *vfio_group_find_or_alloc(struct device *dev) { @@ -824,7 +838,7 @@ static struct vfio_group *vfio_group_find_or_alloc(struct device *dev) * bus. Taint the kernel because we're about to give a DMA * capable device to a user without IOMMU protection. */ - group = vfio_noiommu_group_alloc(dev); + group = vfio_noiommu_group_alloc(dev, VFIO_NO_IOMMU); if (group) { add_taint(TAINT_USER, LOCKDEP_STILL_OK); dev_warn(dev, "Adding kernel taint for vfio-noiommu group on device\n"); @@ -841,7 +855,7 @@ static struct vfio_group *vfio_group_find_or_alloc(struct device *dev) goto out_put; /* a newly created vfio_group keeps the reference. */ - group = vfio_create_group(iommu_group, false); + group = vfio_create_group(iommu_group, 0); if (IS_ERR(group)) goto out_put; return group; @@ -851,10 +865,13 @@ static struct vfio_group *vfio_group_find_or_alloc(struct device *dev) return group; } -int vfio_register_group_dev(struct vfio_device *device) +static int __vfio_register_dev(struct vfio_device *device, + struct vfio_group *group) { struct vfio_device *existing_device; - struct vfio_group *group; + + if (IS_ERR(group)) + return PTR_ERR(group); /* * If the driver doesn't specify a set then the device is added to a @@ -863,16 +880,12 @@ int vfio_register_group_dev(struct vfio_device *device) if (!device->dev_set) vfio_assign_device_set(device, device); - group = vfio_group_find_or_alloc(device->dev); - if (IS_ERR(group)) - return PTR_ERR(group); - existing_device = vfio_group_get_device(group, device->dev); if (existing_device) { dev_WARN(device->dev, "Device already exists on group %d\n", iommu_group_id(group->iommu_group)); vfio_device_put(existing_device); - if (group->noiommu) + if (group->flags & (VFIO_NO_IOMMU | VFIO_EMULATED_IOMMU)) iommu_group_remove_device(device->dev); vfio_group_put(group); return -EBUSY; @@ -891,8 +904,25 @@ int vfio_register_group_dev(struct vfio_device *device) return 0; } + +int vfio_register_group_dev(struct vfio_device *device) +{ + return __vfio_register_dev(device, + vfio_group_find_or_alloc(device->dev)); +} EXPORT_SYMBOL_GPL(vfio_register_group_dev); +/* + * Register a virtual device without IOMMU backing. The user of this + * device must not be able to directly trigger unmediated DMA. + */ +int vfio_register_emulated_iommu_dev(struct vfio_device *device) +{ + return __vfio_register_dev(device, + vfio_noiommu_group_alloc(device->dev, VFIO_EMULATED_IOMMU)); +} +EXPORT_SYMBOL_GPL(vfio_register_emulated_iommu_dev); + /** * Get a reference to the vfio_device for a device. Even if the * caller thinks they own the device, they could be racing with a @@ -1019,7 +1049,7 @@ void vfio_unregister_group_dev(struct vfio_device *device) if (list_empty(&group->device_list)) wait_event(group->container_q, !group->container); - if (group->noiommu) + if (group->flags & (VFIO_NO_IOMMU | VFIO_EMULATED_IOMMU)) iommu_group_remove_device(device->dev); /* Matches the get in vfio_register_group_dev() */ @@ -1368,7 +1398,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) if (atomic_read(&group->container_users)) return -EINVAL; - if (group->noiommu && !capable(CAP_SYS_RAWIO)) + if ((group->flags & VFIO_NO_IOMMU) && !capable(CAP_SYS_RAWIO)) return -EPERM; f = fdget(container_fd); @@ -1388,7 +1418,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) /* Real groups and fake groups cannot mix */ if (!list_empty(&container->group_list) && - container->noiommu != group->noiommu) { + container->noiommu != (group->flags & VFIO_NO_IOMMU)) { ret = -EPERM; goto unlock_out; } @@ -1402,7 +1432,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) } group->container = container; - container->noiommu = group->noiommu; + container->noiommu = (group->flags & VFIO_NO_IOMMU); list_add(&group->container_next, &container->group_list); /* Get a reference on the container and mark a user within the group */ @@ -1426,7 +1456,7 @@ static int vfio_group_add_container_user(struct vfio_group *group) if (!atomic_inc_not_zero(&group->container_users)) return -EINVAL; - if (group->noiommu) { + if (group->flags & VFIO_NO_IOMMU) { atomic_dec(&group->container_users); return -EPERM; } @@ -1451,7 +1481,7 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) !group->container->iommu_driver || !vfio_group_viable(group)) return -EINVAL; - if (group->noiommu && !capable(CAP_SYS_RAWIO)) + if ((group->flags & VFIO_NO_IOMMU) && !capable(CAP_SYS_RAWIO)) return -EPERM; device = vfio_device_get_from_name(group, buf); @@ -1498,7 +1528,7 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) fd_install(fdno, filep); - if (group->noiommu) + if (group->flags & VFIO_NO_IOMMU) dev_warn(device->dev, "vfio-noiommu device opened by user " "(%s:%d)\n", current->comm, task_pid_nr(current)); return fdno; @@ -1594,7 +1624,7 @@ static int vfio_group_fops_open(struct inode *inode, struct file *filep) if (!group) return -ENODEV; - if (group->noiommu && !capable(CAP_SYS_RAWIO)) { + if ((group->flags & VFIO_NO_IOMMU) && !capable(CAP_SYS_RAWIO)) { vfio_group_put(group); return -EPERM; } diff --git a/include/linux/vfio.h b/include/linux/vfio.h index f7083c2fd0d099..bbe29300862649 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -75,6 +75,7 @@ void vfio_init_group_dev(struct vfio_device *device, struct device *dev, const struct vfio_device_ops *ops); void vfio_uninit_group_dev(struct vfio_device *device); int vfio_register_group_dev(struct vfio_device *device); +int vfio_register_emulated_iommu_dev(struct vfio_device *device); void vfio_unregister_group_dev(struct vfio_device *device); extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); extern void vfio_device_put(struct vfio_device *device); diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index c313ab4d1f4e4e..cd41bec5fdeb39 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -553,7 +553,7 @@ static int mbochs_probe(struct mdev_device *mdev) mbochs_create_config_space(mdev_state); mbochs_reset(mdev_state); - ret = vfio_register_group_dev(&mdev_state->vdev); + ret = vfio_register_emulated_iommu_dev(&mdev_state->vdev); if (ret) goto err_mem; dev_set_drvdata(&mdev->dev, mdev_state); diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c index 8d1a80a0722aa9..fe5d43e797b6d3 100644 --- a/samples/vfio-mdev/mdpy.c +++ b/samples/vfio-mdev/mdpy.c @@ -258,7 +258,7 @@ static int mdpy_probe(struct mdev_device *mdev) mdpy_count++; - ret = vfio_register_group_dev(&mdev_state->vdev); + ret = vfio_register_emulated_iommu_dev(&mdev_state->vdev); if (ret) goto err_mem; dev_set_drvdata(&mdev->dev, mdev_state); diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index 5983cdb16e3d1d..a0e1a469bd47af 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -741,7 +741,7 @@ static int mtty_probe(struct mdev_device *mdev) mtty_create_config_space(mdev_state); - ret = vfio_register_group_dev(&mdev_state->vdev); + ret = vfio_register_emulated_iommu_dev(&mdev_state->vdev); if (ret) goto err_vconfig; dev_set_drvdata(&mdev->dev, mdev_state); From patchwork Thu Aug 26 13:34:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459905 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 744B5C4320E for ; Thu, 26 Aug 2021 13:44:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5616F6102A for ; Thu, 26 Aug 2021 13:44:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238023AbhHZNpi (ORCPT ); Thu, 26 Aug 2021 09:45:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232699AbhHZNph (ORCPT ); Thu, 26 Aug 2021 09:45:37 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99278C0613C1 for ; Thu, 26 Aug 2021 06:44:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=F3Vr4Dqr//F1nYSM5embQqT99tUV1mTvIL5pJuuP3ik=; b=oXMZho98fxk3gliGmjvY18Fw4x +jTyynpWf5W1bH8ejKYcs7PRSReM1dVaUOCBq6fBtQI8yTePCZs3+kis5mtxNMPpyCiXClWvjtbKp HfQRyLD3OtUAMAxvX1eJBXn6Is3JpAzRiRUXqzwk4UnxSLwx5M7sIsZK6k2GFs0JWbNiWWF9D4lZA DQ5xTfzUFigql0Zl/iATJSH8ql5oOMvpjHedgs6saRLsbWeqoOP4TlTFnK4FxpbxLvQZpz6HQFNIj sUwx1H/gGayoegKEWV/d4YalcbjRFuHZVqA7iAxzhkDDyaCFeqaI34uK2wZmQGR9/t+3ATolXm6Es UaFz66LA==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFer-00DLPn-0Y; Thu, 26 Aug 2021 13:43:25 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe , Kevin Tian Subject: [PATCH 08/14] vfio: remove unused method from vfio_iommu_driver_ops Date: Thu, 26 Aug 2021 15:34:18 +0200 Message-Id: <20210826133424.3362-9-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The read, write and mmap methods are never implemented, so remove them. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/vfio/vfio.c | 50 -------------------------------------------- include/linux/vfio.h | 5 ----- 2 files changed, 55 deletions(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 467432379b91ef..8b815763f6dcf9 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -1266,62 +1266,12 @@ static int vfio_fops_release(struct inode *inode, struct file *filep) return 0; } -/* - * Once an iommu driver is set, we optionally pass read/write/mmap - * on to the driver, allowing management interfaces beyond ioctl. - */ -static ssize_t vfio_fops_read(struct file *filep, char __user *buf, - size_t count, loff_t *ppos) -{ - struct vfio_container *container = filep->private_data; - struct vfio_iommu_driver *driver; - ssize_t ret = -EINVAL; - - driver = container->iommu_driver; - if (likely(driver && driver->ops->read)) - ret = driver->ops->read(container->iommu_data, - buf, count, ppos); - - return ret; -} - -static ssize_t vfio_fops_write(struct file *filep, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct vfio_container *container = filep->private_data; - struct vfio_iommu_driver *driver; - ssize_t ret = -EINVAL; - - driver = container->iommu_driver; - if (likely(driver && driver->ops->write)) - ret = driver->ops->write(container->iommu_data, - buf, count, ppos); - - return ret; -} - -static int vfio_fops_mmap(struct file *filep, struct vm_area_struct *vma) -{ - struct vfio_container *container = filep->private_data; - struct vfio_iommu_driver *driver; - int ret = -EINVAL; - - driver = container->iommu_driver; - if (likely(driver && driver->ops->mmap)) - ret = driver->ops->mmap(container->iommu_data, vma); - - return ret; -} - static const struct file_operations vfio_fops = { .owner = THIS_MODULE, .open = vfio_fops_open, .release = vfio_fops_release, - .read = vfio_fops_read, - .write = vfio_fops_write, .unlocked_ioctl = vfio_fops_unl_ioctl, .compat_ioctl = compat_ptr_ioctl, - .mmap = vfio_fops_mmap, }; /** diff --git a/include/linux/vfio.h b/include/linux/vfio.h index bbe29300862649..7a57a0077f9637 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -95,13 +95,8 @@ struct vfio_iommu_driver_ops { struct module *owner; void *(*open)(unsigned long arg); void (*release)(void *iommu_data); - ssize_t (*read)(void *iommu_data, char __user *buf, - size_t count, loff_t *ppos); - ssize_t (*write)(void *iommu_data, const char __user *buf, - size_t count, loff_t *size); long (*ioctl)(void *iommu_data, unsigned int cmd, unsigned long arg); - int (*mmap)(void *iommu_data, struct vm_area_struct *vma); int (*attach_group)(void *iommu_data, struct iommu_group *group); void (*detach_group)(void *iommu_data, From patchwork Thu Aug 26 13:34:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459907 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A587C432BE for ; Thu, 26 Aug 2021 13:45:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7B4F160E73 for ; Thu, 26 Aug 2021 13:45:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242714AbhHZNqe (ORCPT ); Thu, 26 Aug 2021 09:46:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232699AbhHZNqe (ORCPT ); Thu, 26 Aug 2021 09:46:34 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD6AAC061757 for ; Thu, 26 Aug 2021 06:45:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=UPp5A46X9pXmmyMopFzDwPuiyi/A59XZ5+zasTYdlm8=; b=Fam10TNNyds12PR9o2Jy22rk38 BvmlpADtnt/+FlWAA3GbFXvRrGJUWWwWLjI+pqWa5luh9pRr/KtIxPLaKRXjbaaX0x/j6fVXwJrDE xJxBJbT4nwGAuzMWsQRaSxqLZ4aPtk0wXhMxtt7uSJv8apwm1EMsTSCP6JJ5LBREVHmtn0480SuzG /TBqsNAzJ3OKNHwVqKFxHYTeQX8/T5e4AA7fWb95ujDGMD7Skd8mvGtbMU8gLW1Th9dlOoYIBclZp BVw32b2cCZ3a7UWPx3LkRS7l1dAsTFa83+8DDSUM+wxFZvKAF7imwPyKhvJPVJkIgGzl6sh7g/Rmn 50B1wrJA==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFfn-00DLTP-TC; Thu, 26 Aug 2021 13:44:33 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe , Kevin Tian Subject: [PATCH 09/14] vfio: move the vfio_iommu_driver_ops interface out of Date: Thu, 26 Aug 2021 15:34:19 +0200 Message-Id: <20210826133424.3362-10-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Create a new private drivers/vfio/vfio.h header for the interface between the VFIO core and the iommu drivers. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/vfio/vfio.c | 1 + drivers/vfio/vfio.h | 47 +++++++++++++++++++++++++++++ drivers/vfio/vfio_iommu_spapr_tce.c | 1 + drivers/vfio/vfio_iommu_type1.c | 1 + include/linux/vfio.h | 44 --------------------------- 5 files changed, 50 insertions(+), 44 deletions(-) create mode 100644 drivers/vfio/vfio.h diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 8b815763f6dcf9..b2f2951f7fc759 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -32,6 +32,7 @@ #include #include #include +#include "vfio.h" #define DRIVER_VERSION "0.3" #define DRIVER_AUTHOR "Alex Williamson " diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h new file mode 100644 index 00000000000000..a78de649eb2f16 --- /dev/null +++ b/drivers/vfio/vfio.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2012 Red Hat, Inc. All rights reserved. + * Author: Alex Williamson + */ + +/* events for the backend driver notify callback */ +enum vfio_iommu_notify_type { + VFIO_IOMMU_CONTAINER_CLOSE = 0, +}; + +/** + * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks + */ +struct vfio_iommu_driver_ops { + char *name; + struct module *owner; + void *(*open)(unsigned long arg); + void (*release)(void *iommu_data); + long (*ioctl)(void *iommu_data, unsigned int cmd, + unsigned long arg); + int (*attach_group)(void *iommu_data, + struct iommu_group *group); + void (*detach_group)(void *iommu_data, + struct iommu_group *group); + int (*pin_pages)(void *iommu_data, + struct iommu_group *group, + unsigned long *user_pfn, + int npage, int prot, + unsigned long *phys_pfn); + int (*unpin_pages)(void *iommu_data, + unsigned long *user_pfn, int npage); + int (*register_notifier)(void *iommu_data, + unsigned long *events, + struct notifier_block *nb); + int (*unregister_notifier)(void *iommu_data, + struct notifier_block *nb); + int (*dma_rw)(void *iommu_data, dma_addr_t user_iova, + void *data, size_t count, bool write); + struct iommu_domain *(*group_iommu_domain)(void *iommu_data, + struct iommu_group *group); + void (*notify)(void *iommu_data, + enum vfio_iommu_notify_type event); +}; + +int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops); +void vfio_unregister_iommu_driver(const struct vfio_iommu_driver_ops *ops); diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index fe888b5dcc0062..3efd09faeca4a8 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -20,6 +20,7 @@ #include #include #include +#include "vfio.h" #include #include diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 0b4f7c174c7a2b..92777797578e50 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -40,6 +40,7 @@ #include #include #include +#include "vfio.h" #define DRIVER_VERSION "0.2" #define DRIVER_AUTHOR "Alex Williamson " diff --git a/include/linux/vfio.h b/include/linux/vfio.h index 7a57a0077f9637..76191d7abed185 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -82,50 +82,6 @@ extern void vfio_device_put(struct vfio_device *device); int vfio_assign_device_set(struct vfio_device *device, void *set_id); -/* events for the backend driver notify callback */ -enum vfio_iommu_notify_type { - VFIO_IOMMU_CONTAINER_CLOSE = 0, -}; - -/** - * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks - */ -struct vfio_iommu_driver_ops { - char *name; - struct module *owner; - void *(*open)(unsigned long arg); - void (*release)(void *iommu_data); - long (*ioctl)(void *iommu_data, unsigned int cmd, - unsigned long arg); - int (*attach_group)(void *iommu_data, - struct iommu_group *group); - void (*detach_group)(void *iommu_data, - struct iommu_group *group); - int (*pin_pages)(void *iommu_data, - struct iommu_group *group, - unsigned long *user_pfn, - int npage, int prot, - unsigned long *phys_pfn); - int (*unpin_pages)(void *iommu_data, - unsigned long *user_pfn, int npage); - int (*register_notifier)(void *iommu_data, - unsigned long *events, - struct notifier_block *nb); - int (*unregister_notifier)(void *iommu_data, - struct notifier_block *nb); - int (*dma_rw)(void *iommu_data, dma_addr_t user_iova, - void *data, size_t count, bool write); - struct iommu_domain *(*group_iommu_domain)(void *iommu_data, - struct iommu_group *group); - void (*notify)(void *iommu_data, - enum vfio_iommu_notify_type event); -}; - -extern int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops); - -extern void vfio_unregister_iommu_driver( - const struct vfio_iommu_driver_ops *ops); - /* * External user API */ From patchwork Thu Aug 26 13:34:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459909 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 19610C4320E for ; Thu, 26 Aug 2021 13:47:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ECAA76102A for ; Thu, 26 Aug 2021 13:47:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241640AbhHZNsF (ORCPT ); Thu, 26 Aug 2021 09:48:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242723AbhHZNsA (ORCPT ); Thu, 26 Aug 2021 09:48:00 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42207C061757 for ; Thu, 26 Aug 2021 06:47:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=uon3C5SNpeGUiY2/ti4PD6HcXIXshXhAJ87ZDRcvQVw=; b=JzNgepDywkwP6LU2buQK6E6t7H bhFMFEvCaYEtzbuwQMLPWn3xvt9L11u4Bpo1JRD4sWDUnR6F2ics5tbKHlj4AJzrm2kFyryF3e3dq uVgwaxpBR3bI04HlgVPljm54Do07L7z4WP6YPkI4ekMaeOs4OSVuuHccTaE7Q+dX186jWOOwIF47d WsktD4jVL5Jx3INhke8Gil2lT3VMyigBq6T1J4vrktD7oUk5JG24tF42H5xw7Wz3MQUxVPN0tApVj fzt2gxG6ve9x5E1Wwd2tP7M+D6UrmVJd4K7xuzxSoeT4STJfYjdSaS9k5zwKz0DQPtmfaYlLcV5GW mq9Fv6mA==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFgp-00DLWt-Bq; Thu, 26 Aug 2021 13:45:27 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe , Kevin Tian Subject: [PATCH 10/14] vfio: remove the unused mdev iommu hook Date: Thu, 26 Aug 2021 15:34:20 +0200 Message-Id: <20210826133424.3362-11-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The iommu_device field in struct mdev_device has never been used since it was added more than 2 years ago. This is a manual revert of commit 7bd50f0cd2 ("vfio/type1: Add domain at(de)taching group helpers"). Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/vfio/vfio_iommu_type1.c | 133 +++++++------------------------- include/linux/mdev.h | 20 ----- 2 files changed, 26 insertions(+), 127 deletions(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 92777797578e50..39e2706d0b3f34 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -114,7 +114,6 @@ struct vfio_batch { struct vfio_iommu_group { struct iommu_group *iommu_group; struct list_head next; - bool mdev_group; /* An mdev group */ bool pinned_page_dirty_scope; }; @@ -1935,61 +1934,6 @@ static bool vfio_iommu_has_sw_msi(struct list_head *group_resv_regions, return ret; } -static int vfio_mdev_attach_domain(struct device *dev, void *data) -{ - struct mdev_device *mdev = to_mdev_device(dev); - struct iommu_domain *domain = data; - struct device *iommu_device; - - iommu_device = mdev_get_iommu_device(mdev); - if (iommu_device) { - if (iommu_dev_feature_enabled(iommu_device, IOMMU_DEV_FEAT_AUX)) - return iommu_aux_attach_device(domain, iommu_device); - else - return iommu_attach_device(domain, iommu_device); - } - - return -EINVAL; -} - -static int vfio_mdev_detach_domain(struct device *dev, void *data) -{ - struct mdev_device *mdev = to_mdev_device(dev); - struct iommu_domain *domain = data; - struct device *iommu_device; - - iommu_device = mdev_get_iommu_device(mdev); - if (iommu_device) { - if (iommu_dev_feature_enabled(iommu_device, IOMMU_DEV_FEAT_AUX)) - iommu_aux_detach_device(domain, iommu_device); - else - iommu_detach_device(domain, iommu_device); - } - - return 0; -} - -static int vfio_iommu_attach_group(struct vfio_domain *domain, - struct vfio_iommu_group *group) -{ - if (group->mdev_group) - return iommu_group_for_each_dev(group->iommu_group, - domain->domain, - vfio_mdev_attach_domain); - else - return iommu_attach_group(domain->domain, group->iommu_group); -} - -static void vfio_iommu_detach_group(struct vfio_domain *domain, - struct vfio_iommu_group *group) -{ - if (group->mdev_group) - iommu_group_for_each_dev(group->iommu_group, domain->domain, - vfio_mdev_detach_domain); - else - iommu_detach_group(domain->domain, group->iommu_group); -} - static bool vfio_bus_is_mdev(struct bus_type *bus) { struct bus_type *mdev_bus; @@ -2004,20 +1948,6 @@ static bool vfio_bus_is_mdev(struct bus_type *bus) return ret; } -static int vfio_mdev_iommu_device(struct device *dev, void *data) -{ - struct mdev_device *mdev = to_mdev_device(dev); - struct device **old = data, *new; - - new = mdev_get_iommu_device(mdev); - if (!new || (*old && *old != new)) - return -EINVAL; - - *old = new; - - return 0; -} - /* * This is a helper function to insert an address range to iova list. * The list is initially created with a single entry corresponding to @@ -2278,38 +2208,25 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, goto out_free; if (vfio_bus_is_mdev(bus)) { - struct device *iommu_device = NULL; - - group->mdev_group = true; - - /* Determine the isolation type */ - ret = iommu_group_for_each_dev(iommu_group, &iommu_device, - vfio_mdev_iommu_device); - if (ret || !iommu_device) { - if (!iommu->external_domain) { - INIT_LIST_HEAD(&domain->group_list); - iommu->external_domain = domain; - vfio_update_pgsize_bitmap(iommu); - } else { - kfree(domain); - } - - list_add(&group->next, - &iommu->external_domain->group_list); - /* - * Non-iommu backed group cannot dirty memory directly, - * it can only use interfaces that provide dirty - * tracking. - * The iommu scope can only be promoted with the - * addition of a dirty tracking group. - */ - group->pinned_page_dirty_scope = true; - mutex_unlock(&iommu->lock); - - return 0; + if (!iommu->external_domain) { + INIT_LIST_HEAD(&domain->group_list); + iommu->external_domain = domain; + vfio_update_pgsize_bitmap(iommu); + } else { + kfree(domain); } - bus = iommu_device->bus; + list_add(&group->next, &iommu->external_domain->group_list); + /* + * Non-iommu backed group cannot dirty memory directly, it can + * only use interfaces that provide dirty tracking. + * The iommu scope can only be promoted with the addition of a + * dirty tracking group. + */ + group->pinned_page_dirty_scope = true; + mutex_unlock(&iommu->lock); + + return 0; } domain->domain = iommu_domain_alloc(bus); @@ -2324,7 +2241,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, goto out_domain; } - ret = vfio_iommu_attach_group(domain, group); + ret = iommu_attach_group(domain->domain, group->iommu_group); if (ret) goto out_domain; @@ -2391,15 +2308,17 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, list_for_each_entry(d, &iommu->domain_list, next) { if (d->domain->ops == domain->domain->ops && d->prot == domain->prot) { - vfio_iommu_detach_group(domain, group); - if (!vfio_iommu_attach_group(d, group)) { + iommu_detach_group(domain->domain, group->iommu_group); + if (!iommu_attach_group(d->domain, + group->iommu_group)) { list_add(&group->next, &d->group_list); iommu_domain_free(domain->domain); kfree(domain); goto done; } - ret = vfio_iommu_attach_group(domain, group); + ret = iommu_attach_group(domain->domain, + group->iommu_group); if (ret) goto out_domain; } @@ -2436,7 +2355,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, return 0; out_detach: - vfio_iommu_detach_group(domain, group); + iommu_detach_group(domain->domain, group->iommu_group); out_domain: iommu_domain_free(domain->domain); vfio_iommu_iova_free(&iova_copy); @@ -2601,7 +2520,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data, if (!group) continue; - vfio_iommu_detach_group(domain, group); + iommu_detach_group(domain->domain, group->iommu_group); update_dirty_scope = !group->pinned_page_dirty_scope; list_del(&group->next); kfree(group); @@ -2689,7 +2608,7 @@ static void vfio_release_domain(struct vfio_domain *domain, bool external) list_for_each_entry_safe(group, group_tmp, &domain->group_list, next) { if (!external) - vfio_iommu_detach_group(domain, group); + iommu_detach_group(domain->domain, group->iommu_group); list_del(&group->next); kfree(group); } diff --git a/include/linux/mdev.h b/include/linux/mdev.h index 68427e8fadebd6..15d03f6532d073 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -18,7 +18,6 @@ struct mdev_device { void *driver_data; struct list_head next; struct mdev_type *type; - struct device *iommu_device; bool active; }; @@ -27,25 +26,6 @@ static inline struct mdev_device *to_mdev_device(struct device *dev) return container_of(dev, struct mdev_device, dev); } -/* - * Called by the parent device driver to set the device which represents - * this mdev in iommu protection scope. By default, the iommu device is - * NULL, that indicates using vendor defined isolation. - * - * @dev: the mediated device that iommu will isolate. - * @iommu_device: a pci device which represents the iommu for @dev. - */ -static inline void mdev_set_iommu_device(struct mdev_device *mdev, - struct device *iommu_device) -{ - mdev->iommu_device = iommu_device; -} - -static inline struct device *mdev_get_iommu_device(struct mdev_device *mdev) -{ - return mdev->iommu_device; -} - unsigned int mdev_get_type_group_id(struct mdev_device *mdev); unsigned int mtype_get_type_group_id(struct mdev_type *mtype); struct device *mtype_get_parent_dev(struct mdev_type *mtype); From patchwork Thu Aug 26 13:34:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459911 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 834E7C4320A for ; Thu, 26 Aug 2021 13:48:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 673236103A for ; Thu, 26 Aug 2021 13:48:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242723AbhHZNsq (ORCPT ); Thu, 26 Aug 2021 09:48:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242731AbhHZNsq (ORCPT ); Thu, 26 Aug 2021 09:48:46 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E125CC061757 for ; Thu, 26 Aug 2021 06:47:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=46KN0SO8DFFA7SmbbIApjB/CZ+FItjv3FWXKrjt1Cgk=; b=OEaX21I1vj6CZ0PkgRnsJbQ2gK C+pVLSxtX6LZAOAFA0u8MwFqywN4A5zgiWBeSRcejCTncGUPVRNw5djEzJzyzSxF0GhaMPA8I9/8t mzXlbIYXv2+t/J/OVtaHLe1B/vX/UbqoV8MecudKcYYRNdfQCzj16NuAAiAHDdu/EFVyn2jmqyCKE KDv7aCAKpyMItf+FDxtOpBDZY2lT/j9foOx3i5NIJg7eZuYF+xA6lVwPUZByif7rNVQM7Lab4l/BU Y4X4E9u1XXhX9pT/lARNtzhC77tDxk6HKSS0EX/i7QS+bORVsKyIRCqiciktNKx5lzt5LuRVA5DbE 8oAYKxOw==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFhx-00DLZg-0E; Thu, 26 Aug 2021 13:46:35 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe , Kevin Tian Subject: [PATCH 11/14] vfio: clean up the check for mediated device in vfio_iommu_type1 Date: Thu, 26 Aug 2021 15:34:21 +0200 Message-Id: <20210826133424.3362-12-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Pass the group flags to ->attach_group and remove the messy check for the bus type. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/vfio/vfio.c | 23 +++++------------------ drivers/vfio/vfio.h | 18 +++++++++++++++++- drivers/vfio/vfio_iommu_spapr_tce.c | 2 +- drivers/vfio/vfio_iommu_type1.c | 19 ++----------------- 4 files changed, 25 insertions(+), 37 deletions(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index b2f2951f7fc759..3a668fe2ea96f7 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -68,21 +68,6 @@ struct vfio_unbound_dev { struct list_head unbound_next; }; -/* - * Virtual device without IOMMU backing. The VFIO core fakes up an iommu_group - * as the iommu_group sysfs interface is part of the userspace ABI. The user - * of these devices must not be able to directly trigger unmediated DMA. - */ -#define VFIO_EMULATED_IOMMU (1 << 0) - -/* - * Physical device without IOMMU backing. The VFIO core fakes up an iommu_group - * as the iommu_group sysfs interface is part of the userspace ABI. Users can - * trigger unmediated DMA by the device, usage is highly dangerous, requires - * an explicit opt-in and will taint the kernel. - */ -#define VFIO_NO_IOMMU (1 << 1) - struct vfio_group { struct kref kref; int minor; @@ -210,7 +195,7 @@ static long vfio_noiommu_ioctl(void *iommu_data, } static int vfio_noiommu_attach_group(void *iommu_data, - struct iommu_group *iommu_group) + struct iommu_group *iommu_group, unsigned int flags) { return 0; } @@ -1119,7 +1104,8 @@ static int __vfio_container_attach_groups(struct vfio_container *container, int ret = -ENODEV; list_for_each_entry(group, &container->group_list, container_next) { - ret = driver->ops->attach_group(data, group->iommu_group); + ret = driver->ops->attach_group(data, group->iommu_group, + group->flags); if (ret) goto unwind; } @@ -1377,7 +1363,8 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) driver = container->iommu_driver; if (driver) { ret = driver->ops->attach_group(container->iommu_data, - group->iommu_group); + group->iommu_group, + group->flags); if (ret) goto unlock_out; } diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h index a78de649eb2f16..3bdf21416563a4 100644 --- a/drivers/vfio/vfio.h +++ b/drivers/vfio/vfio.h @@ -9,6 +9,21 @@ enum vfio_iommu_notify_type { VFIO_IOMMU_CONTAINER_CLOSE = 0, }; +/* + * Virtual device without IOMMU backing. The VFIO core fakes up an iommu_group + * as the iommu_group sysfs interface is part of the userspace ABI. The user + * of these devices must not be able to directly trigger unmediated DMA. + */ +#define VFIO_EMULATED_IOMMU (1 << 0) + +/* + * Physical device without IOMMU backing. The VFIO core fakes up an iommu_group + * as the iommu_group sysfs interface is part of the userspace ABI. Users can + * trigger unmediated DMA by the device, usage is highly dangerous, requires + * an explicit opt-in and will taint the kernel. + */ +#define VFIO_NO_IOMMU (1 << 1) + /** * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks */ @@ -20,7 +35,8 @@ struct vfio_iommu_driver_ops { long (*ioctl)(void *iommu_data, unsigned int cmd, unsigned long arg); int (*attach_group)(void *iommu_data, - struct iommu_group *group); + struct iommu_group *group, + unsigned int flags); void (*detach_group)(void *iommu_data, struct iommu_group *group); int (*pin_pages)(void *iommu_data, diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 3efd09faeca4a8..7567328d347d25 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -1239,7 +1239,7 @@ static long tce_iommu_take_ownership_ddw(struct tce_container *container, } static int tce_iommu_attach_group(void *iommu_data, - struct iommu_group *iommu_group) + struct iommu_group *iommu_group, unsigned int flags) { int ret = 0; struct tce_container *container = iommu_data; diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 39e2706d0b3f34..ca3c995c84166f 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -1934,20 +1933,6 @@ static bool vfio_iommu_has_sw_msi(struct list_head *group_resv_regions, return ret; } -static bool vfio_bus_is_mdev(struct bus_type *bus) -{ - struct bus_type *mdev_bus; - bool ret = false; - - mdev_bus = symbol_get(mdev_bus_type); - if (mdev_bus) { - ret = (bus == mdev_bus); - symbol_put(mdev_bus_type); - } - - return ret; -} - /* * This is a helper function to insert an address range to iova list. * The list is initially created with a single entry corresponding to @@ -2172,7 +2157,7 @@ static void vfio_iommu_iova_insert_copy(struct vfio_iommu *iommu, } static int vfio_iommu_type1_attach_group(void *iommu_data, - struct iommu_group *iommu_group) + struct iommu_group *iommu_group, unsigned int flags) { struct vfio_iommu *iommu = iommu_data; struct vfio_iommu_group *group; @@ -2207,7 +2192,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, if (ret) goto out_free; - if (vfio_bus_is_mdev(bus)) { + if (flags & VFIO_EMULATED_IOMMU) { if (!iommu->external_domain) { INIT_LIST_HEAD(&domain->group_list); iommu->external_domain = domain; From patchwork Thu Aug 26 13:34:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459913 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2556AC4320A for ; Thu, 26 Aug 2021 13:49:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0B6AB60F4C for ; Thu, 26 Aug 2021 13:49:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231875AbhHZNuE (ORCPT ); Thu, 26 Aug 2021 09:50:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229793AbhHZNuD (ORCPT ); Thu, 26 Aug 2021 09:50:03 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 05A41C061757 for ; Thu, 26 Aug 2021 06:49:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=wOMJ3wM1RSJrSJxQNcsqgw3rWyngt+Kpgr9OnhK8cA8=; b=MngNAAqbAjxMZphor/g0nf82Cf P6/k+D237HlxtVP0du5h3hkqMEwCRLcrV0Z5tU0PoPHcVQ4r0KWqtGMXAXwf0Az44FTw7DOMIBkNl 6bW+WLFLlVinvpwWhEhslxedXenaSHg/uyRyoJRKJhi4F4Xw6LqSxZISvxUbNYwucWNFaqTs0lCKE iQM3xlEG6fyVSOg5cs+mVI+KNYH3jxRBEtEL9VB2/CGt2/JyR8Lz2AZ9+vrpzO7L3b4u+D6mdvtNO EXljD+R7DtH/zpBJE2TdHY8LGZFXkuTUsxLIRXpZxeFAmUA9avpOMVof4YS3MmMqkUf3pZRB/9lm0 VvGukM6A==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFj2-00DLeX-Sv; Thu, 26 Aug 2021 13:47:34 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe , Kevin Tian Subject: [PATCH 12/14] vfio/spapr_tce: reject mediated devices Date: Thu, 26 Aug 2021 15:34:22 +0200 Message-Id: <20210826133424.3362-13-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Unlike the the type1 IOMMU backend, the SPAPR one does not contain any support for the magic non-IOMMU backed iommu_group used by mediated devices, so reject them in ->attach_group. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/vfio/vfio_iommu_spapr_tce.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 7567328d347d25..0fbce1bcb6493b 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -1246,6 +1246,9 @@ static int tce_iommu_attach_group(void *iommu_data, struct iommu_table_group *table_group; struct tce_iommu_group *tcegrp = NULL; + if (flags & VFIO_EMULATED_IOMMU) + return -EINVAL; + mutex_lock(&container->lock); /* pr_debug("tce_vfio: Attaching group #%u to iommu %p\n", From patchwork Thu Aug 26 13:34:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459915 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E7F8C432BE for ; Thu, 26 Aug 2021 13:50:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E321860F4C for ; Thu, 26 Aug 2021 13:50:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235683AbhHZNvU (ORCPT ); Thu, 26 Aug 2021 09:51:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229793AbhHZNvT (ORCPT ); Thu, 26 Aug 2021 09:51:19 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 20778C061757 for ; Thu, 26 Aug 2021 06:50:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=2MgG7sQzX7WPVyjbtLfGT1hJstUYoxVBLRsehGIsEV8=; b=i9kxgnBZ5nuLASufdwrVNG3yYY lOEfC1OLxDpnWtn0Jil8bvizPbHgR+EA2poUf9CoNiebh7CqMHEzmr5yhhwASM+pR7627szDFPBHV 6xZbYn6BrhV5FHgfnHNl7A8Ksn31aQlNIXcJC7s5yBJuUFJrVtMTp9wot6vByL2GZf7A8qN4ax0Ag xULgxFVKAoRIpK2JCHUyL2978ojREZuuyM+ZjLRfHE/gBj5rURnIii/yxih4HlfwAIy9bHNmQcJer ih8M4gWCv3X0OCWU/yRJHlPByPcnW/7zZajKbDuf9HDOoVoGUOb0lSY9fd9tVeNi2gX5k/pb9SuIQ AsUUfkEA==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFkA-00DLiY-Qz; Thu, 26 Aug 2021 13:48:55 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe , Kevin Tian Subject: [PATCH 13/14] vfio/iommu_type1: remove the "external" domain Date: Thu, 26 Aug 2021 15:34:23 +0200 Message-Id: <20210826133424.3362-14-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The external_domain concept rather misleading and not actually needed. Replace it with a list of emulated groups in struct vfio_iommu and document the purpose. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/vfio/vfio_iommu_type1.c | 121 ++++++++++++++------------------ 1 file changed, 54 insertions(+), 67 deletions(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index ca3c995c84166f..1ef98d4e2abecf 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -65,7 +65,6 @@ MODULE_PARM_DESC(dma_entry_limit, struct vfio_iommu { struct list_head domain_list; struct list_head iova_list; - struct vfio_domain *external_domain; /* domain for external user */ struct mutex lock; struct rb_root dma_list; struct blocking_notifier_head notifier; @@ -78,6 +77,7 @@ struct vfio_iommu { bool nesting; bool dirty_page_tracking; bool container_open; + struct list_head emulated_iommu_groups; }; struct vfio_domain { @@ -1892,8 +1892,8 @@ static struct vfio_iommu_group* vfio_iommu_find_iommu_group(struct vfio_iommu *iommu, struct iommu_group *iommu_group) { + struct vfio_iommu_group *group; struct vfio_domain *domain; - struct vfio_iommu_group *group = NULL; list_for_each_entry(domain, &iommu->domain_list, next) { group = find_iommu_group(domain, iommu_group); @@ -1901,10 +1901,10 @@ vfio_iommu_find_iommu_group(struct vfio_iommu *iommu, return group; } - if (iommu->external_domain) - group = find_iommu_group(iommu->external_domain, iommu_group); - - return group; + list_for_each_entry(group, &iommu->emulated_iommu_groups, next) + if (group->iommu_group == iommu_group) + return group; + return NULL; } static bool vfio_iommu_has_sw_msi(struct list_head *group_resv_regions, @@ -2163,62 +2163,52 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, struct vfio_iommu_group *group; struct vfio_domain *domain, *d; struct bus_type *bus = NULL; - int ret; bool resv_msi, msi_remap; phys_addr_t resv_msi_base = 0; struct iommu_domain_geometry *geo; LIST_HEAD(iova_copy); LIST_HEAD(group_resv_regions); + int ret = -EINVAL; mutex_lock(&iommu->lock); /* Check for duplicates */ - if (vfio_iommu_find_iommu_group(iommu, iommu_group)) { - mutex_unlock(&iommu->lock); - return -EINVAL; - } + if (vfio_iommu_find_iommu_group(iommu, iommu_group)) + goto out_unlock; + ret = -ENOMEM; group = kzalloc(sizeof(*group), GFP_KERNEL); - domain = kzalloc(sizeof(*domain), GFP_KERNEL); - if (!group || !domain) { - ret = -ENOMEM; - goto out_free; - } - + if (!group) + goto out_unlock; group->iommu_group = iommu_group; - /* Determine bus_type in order to allocate a domain */ - ret = iommu_group_for_each_dev(iommu_group, &bus, vfio_bus_type); - if (ret) - goto out_free; - if (flags & VFIO_EMULATED_IOMMU) { - if (!iommu->external_domain) { - INIT_LIST_HEAD(&domain->group_list); - iommu->external_domain = domain; - vfio_update_pgsize_bitmap(iommu); - } else { - kfree(domain); - } - - list_add(&group->next, &iommu->external_domain->group_list); + list_add(&group->next, &iommu->emulated_iommu_groups); /* - * Non-iommu backed group cannot dirty memory directly, it can + * An emulated IOMMU group cannot dirty memory directly, it can * only use interfaces that provide dirty tracking. * The iommu scope can only be promoted with the addition of a * dirty tracking group. */ group->pinned_page_dirty_scope = true; - mutex_unlock(&iommu->lock); - - return 0; + ret = 0; + goto out_unlock; } + /* Determine bus_type in order to allocate a domain */ + ret = iommu_group_for_each_dev(iommu_group, &bus, vfio_bus_type); + if (ret) + goto out_free_group; + + ret = -ENOMEM; + domain = kzalloc(sizeof(*domain), GFP_KERNEL); + if (!domain) + goto out_free_group; + + ret = -EIO; domain->domain = iommu_domain_alloc(bus); - if (!domain->domain) { - ret = -EIO; - goto out_free; - } + if (!domain->domain) + goto out_free_domain; if (iommu->nesting) { ret = iommu_enable_nesting(domain->domain); @@ -2345,9 +2335,11 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, iommu_domain_free(domain->domain); vfio_iommu_iova_free(&iova_copy); vfio_iommu_resv_free(&group_resv_regions); -out_free: +out_free_domain: kfree(domain); +out_free_group: kfree(group); +out_unlock: mutex_unlock(&iommu->lock); return ret; } @@ -2472,25 +2464,19 @@ static void vfio_iommu_type1_detach_group(void *iommu_data, LIST_HEAD(iova_copy); mutex_lock(&iommu->lock); + list_for_each_entry(group, &iommu->emulated_iommu_groups, next) { + if (group->iommu_group != iommu_group) + continue; + update_dirty_scope = !group->pinned_page_dirty_scope; + list_del(&group->next); + kfree(group); - if (iommu->external_domain) { - group = find_iommu_group(iommu->external_domain, iommu_group); - if (group) { - update_dirty_scope = !group->pinned_page_dirty_scope; - list_del(&group->next); - kfree(group); - - if (list_empty(&iommu->external_domain->group_list)) { - if (!IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)) { - WARN_ON(iommu->notifier.head); - vfio_iommu_unmap_unpin_all(iommu); - } - - kfree(iommu->external_domain); - iommu->external_domain = NULL; - } - goto detach_group_done; + if (list_empty(&iommu->emulated_iommu_groups) && + !IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)) { + WARN_ON(iommu->notifier.head); + vfio_iommu_unmap_unpin_all(iommu); } + goto detach_group_done; } /* @@ -2518,7 +2504,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data, */ if (list_empty(&domain->group_list)) { if (list_is_singular(&iommu->domain_list)) { - if (!iommu->external_domain) { + if (list_empty(&iommu->emulated_iommu_groups)) { WARN_ON(iommu->notifier.head); vfio_iommu_unmap_unpin_all(iommu); } else { @@ -2582,41 +2568,42 @@ static void *vfio_iommu_type1_open(unsigned long arg) mutex_init(&iommu->lock); BLOCKING_INIT_NOTIFIER_HEAD(&iommu->notifier); init_waitqueue_head(&iommu->vaddr_wait); + INIT_LIST_HEAD(&iommu->emulated_iommu_groups); return iommu; } -static void vfio_release_domain(struct vfio_domain *domain, bool external) +static void vfio_release_domain(struct vfio_domain *domain) { struct vfio_iommu_group *group, *group_tmp; list_for_each_entry_safe(group, group_tmp, &domain->group_list, next) { - if (!external) - iommu_detach_group(domain->domain, group->iommu_group); + iommu_detach_group(domain->domain, group->iommu_group); list_del(&group->next); kfree(group); } - if (!external) - iommu_domain_free(domain->domain); + iommu_domain_free(domain->domain); } static void vfio_iommu_type1_release(void *iommu_data) { struct vfio_iommu *iommu = iommu_data; struct vfio_domain *domain, *domain_tmp; + struct vfio_iommu_group *group, *next_group; - if (iommu->external_domain) { - vfio_release_domain(iommu->external_domain, true); - kfree(iommu->external_domain); + list_for_each_entry_safe(group, next_group, + &iommu->emulated_iommu_groups, next) { + list_del(&group->next); + kfree(group); } vfio_iommu_unmap_unpin_all(iommu); list_for_each_entry_safe(domain, domain_tmp, &iommu->domain_list, next) { - vfio_release_domain(domain, false); + vfio_release_domain(domain); list_del(&domain->next); kfree(domain); } From patchwork Thu Aug 26 13:34:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12459917 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E756AC432BE for ; Thu, 26 Aug 2021 13:51:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C3A406103A for ; Thu, 26 Aug 2021 13:51:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242687AbhHZNwZ (ORCPT ); Thu, 26 Aug 2021 09:52:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51410 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231934AbhHZNwY (ORCPT ); Thu, 26 Aug 2021 09:52:24 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 818EAC061757 for ; Thu, 26 Aug 2021 06:51:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=20dC0MIl5V0+AlR4PNwSgV2vrmvVudgZDf3FOUU0Hpg=; b=h1ajGa+0Mn0OIVtGqi+Q+uwZr4 CPwko4pn6j/rb5qnOoBH9tFnird4fIpEbW2rNkrN+VL805h1/jTnI6NQvRkcgw7gIAlvNKKifNnuB L8238/3LRExm7bRbCHyzsgUTtzVLyQIL9/WKhgqcpSJvrzZXERbyoWD6GLl8VC9mgiKmB5PY20shM KBSLAPARtPWz9lvTt9c4tNHDZ/kq+yreahnR/PDENy+V3Izs3ogc/c2EdZ994b6lc0Ays5IU4fC8x 6vqquyRO3rIjxrCLydu/xQ+eVF7Txsz1ZnH8ZJpx7Y+aMQFnqu0Syv8BDDOa7hXwiBN2QeRFQ9xaf 7EJiXgHg==; Received: from [2001:4bb8:193:fd10:d9d9:6c15:481b:99c4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJFlB-00DLpF-Ta; Thu, 26 Aug 2021 13:50:04 +0000 From: Christoph Hellwig To: Alex Williamson Cc: Diana Craciun , Cornelia Huck , Kirti Wankhede , Eric Auger , Jason Gunthorpe , kvm@vger.kernel.org, Jason Gunthorpe , Kevin Tian Subject: [PATCH 14/14] vfio/iommu_type1: remove IS_IOMMU_CAP_DOMAIN_IN_CONTAINER Date: Thu, 26 Aug 2021 15:34:24 +0200 Message-Id: <20210826133424.3362-15-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210826133424.3362-1-hch@lst.de> References: <20210826133424.3362-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org IS_IOMMU_CAP_DOMAIN_IN_CONTAINER just obsfucated the checks being performed, so open code it in the callers. Signed-off-by: Christoph Hellwig Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/vfio/vfio_iommu_type1.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 1ef98d4e2abecf..94441e6c0983be 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -139,9 +139,6 @@ struct vfio_regions { size_t len; }; -#define IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu) \ - (!list_empty(&iommu->domain_list)) - #define DIRTY_BITMAP_BYTES(n) (ALIGN(n, BITS_PER_TYPE(u64)) / BITS_PER_BYTE) /* @@ -879,7 +876,7 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data, * already pinned and accounted. Accounting should be done if there is no * iommu capable domain in the container. */ - do_accounting = !IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu); + do_accounting = list_empty(&iommu->domain_list); for (i = 0; i < npage; i++) { struct vfio_pfn *vpfn; @@ -968,7 +965,7 @@ static int vfio_iommu_type1_unpin_pages(void *iommu_data, mutex_lock(&iommu->lock); - do_accounting = !IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu); + do_accounting = list_empty(&iommu->domain_list); for (i = 0; i < npage; i++) { struct vfio_dma *dma; dma_addr_t iova; @@ -1089,7 +1086,7 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma, if (!dma->size) return 0; - if (!IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)) + if (list_empty(&iommu->domain_list)) return 0; /* @@ -1666,7 +1663,7 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu, vfio_link_dma(iommu, dma); /* Don't pin and map if container doesn't contain IOMMU capable domain*/ - if (!IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)) + if (list_empty(&iommu->domain_list)) dma->size = size; else ret = vfio_pin_map_dma(iommu, dma, size); @@ -2472,7 +2469,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data, kfree(group); if (list_empty(&iommu->emulated_iommu_groups) && - !IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)) { + list_empty(&iommu->domain_list)) { WARN_ON(iommu->notifier.head); vfio_iommu_unmap_unpin_all(iommu); }