提交 29ed1f29 编写于 作者: Y Yinghai Lu 提交者: Bjorn Helgaas

PCI: pciehp: Fix null pointer deref when hot-removing SR-IOV device

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 ba518e3c ("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.

ac205b7b ("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=60604Signed-off-by: NYinghai Lu <yinghai@kernel.org>
Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
Acked-by: NYijing Wang <wangyijing@huawei.com>
CC: stable@vger.kernel.org	# v3.9+
上级 3b2f64d0
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册