From 479380efe1625e251008d24b2810283db60d6fcd Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Fri, 7 Feb 2025 14:56:00 -0600 Subject: [PATCH] PCI: Avoid reset when disabled via sysfs After d88f521da3ef ("PCI: Allow userspace to query and set device reset mechanism"), userspace can disable reset of specific PCI devices by writing an empty string to the sysfs reset_method file. However, pci_slot_resettable() does not check pci_reset_supported(), which means that pci_reset_function() will still reset the device even if userspace has disabled all the reset methods. I was able to reproduce this issue with a vfio device passed to a qemu guest, where I had disabled PCI reset via sysfs. Add an explicit check of pci_reset_supported() in both pci_slot_resettable() and pci_bus_resettable() to ensure both the reset status and reset execution are bypassed if an administrator disables it for a device. Link: https://lore.kernel.org/r/20250207205600.1846178-1-naravamudan@nvidia.com Fixes: d88f521da3ef ("PCI: Allow userspace to query and set device reset mechanism") Signed-off-by: Nishanth Aravamudan [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas Cc: Alex Williamson Cc: Raphael Norwitz Cc: Amey Narkhede Cc: Jason Gunthorpe Cc: Yishai Hadas Cc: Shameer Kolothum Cc: Kevin Tian --- drivers/pci/pci.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 3d13bb8e5c53..c6c25b910bde 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5410,6 +5410,8 @@ static bool pci_bus_resettable(struct pci_bus *bus) return false; list_for_each_entry(dev, &bus->devices, bus_list) { + if (!pci_reset_supported(dev)) + return false; if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || (dev->subordinate && !pci_bus_resettable(dev->subordinate))) return false; @@ -5486,6 +5488,8 @@ static bool pci_slot_resettable(struct pci_slot *slot) list_for_each_entry(dev, &slot->bus->devices, bus_list) { if (!dev->slot || dev->slot != slot) continue; + if (!pci_reset_supported(dev)) + return false; if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || (dev->subordinate && !pci_bus_resettable(dev->subordinate))) return false; -- 2.25.1