| From 25f96af91e07bb5e2e6d65ba8727975024976b78 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 7 Feb 2025 14:56:00 -0600 |
| Subject: PCI: Avoid reset when disabled via sysfs |
| |
| From: Nishanth Aravamudan <naravamudan@nvidia.com> |
| |
| [ Upstream commit 479380efe1625e251008d24b2810283db60d6fcd ] |
| |
| 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 <naravamudan@nvidia.com> |
| [bhelgaas: commit log] |
| Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> |
| Cc: Alex Williamson <alex.williamson@redhat.com> |
| Cc: Raphael Norwitz <raphael.norwitz@nutanix.com> |
| Cc: Amey Narkhede <ameynarkhede03@gmail.com> |
| Cc: Jason Gunthorpe <jgg@nvidia.com> |
| Cc: Yishai Hadas <yishaih@nvidia.com> |
| Cc: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> |
| Cc: Kevin Tian <kevin.tian@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/pci/pci.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c |
| index fbaf9af62bd67..6a5f53f968c3d 100644 |
| --- a/drivers/pci/pci.c |
| +++ b/drivers/pci/pci.c |
| @@ -5484,6 +5484,8 @@ static bool pci_bus_resetable(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_resetable(dev->subordinate))) |
| return false; |
| @@ -5560,6 +5562,8 @@ static bool pci_slot_resetable(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_resetable(dev->subordinate))) |
| return false; |
| -- |
| 2.39.5 |
| |