* [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs
@ 2026-08-12 4:53 Alex Williamson
2026-08-12 4:53 ` [RFC PATCH 1/5] PCI: Refuse function reset of an SR-IOV PF with enabled VFs Alex Williamson
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Alex Williamson @ 2026-08-12 4:53 UTC (permalink / raw)
To: kvm, Alex Williamson
Cc: Alex Williamson, skhawaja, Jason Gunthorpe, Bjorn Helgaas,
Kevin Tian, linux-kernel, linux-pci
It's recently been found[1] that vfio-pci doesn't restrict resets on PFs
while SR-IOV is enabled. This can not only result in an uncoordinated
disruption of the use of the associated VFs, but the ongoing use of and
access to the VF has the potential to result in machine checks.
This series proposes that this gap is largely an oversight of
pci_reset_function() to recognize that a PF reset affecting SR-IOV VFs
violates the scope boundary of the pci_reset_function() API.
Patch 1 introduces guards in the common wrappers where we can hold
device_lock to prevent .sriov_configure races. This covers locking
conformant use cases. __pci_reset_function_locked() can't be gated in
PCI-core; it runs after the potentially destructive .reset_prepare.
Therefore its callers must provide the gating, along with the locking
and state manipulation the interface already demands. The vfio-pci
change is included as an example and known use case here.
Patch 2 introduces a callback to pci_reset_bus() which allows a lock
dependent callback to be evaluated after locking the physical hierarchy
and before initiating the actual reset. This allows use cases such as
in the following patch to evaluate the SR-IOV PF configuration without
racing.
Patch 3 implements exactly that test in vfio-pci-core, such that the
hot-reset ioctl can be blocked when SR-IOV VFs are present on a bus/slot
affected PF. This completes the lockdown of resets induced on behalf of
the vfio-pci in-kernel or userspace drivers.
Patch 4 exports pci_reset_supported, which allows patch 5 to remove the
latched reset_works flag, which already had the potential to become
stale due to reset_method manipulation through sysfs, but now may also
become stale due to the SR-IOV state of the PF.
This is RFC to capture the discussion of [1] while it's active but
requires testing before formal proposal. This effectively side-steps
the feasibility and security question of the operating model in use by
the referenced thread by generically gating resets affecting PFs with
active SR-IOV. Please review and comment. Thanks,
Alex
[1]https://lore.kernel.org/all/20260805003355.728299-1-skhawaja@google.com/
Alex Williamson (5):
PCI: Refuse function reset of an SR-IOV PF with enabled VFs
PCI: Add pci_reset_bus_cond() for a caller-gated slot or bus reset
vfio/pci: Refuse to reset an SR-IOV PF with enabled VFs
PCI: Export pci_reset_supported()
vfio/pci: Use pci_reset_supported() in place of reset_works
drivers/pci/pci.c | 117 +++++++++++++++++++++++++++----
drivers/pci/pci.h | 1 -
drivers/vfio/pci/vfio_pci_core.c | 28 +++++---
include/linux/pci.h | 4 ++
include/linux/vfio_pci_core.h | 1 -
include/uapi/linux/vfio.h | 3 +
6 files changed, 129 insertions(+), 25 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [RFC PATCH 1/5] PCI: Refuse function reset of an SR-IOV PF with enabled VFs
2026-08-12 4:53 [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs Alex Williamson
@ 2026-08-12 4:53 ` Alex Williamson
2026-08-12 5:01 ` sashiko-bot
2026-08-12 4:53 ` [RFC PATCH 2/5] PCI: Add pci_reset_bus_cond() for a caller-gated slot or bus reset Alex Williamson
` (3 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Alex Williamson @ 2026-08-12 4:53 UTC (permalink / raw)
To: kvm, Alex Williamson
Cc: Alex Williamson, skhawaja, Jason Gunthorpe, Bjorn Helgaas,
Kevin Tian, linux-kernel, linux-pci
pci_reset_function() and its locked and try variants are intended to
provide a function-scoped reset. The bus and slot methods supporting
this interface refuse when sibling or subordinate devices are present.
SR-IOV VFs however, are not currently considered in this scope.
Correct this oversight by testing for non-zero VF count in calls
through the pci_reset_function() interfaces. This test needs to occur
under device_lock to avoid races with .sriov_configure. It should
also occur before pci_dev_save_and_disable() to avoid calling
potentially destructive reset hooks. Tests are therefore added
to each of pci_reset_function(), pci_reset_function_locked(), and
pci_try_reset_function().
The __pci_reset_function_locked() interface remains a low-level
primitive depending on the caller to perform such tests as necessary.
The vfio_pci_core use case of __pci_reset_function_locked() is pulled
through with this test. Other use cases, such as xen-pciback, that
don't obviously support or prevent binding to SR-IOV enabled PFs will
need to decide whether VFs are possible and can be preserved.
Additionally, direct callers of sriov_enable() that do not hold
device_lock (lpfc) are considered a preexisting, non-compliance issue.
Fixes: dd7cc44d0bce ("PCI: add SR-IOV API for Physical Function driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
---
drivers/pci/pci.c | 19 +++++++++++++++++++
drivers/vfio/pci/vfio_pci_core.c | 4 +++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 77b17b13ee61..b40b00c0c0c9 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5222,11 +5222,22 @@ int pci_reset_function(struct pci_dev *dev)
pci_dev_lock(bridge);
pci_dev_lock(dev);
+
+ /*
+ * Reset of an SR-IOV PF necessarily resets any active VFs. Such resets are
+ * beyond the scope advertised for pci_reset_function() and variants, refuse.
+ */
+ if (pci_num_vf(dev) > 0) {
+ rc = -ENOTTY;
+ goto unlock;
+ }
+
pci_dev_save_and_disable(dev);
rc = __pci_reset_function_locked(dev);
pci_dev_restore(dev);
+unlock:
pci_dev_unlock(dev);
if (bridge)
@@ -5264,6 +5275,9 @@ int pci_reset_function_locked(struct pci_dev *dev)
if (!pci_reset_supported(dev))
return -ENOTTY;
+ if (pci_num_vf(dev) > 0)
+ return -ENOTTY;
+
pci_dev_save_and_disable(dev);
rc = __pci_reset_function_locked(dev);
@@ -5290,6 +5304,11 @@ int pci_try_reset_function(struct pci_dev *dev)
if (!pci_dev_trylock(dev))
return -EAGAIN;
+ if (pci_num_vf(dev) > 0) {
+ pci_dev_unlock(dev);
+ return -ENOTTY;
+ }
+
pci_dev_save_and_disable(dev);
rc = __pci_reset_function_locked(dev);
pci_dev_restore(dev);
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 3f11a9624b9c..9757b171791c 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -790,7 +790,9 @@ void vfio_pci_core_disable(struct vfio_pci_core_device *vdev)
if (bridge && !pci_dev_trylock(bridge))
goto out_restore_state;
if (pci_dev_trylock(pdev)) {
- if (!__pci_reset_function_locked(pdev))
+ /* Enforce function scope under lock for SR-IOV PFs */
+ if (!pci_num_vf(pdev) &&
+ !__pci_reset_function_locked(pdev))
vdev->needs_reset = false;
pci_dev_unlock(pdev);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 2/5] PCI: Add pci_reset_bus_cond() for a caller-gated slot or bus reset
2026-08-12 4:53 [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs Alex Williamson
2026-08-12 4:53 ` [RFC PATCH 1/5] PCI: Refuse function reset of an SR-IOV PF with enabled VFs Alex Williamson
@ 2026-08-12 4:53 ` Alex Williamson
2026-08-12 5:00 ` sashiko-bot
2026-08-12 4:53 ` [RFC PATCH 3/5] vfio/pci: Refuse to reset an SR-IOV PF with enabled VFs Alex Williamson
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Alex Williamson @ 2026-08-12 4:53 UTC (permalink / raw)
To: kvm, Alex Williamson
Cc: Alex Williamson, skhawaja, Jason Gunthorpe, Bjorn Helgaas,
Kevin Tian, linux-kernel, linux-pci
pci_reset_bus() locks every device affected by a slot or bus reset,
performs the reset, and unlocks the devices, all internally. A caller
has no way to evaluate what the reset would actually touch.
Add pci_reset_bus_cond(), which takes a callback invoked on each
affected device once they are all locked. A nonzero return value from
the callback aborts the reset and the value is returned to the caller.
This allows, for instance, the caller to validate that SR-IOV is not
enabled on any affected device under device_lock, where the value is
known stable across the reset.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
---
drivers/pci/pci.c | 97 ++++++++++++++++++++++++++++++++++++++-------
include/linux/pci.h | 3 ++
2 files changed, 85 insertions(+), 15 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index b40b00c0c0c9..06728137c407 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5567,9 +5567,36 @@ int pci_probe_reset_slot(struct pci_slot *slot)
}
EXPORT_SYMBOL_GPL(pci_probe_reset_slot);
+/* Call @cb on every device a slot or bus reset affects, stopping on error. */
+static int pci_walk_reset_check(struct pci_bus *bus, struct pci_slot *slot,
+ int (*cb)(struct pci_dev *dev, void *data),
+ void *data)
+{
+ struct pci_dev *dev;
+ int rc;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ if (slot && (!dev->slot || dev->slot != slot))
+ continue;
+ rc = cb(dev, data);
+ if (rc)
+ return rc;
+ if (dev->subordinate) {
+ rc = pci_walk_reset_check(dev->subordinate,
+ NULL, cb, data);
+ if (rc)
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
/**
* pci_try_reset_slot - Try to reset a PCI slot
* @slot: PCI slot to reset
+ * @check: optional per-device callback that can abort the reset
+ * @data: opaque argument for @check
*
* A PCI bus may host multiple slots, each slot may support a reset mechanism
* independent of other slots. For instance, some slots may support slot power
@@ -5582,7 +5609,9 @@ EXPORT_SYMBOL_GPL(pci_probe_reset_slot);
*
* Same as above except return -EAGAIN if the slot cannot be locked
*/
-static int pci_try_reset_slot(struct pci_slot *slot)
+static int pci_try_reset_slot(struct pci_slot *slot,
+ int (*check)(struct pci_dev *dev, void *data),
+ void *data)
{
int rc;
@@ -5591,10 +5620,14 @@ static int pci_try_reset_slot(struct pci_slot *slot)
return rc;
if (pci_slot_trylock(slot)) {
- pci_slot_save_and_disable_locked(slot);
- might_sleep();
- rc = pci_reset_hotplug_slot(slot->hotplug, PCI_RESET_DO_RESET);
- pci_slot_restore_locked(slot);
+ rc = check ? pci_walk_reset_check(slot->bus, slot, check, data) : 0;
+ if (!rc) {
+ pci_slot_save_and_disable_locked(slot);
+ might_sleep();
+ rc = pci_reset_hotplug_slot(slot->hotplug,
+ PCI_RESET_DO_RESET);
+ pci_slot_restore_locked(slot);
+ }
pci_slot_unlock(slot);
} else
rc = -EAGAIN;
@@ -5626,10 +5659,14 @@ static int pci_bus_reset(struct pci_bus *bus, bool probe)
/**
* pci_try_reset_bus - Try to reset a PCI bus
* @bus: top level PCI bus to reset
+ * @check: optional per-device callback that can abort the reset
+ * @data: opaque argument for @check
*
* Same as above except return -EAGAIN if the bus cannot be locked
*/
-static int pci_try_reset_bus(struct pci_bus *bus)
+static int pci_try_reset_bus(struct pci_bus *bus,
+ int (*check)(struct pci_dev *dev, void *data),
+ void *data)
{
int rc;
@@ -5638,10 +5675,13 @@ static int pci_try_reset_bus(struct pci_bus *bus)
return rc;
if (pci_bus_trylock(bus)) {
- pci_bus_save_and_disable_locked(bus);
- might_sleep();
- rc = pci_bridge_secondary_bus_reset(bus->self);
- pci_bus_restore_locked(bus);
+ rc = check ? pci_walk_reset_check(bus, NULL, check, data) : 0;
+ if (!rc) {
+ pci_bus_save_and_disable_locked(bus);
+ might_sleep();
+ rc = pci_bridge_secondary_bus_reset(bus->self);
+ pci_bus_restore_locked(bus);
+ }
pci_bus_unlock(bus);
} else
rc = -EAGAIN;
@@ -5680,7 +5720,7 @@ static int pci_reset_bridge(struct pci_dev *bridge, bool restore)
list_for_each_entry(slot, &bus->slots, list) {
if (restore)
- ret = pci_try_reset_slot(slot);
+ ret = pci_try_reset_slot(slot, NULL, NULL);
else
ret = pci_slot_reset(slot, PCI_RESET_DO_RESET);
@@ -5694,7 +5734,7 @@ static int pci_reset_bridge(struct pci_dev *bridge, bool restore)
mutex_unlock(&pci_slot_mutex);
if (restore)
- return pci_try_reset_bus(bus);
+ return pci_try_reset_bus(bus, NULL, NULL);
return pci_bus_reset(bridge->subordinate, PCI_RESET_DO_RESET);
}
@@ -5724,16 +5764,43 @@ int pci_probe_reset_bus(struct pci_bus *bus)
}
EXPORT_SYMBOL_GPL(pci_probe_reset_bus);
+/**
+ * pci_reset_bus_cond - conditionally reset the slot or bus containing a device
+ * @pdev: top level PCI device to reset via slot/bus
+ * @check: optional callback invoked on each affected device before the reset
+ * @data: opaque argument passed to @check
+ *
+ * Reset the slot or bus containing @pdev. Once the entire physical bus/slot
+ * hierarchy is locked, @check (if not NULL) is called on each of those locked
+ * devices. A nonzero return aborts the reset and is returned to the caller,
+ * otherwise the reset proceeds.
+ *
+ * NB. @check runs with the full set of device_locks noted above held; callbacks
+ * must take these locking semantics into account. Use NULL to perform an
+ * unconditional reset.
+ *
+ * Return: 0 on success, -ENOTTY if @pdev is not resettable, -EAGAIN if the
+ * devices cannot be locked, or the value returned by @check.
+ */
+int pci_reset_bus_cond(struct pci_dev *pdev,
+ int (*check)(struct pci_dev *dev, void *data),
+ void *data)
+{
+ return !pci_probe_reset_slot(pdev->slot) ?
+ pci_try_reset_slot(pdev->slot, check, data) :
+ pci_try_reset_bus(pdev->bus, check, data);
+}
+EXPORT_SYMBOL_GPL(pci_reset_bus_cond);
+
/**
* pci_reset_bus - Try to reset a PCI bus
* @pdev: top level PCI device to reset via slot/bus
*
- * Same as above except return -EAGAIN if the bus cannot be locked
+ * Same as above without the conditional check.
*/
int pci_reset_bus(struct pci_dev *pdev)
{
- return (!pci_probe_reset_slot(pdev->slot)) ?
- pci_try_reset_slot(pdev->slot) : pci_try_reset_bus(pdev->bus);
+ return pci_reset_bus_cond(pdev, NULL, NULL);
}
EXPORT_SYMBOL_GPL(pci_reset_bus);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 64b308b6e61c..ab41a49f4eb7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1480,6 +1480,9 @@ int pci_try_reset_function(struct pci_dev *dev);
int pci_probe_reset_slot(struct pci_slot *slot);
int pci_probe_reset_bus(struct pci_bus *bus);
int pci_reset_bus(struct pci_dev *dev);
+int pci_reset_bus_cond(struct pci_dev *pdev,
+ int (*check)(struct pci_dev *dev, void *data),
+ void *data);
void pci_reset_secondary_bus(struct pci_dev *dev);
void pcibios_reset_secondary_bus(struct pci_dev *dev);
void pci_update_resource(struct pci_dev *dev, int resno);
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 3/5] vfio/pci: Refuse to reset an SR-IOV PF with enabled VFs
2026-08-12 4:53 [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs Alex Williamson
2026-08-12 4:53 ` [RFC PATCH 1/5] PCI: Refuse function reset of an SR-IOV PF with enabled VFs Alex Williamson
2026-08-12 4:53 ` [RFC PATCH 2/5] PCI: Add pci_reset_bus_cond() for a caller-gated slot or bus reset Alex Williamson
@ 2026-08-12 4:53 ` Alex Williamson
2026-08-12 5:02 ` sashiko-bot
2026-08-12 4:53 ` [RFC PATCH 4/5] PCI: Export pci_reset_supported() Alex Williamson
2026-08-12 4:53 ` [RFC PATCH 5/5] vfio/pci: Use pci_reset_supported() in place of reset_works Alex Williamson
4 siblings, 1 reply; 11+ messages in thread
From: Alex Williamson @ 2026-08-12 4:53 UTC (permalink / raw)
To: kvm, Alex Williamson
Cc: Alex Williamson, skhawaja, Jason Gunthorpe, Bjorn Helgaas,
Kevin Tian, linux-kernel, linux-pci
The vfio-pci hot-reset interface VFIO_DEVICE_PCI_HOT_RESET does not
take into account whether an SR-IOV PF has active VFs. The VFs appear
on a virtual bus, which is not enumerated in collecting affected
devices.
Move the burden to the user when active VFs are present, require that
there are no VFs present on SR-IOV capable PFs in order to conduct a
hot reset.
Fixes: 137e5531351d ("vfio/pci: Add sriov_configure support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
---
drivers/vfio/pci/vfio_pci_core.c | 15 +++++++++++++--
include/uapi/linux/vfio.h | 3 +++
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 9757b171791c..956a05ca12e5 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -894,6 +894,17 @@ static int vfio_pci_count_devs(struct pci_dev *pdev, void *data)
return 0;
}
+/*
+ * PCI walk callback to check for SR-IOV PFs with active VFs. VFs are not
+ * enumerated when determining affected devices and may be owned by separate
+ * userspace processes from the PF. It's therefore the user's responsibility
+ * to teardown VFs for any affected PF before performing a hot-reset.
+ */
+static int vfio_pci_dev_has_vfs(struct pci_dev *pdev, void *data)
+{
+ return pci_num_vf(pdev) ? -EBUSY : 0;
+}
+
struct vfio_pci_fill_info {
struct vfio_device *vdev;
struct vfio_pci_dependent_device *devices;
@@ -2598,7 +2609,7 @@ static int vfio_pci_dev_set_hot_reset(struct vfio_device_set *dev_set,
list_for_each_entry(vdev, &dev_set->device_list, vdev.dev_set_list)
vfio_pci_set_power_state(vdev, PCI_D0);
- ret = pci_reset_bus(pdev);
+ ret = pci_reset_bus_cond(pdev, vfio_pci_dev_has_vfs, NULL);
vdev = list_last_entry(&dev_set->device_list,
struct vfio_pci_core_device, vdev.dev_set_list);
@@ -2661,7 +2672,7 @@ static void vfio_pci_dev_set_try_reset(struct vfio_device_set *dev_set)
if (vfio_pci_dev_set_pm_runtime_get(dev_set))
return;
- if (!pci_reset_bus(pdev))
+ if (!pci_reset_bus_cond(pdev, vfio_pci_dev_has_vfs, NULL))
reset_done = true;
list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list) {
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 5de618a3a5ee..8603959f1735 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -772,6 +772,9 @@ struct vfio_pci_hot_reset_info {
* Mixed usage of legacy groups and cdevs across the set of affected
* devices is not supported.
*
+ * Hot reset of SR-IOV PFs with active VFs is not supported, SR-IOV
+ * should first be disabled on any affected PF.
+ *
* Return: 0 on success, -errno on failure.
*/
struct vfio_pci_hot_reset {
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 4/5] PCI: Export pci_reset_supported()
2026-08-12 4:53 [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs Alex Williamson
` (2 preceding siblings ...)
2026-08-12 4:53 ` [RFC PATCH 3/5] vfio/pci: Refuse to reset an SR-IOV PF with enabled VFs Alex Williamson
@ 2026-08-12 4:53 ` Alex Williamson
2026-08-12 4:59 ` sashiko-bot
2026-08-12 4:53 ` [RFC PATCH 5/5] vfio/pci: Use pci_reset_supported() in place of reset_works Alex Williamson
4 siblings, 1 reply; 11+ messages in thread
From: Alex Williamson @ 2026-08-12 4:53 UTC (permalink / raw)
To: kvm, Alex Williamson
Cc: Alex Williamson, skhawaja, Jason Gunthorpe, Bjorn Helgaas,
Kevin Tian, linux-kernel, linux-pci
The success or failure of pci_reset_function() is conditional on the
state of the device, ex. VFs enabled on an SR-IOV PF. Therefore a
driver can no longer infer through executing pci_reset_function()
whether a device has supported reset methods. The reset_methods
array indicates whether the device has any available reset mechanisms
and is not gated on dynamic blockers, like SR-IOV enablement.
Export pci_reset_supported() for drivers to use for an instant
snapshot of reset support.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
---
drivers/pci/pci.c | 1 +
drivers/pci/pci.h | 1 -
include/linux/pci.h | 1 +
3 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 06728137c407..0b4f13397da2 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -98,6 +98,7 @@ bool pci_reset_supported(struct pci_dev *dev)
{
return dev->reset_methods[0] != 0;
}
+EXPORT_SYMBOL_GPL(pci_reset_supported);
#ifdef CONFIG_PCI_DOMAINS
int pci_domains_supported = 1;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4469e1a77f3c..416fd6b74abe 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -230,7 +230,6 @@ enum pci_mmap_api {
int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vmai,
enum pci_mmap_api mmap_api);
-bool pci_reset_supported(struct pci_dev *dev);
void pci_init_reset_methods(struct pci_dev *dev);
int pci_bridge_secondary_bus_reset(struct pci_dev *dev);
int pci_bus_error_reset(struct pci_dev *dev);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index ab41a49f4eb7..4de21e6ac538 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1474,6 +1474,7 @@ void pcie_print_link_status(struct pci_dev *dev);
int pcie_reset_flr(struct pci_dev *dev, bool probe);
int pcie_flr(struct pci_dev *dev);
int __pci_reset_function_locked(struct pci_dev *dev);
+bool pci_reset_supported(struct pci_dev *dev);
int pci_reset_function(struct pci_dev *dev);
int pci_reset_function_locked(struct pci_dev *dev);
int pci_try_reset_function(struct pci_dev *dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 5/5] vfio/pci: Use pci_reset_supported() in place of reset_works
2026-08-12 4:53 [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs Alex Williamson
` (3 preceding siblings ...)
2026-08-12 4:53 ` [RFC PATCH 4/5] PCI: Export pci_reset_supported() Alex Williamson
@ 2026-08-12 4:53 ` Alex Williamson
2026-08-12 4:59 ` sashiko-bot
4 siblings, 1 reply; 11+ messages in thread
From: Alex Williamson @ 2026-08-12 4:53 UTC (permalink / raw)
To: kvm, Alex Williamson
Cc: Alex Williamson, skhawaja, Jason Gunthorpe, Bjorn Helgaas,
Kevin Tian, linux-kernel, linux-pci
vfio-pci latches whether pci_reset_function() works at open device and
makes decisions based on this latched value at runtime. With the
introduction of the reset_method pci-sysfs attribute, this flag can
be made stale at runtime by administrative action. Further, with the
SR-IOV active VFs gating of pci_reset_function(), the flag can be made
stale via more subtle dependencies.
Drop the latched flag and rely on pci_reset_supported() to indicate
whether reset methods exist for the device. This is no guarantee that
those reset methods work, nor has the RESET flag in struct
vfio_device_info ever been a guarantee of VFIO_DEVICE_RESET success.
It's only a guarantee that there are reset methods that are
applicable to the device at the instant it's called.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
---
drivers/vfio/pci/vfio_pci_core.c | 9 ++++-----
include/linux/vfio_pci_core.h | 1 -
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 956a05ca12e5..8e42342d56d3 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -609,7 +609,6 @@ int vfio_pci_core_enable(struct vfio_pci_core_device *vdev)
if (ret == -EAGAIN)
goto out_disable_device;
- vdev->reset_works = !ret;
pci_save_state(pdev);
vdev->pci_saved_state = pci_store_saved_state(pdev);
if (!vdev->pci_saved_state)
@@ -766,7 +765,7 @@ void vfio_pci_core_disable(struct vfio_pci_core_device *vdev)
if (pci_load_and_free_saved_state(pdev, &vdev->pci_saved_state)) {
pci_info(pdev, "%s: Couldn't reload saved state\n", __func__);
- if (!vdev->reset_works)
+ if (!pci_reset_supported(pdev))
goto out;
pci_save_state(pdev);
@@ -785,7 +784,7 @@ void vfio_pci_core_disable(struct vfio_pci_core_device *vdev)
* We can not use the "try" reset interface here, which will
* overwrite the previously restored configuration information.
*/
- if (vdev->reset_works) {
+ if (pci_reset_supported(pdev)) {
bridge = pci_upstream_bridge(pdev);
if (bridge && !pci_dev_trylock(bridge))
goto out_restore_state;
@@ -1098,7 +1097,7 @@ static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
info.flags = VFIO_DEVICE_FLAGS_PCI;
- if (vdev->reset_works)
+ if (pci_reset_supported(vdev->pdev))
info.flags |= VFIO_DEVICE_FLAGS_RESET;
info.num_regions = VFIO_PCI_NUM_REGIONS + vdev->num_regions;
@@ -1330,7 +1329,7 @@ static int vfio_pci_ioctl_reset(struct vfio_pci_core_device *vdev,
{
int ret;
- if (!vdev->reset_works)
+ if (!pci_reset_supported(vdev->pdev))
return -EINVAL;
vfio_pci_zap_and_down_write_memory_lock(vdev);
diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
index 9a1674c152aa..6fb599ec2919 100644
--- a/include/linux/vfio_pci_core.h
+++ b/include/linux/vfio_pci_core.h
@@ -121,7 +121,6 @@ struct vfio_pci_core_device {
/* Flags only modified on setup/release - bitfield ok */
bool has_dyn_msix:1;
bool pci_2_3:1;
- bool reset_works:1;
bool extended_caps:1;
bool has_vga:1;
bool nointx:1;
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 4/5] PCI: Export pci_reset_supported()
2026-08-12 4:53 ` [RFC PATCH 4/5] PCI: Export pci_reset_supported() Alex Williamson
@ 2026-08-12 4:59 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-12 4:59 UTC (permalink / raw)
To: Alex Williamson; +Cc: linux-pci, kvm
> The success or failure of pci_reset_function() is conditional on the
> state of the device, ex. VFs enabled on an SR-IOV PF. Therefore a
> driver can no longer infer through executing pci_reset_function()
> whether a device has supported reset methods. The reset_methods
> array indicates whether the device has any available reset mechanisms
> and is not gated on dynamic blockers, like SR-IOV enablement.
>
> Export pci_reset_supported() for drivers to use for an instant
> snapshot of reset support.
>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260812045325.2733631-1-alex.williamson@nvidia.com?part=4
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 5/5] vfio/pci: Use pci_reset_supported() in place of reset_works
2026-08-12 4:53 ` [RFC PATCH 5/5] vfio/pci: Use pci_reset_supported() in place of reset_works Alex Williamson
@ 2026-08-12 4:59 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-12 4:59 UTC (permalink / raw)
To: Alex Williamson; +Cc: kvm, linux-pci
> vfio-pci latches whether pci_reset_function() works at open device and
> makes decisions based on this latched value at runtime. With the
> introduction of the reset_method pci-sysfs attribute, this flag can
> be made stale at runtime by administrative action. Further, with the
> SR-IOV active VFs gating of pci_reset_function(), the flag can be made
> stale via more subtle dependencies.
>
> Drop the latched flag and rely on pci_reset_supported() to indicate
> whether reset methods exist for the device. This is no guarantee that
> those reset methods work, nor has the RESET flag in struct
> vfio_device_info ever been a guarantee of VFIO_DEVICE_RESET success.
> It's only a guarantee that there are reset methods that are
> applicable to the device at the instant it's called.
>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260812045325.2733631-1-alex.williamson@nvidia.com?part=5
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 2/5] PCI: Add pci_reset_bus_cond() for a caller-gated slot or bus reset
2026-08-12 4:53 ` [RFC PATCH 2/5] PCI: Add pci_reset_bus_cond() for a caller-gated slot or bus reset Alex Williamson
@ 2026-08-12 5:00 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-12 5:00 UTC (permalink / raw)
To: Alex Williamson; +Cc: kvm, linux-pci
> pci_reset_bus() locks every device affected by a slot or bus reset,
> performs the reset, and unlocks the devices, all internally. A caller
> has no way to evaluate what the reset would actually touch.
>
> Add pci_reset_bus_cond(), which takes a callback invoked on each
> affected device once they are all locked. A nonzero return value from
> the callback aborts the reset and the value is returned to the caller.
> This allows, for instance, the caller to validate that SR-IOV is not
> enabled on any affected device under device_lock, where the value is
> known stable across the reset.
>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260812045325.2733631-1-alex.williamson@nvidia.com?part=2
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 1/5] PCI: Refuse function reset of an SR-IOV PF with enabled VFs
2026-08-12 4:53 ` [RFC PATCH 1/5] PCI: Refuse function reset of an SR-IOV PF with enabled VFs Alex Williamson
@ 2026-08-12 5:01 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-12 5:01 UTC (permalink / raw)
To: Alex Williamson; +Cc: linux-pci, kvm
> pci_reset_function() and its locked and try variants are intended to
> provide a function-scoped reset. The bus and slot methods supporting
> this interface refuse when sibling or subordinate devices are present.
> SR-IOV VFs however, are not currently considered in this scope.
>
> Correct this oversight by testing for non-zero VF count in calls
> through the pci_reset_function() interfaces. This test needs to occur
> under device_lock to avoid races with .sriov_configure. It should
> also occur before pci_dev_save_and_disable() to avoid calling
> potentially destructive reset hooks. Tests are therefore added
> to each of pci_reset_function(), pci_reset_function_locked(), and
> pci_try_reset_function().
>
> The __pci_reset_function_locked() interface remains a low-level
> primitive depending on the caller to perform such tests as necessary.
> The vfio_pci_core use case of __pci_reset_function_locked() is pulled
> through with this test. Other use cases, such as xen-pciback, that
> don't obviously support or prevent binding to SR-IOV enabled PFs will
> need to decide whether VFs are possible and can be preserved.
> Additionally, direct callers of sriov_enable() that do not hold
> device_lock (lpfc) are considered a preexisting, non-compliance issue.
>
> Fixes: dd7cc44d0bce ("PCI: add SR-IOV API for Physical Function driver")
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260812045325.2733631-1-alex.williamson@nvidia.com?part=1
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 3/5] vfio/pci: Refuse to reset an SR-IOV PF with enabled VFs
2026-08-12 4:53 ` [RFC PATCH 3/5] vfio/pci: Refuse to reset an SR-IOV PF with enabled VFs Alex Williamson
@ 2026-08-12 5:02 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-12 5:02 UTC (permalink / raw)
To: Alex Williamson; +Cc: kvm, linux-pci
> The vfio-pci hot-reset interface VFIO_DEVICE_PCI_HOT_RESET does not
> take into account whether an SR-IOV PF has active VFs. The VFs appear
> on a virtual bus, which is not enumerated in collecting affected
> devices.
>
> Move the burden to the user when active VFs are present, require that
> there are no VFs present on SR-IOV capable PFs in order to conduct a
> hot reset.
>
> Fixes: 137e5531351d ("vfio/pci: Add sriov_configure support")
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260812045325.2733631-1-alex.williamson@nvidia.com?part=3
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-08-12 5:02 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-12 4:53 [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs Alex Williamson
2026-08-12 4:53 ` [RFC PATCH 1/5] PCI: Refuse function reset of an SR-IOV PF with enabled VFs Alex Williamson
2026-08-12 5:01 ` sashiko-bot
2026-08-12 4:53 ` [RFC PATCH 2/5] PCI: Add pci_reset_bus_cond() for a caller-gated slot or bus reset Alex Williamson
2026-08-12 5:00 ` sashiko-bot
2026-08-12 4:53 ` [RFC PATCH 3/5] vfio/pci: Refuse to reset an SR-IOV PF with enabled VFs Alex Williamson
2026-08-12 5:02 ` sashiko-bot
2026-08-12 4:53 ` [RFC PATCH 4/5] PCI: Export pci_reset_supported() Alex Williamson
2026-08-12 4:59 ` sashiko-bot
2026-08-12 4:53 ` [RFC PATCH 5/5] vfio/pci: Use pci_reset_supported() in place of reset_works Alex Williamson
2026-08-12 4:59 ` sashiko-bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.