Skip to content

Commit

Permalink
PCI: pciehp: Fix null pointer deref when hot-removing SR-IOV device
Browse files Browse the repository at this point in the history
Hot-removing a device with SR-IOV enabled causes a null pointer dereference
in v3.9 and v3.10.

This is a regression caused by ba518e3 ("PCI: pciehp: Iterate over all
devices in slot, not functions 0-7").  When we iterate over the
bus->devices list, we first remove the PF, which also removes all the VFs
from the list.  Then the list iterator blows up because more than just the
current entry was removed from the list.

ac205b7 ("PCI: make sriov work with hotplug remove") works around a
similar problem in pci_stop_bus_devices() by iterating over the list in
reverse, so the VFs are stopped and removed from the list first, before the
PF.

This patch changes pciehp_unconfigure_device() to iterate over the list in
reverse, too.

[bhelgaas: bugzilla, changelog]
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=60604
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Yijing Wang <wangyijing@huawei.com>
CC: stable@vger.kernel.org	# v3.9+
  • Loading branch information
Yinghai Lu authored and Bjorn Helgaas committed Jul 25, 2013
1 parent 3b2f64d commit 29ed1f2
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion drivers/pci/hotplug/pciehp_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,14 @@ int pciehp_unconfigure_device(struct slot *p_slot)
if (ret)
presence = 0;

list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {
/*
* Stopping an SR-IOV PF device removes all the associated VFs,
* which will update the bus->devices list and confuse the
* iterator. Therefore, iterate in reverse so we remove the VFs
* first, then the PF. We do the same in pci_stop_bus_device().
*/
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);
Expand Down

0 comments on commit 29ed1f2

Please sign in to comment.