linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5] PCI: hotplug: Drop checking of PCI_BRIDGE_CONTROL in *_unconfigure_device()
@ 2017-11-09 11:15 Mika Westerberg
  2017-12-05 10:11 ` Mika Westerberg
  2017-12-13 21:43 ` Bjorn Helgaas
  0 siblings, 2 replies; 3+ messages in thread
From: Mika Westerberg @ 2017-11-09 11:15 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Ashok Raj, Keith Busch, Rafael J . Wysocki, Lukas Wunner,
	Michael Jamet, Yehezkel Bernat, Mario.Limonciello,
	Mika Westerberg, linux-pci, linux-kernel

During PCIe surprise hot-unplug the device is not accessible anymore and
register reads return 0xffffffff. When that happens pciehp_unconfigure_device()
may inadvertently think the device below the bridge may be a display
device of somesort as reading PCI_BRIDGE_CONTROL register also returns
0xff. This results failure of the remove operation:

  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

Because of this the hierarchy is left untouched preventing further
hotplug operations.

Now, it is not clear why the check is there in the first place and why
we would like to prevent removing a bridge if it has PCI_BRIDGE_CTL_VGA
set. In case of PCIe surprise hot-unplug, it would not even be possible
to prevent the removal.

Given this and the issue described above, I think it makes sense to drop
the whole PCI_BRIDGE_CONTROL check from pciehp_unconfigure_device().
While there do the same for shpchp_configure_device() based on the same
reasoning and the fact that the same bug might trigger in standard PCI
hotplug as well.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
The previous version (v4) of the patch can be found here:

  https://patchwork.kernel.org/patch/10026551/

Changes from v4:

  - Drop the check from shpchp_configure_device() as well

 drivers/pci/hotplug/pciehp_pci.c | 12 ------------
 drivers/pci/hotplug/shpchp_pci.c | 12 ------------
 2 files changed, 24 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 2a1ca020cf5a..acc360d1a1fb 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;
@@ -101,17 +100,6 @@ int pciehp_unconfigure_device(struct slot *p_slot)
 	list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
 					 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) {
-				ctrl_err(ctrl,
-					 "Cannot remove display device %s\n",
-					 pci_name(dev));
-				pci_dev_put(dev);
-				rc = -EINVAL;
-				break;
-			}
-		}
 		if (!presence) {
 			pci_dev_set_disconnected(dev, NULL);
 			if (pci_has_subordinate(dev))
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index ea63db58b4b1..79f1682c858e 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -78,7 +78,6 @@ int shpchp_configure_device(struct slot *p_slot)
 int shpchp_unconfigure_device(struct slot *p_slot)
 {
 	int rc = 0;
-	u8 bctl = 0;
 	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
 	struct pci_dev *dev, *temp;
 	struct controller *ctrl = p_slot->ctrl;
@@ -93,17 +92,6 @@ int shpchp_unconfigure_device(struct slot *p_slot)
 			continue;
 
 		pci_dev_get(dev);
-		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-			pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
-			if (bctl & PCI_BRIDGE_CTL_VGA) {
-				ctrl_err(ctrl,
-					 "Cannot remove display device %s\n",
-					 pci_name(dev));
-				pci_dev_put(dev);
-				rc = -EINVAL;
-				break;
-			}
-		}
 		pci_stop_and_remove_bus_device(dev);
 		pci_dev_put(dev);
 	}
-- 
2.14.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v5] PCI: hotplug: Drop checking of PCI_BRIDGE_CONTROL in *_unconfigure_device()
  2017-11-09 11:15 [PATCH v5] PCI: hotplug: Drop checking of PCI_BRIDGE_CONTROL in *_unconfigure_device() Mika Westerberg
@ 2017-12-05 10:11 ` Mika Westerberg
  2017-12-13 21:43 ` Bjorn Helgaas
  1 sibling, 0 replies; 3+ messages in thread
From: Mika Westerberg @ 2017-12-05 10:11 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Ashok Raj, Keith Busch, Rafael J . Wysocki, Lukas Wunner,
	Michael Jamet, Yehezkel Bernat, Mario.Limonciello, linux-pci,
	linux-kernel

On Thu, Nov 09, 2017 at 02:15:08PM +0300, Mika Westerberg wrote:
> During PCIe surprise hot-unplug the device is not accessible anymore and
> register reads return 0xffffffff. When that happens pciehp_unconfigure_device()
> may inadvertently think the device below the bridge may be a display
> device of somesort as reading PCI_BRIDGE_CONTROL register also returns
> 0xff. This results failure of the remove operation:
> 
>   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
> 
> Because of this the hierarchy is left untouched preventing further
> hotplug operations.
> 
> Now, it is not clear why the check is there in the first place and why
> we would like to prevent removing a bridge if it has PCI_BRIDGE_CTL_VGA
> set. In case of PCIe surprise hot-unplug, it would not even be possible
> to prevent the removal.
> 
> Given this and the issue described above, I think it makes sense to drop
> the whole PCI_BRIDGE_CONTROL check from pciehp_unconfigure_device().
> While there do the same for shpchp_configure_device() based on the same
> reasoning and the fact that the same bug might trigger in standard PCI
> hotplug as well.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Hi Bjorn,

