From patchwork Fri Mar 22 23:20:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 10866625 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3E50315AC for ; Fri, 22 Mar 2019 23:21:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 27C702AA1A for ; Fri, 22 Mar 2019 23:21:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1C4232AA1C; Fri, 22 Mar 2019 23:21:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C8DF22AA12 for ; Fri, 22 Mar 2019 23:21:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728107AbfCVXUo (ORCPT ); Fri, 22 Mar 2019 19:20:44 -0400 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:56779 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726038AbfCVXUo (ORCPT ); Fri, 22 Mar 2019 19:20:44 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from parav@mellanox.com) with ESMTPS (AES256-SHA encrypted); 23 Mar 2019 01:20:42 +0200 Received: from sw-mtx-036.mtx.labs.mlnx (sw-mtx-036.mtx.labs.mlnx [10.12.150.149]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x2MNKavx007896; Sat, 23 Mar 2019 01:20:40 +0200 From: Parav Pandit To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com Cc: parav@mellanox.com Subject: [PATCH 1/8] vfio/mdev: Fix to not do put_device on device_register failure Date: Fri, 22 Mar 2019 18:20:28 -0500 Message-Id: <1553296835-37522-2-git-send-email-parav@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553296835-37522-1-git-send-email-parav@mellanox.com> References: <1553296835-37522-1-git-send-email-parav@mellanox.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP device_register() performs put_device() if device_add() fails. This balances with device_initialize(). mdev core performing put_device() when device_register() fails, is an error that puts already released device again. Therefore, don't put the device on error. Fixes: 7b96953bc640 ("vfio: Mediated device Core driver") Signed-off-by: Parav Pandit Reviewed-by: Maxim Levitsky --- drivers/vfio/mdev/mdev_core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index 0212f0e..3e5880a 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -318,10 +318,8 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) dev_set_name(&mdev->dev, "%pUl", uuid.b); ret = device_register(&mdev->dev); - if (ret) { - put_device(&mdev->dev); + if (ret) goto mdev_fail; - } ret = mdev_device_create_ops(kobj, mdev); if (ret) From patchwork Fri Mar 22 23:20:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 10866619 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5364A15AC for ; Fri, 22 Mar 2019 23:21:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C74D2AA12 for ; Fri, 22 Mar 2019 23:21:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 312B32AA13; Fri, 22 Mar 2019 23:21:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E1FA02AA15 for ; Fri, 22 Mar 2019 23:21:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728409AbfCVXUt (ORCPT ); Fri, 22 Mar 2019 19:20:49 -0400 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:56800 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728380AbfCVXUt (ORCPT ); Fri, 22 Mar 2019 19:20:49 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from parav@mellanox.com) with ESMTPS (AES256-SHA encrypted); 23 Mar 2019 01:20:44 +0200 Received: from sw-mtx-036.mtx.labs.mlnx (sw-mtx-036.mtx.labs.mlnx [10.12.150.149]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x2MNKaw0007896; Sat, 23 Mar 2019 01:20:42 +0200 From: Parav Pandit To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com Cc: parav@mellanox.com Subject: [PATCH 2/8] vfio/mdev: Avoid release parent reference during error path Date: Fri, 22 Mar 2019 18:20:29 -0500 Message-Id: <1553296835-37522-3-git-send-email-parav@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553296835-37522-1-git-send-email-parav@mellanox.com> References: <1553296835-37522-1-git-send-email-parav@mellanox.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP During mdev parent registration in mdev_register_device(), if parent device is duplicate, it releases the reference of existing parent device. This is incorrect. Existing parent device should not be touched. Fixes: 7b96953bc640 ("vfio: Mediated device Core driver") Signed-off-by: Parav Pandit Reviewed-by: Maxim Levitsky --- drivers/vfio/mdev/mdev_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index 3e5880a..4f213e4d 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -182,6 +182,7 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops) /* Check for duplicate */ parent = __find_parent_device(dev); if (parent) { + parent = NULL; ret = -EEXIST; goto add_dev_err; } From patchwork Fri Mar 22 23:20:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 10866621 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1CA331669 for ; Fri, 22 Mar 2019 23:21:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 05DC72AA1B for ; Fri, 22 Mar 2019 23:21:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EE50A2AA12; Fri, 22 Mar 2019 23:21:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E03602AA14 for ; Fri, 22 Mar 2019 23:21:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728397AbfCVXUt (ORCPT ); Fri, 22 Mar 2019 19:20:49 -0400 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:56802 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728379AbfCVXUt (ORCPT ); Fri, 22 Mar 2019 19:20:49 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from parav@mellanox.com) with ESMTPS (AES256-SHA encrypted); 23 Mar 2019 01:20:47 +0200 Received: from sw-mtx-036.mtx.labs.mlnx (sw-mtx-036.mtx.labs.mlnx [10.12.150.149]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x2MNKaw1007896; Sat, 23 Mar 2019 01:20:45 +0200 From: Parav Pandit To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com Cc: parav@mellanox.com Subject: [PATCH 3/8] vfio/mdev: Removed unused kref Date: Fri, 22 Mar 2019 18:20:30 -0500 Message-Id: <1553296835-37522-4-git-send-email-parav@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553296835-37522-1-git-send-email-parav@mellanox.com> References: <1553296835-37522-1-git-send-email-parav@mellanox.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Remove unused kref from the mdev_device structure. Fixes: 7b96953bc640 ("vfio: Mediated device Core driver") Signed-off-by: Parav Pandit Reviewed-by: Maxim Levitsky --- drivers/vfio/mdev/mdev_core.c | 1 - drivers/vfio/mdev/mdev_private.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index 4f213e4d..3d91f62 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -311,7 +311,6 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) mutex_unlock(&mdev_list_lock); mdev->parent = parent; - kref_init(&mdev->ref); mdev->dev.parent = dev; mdev->dev.bus = &mdev_bus_type; diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h index b5819b7..84b2b6c 100644 --- a/drivers/vfio/mdev/mdev_private.h +++ b/drivers/vfio/mdev/mdev_private.h @@ -30,7 +30,6 @@ struct mdev_device { struct mdev_parent *parent; uuid_le uuid; void *driver_data; - struct kref ref; struct list_head next; struct kobject *type_kobj; bool active; From patchwork Fri Mar 22 23:20:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 10866615 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0863015AC for ; Fri, 22 Mar 2019 23:21:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E6B542AA12 for ; Fri, 22 Mar 2019 23:21:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DB3A02AA13; Fri, 22 Mar 2019 23:21:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 83A5E2AA1A for ; Fri, 22 Mar 2019 23:21:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728467AbfCVXUy (ORCPT ); Fri, 22 Mar 2019 19:20:54 -0400 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:56819 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728455AbfCVXUy (ORCPT ); Fri, 22 Mar 2019 19:20:54 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from parav@mellanox.com) with ESMTPS (AES256-SHA encrypted); 23 Mar 2019 01:20:49 +0200 Received: from sw-mtx-036.mtx.labs.mlnx (sw-mtx-036.mtx.labs.mlnx [10.12.150.149]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x2MNKaw2007896; Sat, 23 Mar 2019 01:20:47 +0200 From: Parav Pandit To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com Cc: parav@mellanox.com Subject: [PATCH 4/8] vfio/mdev: Drop redundant extern for exported symbols Date: Fri, 22 Mar 2019 18:20:31 -0500 Message-Id: <1553296835-37522-5-git-send-email-parav@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553296835-37522-1-git-send-email-parav@mellanox.com> References: <1553296835-37522-1-git-send-email-parav@mellanox.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There is no need use 'extern' for exported functions. Signed-off-by: Parav Pandit Reviewed-by: Maxim Levitsky --- include/linux/mdev.h | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/include/linux/mdev.h b/include/linux/mdev.h index b6e048e..0924c48 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -118,21 +118,20 @@ struct mdev_driver { #define to_mdev_driver(drv) container_of(drv, struct mdev_driver, driver) -extern void *mdev_get_drvdata(struct mdev_device *mdev); -extern void mdev_set_drvdata(struct mdev_device *mdev, void *data); -extern uuid_le mdev_uuid(struct mdev_device *mdev); +void *mdev_get_drvdata(struct mdev_device *mdev); +void mdev_set_drvdata(struct mdev_device *mdev, void *data); +uuid_le mdev_uuid(struct mdev_device *mdev); extern struct bus_type mdev_bus_type; -extern int mdev_register_device(struct device *dev, - const struct mdev_parent_ops *ops); -extern void mdev_unregister_device(struct device *dev); +int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops); +void mdev_unregister_device(struct device *dev); -extern int mdev_register_driver(struct mdev_driver *drv, struct module *owner); -extern void mdev_unregister_driver(struct mdev_driver *drv); +int mdev_register_driver(struct mdev_driver *drv, struct module *owner); +void mdev_unregister_driver(struct mdev_driver *drv); -extern struct device *mdev_parent_dev(struct mdev_device *mdev); -extern struct device *mdev_dev(struct mdev_device *mdev); -extern struct mdev_device *mdev_from_dev(struct device *dev); +struct device *mdev_parent_dev(struct mdev_device *mdev); +struct device *mdev_dev(struct mdev_device *mdev); +struct mdev_device *mdev_from_dev(struct device *dev); #endif /* MDEV_H */ From patchwork Fri Mar 22 23:20:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 10866617 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 04F1915AC for ; Fri, 22 Mar 2019 23:21:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E313B2AA13 for ; Fri, 22 Mar 2019 23:21:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D792F2AA14; Fri, 22 Mar 2019 23:21:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9574E2AA16 for ; Fri, 22 Mar 2019 23:21:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728512AbfCVXV2 (ORCPT ); Fri, 22 Mar 2019 19:21:28 -0400 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:56822 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725982AbfCVXUy (ORCPT ); Fri, 22 Mar 2019 19:20:54 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from parav@mellanox.com) with ESMTPS (AES256-SHA encrypted); 23 Mar 2019 01:20:52 +0200 Received: from sw-mtx-036.mtx.labs.mlnx (sw-mtx-036.mtx.labs.mlnx [10.12.150.149]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x2MNKaw3007896; Sat, 23 Mar 2019 01:20:50 +0200 From: Parav Pandit To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com Cc: parav@mellanox.com Subject: [PATCH 5/8] vfio/mdev: Avoid masking error code to EBUSY Date: Fri, 22 Mar 2019 18:20:32 -0500 Message-Id: <1553296835-37522-6-git-send-email-parav@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553296835-37522-1-git-send-email-parav@mellanox.com> References: <1553296835-37522-1-git-send-email-parav@mellanox.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Instead of masking return error to -EBUSY, return actual error returned by the driver. Signed-off-by: Parav Pandit Reviewed-by: Maxim Levitsky --- drivers/vfio/mdev/mdev_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index 3d91f62..ab05464 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -142,7 +142,7 @@ static int mdev_device_remove_ops(struct mdev_device *mdev, bool force_remove) */ ret = parent->ops->remove(mdev); if (ret && !force_remove) - return -EBUSY; + return ret; sysfs_remove_groups(&mdev->dev.kobj, parent->ops->mdev_attr_groups); return 0; From patchwork Fri Mar 22 23:20:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 10866613 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 989FB1669 for ; Fri, 22 Mar 2019 23:21:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 826822A9F9 for ; Fri, 22 Mar 2019 23:21:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 76F2F2AA15; Fri, 22 Mar 2019 23:21:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F150B2AA18 for ; Fri, 22 Mar 2019 23:21:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728227AbfCVXVT (ORCPT ); Fri, 22 Mar 2019 19:21:19 -0400 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:56837 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728512AbfCVXU7 (ORCPT ); Fri, 22 Mar 2019 19:20:59 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from parav@mellanox.com) with ESMTPS (AES256-SHA encrypted); 23 Mar 2019 01:20:54 +0200 Received: from sw-mtx-036.mtx.labs.mlnx (sw-mtx-036.mtx.labs.mlnx [10.12.150.149]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x2MNKaw4007896; Sat, 23 Mar 2019 01:20:52 +0200 From: Parav Pandit To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com Cc: parav@mellanox.com Subject: [PATCH 6/8] vfio/mdev: Follow correct remove sequence Date: Fri, 22 Mar 2019 18:20:33 -0500 Message-Id: <1553296835-37522-7-git-send-email-parav@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553296835-37522-1-git-send-email-parav@mellanox.com> References: <1553296835-37522-1-git-send-email-parav@mellanox.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP mdev_remove_sysfs_files() should follow exact mirror sequence of a create, similar to what is followed in error unwinding path of mdev_create_sysfs_files(). Fixes: 7b96953bc640 ("vfio: Mediated device Core driver") Signed-off-by: Parav Pandit Reviewed-by: Maxim Levitsky --- drivers/vfio/mdev/mdev_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c index ce5dd21..c782fa9 100644 --- a/drivers/vfio/mdev/mdev_sysfs.c +++ b/drivers/vfio/mdev/mdev_sysfs.c @@ -280,7 +280,7 @@ int mdev_create_sysfs_files(struct device *dev, struct mdev_type *type) void mdev_remove_sysfs_files(struct device *dev, struct mdev_type *type) { + sysfs_remove_files(&dev->kobj, mdev_device_attrs); sysfs_remove_link(&dev->kobj, "mdev_type"); sysfs_remove_link(type->devices_kobj, dev_name(dev)); - sysfs_remove_files(&dev->kobj, mdev_device_attrs); } From patchwork Fri Mar 22 23:20:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 10866611 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8703C15AC for ; Fri, 22 Mar 2019 23:21:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 701D62AA12 for ; Fri, 22 Mar 2019 23:21:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 633C92AA16; Fri, 22 Mar 2019 23:21:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 017732AA13 for ; Fri, 22 Mar 2019 23:21:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728531AbfCVXVA (ORCPT ); Fri, 22 Mar 2019 19:21:00 -0400 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:56842 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728515AbfCVXU7 (ORCPT ); Fri, 22 Mar 2019 19:20:59 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from parav@mellanox.com) with ESMTPS (AES256-SHA encrypted); 23 Mar 2019 01:20:57 +0200 Received: from sw-mtx-036.mtx.labs.mlnx (sw-mtx-036.mtx.labs.mlnx [10.12.150.149]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x2MNKaw5007896; Sat, 23 Mar 2019 01:20:55 +0200 From: Parav Pandit To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com Cc: parav@mellanox.com Subject: [PATCH 7/8] vfio/mdev: Fix aborting mdev child device removal if one fails Date: Fri, 22 Mar 2019 18:20:34 -0500 Message-Id: <1553296835-37522-8-git-send-email-parav@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553296835-37522-1-git-send-email-parav@mellanox.com> References: <1553296835-37522-1-git-send-email-parav@mellanox.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP device_for_each_child() stops executing callback function for remaining child devices, if callback hits an error. Each child mdev device is independent of each other. While unregistering parent device, mdev core must remove all child mdev devices. Therefore, mdev_device_remove_cb() always returns success so that device_for_each_child doesn't abort if one child removal hits error. While at it, improve remove and unregister functions for below simplicity. There isn't need to pass forced flag pointer during mdev parent removal which invokes mdev_device_remove(). So simplify the flow. mdev_device_remove() is called from two paths. 1. mdev_unregister_driver() mdev_device_remove_cb() mdev_device_remove() 2. remove_store() mdev_device_remove() When device is removed by user using remote_store(), device under removal is mdev device. When device is removed during parent device removal using generic child iterator, mdev check is already done using dev_is_mdev(). Hence, remove the unnecessary loop in mdev_device_remove(). Fixes: 7b96953bc640 ("vfio: Mediated device Core driver") Signed-off-by: Parav Pandit Reviewed-by: Maxim Levitsky --- drivers/vfio/mdev/mdev_core.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index ab05464..944a058 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -150,10 +150,10 @@ static int mdev_device_remove_ops(struct mdev_device *mdev, bool force_remove) static int mdev_device_remove_cb(struct device *dev, void *data) { - if (!dev_is_mdev(dev)) - return 0; + if (dev_is_mdev(dev)) + mdev_device_remove(dev, true); - return mdev_device_remove(dev, data ? *(bool *)data : true); + return 0; } /* @@ -241,7 +241,6 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops) void mdev_unregister_device(struct device *dev) { struct mdev_parent *parent; - bool force_remove = true; mutex_lock(&parent_list_lock); parent = __find_parent_device(dev); @@ -255,8 +254,7 @@ void mdev_unregister_device(struct device *dev) list_del(&parent->next); class_compat_remove_link(mdev_bus_compat_class, dev, NULL); - device_for_each_child(dev, (void *)&force_remove, - mdev_device_remove_cb); + device_for_each_child(dev, NULL, mdev_device_remove_cb); parent_remove_sysfs_files(parent); @@ -346,24 +344,12 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) int mdev_device_remove(struct device *dev, bool force_remove) { - struct mdev_device *mdev, *tmp; + struct mdev_device *mdev; struct mdev_parent *parent; struct mdev_type *type; int ret; mdev = to_mdev_device(dev); - - mutex_lock(&mdev_list_lock); - list_for_each_entry(tmp, &mdev_list, next) { - if (tmp == mdev) - break; - } - - if (tmp != mdev) { - mutex_unlock(&mdev_list_lock); - return -ENODEV; - } - if (!mdev->active) { mutex_unlock(&mdev_list_lock); return -EAGAIN; From patchwork Fri Mar 22 23:20:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 10866609 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 019C115AC for ; Fri, 22 Mar 2019 23:21:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DD4822AA1C for ; Fri, 22 Mar 2019 23:21:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D1B172AA1E; Fri, 22 Mar 2019 23:21:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CC0792AA13 for ; Fri, 22 Mar 2019 23:21:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728573AbfCVXVG (ORCPT ); Fri, 22 Mar 2019 19:21:06 -0400 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:56855 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728513AbfCVXVF (ORCPT ); Fri, 22 Mar 2019 19:21:05 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from parav@mellanox.com) with ESMTPS (AES256-SHA encrypted); 23 Mar 2019 01:20:59 +0200 Received: from sw-mtx-036.mtx.labs.mlnx (sw-mtx-036.mtx.labs.mlnx [10.12.150.149]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x2MNKaw6007896; Sat, 23 Mar 2019 01:20:57 +0200 From: Parav Pandit To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com Cc: parav@mellanox.com Subject: [PATCH 8/8] vfio/mdev: Improve the create/remove sequence Date: Fri, 22 Mar 2019 18:20:35 -0500 Message-Id: <1553296835-37522-9-git-send-email-parav@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553296835-37522-1-git-send-email-parav@mellanox.com> References: <1553296835-37522-1-git-send-email-parav@mellanox.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There are five problems with current code structure. 1. mdev device is placed on the mdev bus before it is created in the vendor driver. Once a device is placed on the mdev bus without creating its supporting underlying vendor device, an open() can get triggered by userspace on partially initialized device. Below ladder diagram highlight it. cpu-0 cpu-1 ----- ----- create_store() mdev_create_device() device_register() ... vfio_mdev_probe() ...creates char device vfio_mdev_open() parent->ops->open(mdev) vfio_ap_mdev_open() matrix_mdev = NULL [...] parent->ops->create() vfio_ap_mdev_create() mdev_set_drvdata(mdev, matrix_mdev); /* Valid pointer set above */ 2. Current creation sequence is, parent->ops_create() groups_register() Remove sequence is, parent->ops->remove() groups_unregister() However, remove sequence should be exact mirror of creation sequence. Once this is achieved, all users of the mdev will be terminated first before removing underlying vendor device. (Follow standard linux driver model). At that point vendor's remove() ops shouldn't failed because device is taken off the bus that should terminate the users. 3. Additionally any new mdev driver that wants to work on mdev device during probe() routine registered using mdev_register_driver() needs to get stable mdev structure. 4. In following sequence, child devices created while removing mdev parent device can be left out, or it may lead to race of removing half initialized child mdev devices. issue-1: -------- cpu-0 cpu-1 ----- ----- mdev_unregister_device() device_for_each_child() mdev_device_remove_cb() mdev_device_remove() create_store() mdev_device_create() [...] device_register() parent_remove_sysfs_files() /* BUG: device added by cpu-0 * whose parent is getting removed. */ issue-2: -------- cpu-0 cpu-1 ----- ----- create_store() mdev_device_create() [...] device_register() [...] mdev_unregister_device() device_for_each_child() mdev_device_remove_cb() mdev_device_remove() mdev_create_sysfs_files() /* BUG: create is adding * sysfs files for a device * which is undergoing removal. */ parent_remove_sysfs_files() 5. Below crash is observed when user initiated remove is in progress and mdev_unregister_driver() completes parent unregistration. cpu-0 cpu-1 ----- ----- remove_store() mdev_device_remove() active = false; mdev_unregister_device() remove type [...] mdev_remove_ops() crashes. This is similar race like create() racing with mdev_unregister_device(). mtty mtty: MDEV: Registered iommu: Adding device 83b8f4f2-509f-382f-3c1e-e6bfe0fa1001 to group 57 vfio_mdev 83b8f4f2-509f-382f-3c1e-e6bfe0fa1001: MDEV: group_id = 57 mdev_device_remove sleep started mtty mtty: MDEV: Unregistering mtty_dev: Unloaded! BUG: unable to handle kernel paging request at ffffffffc027d668 PGD af9818067 P4D af9818067 PUD af981a067 PMD 8583c3067 PTE 0 Oops: 0000 [#1] SMP PTI CPU: 15 PID: 3517 Comm: bash Kdump: loaded Not tainted 5.0.0-rc7-vdevbus+ #2 Hardware name: Supermicro SYS-6028U-TR4+/X10DRU-i+, BIOS 2.0b 08/09/2016 RIP: 0010:mdev_device_remove_ops+0x1a/0x50 [mdev] Call Trace: mdev_device_remove+0xef/0x130 [mdev] remove_store+0x77/0xa0 [mdev] kernfs_fop_write+0x113/0x1a0 __vfs_write+0x33/0x1b0 ? rcu_read_lock_sched_held+0x64/0x70 ? rcu_sync_lockdep_assert+0x2a/0x50 ? __sb_start_write+0x121/0x1b0 ? vfs_write+0x17c/0x1b0 vfs_write+0xad/0x1b0 ? trace_hardirqs_on_thunk+0x1a/0x1c ksys_write+0x55/0xc0 do_syscall_64+0x5a/0x210 Therefore, mdev core is improved in following ways to overcome above issues. 1. Before placing mdev devices on the bus, perform vendor drivers creation which supports the mdev creation. This ensures that mdev specific all necessary fields are initialized before a given mdev can be accessed by bus driver. 2. During remove flow, first remove the device from the bus. This ensures that any bus specific devices and data is cleared. Once device is taken of the mdev bus, perform remove() of mdev from the vendor driver. 3. Linux core device model provides way to register and auto unregister the device sysfs attribute groups at dev->groups. Make use of this groups to let core create the groups and simplify code to avoid explicit groups creation and removal. 4. Wait for any ongoing mdev create() and remove() to finish before unregistering parent device using srcu. This continues to allow multiple create and remove to progress in parallel. At the same time guard parent removal while parent is being access by create() and remove callbacks. Fixes: 7b96953bc640 ("vfio: Mediated device Core driver") Signed-off-by: Parav Pandit Reviewed-by: Maxim Levitsky --- drivers/vfio/mdev/mdev_core.c | 142 +++++++++++++++++++++------------------ drivers/vfio/mdev/mdev_private.h | 7 +- drivers/vfio/mdev/mdev_sysfs.c | 6 +- 3 files changed, 84 insertions(+), 71 deletions(-) diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index 944a058..8fe0ed1 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -84,6 +84,7 @@ static void mdev_release_parent(struct kref *kref) ref); struct device *dev = parent->dev; + cleanup_srcu_struct(&parent->unreg_srcu); kfree(parent); put_device(dev); } @@ -103,56 +104,30 @@ static inline void mdev_put_parent(struct mdev_parent *parent) kref_put(&parent->ref, mdev_release_parent); } -static int mdev_device_create_ops(struct kobject *kobj, - struct mdev_device *mdev) +static int mdev_device_must_remove(struct mdev_device *mdev) { - struct mdev_parent *parent = mdev->parent; + struct mdev_parent *parent; + struct mdev_type *type; int ret; - ret = parent->ops->create(kobj, mdev); - if (ret) - return ret; + type = to_mdev_type(mdev->type_kobj); - ret = sysfs_create_groups(&mdev->dev.kobj, - parent->ops->mdev_attr_groups); + mdev_remove_sysfs_files(&mdev->dev, type); + device_del(&mdev->dev); + parent = mdev->parent; + ret = parent->ops->remove(mdev); if (ret) - parent->ops->remove(mdev); + dev_err(&mdev->dev, "Remove failed: err=%d\n", ret); + /* Balances with device_initialize() */ + put_device(&mdev->dev); return ret; } -/* - * mdev_device_remove_ops gets called from sysfs's 'remove' and when parent - * device is being unregistered from mdev device framework. - * - 'force_remove' is set to 'false' when called from sysfs's 'remove' which - * indicates that if the mdev device is active, used by VMM or userspace - * application, vendor driver could return error then don't remove the device. - * - 'force_remove' is set to 'true' when called from mdev_unregister_device() - * which indicate that parent device is being removed from mdev device - * framework so remove mdev device forcefully. - */ -static int mdev_device_remove_ops(struct mdev_device *mdev, bool force_remove) -{ - struct mdev_parent *parent = mdev->parent; - int ret; - - /* - * Vendor driver can return error if VMM or userspace application is - * using this mdev device. - */ - ret = parent->ops->remove(mdev); - if (ret && !force_remove) - return ret; - - sysfs_remove_groups(&mdev->dev.kobj, parent->ops->mdev_attr_groups); - return 0; -} - static int mdev_device_remove_cb(struct device *dev, void *data) { if (dev_is_mdev(dev)) - mdev_device_remove(dev, true); - + mdev_device_must_remove(to_mdev_device(dev)); return 0; } @@ -194,6 +169,7 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops) } kref_init(&parent->ref); + init_srcu_struct(&parent->unreg_srcu); parent->dev = dev; parent->ops = ops; @@ -214,6 +190,7 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops) if (ret) dev_warn(dev, "Failed to create compatibility class link\n"); + rcu_assign_pointer(parent->self, parent); list_add(&parent->next, &parent_list); mutex_unlock(&parent_list_lock); @@ -244,21 +221,36 @@ void mdev_unregister_device(struct device *dev) mutex_lock(&parent_list_lock); parent = __find_parent_device(dev); - if (!parent) { mutex_unlock(&parent_list_lock); return; } + list_del(&parent->next); + mutex_unlock(&parent_list_lock); + dev_info(dev, "MDEV: Unregistering\n"); - list_del(&parent->next); + /* Publish that this mdev parent is unregistering. So any new + * create/remove cannot start on this parent anymore by user. + */ + rcu_assign_pointer(parent->self, NULL); + + /* + * Wait for any active create() or remove() mdev ops on the parent + * to complete. + */ + synchronize_srcu(&parent->unreg_srcu); + + /* At this point it is confirmed that any pending user initiated + * create or remove callbacks accessing the parent are completed. + * It is safe to remove the parent now. + */ class_compat_remove_link(mdev_bus_compat_class, dev, NULL); device_for_each_child(dev, NULL, mdev_device_remove_cb); parent_remove_sysfs_files(parent); - mutex_unlock(&parent_list_lock); mdev_put_parent(parent); } EXPORT_SYMBOL(mdev_unregister_device); @@ -278,14 +270,24 @@ static void mdev_device_release(struct device *dev) int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) { int ret; + struct mdev_parent *valid_parent; struct mdev_device *mdev, *tmp; struct mdev_parent *parent; struct mdev_type *type = to_mdev_type(kobj); + int srcu_idx; parent = mdev_get_parent(type->parent); if (!parent) return -EINVAL; + srcu_idx = srcu_read_lock(&parent->unreg_srcu); + valid_parent = srcu_dereference(parent->self, &parent->unreg_srcu); + if (!valid_parent) { + /* parent is undergoing unregistration */ + ret = -ENODEV; + goto mdev_fail; + } + mutex_lock(&mdev_list_lock); /* Check for duplicate */ @@ -310,68 +312,76 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) mdev->parent = parent; + device_initialize(&mdev->dev); mdev->dev.parent = dev; mdev->dev.bus = &mdev_bus_type; mdev->dev.release = mdev_device_release; + mdev->dev.groups = type->parent->ops->mdev_attr_groups; dev_set_name(&mdev->dev, "%pUl", uuid.b); - ret = device_register(&mdev->dev); + ret = type->parent->ops->create(kobj, mdev); if (ret) - goto mdev_fail; + goto create_fail; - ret = mdev_device_create_ops(kobj, mdev); + ret = device_add(&mdev->dev); if (ret) - goto create_fail; + goto dev_fail; ret = mdev_create_sysfs_files(&mdev->dev, type); - if (ret) { - mdev_device_remove_ops(mdev, true); - goto create_fail; - } + if (ret) + goto sysfs_fail; mdev->type_kobj = kobj; mdev->active = true; dev_dbg(&mdev->dev, "MDEV: created\n"); + srcu_read_unlock(&parent->unreg_srcu, srcu_idx); return 0; +sysfs_fail: + device_del(&mdev->dev); +dev_fail: + type->parent->ops->remove(mdev); create_fail: - device_unregister(&mdev->dev); + put_device(&mdev->dev); mdev_fail: + srcu_read_unlock(&parent->unreg_srcu, srcu_idx); mdev_put_parent(parent); return ret; } -int mdev_device_remove(struct device *dev, bool force_remove) +int mdev_device_remove(struct device *dev) { + struct mdev_parent *valid_parent; struct mdev_device *mdev; struct mdev_parent *parent; - struct mdev_type *type; + int srcu_idx; int ret; mdev = to_mdev_device(dev); + parent = mdev->parent; + srcu_idx = srcu_read_lock(&parent->unreg_srcu); + valid_parent = srcu_dereference(parent->self, &parent->unreg_srcu); + if (!valid_parent) { + srcu_read_unlock(&parent->unreg_srcu, srcu_idx); + /* parent is undergoing unregistration */ + return -ENODEV; + } + + mutex_lock(&mdev_list_lock); if (!mdev->active) { mutex_unlock(&mdev_list_lock); - return -EAGAIN; + srcu_read_unlock(&parent->unreg_srcu, srcu_idx); + return -ENODEV; } - mdev->active = false; mutex_unlock(&mdev_list_lock); - type = to_mdev_type(mdev->type_kobj); - parent = mdev->parent; - - ret = mdev_device_remove_ops(mdev, force_remove); - if (ret) { - mdev->active = true; - return ret; - } + ret = mdev_device_must_remove(mdev); + srcu_read_unlock(&parent->unreg_srcu, srcu_idx); - mdev_remove_sysfs_files(dev, type); - device_unregister(dev); mdev_put_parent(parent); - - return 0; + return ret; } static int __init mdev_init(void) diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h index 84b2b6c..3d17db9 100644 --- a/drivers/vfio/mdev/mdev_private.h +++ b/drivers/vfio/mdev/mdev_private.h @@ -23,6 +23,11 @@ struct mdev_parent { struct list_head next; struct kset *mdev_types_kset; struct list_head type_list; + /* Protects unregistration to wait until create/remove + * are completed. + */ + struct srcu_struct unreg_srcu; + struct mdev_parent __rcu *self; }; struct mdev_device { @@ -58,6 +63,6 @@ struct mdev_type { void mdev_remove_sysfs_files(struct device *dev, struct mdev_type *type); int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid); -int mdev_device_remove(struct device *dev, bool force_remove); +int mdev_device_remove(struct device *dev); #endif /* MDEV_PRIVATE_H */ diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c index c782fa9..68a8191 100644 --- a/drivers/vfio/mdev/mdev_sysfs.c +++ b/drivers/vfio/mdev/mdev_sysfs.c @@ -236,11 +236,9 @@ static ssize_t remove_store(struct device *dev, struct device_attribute *attr, if (val && device_remove_file_self(dev, attr)) { int ret; - ret = mdev_device_remove(dev, false); - if (ret) { - device_create_file(dev, attr); + ret = mdev_device_remove(dev); + if (ret) return ret; - } } return count;