From patchwork Tue Oct 24 11:09:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 10024143 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 EBB3760375 for ; Tue, 24 Oct 2017 11:09:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C83B028712 for ; Tue, 24 Oct 2017 11:09:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BBA102896E; Tue, 24 Oct 2017 11:09: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=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 28AFE28694 for ; Tue, 24 Oct 2017 11:09:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932334AbdJXLJt (ORCPT ); Tue, 24 Oct 2017 07:09:49 -0400 Received: from mga07.intel.com ([134.134.136.100]:30415 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932282AbdJXLJt (ORCPT ); Tue, 24 Oct 2017 07:09:49 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga105.jf.intel.com with ESMTP; 24 Oct 2017 04:09:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,427,1503385200"; d="scan'208";a="1234557491" Received: from black.fi.intel.com ([10.237.72.28]) by fmsmga002.fm.intel.com with ESMTP; 24 Oct 2017 04:09:45 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 603F3206; Tue, 24 Oct 2017 14:09:14 +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 v3] PCI: pciehp: Check for valid PCI_BRIDGE_CONTROL in pciehp_unconfigure_device() Date: Tue, 24 Oct 2017 14:09:14 +0300 Message-Id: <20171024110914.53612-1-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.14.2 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() might inadvertently think 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. Fix this so that we first compare the read bctl value against 0xffff (device is not present anymore) before determining whether the device is a display or not. Signed-off-by: Mika Westerberg --- Hi Bjorn, This is an updated version of the patch 8/8 in my "PCI: Improvements for native PCIe hotplug" patch series and applies on top of pci.git/pci/hotplug. We now just check bctl against 0xffff before preventing removal of the "display" device. I'm inclined to remove the whole check of "display" device because I don't see any reason for it to be there in the first place. This code is pretty much duplicated from shpchp_pci.c where it might make some sense. drivers/pci/hotplug/pciehp_pci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 2a1ca020cf5a..5225b12c5a75 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -79,7 +79,6 @@ int pciehp_configure_device(struct slot *p_slot) int pciehp_unconfigure_device(struct slot *p_slot) { int rc = 0; - u8 bctl = 0; u8 presence = 0; struct pci_dev *dev, *temp; struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; @@ -102,8 +101,10 @@ int pciehp_unconfigure_device(struct slot *p_slot) bus_list) { pci_dev_get(dev); if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { - pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); - if (bctl & PCI_BRIDGE_CTL_VGA) { + u16 bctl = 0; + + pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bctl); + if (bctl != 0xffff && (bctl & PCI_BRIDGE_CTL_VGA)) { ctrl_err(ctrl, "Cannot remove display device %s\n", pci_name(dev));