Any comments on this patch?

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v5] PCI: hotplug: Drop checking of PCI_BRIDGE_CONTROL in *_unconfigure_device()
  2017-11-09 11:15 [PATCH v5] PCI: hotplug: Drop checking of PCI_BRIDGE_CONTROL in *_unconfigure_device() Mika Westerberg
  2017-12-05 10:11 ` Mika Westerberg
@ 2017-12-13 21:43 ` Bjorn Helgaas
  1 sibling, 0 replies; 3+ messages in thread
From: Bjorn Helgaas @ 2017-12-13 21:43 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Bjorn Helgaas, Ashok Raj, Keith Busch, Rafael J . Wysocki,
	Lukas Wunner, Michael Jamet, Yehezkel Bernat, Mario.Limonciello,
	linux-pci, linux-kernel

On Thu, Nov 09, 2017 at 02:15:08PM +0300, Mika Westerberg wrote:
> During PCIe surprise hot-unplug the device is not accessible anymore and
> register reads return 0xffffffff. When that happens pciehp_unconfigure_device()
> may inadvertently think the device below the bridge may be a display
> device of somesort as reading PCI_BRIDGE_CONTROL register also returns
> 0xff. This results failure of the remove operation:
> 
>   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
> 
> Because of this the hierarchy is left untouched preventing further
> hotplug operations.
> 
> Now, it is not clear why the check is there in the first place and why
> we would like to prevent removing a bridge if it has PCI_BRIDGE_CTL_VGA
> set. In case of PCIe surprise hot-unplug, it would not even be possible
> to prevent the removal.
> 
> Given this and the issue described above, I think it makes sense to drop
> the whole PCI_BRIDGE_CONTROL check from pciehp_unconfigure_device().
> While there do the same for shpchp_configure_device() based on the same
> reasoning and the fact that the same bug might trigger in standard PCI
> hotplug as well.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Applied to pci/hotplug for v4.16, thanks!

> ---
> The previous version (v4) of the patch can be found here:
> 
>   https://patchwork.kernel.org/patch/10026551/
> 
> Changes from v4:
> 
>   - Drop the check from shpchp_configure_device() as well
> 
>  drivers/pci/hotplug/pciehp_pci.c | 12 ------------
>  drivers/pci/hotplug/shpchp_pci.c | 12 ------------
>  2 files changed, 24 deletions(-)
> 
> diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
> index 2a1ca020cf5a..acc360d1a1fb 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;
> @@ -101,17 +100,6 @@ int pciehp_unconfigure_device(struct slot *p_slot)
>  	list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
>  					 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) {
> -				ctrl_err(ctrl,
> -					 "Cannot remove display device %s\n",
> -					 pci_name(dev));
> -				pci_dev_put(dev);
> -				rc = -EINVAL;
> -				break;
> -			}
> -		}
>  		if (!presence) {
>  			pci_dev_set_disconnected(dev, NULL);
>  			if (pci_has_subordinate(dev))
> diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
> index ea63db58b4b1..79f1682c858e 100644
> --- a/drivers/pci/hotplug/shpchp_pci.c
> +++ b/drivers/pci/hotplug/shpchp_pci.c
> @@ -78,7 +78,6 @@ int shpchp_configure_device(struct slot *p_slot)
>  int shpchp_unconfigure_device(struct slot *p_slot)
>  {
>  	int rc = 0;
> -	u8 bctl = 0;
>  	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
>  	struct pci_dev *dev, *temp;
>  	struct controller *ctrl = p_slot->ctrl;
> @@ -93,17 +92,6 @@ int shpchp_unconfigure_device(struct slot *p_slot)
>  			continue;
>  
>  		pci_dev_get(dev);
> -		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
> -			pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
> -			if (bctl & PCI_BRIDGE_CTL_VGA) {
> -				ctrl_err(ctrl,
> -					 "Cannot remove display device %s\n",
> -					 pci_name(dev));
> -				pci_dev_put(dev);
> -				rc = -EINVAL;
> -				break;
> -			}
> -		}
>  		pci_stop_and_remove_bus_device(dev);
>  		pci_dev_put(dev);
>  	}
> -- 
> 2.14.2
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-12-13 21:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-09 11:15 [PATCH v5] PCI: hotplug: Drop checking of PCI_BRIDGE_CONTROL in *_unconfigure_device() Mika Westerberg
2017-12-05 10:11 ` Mika Westerberg
2017-12-13 21:43 ` Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).