[RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs

Alex Williamson posted 5 patches 1 month, 2 weeks ago
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(-)
[RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs
Posted by Alex Williamson 1 month, 2 weeks ago
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
Re: [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs
Posted by Samiullah Khawaja 1 month, 2 weeks ago
On Tue, Aug 11, 2026 at 10:53:18PM -0600, Alex Williamson wrote:
>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.

Hi Alex,

Thanks for sending out the RFC to fix this issue. I cherry-picked it
into my environment to verify that whether it fixes the issue I was
experiencing and it does fix it. I will continue to do more testing, but
when you send this as a formal v1, you can add:

Tested-by: Samiullah Khawaja <skhawaja@google.com>
Reported-by: Samiullah Khawaja <skhawaja@google.com>

Sami
Re: [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs
Posted by Bjorn Helgaas 1 month, 2 weeks ago
[+cc Andrii, Mitch, Nick, Tony, Przemek]

On Tue, Aug 11, 2026 at 10:53:18PM -0600, Alex Williamson wrote:
> 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.

I suspect this might also be related to the somewhat weird usage of
pci_restore_msi_state() to restore VF MSI state in several network
drivers:

  https://git.kernel.org/linus/371e576ff3e8 ("i40e: Restore VF MSI-X state during PCI reset")
  https://git.kernel.org/linus/7e4dcc13965c ("iavf: restore MSI state on reset")
  https://git.kernel.org/linus/a54a0b24f4f5 ("ice: restore VF MSI-X state during PCI reset")

I think these are a little weird because they only run on a PF but
call pci_restore_msi_state() on all the VFs.

I guess these paths are recovery after FLR of the PF destroys the VFs,
and after the FLR, pci_restore_state() on the PF re-enables the VFs
but leaves them uninitialized.  It seems kind of ad hoc to restore VF
MSI state but not the rest of VF config space.  This all seems kind of
messy and makes me dubious about exporting pci_restore_msi_state()
directly to drivers.

> 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
>
Re: [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs
Posted by Tony Nguyen 1 month, 1 week ago

On 8/12/2026 2:45 PM, Bjorn Helgaas wrote:
> [+cc Andrii, Mitch, Nick, Tony, Przemek]
> 
> On Tue, Aug 11, 2026 at 10:53:18PM -0600, Alex Williamson wrote:
>> 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.
> 
> I suspect this might also be related to the somewhat weird usage of
> pci_restore_msi_state() to restore VF MSI state in several network
> drivers:
> 
>    https://git.kernel.org/linus/371e576ff3e8 ("i40e: Restore VF MSI-X state during PCI reset")
>    https://git.kernel.org/linus/7e4dcc13965c ("iavf: restore MSI state on reset")
>    https://git.kernel.org/linus/a54a0b24f4f5 ("ice: restore VF MSI-X state during PCI reset")
> 
> I think these are a little weird because they only run on a PF but
> call pci_restore_msi_state() on all the VFs.
> 
> I guess these paths are recovery after FLR of the PF destroys the VFs,
> and after the FLR, pci_restore_state() on the PF re-enables the VFs
> but leaves them uninitialized.  It seems kind of ad hoc to restore VF
> MSI state but not the rest of VF config space.  This all seems kind of
> messy and makes me dubious about exporting pci_restore_msi_state()
> directly to drivers.

Yea, this is situation we were trying to address; it seemed better for 
the user to try and recover functionality rather than leave the VFs 
non-operational. I like the idea of not allowing the call, when SR-IOV 
is enabled, to stop it from occurring in the first place though.

Thanks,
Tony

>> 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
>>
Re: [RFC PATCH 0/5] PCI/vfio-pci: Guard resets against active SR-IOV VFs
Posted by Alex Williamson 1 month, 2 weeks ago
On Wed, 12 Aug 2026 16:45:54 -0500
Bjorn Helgaas <helgaas@kernel.org> wrote:

> [+cc Andrii, Mitch, Nick, Tony, Przemek]
> 
> On Tue, Aug 11, 2026 at 10:53:18PM -0600, Alex Williamson wrote:
> > 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.  
> 
> I suspect this might also be related to the somewhat weird usage of
> pci_restore_msi_state() to restore VF MSI state in several network
> drivers:
> 
>   https://git.kernel.org/linus/371e576ff3e8 ("i40e: Restore VF MSI-X state during PCI reset")
>   https://git.kernel.org/linus/7e4dcc13965c ("iavf: restore MSI state on reset")
>   https://git.kernel.org/linus/a54a0b24f4f5 ("ice: restore VF MSI-X state during PCI reset")
> 
> I think these are a little weird because they only run on a PF but
> call pci_restore_msi_state() on all the VFs.
> 
> I guess these paths are recovery after FLR of the PF destroys the VFs,
> and after the FLR, pci_restore_state() on the PF re-enables the VFs
> but leaves them uninitialized.  It seems kind of ad hoc to restore VF
> MSI state but not the rest of VF config space.  This all seems kind of
> messy and makes me dubious about exporting pci_restore_msi_state()
> directly to drivers.

I don't understand how the i40e and ice NIC VFs can continue operation
with only MSI-X state restored.  It seems to directly contradict the
requirements of the PCIe spec (7.0):

9.2.2.3 FLR That Targets a PF §

  PFs must support FLR.

  FLR to a PF resets the PF state as well as the SR-IOV extended
  capability including VF Enable which means that VFs no longer exist.

9.2.3 IOV Re-initialization and Reallocation §

  If VF Enable is Cleared after having been Set, all of the VFs
  associated with the PF no longer exist and must no longer issue PCIe
  transactions or respond to Configuration Space or Memory Space
  accesses. VFs must not retain any architected state after VF Enable
  has been Cleared (including sticky bits). For security, unarchitected
  VF state configured through the VF must be cleared or randomized,
  with the exception of persistent storage data.

For the PF driver patches noted to be effective, the VFs must not be
scrubbed on re-initialization, nor can a .reset_done hook in the PF
driver do anything to avoid unsupported requests from ongoing DMA and
MMIO accesses while VF Enable is cleared.  So it looks like an
incomplete fix for non-compliant devices?  Thanks,

Alex