From patchwork Thu Mar 5 21:06:58 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 5949121 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 081E59F36A for ; Thu, 5 Mar 2015 21:07:29 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A136B20397 for ; Thu, 5 Mar 2015 21:07:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 461A220392 for ; Thu, 5 Mar 2015 21:07:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756030AbbCEVHX (ORCPT ); Thu, 5 Mar 2015 16:07:23 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51608 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751846AbbCEVHX (ORCPT ); Thu, 5 Mar 2015 16:07:23 -0500 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t25L6xgD018516 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 5 Mar 2015 16:06:59 -0500 Received: from gimli.home (ovpn-113-210.phx2.redhat.com [10.3.113.210]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t25L6w4K001815; Thu, 5 Mar 2015 16:06:58 -0500 Subject: [PATCH] x86/PCI: Fully disable devices before releasing IRQ resource From: Alex Williamson To: x86@kernel.org, rjw@rjwysocki.net, mingo@redhat.com, bp@alien8.de, lv.zheng@intel.com, hpa@zytor.com, bhelgaas@google.com, tglx@linutronix.de, yinghai@kernel.org, lenb@kernel.org Cc: linux-pci@vger.kernel.org, tony.luck@intel.com, linux-acpi@vger.kernel.org, jiang.liu@linux.intel.com, linux-kernel@vger.kernel.org Date: Thu, 05 Mar 2015 14:06:58 -0700 Message-ID: <20150305210529.6393.29546.stgit@gimli.home> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The IRQ resource for a device is established when pci_enabled_device() is called on a fully disabled device (ie. enable_cnt == 0). With commit b4b55cda5874 ("x86/PCI: Refine the way to release PCI IRQ resources") this same IRQ resource is released when the driver is unbound from the device, regardless of the enable_cnt. This presents the situation that an ill-behaved driver can now make a device unusable to subsequent drivers by an imbalance in their use of pci_enable/disable_device(). It's one thing to break your own device if you're one of these ill-behaved drivers, but it's a serious regression for secondary drivers like vfio-pci, which are innocent of the transgressions of the previous driver. Resolve by pushing the device to a fully disabled state before releasing the IRQ resource. Fixes: b4b55cda5874 ("x86/PCI: Refine the way to release PCI IRQ resources") Signed-off-by: Alex Williamson Cc: Jiang Liu --- arch/x86/pci/common.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 3d2612b..4810194 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -527,8 +527,19 @@ static int pci_irq_notifier(struct notifier_block *nb, unsigned long action, if (action != BUS_NOTIFY_UNBOUND_DRIVER) return NOTIFY_DONE; - if (pcibios_disable_irq) + if (pcibios_disable_irq) { + /* + * Broken drivers may allow a device to be .remove()'d while + * still enabled. pci_enable_device() will only re-establish + * dev->irq if the devices is fully disabled. So if we want + * to release the IRQ, we need to make sure the next driver + * can re-establish it using pci_enable_device(). + */ + while (pci_is_enabled(dev)) + pci_disable_device(dev); + pcibios_disable_irq(dev); + } return NOTIFY_OK; }