From patchwork Thu Apr 21 16:28:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Gunthorpe X-Patchwork-Id: 12821976 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1C08FC433EF for ; Thu, 21 Apr 2022 16:31:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231858AbiDUQeB (ORCPT ); Thu, 21 Apr 2022 12:34:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46584 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1390643AbiDUQdk (ORCPT ); Thu, 21 Apr 2022 12:33:40 -0400 Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2049.outbound.protection.outlook.com [40.107.236.49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4101E488BB; Thu, 21 Apr 2022 09:28:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BQ/2ZFLejbnejIfV3ya0BrIaRAquK/BBKuPGXgq3g+Z2k2iAxx0HniUZYQYA3RkTsUeTHJttNYBm0K8BQ7lzjIgkkbcWt0RrLqwW41PxI+RqfTdk4U4DPDevdJcvBNsChEB2EqMoRqi9qfTI7wJNo9pN+XhcE8mkD8HrUoOZHBvg25po9JaElywJXfSfS79Z5vocHE6zBP6CB/JbX4+i2rEo0u323fUW/XFX32LcdQ69fYu9AmXaKqH1vbe1RxEgWE1ISDv8SDzRJro1VYuFDy1bDGU/2OqAszy1rwCBSy4+vfAnMUESQ1Rp+aVHT8bcPxKTucAaWUqxCeNUSB6MYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=vbVOaJ0V4NV+PN2yzjHQXErdQPPlNnEkO4/VJR1NOKQ=; b=Dfc92FVS+108ovlHqELIAPcH26i1XCQzV1vOZflp82cRefjU7VTKdBp3vdssn86gaMIYjYi/NNOwZDCITCJzfR8BDKkaJL97WowQlQgLXA6ReCA5uhI2j82A8vq1ApeK5aIehFchueT8QEGvASjWbIPFWiZ6sjwRwHJlk30v+JgNkZQIdJPPNwRU8gSlm5/zZxhBysu9EmfaZaWQUoY78HEOkB98T1efKxpsu4lxtMqtJDw7ZlsA57KLiobfWcpWHFnaheDWPg6TBRDfiNOVHL5KCAIE1bbnOoHWZmeCulu40ryFHfCxJ20os0LFzX9cvis0BTSKbV5QWZyx3d6EqA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=vbVOaJ0V4NV+PN2yzjHQXErdQPPlNnEkO4/VJR1NOKQ=; b=JkvWV1/zICrPRnV3YxCd7pcfN4LgoSyy9Y9q0LHgyincvVNhJ2DY0ENLDjuj01hkei0/DpHDycV+e/daIAJQbN2jeDK9noMVsdT7mEWODic4ueLZ2NFUWKDvJD/l9+zMNQbP6nq3sNieS+qfO2xFXEgA0nFremHEkUxZmSK3DqnePCJjiRnAMMspFIiGcIcBaBEv3hIUMBgswicWoatH8p7IevV8dLJFy4e57VLKgFrU6JK4j2cgssEXY0vmosdM/VrpZk7ELfx/yuNikPT8PV6aewean4z3va3yGM/FAFsVFmwNa9MGvPBoeejd1wsR3hSGHQwv6fmL1/Bv2eKr+w== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from MN2PR12MB4192.namprd12.prod.outlook.com (2603:10b6:208:1d5::15) by DM6PR12MB2907.namprd12.prod.outlook.com (2603:10b6:5:183::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5164.20; Thu, 21 Apr 2022 16:28:42 +0000 Received: from MN2PR12MB4192.namprd12.prod.outlook.com ([fe80::ec2d:9167:1b47:2db2]) by MN2PR12MB4192.namprd12.prod.outlook.com ([fe80::ec2d:9167:1b47:2db2%6]) with mapi id 15.20.5186.015; Thu, 21 Apr 2022 16:28:42 +0000 From: Jason Gunthorpe To: Alexander Gordeev , David Airlie , Alex Williamson , Christian Borntraeger , Cornelia Huck , Jonathan Corbet , Daniel Vetter , dri-devel@lists.freedesktop.org, Harald Freudenberger , Vasily Gorbik , Heiko Carstens , intel-gfx@lists.freedesktop.org, intel-gvt-dev@lists.freedesktop.org, Jani Nikula , Jason Herne , Joonas Lahtinen , kvm@vger.kernel.org, Kirti Wankhede , linux-doc@vger.kernel.org, linux-s390@vger.kernel.org, Matthew Rosato , Peter Oberparleiter , Halil Pasic , Rodrigo Vivi , Sven Schnelle , Tvrtko Ursulin , Vineeth Vijayan , Zhenyu Wang , Zhi Wang Cc: Tony Krowiak , Eric Farman , Christoph Hellwig , "Tian, Kevin" , "Liu, Yi L" Subject: [PATCH v2 7/7] vfio: Remove calls to vfio_group_add_container_user() Date: Thu, 21 Apr 2022 13:28:38 -0300 Message-Id: <7-v2-6011bde8e0a1+5f-vfio_mdev_no_group_jgg@nvidia.com> In-Reply-To: <0-v2-6011bde8e0a1+5f-vfio_mdev_no_group_jgg@nvidia.com> References: X-ClientProxiedBy: BL0PR05CA0010.namprd05.prod.outlook.com (2603:10b6:208:91::20) To MN2PR12MB4192.namprd12.prod.outlook.com (2603:10b6:208:1d5::15) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2001af5b-4c11-4c69-2f51-08da23b3fea6 X-MS-TrafficTypeDiagnostic: DM6PR12MB2907:EE_ X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: J3FqGZvp+iFJKx+1vDVtw5/bg1eGeQu9+0AghpQ5N717ww8Jlto4/nygDX56eegaMLKPYAz7DRi8cBcX7rC8pW3rpPq6J1/WVc1Oq2FU4Gw3hWhbVDwA4X3y4S0608ICXT4osLtuEzKx2b7KMgo587mYCavKih6J/sfbFl2J3F65243kadMN0vy4ukzbDj+Q4jj0OLCBzEB40KRoasjCpE6jTkWdB//wrWZfnzXW4jIRlxXS/9UJOZgz28oucRpqzP4q/vFaM1AlyRCVDByJxpXhkrw8W/oobideO9wEBvSj9iq9hDJZq9YLr448MO5JskbcelrwuarTKzLUSUJtXpeBGnkB4FyNClyjP2JUkjxufeQ736iyROqYC3IZ6m5fgdOYbe3rQlkUAjzB/1SYgg4hZn+idBLZQ0eOpO3LqkpND7KXWtfsbvSIAqnqK4pUsxe90enHFpsI4InteEuw5KOQIvRGdXjfilf+RPVIeR3b49tfDvH2qpUtkGq9Yl/PFkmkkYqpPgja0UOXmyKQK0WKC9/pNgYTAs1XvceaRE00JOip3XK3NPSx9Qgmt9LYB4+DLG8lthcgj8vV5ch2u4UPbhDCq29u1XvOWQIcCXH8c78z7VU2LNiW+VVcNKeQya5Hnw0aRVrgtYw9wwAyg44bozoRzeH2SNj1H+RpFdGGRBHvFkoz8wIeT7oaHoMS1CEPUTJb2rqiiGGDOIWrrQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4192.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230001)(4636009)(366004)(6486002)(6506007)(316002)(5660300002)(38100700002)(6512007)(54906003)(36756003)(66946007)(86362001)(186003)(921005)(110136005)(508600001)(8936002)(6666004)(2616005)(83380400001)(8676002)(7416002)(7406005)(66556008)(4326008)(26005)(2906002)(66476007)(4216001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 2seeYSoi2u2IQwLifh/apfuLwQhufLLl+X/4mSw0ahJDCXUuMAn7+/XzERzTyMQlou415UmgS6OavH77wxDw9/SHRZD/VHMm+FP9h5Cd4oenVKX1xgBqYrm7KEw/CRK4LWKJVw1z55cd0hvFSUH+rzrIiY5VbeGyaKenTsOIeib6iJGi74Us6kmr3pRJ1KxIxOd9ORAKB4IBENpOnSBl5GaZlQHlvuhERqPRzAnankANGR0meKRkcP+f9dSmYDBEmdI/HVxR8zUn/+iAtg77aJ9tvImeUyXyqpcv95rZ8jYRq0KxE7hlqzcFVkxLMAfS9n6u/5Sbly0hzT8b6CnSoimwcnRHNkjDS3gqYfLdDgPdERWTqoq4YR9Fp3LLiG9uRwvXxJ4tFEDJa65WC8i3cqktTKBXbLph3beN0WHOE9AeYa+gZSvxJDK69rTLzbDAOyTxa97vNYokLq8UDNV2G3A4xdKIMWaymr/OVTqmAESE2qRxVbzY6UARIVZ5qdvFv0dtUP+054cr6D6oK1OHBEKD9M/qlKgmUPPtFpkBtZEZOUyRaYpO9yiU3YX61GzDj3W7xG2q7D1fmVyEp6U0yhL7uWvfY5LV8As4tG2haBgjgqGoMdwxxp0GbLYx+AedgHg12lsb27HwywoVwd3Yn+KI/kd3Etu0OoTOkJNSDW/8qYzaEaSpyKeZlELjxyKqRnQET62tQ9hKQsnWM0t6Rptu3w1LpefFzBSdFwZbD++wvRd4uW7E5TzjptJv9CyO3vKuDOKbIh9wxch/Noc2DzYdOSluFHO9WqUVrzGMn72IjImESY7ymAxRZ2Uf/DdRs6FsPsYWkPHoSaJyx+UzwYZAKF6BF5Lo0v6km64VcEr7/69K/Mr6Kc5gDRHQ8jyfTatogBavi0F58QPQ9xO3+uoxh/uxI4XqLLOYW/7w6Lcd2o3FSDxLz2Ka0VK2S/FHEQ8EL+66GP6WksxZQfSvS8nEwEYZF+yHTK4HRGOjGJjru04LJ+HOlimaHP+ITVqR2LP9QcnOQ2XUlCBDhkQRTCLCQU6Cy5QmVAJ3IcKfJLYnAPMEOhpJcjji/MxKCOrN0VVwfPjpelPGEQyszyo9uKtR0vIOcRQN0TynnU1PJ4vY1uigJbvC1lWiNbzWn4GJfwzU5ehcABpY94TZVVfLFKY1GVnJWP/x/rE4VoCMxuiCC8g+v+LjvlIfz3yrkcQQRklK+tulNG/cHjqrBoRLC6raOntpVG70jkeIQL+x7s7fb9CD1A4PgWEGHDUU1JH4aOVNDyYRv3A+IK68nZWTlBf7Xz9jwbXNAoXHBK+1sFq8cvQL1xxjU33l4mATQF1L5qcg7LXRxys29TpdU6BfWGCVoo1QFBMQ76uHfA1NeyYj2WjsJ0sKuLtWFGMGlFu/XYCOoL7Ar20LrsTVtbfKWnOUHmj4VduS9Ix3+2zbCvRjh62PJAv/jzMg2NBRZjcHzWU8Dg/TPlwY5VplxOVqAT0pEBMHlwSBsJkATeweuIauAK7bK5ILKkaRtQC8iI+dbP1k/TSYPyRDpYaScHgCNBppz8n9fiGUZMaOz8ET4wwHIVPNyEVR+dQ0n6C9HINtQX1g+9TqWFASwf3mzCts5lpu7+DLwYcs1lWJz3f71LWppZIHWPFTj3XRb0QDU2hctaS2P/CaajNyREobMZFCPb6s15CwYe62A+yQB8rIlqzAARE/xmqGjmKP4yzrw2wb2a7jVa1ibfs04uTjB4FnwA== X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2001af5b-4c11-4c69-2f51-08da23b3fea6 X-MS-Exchange-CrossTenant-AuthSource: MN2PR12MB4192.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Apr 2022 16:28:40.6487 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: xGwi+z9QkRxI48xbFq3q5zjqpNpfGV4ZiWbH/mfvaArGwHSgjdLlLzhhIPII483C X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB2907 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org When the open_device() op is called the container_users is incremented and held incremented until close_device(). Thus, so long as drivers call functions within their open_device()/close_device() region they do not need to worry about the container_users. These functions can all only be called between open_device() and close_device(): vfio_pin_pages() vfio_unpin_pages() vfio_dma_rw() vfio_register_notifier() vfio_unregister_notifier() Eliminate the calls to vfio_group_add_container_user() and add vfio_assert_device_open() to detect driver mis-use. Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Reviewed-by: Kevin Tian , with one nit --- drivers/vfio/vfio.c | 78 +++++++++------------------------------------ 1 file changed, 15 insertions(+), 63 deletions(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index ba6fae95555ec7..b566ae3d320b36 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -1330,6 +1330,12 @@ static int vfio_group_add_container_user(struct vfio_group *group) static const struct file_operations vfio_device_fops; +/* true if the vfio_device has open_device() called but not close_device() */ +static bool vfio_assert_device_open(struct vfio_device *device) +{ + return !WARN_ON_ONCE(!READ_ONCE(device->open_count)); +} + static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) { struct vfio_device *device; @@ -1544,8 +1550,10 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep) struct vfio_device *device = filep->private_data; mutex_lock(&device->dev_set->lock); - if (!--device->open_count && device->ops->close_device) + vfio_assert_device_open(device); + if (device->open_count == 1 && device->ops->close_device) device->ops->close_device(device); + device->open_count--; mutex_unlock(&device->dev_set->lock); module_put(device->dev->driver->owner); @@ -2112,7 +2120,7 @@ int vfio_pin_pages(struct vfio_device *vdev, unsigned long *user_pfn, int npage, struct vfio_iommu_driver *driver; int ret; - if (!user_pfn || !phys_pfn || !npage) + if (!user_pfn || !phys_pfn || !npage || !vfio_assert_device_open(vdev)) return -EINVAL; if (npage > VFIO_PIN_PAGES_MAX_ENTRIES) @@ -2121,10 +2129,6 @@ int vfio_pin_pages(struct vfio_device *vdev, unsigned long *user_pfn, int npage, if (group->dev_counter > 1) return -EINVAL; - ret = vfio_group_add_container_user(group); - if (ret) - return ret; - container = group->container; driver = container->iommu_driver; if (likely(driver && driver->ops->pin_pages)) @@ -2134,8 +2138,6 @@ int vfio_pin_pages(struct vfio_device *vdev, unsigned long *user_pfn, int npage, else ret = -ENOTTY; - vfio_group_try_dissolve_container(group); - return ret; } EXPORT_SYMBOL(vfio_pin_pages); @@ -2156,16 +2158,12 @@ int vfio_unpin_pages(struct vfio_device *vdev, unsigned long *user_pfn, struct vfio_iommu_driver *driver; int ret; - if (!user_pfn || !npage) + if (!user_pfn || !npage || !vfio_assert_device_open(vdev)) return -EINVAL; if (npage > VFIO_PIN_PAGES_MAX_ENTRIES) return -E2BIG; - ret = vfio_group_add_container_user(vdev->group); - if (ret) - return ret; - container = vdev->group->container; driver = container->iommu_driver; if (likely(driver && driver->ops->unpin_pages)) @@ -2174,8 +2172,6 @@ int vfio_unpin_pages(struct vfio_device *vdev, unsigned long *user_pfn, else ret = -ENOTTY; - vfio_group_try_dissolve_container(vdev->group); - return ret; } EXPORT_SYMBOL(vfio_unpin_pages); @@ -2204,13 +2200,9 @@ int vfio_dma_rw(struct vfio_device *vdev, dma_addr_t user_iova, void *data, struct vfio_iommu_driver *driver; int ret = 0; - if (!data || len <= 0) + if (!data || len <= 0 || !vfio_assert_device_open(vdev)) return -EINVAL; - ret = vfio_group_add_container_user(vdev->group); - if (ret) - return ret; - container = vdev->group->container; driver = container->iommu_driver; @@ -2219,9 +2211,6 @@ int vfio_dma_rw(struct vfio_device *vdev, dma_addr_t user_iova, void *data, user_iova, data, len, write); else ret = -ENOTTY; - - vfio_group_try_dissolve_container(vdev->group); - return ret; } EXPORT_SYMBOL(vfio_dma_rw); @@ -2234,10 +2223,6 @@ static int vfio_register_iommu_notifier(struct vfio_group *group, struct vfio_iommu_driver *driver; int ret; - ret = vfio_group_add_container_user(group); - if (ret) - return -EINVAL; - container = group->container; driver = container->iommu_driver; if (likely(driver && driver->ops->register_notifier)) @@ -2245,9 +2230,6 @@ static int vfio_register_iommu_notifier(struct vfio_group *group, events, nb); else ret = -ENOTTY; - - vfio_group_try_dissolve_container(group); - return ret; } @@ -2258,10 +2240,6 @@ static int vfio_unregister_iommu_notifier(struct vfio_group *group, struct vfio_iommu_driver *driver; int ret; - ret = vfio_group_add_container_user(group); - if (ret) - return -EINVAL; - container = group->container; driver = container->iommu_driver; if (likely(driver && driver->ops->unregister_notifier)) @@ -2269,9 +2247,6 @@ static int vfio_unregister_iommu_notifier(struct vfio_group *group, nb); else ret = -ENOTTY; - - vfio_group_try_dissolve_container(group); - return ret; } @@ -2300,10 +2275,6 @@ static int vfio_register_group_notifier(struct vfio_group *group, if (*events) return -EINVAL; - ret = vfio_group_add_container_user(group); - if (ret) - return -EINVAL; - ret = blocking_notifier_chain_register(&group->notifier, nb); /* @@ -2313,25 +2284,6 @@ static int vfio_register_group_notifier(struct vfio_group *group, if (!ret && set_kvm && group->kvm) blocking_notifier_call_chain(&group->notifier, VFIO_GROUP_NOTIFY_SET_KVM, group->kvm); - - vfio_group_try_dissolve_container(group); - - return ret; -} - -static int vfio_unregister_group_notifier(struct vfio_group *group, - struct notifier_block *nb) -{ - int ret; - - ret = vfio_group_add_container_user(group); - if (ret) - return -EINVAL; - - ret = blocking_notifier_chain_unregister(&group->notifier, nb); - - vfio_group_try_dissolve_container(group); - return ret; } @@ -2341,7 +2293,7 @@ int vfio_register_notifier(struct vfio_device *dev, enum vfio_notify_type type, struct vfio_group *group = dev->group; int ret; - if (!nb || !events || (*events == 0)) + if (!nb || !events || (*events == 0) || !vfio_assert_device_open(dev)) return -EINVAL; switch (type) { @@ -2365,7 +2317,7 @@ int vfio_unregister_notifier(struct vfio_device *dev, struct vfio_group *group = dev->group; int ret; - if (!nb) + if (!nb || !vfio_assert_device_open(dev)) return -EINVAL; switch (type) { @@ -2373,7 +2325,7 @@ int vfio_unregister_notifier(struct vfio_device *dev, ret = vfio_unregister_iommu_notifier(group, nb); break; case VFIO_GROUP_NOTIFY: - ret = vfio_unregister_group_notifier(group, nb); + ret = blocking_notifier_chain_unregister(&group->notifier, nb); break; default: ret = -EINVAL;