From patchwork Fri Oct 13 18:35:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 10005671 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9D32360325 for ; Fri, 13 Oct 2017 18:36:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9486729138 for ; Fri, 13 Oct 2017 18:36:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 896BA2913A; Fri, 13 Oct 2017 18:36:51 +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=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable 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 2263F29138 for ; Fri, 13 Oct 2017 18:36:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750907AbdJMSgW (ORCPT ); Fri, 13 Oct 2017 14:36:22 -0400 Received: from mga04.intel.com ([192.55.52.120]:21842 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751339AbdJMSf5 (ORCPT ); Fri, 13 Oct 2017 14:35:57 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Oct 2017 11:35:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,372,1503385200"; d="scan'208";a="1230534183" Received: from black.fi.intel.com ([10.237.72.28]) by fmsmga002.fm.intel.com with ESMTP; 13 Oct 2017 11:35:54 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 64B51548; Fri, 13 Oct 2017 21:35:49 +0300 (EEST) From: Mika Westerberg To: Bjorn Helgaas Cc: Ashok Raj , Keith Busch , "Rafael J . Wysocki" , Lukas Wunner , Michael Jamet , Yehezkel Bernat , Mario.Limonciello@dell.com, Mika Westerberg , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 8/8] PCI: pciehp: Check that the device is really present before touching it Date: Fri, 13 Oct 2017 21:35:48 +0300 Message-Id: <20171013183548.68283-9-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171013183548.68283-1-mika.westerberg@linux.intel.com> References: <20171013183548.68283-1-mika.westerberg@linux.intel.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP During surprise hot-unplug the device is not there anymore. When that happens we read 0xffffffff from the registers and pciehp_unconfigure_device() inadvertently thinks the device is a display device because bridge control register returns 0xff refusing to remove it: pciehp 0000:00:1c.0:pcie004: Slot(0): Link Down pciehp 0000:00:1c.0:pcie004: Slot(0): Card present pciehp 0000:00:1c.0:pcie004: Cannot remove display device 0000:01:00.0 This causes the hotplug functionality to leave the hierarcy untouched preventing further hotplug operations. To fix this verify presence of a device by calling pci_device_is_present() for it before we touch it any further. Signed-off-by: Mika Westerberg --- drivers/pci/hotplug/pciehp_pci.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 2a1ca020cf5a..fb4333168e23 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -100,8 +100,14 @@ int pciehp_unconfigure_device(struct slot *p_slot) */ list_for_each_entry_safe_reverse(dev, temp, &parent->devices, bus_list) { + bool present; + pci_dev_get(dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { + + /* Check if the device is really there anymore */ + present = presence ? pci_device_is_present(dev) : false; + + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && present) { pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); if (bctl & PCI_BRIDGE_CTL_VGA) { ctrl_err(ctrl, @@ -112,7 +118,7 @@ int pciehp_unconfigure_device(struct slot *p_slot) break; } } - if (!presence) { + if (!present) { pci_dev_set_disconnected(dev, NULL); if (pci_has_subordinate(dev)) pci_walk_bus(dev->subordinate, @@ -123,7 +129,7 @@ int pciehp_unconfigure_device(struct slot *p_slot) * Ensure that no new Requests will be generated from * the device. */ - if (presence) { + if (present) { pci_read_config_word(dev, PCI_COMMAND, &command); command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR); command |= PCI_COMMAND_INTX_DISABLE;