From patchwork Thu Dec 6 12:32:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Whitcroft X-Patchwork-Id: 1008762 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 439Zjt4rdXz9s3Z; Thu, 6 Dec 2018 23:32:18 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1gUsp8-0003Bc-32; Thu, 06 Dec 2018 12:32:10 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1gUsp4-0003BV-1i for kernel-team@lists.ubuntu.com; Thu, 06 Dec 2018 12:32:06 +0000 Received: from 1.general.apw.uk.vpn ([10.172.192.78] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1gUsp3-0004Bq-PO; Thu, 06 Dec 2018 12:32:05 +0000 From: Andy Whitcroft To: kernel-team@lists.ubuntu.com Subject: [SRU bionic/master-next 1/1 V2] UBUNTU: SAUCE: base/dd: limit release function changes to vfio driver only Date: Thu, 6 Dec 2018 12:32:05 +0000 Message-Id: <20181206123205.10050-1-apw@canonical.com> X-Mailer: git-send-email 2.19.1 MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andy Whitcroft Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" It seems that we can trigger the new race detection after remove() with some drivers which clear the driver as they unreference the module. This leads us to fail to clear down those devices which triggers suspend/resume issues. Limit the core changes to only apply to the vfio driver while we work with upstream on a more generic fix. Fixes: 876dcb5f4576 ("UBUNTU: SAUCE: vfio -- release device lock before userspace requests") BugLink: http://bugs.launchpad.net/bugs/1803942 Signed-off-by: Andy Whitcroft Acked-by: Colin Ian King Acked-by: Stefan Bader --- drivers/base/dd.c | 10 +++++++++- drivers/vfio/pci/vfio_pci.c | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 37c01054521b..045d4e4485b8 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -820,6 +820,9 @@ int driver_attach(struct device_driver *drv) } EXPORT_SYMBOL_GPL(driver_attach); +void *vfio_pci_driver_ptr = (void *)0xdeadfeed; +EXPORT_SYMBOL(vfio_pci_driver_ptr); + /* * __device_release_driver() must be called with @dev lock held. * When called for a USB interface, @dev->parent lock must be held as well. @@ -872,8 +875,13 @@ static void __device_release_driver(struct device *dev, struct device *parent) * A concurrent invocation of the same function might * have released the driver successfully while this one * was waiting, so check for that. + * LP: #1792099 + * + * Limit this to the vfio_pci_driver as some drivers NULL + * out this pointer in their remove() function. + * LP: #1803942 */ - if (dev->driver != drv) + if (drv == vfio_pci_driver_ptr && dev->driver != drv) return; device_links_driver_cleanup(dev); diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index f041b1a6cf66..6e70281715c4 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -1310,6 +1310,7 @@ static struct pci_driver vfio_pci_driver = { .remove = vfio_pci_remove, .err_handler = &vfio_err_handlers, }; +extern void *vfio_pci_driver_ptr; struct vfio_devices { struct vfio_device **devices; @@ -1404,6 +1405,8 @@ static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev) static void __exit vfio_pci_cleanup(void) { + vfio_pci_driver_ptr = (void *)0xdeadfeed; + pci_unregister_driver(&vfio_pci_driver); vfio_pci_uninit_perm_bits(); } @@ -1465,6 +1468,9 @@ static int __init vfio_pci_init(void) vfio_pci_fill_ids(); + /* Advertise my address. */ + vfio_pci_driver_ptr = &vfio_pci_driver; + return 0; out_driver: