public inbox for rust-for-linux@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
@ 2026-03-03 21:15 Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 01/10] PCI: add driver flag to opt into disabling SR-IOV on remove() Peter Colberg
                   ` (10 more replies)
  0 siblings, 11 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

Add Rust abstractions for the Single Root I/O Virtualization (SR-IOV)
capability of a PCI device. Provide a minimal set of wrappers for the
SR-IOV C API to enable and disable SR-IOV for a device, and query if
a PCI device is a Physical Function (PF) or Virtual Function (VF).

Using the #[vtable] attribute, extend the pci::Driver trait with an
optional bus callback sriov_configure() that is invoked when a
user-space application writes the number of VFs to the sysfs file
`sriov_numvfs` to enable SR-IOV, or zero to disable SR-IOV [1].

Add a method physfn() to return the Physical Function (PF) device for a
Virtual Function (VF) device in the bound device context. Unlike for a
PCI driver written in C, guarantee that when a VF device is bound to a
driver, the underlying PF device is bound to a driver, too.

When a device with enabled VFs is unbound from a driver, invoke the
sriov_configure() callback to disable SR-IOV before the remove()
callback. To ensure the guarantee is upheld, call disable_sriov()
to remove all VF devices if the driver has not done so already.

For PF drivers written in C, disabling SR-IOV on remove() may be opted
into by setting the flag managed_sriov in the pci_driver structure. For
PF drivers written in Rust, disabling SR-IOV on unbind() is mandatory.

This series is based on Danilo Krummrich's series "Device::drvdata() and
driver/driver interaction (auxiliary)" applied to driver-core-next,
which similarly guarantees that when an auxiliary bus device is bound to
a driver, the underlying parent device is bound to a driver, too [2, 3].

Add an SR-IOV driver sample that exercises the SR-IOV capability using
QEMU's 82576 (igb) emulation and was used to test the abstractions [4].

[1] https://docs.kernel.org/PCI/pci-iov-howto.html
[2] https://lore.kernel.org/rust-for-linux/20251020223516.241050-1-dakr@kernel.org/
[3] https://lore.kernel.org/rust-for-linux/20260107103511.570525-7-dakr@kernel.org/
[4] https://www.qemu.org/docs/master/system/devices/igb.html

Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
Changes in v3:
- Replace SR_IOV -> SR-IOV in description.
- Drop redundant `.as_ref()` for `dev_*` prints.
- Link to v2: https://lore.kernel.org/r/20260205-rust-pci-sriov-v2-0-ef9400c7767b@redhat.com

Changes in v2:
- Move logic to disable SR-IOV on remove() from Rust to C.
- Add driver flag managed_sriov to opt into disabling SR-IOV on remove().
- Demonstrate flag managed_sriov for dfl-pci driver.
- Uphold safety guarantee for physfn() when PF driver is written in C.
- Let physfn() return error if driver flag managed_sriov is unset.
- Use "kernel vertical" style on imports.
- Use to_result() to handle error in enable_sriov().
- Note Bound device context in SAFETY comments for {enable,disable}_sriov().
- Demonstrate how to reach driver data of PF device from VF device.
- Add missing #[vtable] attribute in PCI driver trait example.
- Add missing #[vtable] attribute in nova-core driver.
- Define struct MyDriver such that physfn() example compiles.
- Replace VF -> PF in doc comment of is_physfn().
- Add #[inline] to is_physfn() and is_virtfn().
- Link to v1: https://lore.kernel.org/r/20251119-rust-pci-sriov-v1-0-883a94599a97@redhat.com

---
John Hubbard (1):
      rust: pci: add is_virtfn(), to check for VFs

Peter Colberg (9):
      PCI: add driver flag to opt into disabling SR-IOV on remove()
      fpga: dfl-pci: set driver flag to disable SR-IOV on remove()
      rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability
      rust: pci: add vtable attribute to pci::Driver trait
      rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs
      rust: pci: add is_physfn(), to check for PFs
      rust: pci: add num_vf(), to return number of VFs
      rust: pci: add physfn(), to return PF device for VF device
      samples: rust: add SR-IOV driver sample

 MAINTAINERS                           |   1 +
 drivers/fpga/dfl-pci.c                |  17 ++--
 drivers/gpu/nova-core/driver.rs       |   1 +
 drivers/pci/iov.c                     |  41 ++++++++-
 drivers/pci/pci-driver.c              |   3 +-
 drivers/pci/pci.h                     |   2 +
 include/linux/pci.h                   |   8 ++
 rust/kernel/pci.rs                    | 165 ++++++++++++++++++++++++++++++++++
 samples/rust/Kconfig                  |  11 +++
 samples/rust/Makefile                 |   1 +
 samples/rust/rust_dma.rs              |   1 +
 samples/rust/rust_driver_auxiliary.rs |   1 +
 samples/rust/rust_driver_pci.rs       |   1 +
 samples/rust/rust_driver_sriov.rs     | 127 ++++++++++++++++++++++++++
 14 files changed, 366 insertions(+), 14 deletions(-)
---
base-commit: 1b9a5bc8513d081c1bfe2c096b6dc502a4660f47
change-id: 20251026-rust-pci-sriov-ca8f501b2ae3

Best regards,
-- 
Peter Colberg <pcolberg@redhat.com>


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v3 01/10] PCI: add driver flag to opt into disabling SR-IOV on remove()
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
@ 2026-03-03 21:15 ` Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 02/10] fpga: dfl-pci: set driver flag to disable " Peter Colberg
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

Add a flag managed_sriov to the pci_driver structure that allows a
driver to opt into disabling the Single Root I/O Virtualization (SR-IOV)
capability of the device when the driver is unbound.

Add a new function pci_iov_disable() that is invoked before the remove()
callback of a PCI driver and checks for the presence of the new flag.
If the flag is set, invoke the sriov_configure() callback to allow the
driver to gracefully disable SR-IOV. Warn if the driver fails to do so
and forcibly disable SR-IOV using sriov_disable().

Since a (broken) driver may theoretically re-enable SR-IOV during its
remove() callback, extend pci_iov_remove() to forcibly disable SR-IOV
after remove() if needed and only if the flag managed_sriov is set.

Altogether the flag ensures that when a Virtual Function (VF) is bound
to a driver, the corresponding Physical Function (PF) is bound to a
driver, too, since the VF devices are destroyed when the PF driver is
unbound. This guarantee is a prerequisite for exposing a safe Rust
API that allows a VF driver to obtain the PF device for a VF device
and subsequently access the device private data of the PF device.

Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
Changes in v2:
- Move logic to disable SR-IOV on remove() from Rust to C.
- Add driver flag managed_sriov to opt into disabling SR-IOV on remove().
---
 drivers/pci/iov.c        | 41 ++++++++++++++++++++++++++++++++++++++++-
 drivers/pci/pci-driver.c |  3 ++-
 drivers/pci/pci.h        |  2 ++
 include/linux/pci.h      |  8 ++++++++
 4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 91ac4e37ecb9c0c5265aa40c235e84b430f43a96..da64d6ce5d30de8a52089b36fcb013937cf8b6fe 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -1010,20 +1010,59 @@ void pci_iov_release(struct pci_dev *dev)
 		sriov_release(dev);
 }
 
+/**
+ * pci_iov_disable - disable SR-IOV before PF driver is detached
+ * @dev: the PCI device
+ *
+ * Invoke sriov_configure() callback to allow the driver to gracefully disable
+ * SR-IOV. Warn if the driver fails to do so and forcibly disable SR-IOV.
+ */
+void pci_iov_disable(struct pci_dev *dev)
+{
+	struct pci_driver *drv = dev->driver;
+	struct pci_sriov *iov = dev->sriov;
+
+	if (WARN_ON(!drv))
+		return;
+
+	if (!dev->is_physfn || !iov->num_VFs || !drv->managed_sriov)
+		return;
+
+	if (!drv->sriov_configure) {
+		sriov_disable(dev);
+		return;
+	}
+
+	drv->sriov_configure(dev, 0);
+
+	if (WARN_ON(iov->num_VFs))
+		sriov_disable(dev);
+}
+
 /**
  * pci_iov_remove - clean up SR-IOV state after PF driver is detached
  * @dev: the PCI device
  */
 void pci_iov_remove(struct pci_dev *dev)
 {
+	struct pci_driver *drv = dev->driver;
 	struct pci_sriov *iov = dev->sriov;
 
+	if (WARN_ON(!drv))
+		return;
+
 	if (!dev->is_physfn)
 		return;
 
 	iov->driver_max_VFs = iov->total_VFs;
-	if (iov->num_VFs)
+
+	if (iov->num_VFs && !drv->managed_sriov) {
 		pci_warn(dev, "driver left SR-IOV enabled after remove\n");
+		return;
+	}
+
+	if (WARN_ON(iov->num_VFs))
+		sriov_disable(dev);
 }
 
 /**
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index dd9075403987d84e068014b35745e8872e93fdae..3fe43711565a3eb61a06cc3700e5ca953961fbe9 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -491,6 +491,7 @@ static void pci_device_remove(struct device *dev)
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 	struct pci_driver *drv = pci_dev->driver;
 
+	pci_iov_disable(pci_dev);
 	if (drv->remove) {
 		pm_runtime_get_sync(dev);
 		/*
@@ -504,8 +505,8 @@ static void pci_device_remove(struct device *dev)
 		pm_runtime_put_noidle(dev);
 	}
 	pcibios_free_irq(pci_dev);
-	pci_dev->driver = NULL;
 	pci_iov_remove(pci_dev);
+	pci_dev->driver = NULL;
 
 	/* Undo the runtime PM settings in local_pci_probe() */
 	pm_runtime_put_sync(dev);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 13d998fbacce6698514d92500dfea03cc562cdc2..66308f5126ff9e4bebb537a541f1dd8717bccbfa 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -943,6 +943,7 @@ static inline void pci_restore_pasid_state(struct pci_dev *pdev) { }
 #ifdef CONFIG_PCI_IOV
 int pci_iov_init(struct pci_dev *dev);
 void pci_iov_release(struct pci_dev *dev);
+void pci_iov_disable(struct pci_dev *dev);
 void pci_iov_remove(struct pci_dev *dev);
 void pci_iov_update_resource(struct pci_dev *dev, int resno);
 resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
@@ -977,6 +978,7 @@ static inline int pci_iov_init(struct pci_dev *dev)
 	return -ENODEV;
 }
 static inline void pci_iov_release(struct pci_dev *dev) { }
+static inline void pci_iov_disable(struct pci_dev *dev) { }
 static inline void pci_iov_remove(struct pci_dev *dev) { }
 static inline void pci_iov_update_resource(struct pci_dev *dev, int resno) { }
 static inline resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev,
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1c270f1d512301de4d462fe7e5097c32af5c6f8d..859f767b30f726bd157a6080f5977c17c4827a1d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1015,6 +1015,13 @@ struct module;
  *		how to manage the DMA themselves and set this flag so that
  *		the IOMMU layer will allow them to setup and manage their
  *		own I/O address space.
+ * @managed_sriov: Disable SR-IOV on remove().
+ *		If set, the Single Root I/O Virtualization (SR-IOV)
+ *		capability of the device is disabled when the driver is
+ *		unbound from the device, by calling sriov_configure()
+ *		before remove(). The presence of this flag guarantees
+ *		that when a Virtual Function (VF) is bound to a driver,
+ *		the Physical Function (PF) is bound to a driver, too.
  */
 struct pci_driver {
 	const char		*name;
@@ -1033,6 +1040,7 @@ struct pci_driver {
 	struct device_driver	driver;
 	struct pci_dynids	dynids;
 	bool driver_managed_dma;
+	bool managed_sriov;
 };
 
 #define to_pci_driver(__drv)	\

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 02/10] fpga: dfl-pci: set driver flag to disable SR-IOV on remove()
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 01/10] PCI: add driver flag to opt into disabling SR-IOV on remove() Peter Colberg
@ 2026-03-03 21:15 ` Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 03/10] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability Peter Colberg
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

Set the flag managed_sriov in the pci_driver structure to show how a
PCI driver may opt into disabling the Single Root I/O Virtualization
(SR-IOV) capability of the device when the driver is removed.

Merge the function cci_remove_feature_devs() into cci_pci_remove().

Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
Changes in v2:
- Demonstrate flag managed_sriov for dfl-pci driver.
---
 drivers/fpga/dfl-pci.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c
index e25205c6d8f00cec579016acade28e743812c924..2410e6f3efe100a635eebfdb21f28f62a3759890 100644
--- a/drivers/fpga/dfl-pci.c
+++ b/drivers/fpga/dfl-pci.c
@@ -125,15 +125,6 @@ static int cci_init_drvdata(struct pci_dev *pcidev)
 	return 0;
 }
 
-static void cci_remove_feature_devs(struct pci_dev *pcidev)
-{
-	struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
-
-	/* remove all children feature devices */
-	dfl_fpga_feature_devs_remove(drvdata->cdev);
-	cci_pci_free_irq(pcidev);
-}
-
 static int *cci_pci_create_irq_table(struct pci_dev *pcidev, unsigned int nvec)
 {
 	unsigned int i;
@@ -425,10 +416,11 @@ static int cci_pci_sriov_configure(struct pci_dev *pcidev, int num_vfs)
 
 static void cci_pci_remove(struct pci_dev *pcidev)
 {
-	if (dev_is_pf(&pcidev->dev))
-		cci_pci_sriov_configure(pcidev, 0);
+	struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
 
-	cci_remove_feature_devs(pcidev);
+	/* remove all children feature devices */
+	dfl_fpga_feature_devs_remove(drvdata->cdev);
+	cci_pci_free_irq(pcidev);
 }
 
 static struct pci_driver cci_pci_driver = {
@@ -437,6 +429,7 @@ static struct pci_driver cci_pci_driver = {
 	.probe = cci_pci_probe,
 	.remove = cci_pci_remove,
 	.sriov_configure = cci_pci_sriov_configure,
+	.managed_sriov = true,
 };
 
 module_pci_driver(cci_pci_driver);

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 03/10] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 01/10] PCI: add driver flag to opt into disabling SR-IOV on remove() Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 02/10] fpga: dfl-pci: set driver flag to disable " Peter Colberg
@ 2026-03-03 21:15 ` Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 04/10] rust: pci: add vtable attribute to pci::Driver trait Peter Colberg
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

Add methods to enable and disable the Single Root I/O Virtualization
(SR-IOV) capability for a PCI device. The wrapped C methods take care
of validating whether the device is a Physical Function (PF), whether
SR-IOV is currently disabled (or enabled), and whether the number of
requested VFs does not exceed the total number of supported VFs.

Set the flag managed_sriov to always disable SR-IOV when a Rust PCI
driver is unbound from a PF device. This ensures that when a Virtual
Function (VF) is bound to a driver, the corresponding Physical Function
(PF) is bound to a driver, too, which is a prerequisite for exposing a
safe Rust API that allows a VF driver to obtain the PF device for a VF
device and subsequently access the private data of the PF driver.

Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
Changes in v2:
- Set flag managed_sriov to disable SR-IOV on remove().
- Use to_result() to handle error in enable_sriov().
- Note Bound device context in SAFETY comments.
---
 rust/kernel/pci.rs | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index af74ddff6114db3c2ce8e228c5a953cd0769e8a5..e1cab1574a3d309d25bf5267c0b0d8da8fb66d44 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -82,6 +82,7 @@ unsafe fn register(
             (*pdrv.get()).probe = Some(Self::probe_callback);
             (*pdrv.get()).remove = Some(Self::remove_callback);
             (*pdrv.get()).id_table = T::ID_TABLE.as_ptr();
+            (*pdrv.get()).managed_sriov = true;
         }
 
         // SAFETY: `pdrv` is guaranteed to be a valid `DriverType`.
@@ -458,6 +459,38 @@ pub fn set_master(&self) {
         // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`.
         unsafe { bindings::pci_set_master(self.as_raw()) };
     }
+
+    /// Enable the Single Root I/O Virtualization (SR-IOV) capability for this device,
+    /// where `nr_virtfn` is number of Virtual Functions (VF) to enable.
+    #[cfg(CONFIG_PCI_IOV)]
+    pub fn enable_sriov(&self, nr_virtfn: i32) -> Result {
+        // SAFETY:
+        // `self.as_raw` returns a valid pointer to a `struct pci_dev`.
+        //
+        // `pci_enable_sriov()` checks that the enable operation is valid:
+        // - the device is a Physical Function (PF),
+        // - SR-IOV is currently disabled, and
+        // - `nr_virtfn` does not exceed the total number of supported VFs.
+        //
+        // The Core device context inherits from the Bound device context,
+        // which guarantees that the PF device is bound to a driver.
+        to_result(unsafe { bindings::pci_enable_sriov(self.as_raw(), nr_virtfn) })
+    }
+
+    /// Disable the Single Root I/O Virtualization (SR-IOV) capability for this device.
+    #[cfg(CONFIG_PCI_IOV)]
+    pub fn disable_sriov(&self) {
+        // SAFETY:
+        // `self.as_raw` returns a valid pointer to a `struct pci_dev`.
+        //
+        // `pci_disable_sriov()` checks that the disable operation is valid:
+        // - the device is a Physical Function (PF), and
+        // - SR-IOV is currently enabled.
+        //
+        // The Core device context inherits from the Bound device context,
+        // which guarantees that the PF device is bound to a driver.
+        unsafe { bindings::pci_disable_sriov(self.as_raw()) };
+    }
 }
 
 // SAFETY: `pci::Device` is a transparent wrapper of `struct pci_dev`.

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 04/10] rust: pci: add vtable attribute to pci::Driver trait
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (2 preceding siblings ...)
  2026-03-03 21:15 ` [PATCH v3 03/10] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability Peter Colberg
@ 2026-03-03 21:15 ` Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 05/10] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs Peter Colberg
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

Add the #[vtable] attribute to pci::Driver trait and implementations,
to prepare a subsequent patch that adds an optional bus callback
sriov_configure() to enable or disable the SR-IOV capability.

Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
Changes in v2:
- Add missing #[vtable] attribute in PCI driver trait example.
- Add missing #[vtable] attribute in nova-core driver.
---
 drivers/gpu/nova-core/driver.rs       | 1 +
 rust/kernel/pci.rs                    | 2 ++
 samples/rust/rust_dma.rs              | 1 +
 samples/rust/rust_driver_auxiliary.rs | 1 +
 samples/rust/rust_driver_pci.rs       | 1 +
 5 files changed, 6 insertions(+)

diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs
index 5a4cc047bcfc9fcef61373ace84ed43958a3bcbd..66a68048006fb33477bb00f61856c1aa92c0a8f1 100644
--- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -64,6 +64,7 @@ pub(crate) struct NovaCore {
     ]
 );
 
+#[vtable]
 impl pci::Driver for NovaCore {
     type IdInfo = ();
     const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index e1cab1574a3d309d25bf5267c0b0d8da8fb66d44..a4c27c674bd8bdf5e3316789d38d566e90b93fe2 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -278,6 +278,7 @@ macro_rules! pci_device_table {
 ///     ]
 /// );
 ///
+/// #[vtable]
 /// impl pci::Driver for MyDriver {
 ///     type IdInfo = ();
 ///     const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
@@ -292,6 +293,7 @@ macro_rules! pci_device_table {
 ///```
 /// Drivers must implement this trait in order to get a PCI driver registered. Please refer to the
 /// `Adapter` documentation for an example.
+#[vtable]
 pub trait Driver: Send {
     /// The type holding information about each device id supported by the driver.
     // TODO: Use `associated_type_defaults` once stabilized:
diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs
index 9c45851c876ef33414eb0071c42a2fb4ac3f1e78..ae6f7328b830e32bcaf7f8b5f8b1f117135ebf8e 100644
--- a/samples/rust/rust_dma.rs
+++ b/samples/rust/rust_dma.rs
@@ -51,6 +51,7 @@ unsafe impl kernel::transmute::FromBytes for MyStruct {}
     [(pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), ())]
 );
 
+#[vtable]
 impl pci::Driver for DmaSampleDriver {
     type IdInfo = ();
     const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs
index 5c5a5105a3fff90f5e396186776e1b3ffdf479b4..2f7ac8f7391f45827c086b704950fd01907c1825 100644
--- a/samples/rust/rust_driver_auxiliary.rs
+++ b/samples/rust/rust_driver_auxiliary.rs
@@ -65,6 +65,7 @@ struct ParentDriver {
     [(pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), ())]
 );
 
+#[vtable]
 impl pci::Driver for ParentDriver {
     type IdInfo = ();
 
diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs
index d3d4a7931deb0c1085cfd817990737717f466ea9..27e603a9509c19b6845c10ef06a0af897aa0e84b 100644
--- a/samples/rust/rust_driver_pci.rs
+++ b/samples/rust/rust_driver_pci.rs
@@ -92,6 +92,7 @@ fn config_space(pdev: &pci::Device<Bound>) {
     }
 }
 
+#[vtable]
 impl pci::Driver for SampleDriver {
     type IdInfo = TestIndex;
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 05/10] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (3 preceding siblings ...)
  2026-03-03 21:15 ` [PATCH v3 04/10] rust: pci: add vtable attribute to pci::Driver trait Peter Colberg
@ 2026-03-03 21:15 ` Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 06/10] rust: pci: add is_virtfn(), to check for VFs Peter Colberg
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

Add an optional bus callback sriov_configure() to pci::Driver trait,
using the vtable attribute to query if the driver implements the
callback. The callback is invoked when a user-space application
writes the number of VFs to the sysfs file `sriov_numvfs` to
enable SR-IOV, or zero to disable SR-IOV for a PCI device.

Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
 rust/kernel/pci.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index a4c27c674bd8bdf5e3316789d38d566e90b93fe2..88bd114970431bf8c3edef94c1d48567d895eaf6 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -83,6 +83,10 @@ unsafe fn register(
             (*pdrv.get()).remove = Some(Self::remove_callback);
             (*pdrv.get()).id_table = T::ID_TABLE.as_ptr();
             (*pdrv.get()).managed_sriov = true;
+            #[cfg(CONFIG_PCI_IOV)]
+            if T::HAS_SRIOV_CONFIGURE {
+                (*pdrv.get()).sriov_configure = Some(Self::sriov_configure_callback);
+            }
         }
 
         // SAFETY: `pdrv` is guaranteed to be a valid `DriverType`.
@@ -135,6 +139,20 @@ extern "C" fn remove_callback(pdev: *mut bindings::pci_dev) {
 
         T::unbind(pdev, data);
     }
+
+    #[cfg(CONFIG_PCI_IOV)]
+    extern "C" fn sriov_configure_callback(
+        pdev: *mut bindings::pci_dev,
+        nr_virtfn: c_int,
+    ) -> c_int {
+        // SAFETY: The PCI bus only ever calls the sriov_configure callback with a valid pointer to
+        // a `struct pci_dev`.
+        //
+        // INVARIANT: `pdev` is valid for the duration of `sriov_configure_callback()`.
+        let pdev = unsafe { &*pdev.cast::<Device<device::CoreInternal>>() };
+
+        from_result(|| T::sriov_configure(pdev, nr_virtfn))
+    }
 }
 
 /// Declares a kernel module that exposes a single PCI driver.
@@ -325,6 +343,44 @@ pub trait Driver: Send {
     fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {
         let _ = (dev, this);
     }
+
+    /// Single Root I/O Virtualization (SR-IOV) configure.
+    ///
+    /// Called when a user-space application enables or disables the SR-IOV capability for a
+    /// [`Device`] by writing the number of Virtual Functions (VF), `nr_virtfn` or zero to the
+    /// sysfs file `sriov_numvfs` for this device. Implementing this callback is optional.
+    ///
+    /// Further, and unlike for a PCI driver written in C, when a PF device with enabled VFs is
+    /// unbound from its bound [`Driver`], the `sriov_configure()` callback is invoked to disable
+    /// SR-IOV before the `unbind()` callback. This guarantees that when a VF device is bound to a
+    /// driver, the underlying PF device is bound to a driver, too.
+    ///
+    /// Upon success, this callback must return the number of VFs that were enabled, or zero if
+    /// SR-IOV was disabled.
+    ///
+    /// See [PCI Express I/O Virtualization].
+    ///
+    /// [PCI Express I/O Virtualization]: https://docs.kernel.org/PCI/pci-iov-howto.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use kernel::{device::Core, pci, prelude::*};
+    /// #[cfg(CONFIG_PCI_IOV)]
+    /// fn sriov_configure(dev: &pci::Device<Core>, nr_virtfn: i32) -> Result<i32> {
+    ///     if nr_virtfn == 0 {
+    ///         dev.disable_sriov();
+    ///     } else {
+    ///         dev.enable_sriov(nr_virtfn)?;
+    ///     }
+    ///     Ok(nr_virtfn)
+    /// }
+    /// ```
+    #[cfg(CONFIG_PCI_IOV)]
+    fn sriov_configure(dev: &Device<device::Core>, nr_virtfn: i32) -> Result<i32> {
+        let _ = (dev, nr_virtfn);
+        build_error!(crate::error::VTABLE_DEFAULT_ERROR)
+    }
 }
 
 /// The PCI device representation.

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 06/10] rust: pci: add is_virtfn(), to check for VFs
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (4 preceding siblings ...)
  2026-03-03 21:15 ` [PATCH v3 05/10] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs Peter Colberg
@ 2026-03-03 21:15 ` Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 07/10] rust: pci: add is_physfn(), to check for PFs Peter Colberg
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

From: John Hubbard <jhubbard@nvidia.com>

Add a method to check if a PCI device is a Virtual Function (VF) created
through Single Root I/O Virtualization (SR-IOV).

Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Reviewed-by: Alistair Popple <apopple@nvidia.com>
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
Changes in v2:
- Add #[inline] to is_virtfn().

This patch was originally part of the series "rust: pci: expose
is_virtfn() and reject VFs in nova-core" and modified as follows:
- Replace true -> `true` in doc comment.
- Shorten description and omit justification specific to nova-core.

Link: https://lore.kernel.org/rust-for-linux/20250930220759.288528-2-jhubbard@nvidia.com/
---
 rust/kernel/pci.rs | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 88bd114970431bf8c3edef94c1d48567d895eaf6..db05641186c3a42922e2b6a463de9c1b099a4673 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -484,6 +484,13 @@ pub fn resource_start(&self, bar: u32) -> Result<bindings::resource_size_t> {
         Ok(unsafe { bindings::pci_resource_start(self.as_raw(), bar.try_into()?) })
     }
 
+    /// Returns `true` if this device is a Virtual Function (VF).
+    #[inline]
+    pub fn is_virtfn(&self) -> bool {
+        // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`.
+        unsafe { (*self.as_raw()).is_virtfn() != 0 }
+    }
+
     /// Returns the size of the given PCI BAR resource.
     pub fn resource_len(&self, bar: u32) -> Result<bindings::resource_size_t> {
         if !Bar::index_is_valid(bar) {

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 07/10] rust: pci: add is_physfn(), to check for PFs
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (5 preceding siblings ...)
  2026-03-03 21:15 ` [PATCH v3 06/10] rust: pci: add is_virtfn(), to check for VFs Peter Colberg
@ 2026-03-03 21:15 ` Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 08/10] rust: pci: add num_vf(), to return number of VFs Peter Colberg
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

Add a method to check if a PCI device is a Physical Function (PF).

Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
Changes in v2:
- Replace VF -> PF in doc comment of is_physfn().
- Add #[inline] to is_physfn().
---
 rust/kernel/pci.rs | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index db05641186c3a42922e2b6a463de9c1b099a4673..df39ad3f0d5fd898b034609efb03368f83c2a2e9 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -484,6 +484,13 @@ pub fn resource_start(&self, bar: u32) -> Result<bindings::resource_size_t> {
         Ok(unsafe { bindings::pci_resource_start(self.as_raw(), bar.try_into()?) })
     }
 
+    /// Returns `true` if this device is a Physical Function (PF).
+    #[inline]
+    pub fn is_physfn(&self) -> bool {
+        // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`.
+        unsafe { (*self.as_raw()).is_physfn() != 0 }
+    }
+
     /// Returns `true` if this device is a Virtual Function (VF).
     #[inline]
     pub fn is_virtfn(&self) -> bool {

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 08/10] rust: pci: add num_vf(), to return number of VFs
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (6 preceding siblings ...)
  2026-03-03 21:15 ` [PATCH v3 07/10] rust: pci: add is_physfn(), to check for PFs Peter Colberg
@ 2026-03-03 21:15 ` Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 09/10] rust: pci: add physfn(), to return PF device for VF device Peter Colberg
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

Add a method to return the number of Virtual Functions (VF) enabled for
a Physical Function (PF).

Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
 rust/kernel/pci.rs | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index df39ad3f0d5fd898b034609efb03368f83c2a2e9..581930d0afe98ccc29d729e4d9aab75b4144e46c 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -498,6 +498,13 @@ pub fn is_virtfn(&self) -> bool {
         unsafe { (*self.as_raw()).is_virtfn() != 0 }
     }
 
+    /// Returns the number of Virtual Functions (VF) enabled for a Physical Function (PF).
+    #[cfg(CONFIG_PCI_IOV)]
+    pub fn num_vf(&self) -> i32 {
+        // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`.
+        unsafe { bindings::pci_num_vf(self.as_raw()) }
+    }
+
     /// Returns the size of the given PCI BAR resource.
     pub fn resource_len(&self, bar: u32) -> Result<bindings::resource_size_t> {
         if !Bar::index_is_valid(bar) {

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 09/10] rust: pci: add physfn(), to return PF device for VF device
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (7 preceding siblings ...)
  2026-03-03 21:15 ` [PATCH v3 08/10] rust: pci: add num_vf(), to return number of VFs Peter Colberg
@ 2026-03-03 21:15 ` Peter Colberg
  2026-03-03 21:15 ` [PATCH v3 10/10] samples: rust: add SR-IOV driver sample Peter Colberg
  2026-03-04  8:47 ` [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Leon Romanovsky
  10 siblings, 0 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

Add a method to return the Physical Function (PF) device for a Virtual
Function (VF) device in the bound device context.

Unlike for a PCI driver written in C, guarantee that when a VF device is
bound to a driver, the underlying PF device is bound to a driver, too,
by always setting the flag managed_sriov in the pci_driver structure.

In case SR-IOV has been enabled by a C driver that has not set the flag
managed_sriov in pci_driver, return an error from physfn().

This change depends on commit a995fe1a3aa7 ("rust: driver: drop device
private data post unbind") to also uphold the safety guarantee in case
a (broken) PF driver re-enables SR-IOV in its unbind() callback. That
commit extends the lifetime of the device private data beyond the
remove_callback() wrapper. In particular, that commit ensures that the
device private data for the PF device is still alive until after the
function pci_iov_remove() is called and forcibly re-disables SR-IOV,
which means the data can be safely accessed by VF drivers until then.

Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
Changes in v3:
- Replace SR_IOV -> SR-IOV in description.

Changes in v2:
- Uphold safety guarantee when PF driver is written in C.
- Let physfn() return error if driver flag managed_sriov is unset.
---
 rust/kernel/pci.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 581930d0afe98ccc29d729e4d9aab75b4144e46c..3b11f73a9f2b69a02fe003b8feadd61864adc8c0 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -525,6 +525,59 @@ pub fn pci_class(&self) -> Class {
     }
 }
 
+impl Device<device::Bound> {
+    /// Returns the Physical Function (PF) device for a Virtual Function (VF) device.
+    ///
+    /// # Examples
+    ///
+    /// The following example illustrates how to obtain the private driver data of the PF device,
+    /// where `vf_pdev` is the VF device of reference type `&Device<Core>` or `&Device<Bound>`.
+    ///
+    /// ```
+    /// # use kernel::{device::Core, pci};
+    /// /// A PCI driver that binds to both the PF and its VF devices.
+    /// struct MyDriver;
+    ///
+    /// impl MyDriver {
+    ///     fn connect(vf_pdev: &pci::Device<Core>) -> Result {
+    ///         let pf_pdev = vf_pdev.physfn()?;
+    ///         let pf_drvdata = pf_pdev.as_ref().drvdata::<Self>()?;
+    ///         Ok(())
+    ///     }
+    /// }
+    /// ```
+    #[cfg(CONFIG_PCI_IOV)]
+    pub fn physfn(&self) -> Result<&Device<device::Bound>> {
+        if !self.is_virtfn() {
+            return Err(EINVAL);
+        }
+
+        // SAFETY: `self.as_raw()` returns a valid pointer to a `struct pci_dev`.
+        // `physfn` is a valid pointer to a `struct pci_dev` since `is_virtfn()` is `true`.
+        let pf_dev = unsafe { (*self.as_raw()).__bindgen_anon_1.physfn };
+
+        // SAFETY: `pf_dev` is a valid pointer to a `struct pci_dev`.
+        // `driver` is either NULL or a valid pointer to a `struct pci_driver`.
+        let pf_drv = unsafe { (*pf_dev).driver };
+        if pf_drv.is_null() {
+            return Err(EINVAL);
+        }
+
+        // SAFETY: `pf_drv` is a valid pointer to a `struct pci_driver`.
+        if !unsafe { (*pf_drv).managed_sriov } {
+            return Err(EINVAL);
+        }
+
+        // SAFETY: `physfn` may be cast to a `Device<device::Bound>` since the
+        // driver flag `managed_sriov` forces SR-IOV to be disabled when the
+        // PF driver is unbound, i.e., all VF devices are destroyed. This
+        // guarantees that the underlying PF device is bound to a driver
+        // when the VF device is bound to a driver, which is the case since
+        // `Device::physfn()` requires a `&Device<Bound>` reference.
+        Ok(unsafe { &*pf_dev.cast() })
+    }
+}
+
 impl Device<device::Core> {
     /// Enable memory resources for this device.
     pub fn enable_device_mem(&self) -> Result {

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 10/10] samples: rust: add SR-IOV driver sample
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (8 preceding siblings ...)
  2026-03-03 21:15 ` [PATCH v3 09/10] rust: pci: add physfn(), to return PF device for VF device Peter Colberg
@ 2026-03-03 21:15 ` Peter Colberg
  2026-03-04  8:47 ` [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Leon Romanovsky
  10 siblings, 0 replies; 21+ messages in thread
From: Peter Colberg @ 2026-03-03 21:15 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, Leon Romanovsky, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng
  Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang, nouveau,
	dri-devel, linux-doc, linux-fpga, driver-core, Peter Colberg,
	Jason Gunthorpe

Add a new SR-IOV driver sample that demonstrates how to enable and
disable the Single Root I/O Virtualization capability for a PCI device.

The sample may be exercised using QEMU's 82576 (igb) emulation.

Link: https://www.qemu.org/docs/master/system/devices/igb.html
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
Changes in v3:
- Drop redundant `.as_ref()` for `dev_*` prints.

Changes in v2:
- Use "kernel vertical" style on imports.
- Demonstrate how to reach driver data of PF device from VF device.
---
 MAINTAINERS                       |   1 +
 samples/rust/Kconfig              |  11 ++++
 samples/rust/Makefile             |   1 +
 samples/rust/rust_driver_sriov.rs | 127 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 140 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 61bf550fd37c274843e516e00068bb2ab1e152ac..8551a9474fc26309d0714aafa104a5e1ed29156b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20454,6 +20454,7 @@ F:	rust/helpers/pci.c
 F:	rust/kernel/pci.rs
 F:	rust/kernel/pci/
 F:	samples/rust/rust_driver_pci.rs
+F:	samples/rust/rust_driver_sriov.rs
 
 PCIE BANDWIDTH CONTROLLER
 M:	Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig
index c49ab910634596aea4a1a73dac87585e084f420a..f244df89c4fc9d741915f581de76107e8eb0121b 100644
--- a/samples/rust/Kconfig
+++ b/samples/rust/Kconfig
@@ -128,6 +128,17 @@ config SAMPLE_RUST_DRIVER_PLATFORM
 
 	  If unsure, say N.
 
+config SAMPLE_RUST_DRIVER_SRIOV
+	tristate "SR-IOV Driver"
+	depends on PCI_IOV
+	help
+	  This option builds the Rust SR-IOV driver sample.
+
+	  To compile this as a module, choose M here:
+	  the module will be called rust_driver_sriov.
+
+	  If unsure, say N.
+
 config SAMPLE_RUST_DRIVER_USB
 	tristate "USB Driver"
 	depends on USB = y
diff --git a/samples/rust/Makefile b/samples/rust/Makefile
index 6c0aaa58ccccfd12ef019f68ca784f6d977bc668..19d700f8210151e298cc049dacc249a121d0f2c4 100644
--- a/samples/rust/Makefile
+++ b/samples/rust/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SAMPLE_RUST_DRIVER_I2C)		+= rust_driver_i2c.o
 obj-$(CONFIG_SAMPLE_RUST_I2C_CLIENT)		+= rust_i2c_client.o
 obj-$(CONFIG_SAMPLE_RUST_DRIVER_PCI)		+= rust_driver_pci.o
 obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM)	+= rust_driver_platform.o
+obj-$(CONFIG_SAMPLE_RUST_DRIVER_SRIOV)		+= rust_driver_sriov.o
 obj-$(CONFIG_SAMPLE_RUST_DRIVER_USB)		+= rust_driver_usb.o
 obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX)		+= rust_driver_faux.o
 obj-$(CONFIG_SAMPLE_RUST_DRIVER_AUXILIARY)	+= rust_driver_auxiliary.o
diff --git a/samples/rust/rust_driver_sriov.rs b/samples/rust/rust_driver_sriov.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a4f7b99d9490f8fed2ab1fedb238c53304af89ee
--- /dev/null
+++ b/samples/rust/rust_driver_sriov.rs
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust SR-IOV driver sample based on QEMU's 82576 ([igb]) emulation.
+//!
+//! To make this driver probe, QEMU must be run with `-device igb`.
+//!
+//! Further, enable [vIOMMU] with interrupt remapping using, e.g.,
+//!
+//! `-M q35,accel=kvm,kernel-irqchip=split -device intel-iommu,intremap=on,caching-mode=on`
+//!
+//! and append `intel_iommu=on` to the guest kernel arguments.
+//!
+//! [igb]: https://www.qemu.org/docs/master/system/devices/igb.html
+//! [vIOMMU]: https://wiki.qemu.org/Features/VT-d
+
+use kernel::{
+    device::Core,
+    pci,
+    prelude::*,
+    sync::aref::ARef, //
+};
+
+use core::any::TypeId;
+
+#[pin_data(PinnedDrop)]
+struct SampleDriver {
+    pdev: ARef<pci::Device>,
+    private: TypeId,
+}
+
+kernel::pci_device_table!(
+    PCI_TABLE,
+    MODULE_PCI_TABLE,
+    <SampleDriver as pci::Driver>::IdInfo,
+    [
+        // E1000_DEV_ID_82576
+        (pci::DeviceId::from_id(pci::Vendor::INTEL, 0x10c9), ()),
+        // E1000_DEV_ID_82576_VF
+        (pci::DeviceId::from_id(pci::Vendor::INTEL, 0x10ca), ())
+    ]
+);
+
+#[vtable]
+impl pci::Driver for SampleDriver {
+    type IdInfo = ();
+
+    const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
+
+    fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
+        pin_init::pin_init_scope(move || {
+            dev_info!(
+                pdev,
+                "Probe Rust SR-IOV driver sample (PCI ID: {}, 0x{:x}).\n",
+                pdev.vendor_id(),
+                pdev.device_id()
+            );
+
+            if pdev.is_virtfn() {
+                let physfn = pdev.physfn()?;
+                let drvdata = physfn.as_ref().drvdata::<Self>()?;
+
+                assert!(physfn.is_physfn());
+
+                dev_info!(
+                    pdev,
+                    "Parent device is PF (PCI ID: {}, 0x{:x}).\n",
+                    physfn.vendor_id(),
+                    physfn.device_id()
+                );
+
+                dev_info!(
+                    pdev,
+                    "We have access to the private data of {:?}.\n",
+                    drvdata.private
+                );
+            }
+
+            pdev.enable_device_mem()?;
+            pdev.set_master();
+
+            Ok(try_pin_init!(Self {
+                pdev: pdev.into(),
+                private: TypeId::of::<Self>()
+            }))
+        })
+    }
+
+    fn sriov_configure(pdev: &pci::Device<Core>, nr_virtfn: i32) -> Result<i32> {
+        assert!(pdev.is_physfn());
+
+        if nr_virtfn == 0 {
+            dev_info!(
+                pdev,
+                "Disable SR-IOV (PCI ID: {}, 0x{:x}).\n",
+                pdev.vendor_id(),
+                pdev.device_id()
+            );
+            pdev.disable_sriov();
+        } else {
+            dev_info!(
+                pdev,
+                "Enable SR-IOV (PCI ID: {}, 0x{:x}).\n",
+                pdev.vendor_id(),
+                pdev.device_id()
+            );
+            pdev.enable_sriov(nr_virtfn)?;
+        }
+
+        assert_eq!(pdev.num_vf(), nr_virtfn);
+        Ok(nr_virtfn)
+    }
+}
+
+#[pinned_drop]
+impl PinnedDrop for SampleDriver {
+    fn drop(self: Pin<&mut Self>) {
+        dev_info!(self.pdev, "Remove Rust SR-IOV driver sample.\n");
+    }
+}
+
+kernel::module_pci_driver! {
+    type: SampleDriver,
+    name: "rust_driver_sriov",
+    authors: ["Peter Colberg"],
+    description: "Rust SR-IOV driver",
+    license: "GPL v2",
+}

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (9 preceding siblings ...)
  2026-03-03 21:15 ` [PATCH v3 10/10] samples: rust: add SR-IOV driver sample Peter Colberg
@ 2026-03-04  8:47 ` Leon Romanovsky
  2026-03-04 14:18   ` Jason Gunthorpe
  10 siblings, 1 reply; 21+ messages in thread
From: Leon Romanovsky @ 2026-03-04  8:47 UTC (permalink / raw)
  To: Peter Colberg
  Cc: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Abdiel Janulgue, Daniel Almeida, Robin Murphy, Greg Kroah-Hartman,
	Dave Ertman, Ira Weiny, David Airlie, Simona Vetter,
	Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng, linux-pci, rust-for-linux,
	linux-kernel, Alexandre Courbot, Alistair Popple, Joel Fernandes,
	John Hubbard, Zhi Wang, nouveau, dri-devel, linux-doc, linux-fpga,
	driver-core, Jason Gunthorpe

On Tue, Mar 03, 2026 at 04:15:20PM -0500, Peter Colberg wrote:
> Add Rust abstractions for the Single Root I/O Virtualization (SR-IOV)
> capability of a PCI device. Provide a minimal set of wrappers for the
> SR-IOV C API to enable and disable SR-IOV for a device, and query if
> a PCI device is a Physical Function (PF) or Virtual Function (VF).

<...>

> For PF drivers written in C, disabling SR-IOV on remove() may be opted
> into by setting the flag managed_sriov in the pci_driver structure. For
> PF drivers written in Rust, disabling SR-IOV on unbind() is mandatory.

Why? Could you explain the rationale behind this difference between C and
Rust? Let me remind you that SR‑IOV devices which do not disable VFs do so
for a practical and well‑established reason: maximizing hardware
utilization.

Thanks

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-03-04  8:47 ` [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Leon Romanovsky
@ 2026-03-04 14:18   ` Jason Gunthorpe
  2026-03-04 14:26     ` Leon Romanovsky
  0 siblings, 1 reply; 21+ messages in thread
From: Jason Gunthorpe @ 2026-03-04 14:18 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Peter Colberg, Danilo Krummrich, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Greg Kroah-Hartman, Dave Ertman, Ira Weiny, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng, linux-pci, rust-for-linux,
	linux-kernel, Alexandre Courbot, Alistair Popple, Joel Fernandes,
	John Hubbard, Zhi Wang, nouveau, dri-devel, linux-doc, linux-fpga,
	driver-core

On Wed, Mar 04, 2026 at 10:47:50AM +0200, Leon Romanovsky wrote:
> On Tue, Mar 03, 2026 at 04:15:20PM -0500, Peter Colberg wrote:
> > Add Rust abstractions for the Single Root I/O Virtualization (SR-IOV)
> > capability of a PCI device. Provide a minimal set of wrappers for the
> > SR-IOV C API to enable and disable SR-IOV for a device, and query if
> > a PCI device is a Physical Function (PF) or Virtual Function (VF).
> 
> <...>
> 
> > For PF drivers written in C, disabling SR-IOV on remove() may be opted
> > into by setting the flag managed_sriov in the pci_driver structure. For
> > PF drivers written in Rust, disabling SR-IOV on unbind() is mandatory.
> 
> Why? Could you explain the rationale behind this difference between C and
> Rust? Let me remind you that SR‑IOV devices which do not disable VFs do so
> for a practical and well‑established reason: maximizing hardware
> utilization.

Personally I think drivers doing this are wrong. That such a driver
bug was allowed to become UAPI is pretty bad. The rust approach is
better.

Jason

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-03-04 14:18   ` Jason Gunthorpe
@ 2026-03-04 14:26     ` Leon Romanovsky
  2026-03-04 14:57       ` Danilo Krummrich
  0 siblings, 1 reply; 21+ messages in thread
From: Leon Romanovsky @ 2026-03-04 14:26 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Peter Colberg, Danilo Krummrich, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Greg Kroah-Hartman, Dave Ertman, Ira Weiny, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng, linux-pci, rust-for-linux,
	linux-kernel, Alexandre Courbot, Alistair Popple, Joel Fernandes,
	John Hubbard, Zhi Wang, nouveau, dri-devel, linux-doc, linux-fpga,
	driver-core

On Wed, Mar 04, 2026 at 10:18:52AM -0400, Jason Gunthorpe wrote:
> On Wed, Mar 04, 2026 at 10:47:50AM +0200, Leon Romanovsky wrote:
> > On Tue, Mar 03, 2026 at 04:15:20PM -0500, Peter Colberg wrote:
> > > Add Rust abstractions for the Single Root I/O Virtualization (SR-IOV)
> > > capability of a PCI device. Provide a minimal set of wrappers for the
> > > SR-IOV C API to enable and disable SR-IOV for a device, and query if
> > > a PCI device is a Physical Function (PF) or Virtual Function (VF).
> > 
> > <...>
> > 
> > > For PF drivers written in C, disabling SR-IOV on remove() may be opted
> > > into by setting the flag managed_sriov in the pci_driver structure. For
> > > PF drivers written in Rust, disabling SR-IOV on unbind() is mandatory.
> > 
> > Why? Could you explain the rationale behind this difference between C and
> > Rust? Let me remind you that SR‑IOV devices which do not disable VFs do so
> > for a practical and well‑established reason: maximizing hardware
> > utilization.
> 
> Personally I think drivers doing this are wrong. That such a driver
> bug was allowed to become UAPI is pretty bad. The rust approach is
> better.

We already had this discussion. I see this as a perfectly valid
use-case.

Thanks

> 
> Jason

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-03-04 14:26     ` Leon Romanovsky
@ 2026-03-04 14:57       ` Danilo Krummrich
  2026-03-04 16:27         ` Leon Romanovsky
  0 siblings, 1 reply; 21+ messages in thread
From: Danilo Krummrich @ 2026-03-04 14:57 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Jason Gunthorpe, Peter Colberg, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Greg Kroah-Hartman, Dave Ertman, Ira Weiny, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng, linux-pci, rust-for-linux,
	linux-kernel, Alexandre Courbot, Alistair Popple, Joel Fernandes,
	John Hubbard, Zhi Wang, nouveau, dri-devel, linux-doc, linux-fpga,
	driver-core

On Wed Mar 4, 2026 at 3:26 PM CET, Leon Romanovsky wrote:
> On Wed, Mar 04, 2026 at 10:18:52AM -0400, Jason Gunthorpe wrote:
>> On Wed, Mar 04, 2026 at 10:47:50AM +0200, Leon Romanovsky wrote:
>> > On Tue, Mar 03, 2026 at 04:15:20PM -0500, Peter Colberg wrote:
>> > > Add Rust abstractions for the Single Root I/O Virtualization (SR-IOV)
>> > > capability of a PCI device. Provide a minimal set of wrappers for the
>> > > SR-IOV C API to enable and disable SR-IOV for a device, and query if
>> > > a PCI device is a Physical Function (PF) or Virtual Function (VF).
>> > 
>> > <...>
>> > 
>> > > For PF drivers written in C, disabling SR-IOV on remove() may be opted
>> > > into by setting the flag managed_sriov in the pci_driver structure. For
>> > > PF drivers written in Rust, disabling SR-IOV on unbind() is mandatory.
>> > 
>> > Why? Could you explain the rationale behind this difference between C and
>> > Rust? Let me remind you that SR‑IOV devices which do not disable VFs do so
>> > for a practical and well‑established reason: maximizing hardware
>> > utilization.
>> 
>> Personally I think drivers doing this are wrong. That such a driver
>> bug was allowed to become UAPI is pretty bad. The rust approach is
>> better.
>
> We already had this discussion. I see this as a perfectly valid
> use-case.

Can you remind about a specific use-case for this please? (Ideally, one that
can't be solved otherwise.)

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-03-04 14:57       ` Danilo Krummrich
@ 2026-03-04 16:27         ` Leon Romanovsky
  2026-03-04 16:45           ` Jason Gunthorpe
  0 siblings, 1 reply; 21+ messages in thread
From: Leon Romanovsky @ 2026-03-04 16:27 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Jason Gunthorpe, Peter Colberg, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Greg Kroah-Hartman, Dave Ertman, Ira Weiny, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng, linux-pci, rust-for-linux,
	linux-kernel, Alexandre Courbot, Alistair Popple, Joel Fernandes,
	John Hubbard, Zhi Wang, nouveau, dri-devel, linux-doc, linux-fpga,
	driver-core

On Wed, Mar 04, 2026 at 03:57:57PM +0100, Danilo Krummrich wrote:
> On Wed Mar 4, 2026 at 3:26 PM CET, Leon Romanovsky wrote:
> > On Wed, Mar 04, 2026 at 10:18:52AM -0400, Jason Gunthorpe wrote:
> >> On Wed, Mar 04, 2026 at 10:47:50AM +0200, Leon Romanovsky wrote:
> >> > On Tue, Mar 03, 2026 at 04:15:20PM -0500, Peter Colberg wrote:
> >> > > Add Rust abstractions for the Single Root I/O Virtualization (SR-IOV)
> >> > > capability of a PCI device. Provide a minimal set of wrappers for the
> >> > > SR-IOV C API to enable and disable SR-IOV for a device, and query if
> >> > > a PCI device is a Physical Function (PF) or Virtual Function (VF).
> >> > 
> >> > <...>
> >> > 
> >> > > For PF drivers written in C, disabling SR-IOV on remove() may be opted
> >> > > into by setting the flag managed_sriov in the pci_driver structure. For
> >> > > PF drivers written in Rust, disabling SR-IOV on unbind() is mandatory.
> >> > 
> >> > Why? Could you explain the rationale behind this difference between C and
> >> > Rust? Let me remind you that SR‑IOV devices which do not disable VFs do so
> >> > for a practical and well‑established reason: maximizing hardware
> >> > utilization.
> >> 
> >> Personally I think drivers doing this are wrong. That such a driver
> >> bug was allowed to become UAPI is pretty bad. The rust approach is
> >> better.
> >
> > We already had this discussion. I see this as a perfectly valid
> > use-case.
> 
> Can you remind about a specific use-case for this please? (Ideally, one that
> can't be solved otherwise.)

You create X VFs through sriov_configure, unbind PF, bind it to vfio
instead and forward (X + 1) functions to different VMs.

If you destroy VFs on PF unbind, you will find yourself with one
function less per-device, as you will have not-utilized PF now,
which consumes HW resources anyway.

Thanks 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-03-04 16:27         ` Leon Romanovsky
@ 2026-03-04 16:45           ` Jason Gunthorpe
  2026-03-04 17:02             ` Leon Romanovsky
  0 siblings, 1 reply; 21+ messages in thread
From: Jason Gunthorpe @ 2026-03-04 16:45 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Danilo Krummrich, Peter Colberg, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Greg Kroah-Hartman, Dave Ertman, Ira Weiny, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng, linux-pci, rust-for-linux,
	linux-kernel, Alexandre Courbot, Alistair Popple, Joel Fernandes,
	John Hubbard, Zhi Wang, nouveau, dri-devel, linux-doc, linux-fpga,
	driver-core

On Wed, Mar 04, 2026 at 06:27:11PM +0200, Leon Romanovsky wrote:
> On Wed, Mar 04, 2026 at 03:57:57PM +0100, Danilo Krummrich wrote:
> > On Wed Mar 4, 2026 at 3:26 PM CET, Leon Romanovsky wrote:
> > > On Wed, Mar 04, 2026 at 10:18:52AM -0400, Jason Gunthorpe wrote:
> > >> On Wed, Mar 04, 2026 at 10:47:50AM +0200, Leon Romanovsky wrote:
> > >> > On Tue, Mar 03, 2026 at 04:15:20PM -0500, Peter Colberg wrote:
> > >> > > Add Rust abstractions for the Single Root I/O Virtualization (SR-IOV)
> > >> > > capability of a PCI device. Provide a minimal set of wrappers for the
> > >> > > SR-IOV C API to enable and disable SR-IOV for a device, and query if
> > >> > > a PCI device is a Physical Function (PF) or Virtual Function (VF).
> > >> > 
> > >> > <...>
> > >> > 
> > >> > > For PF drivers written in C, disabling SR-IOV on remove() may be opted
> > >> > > into by setting the flag managed_sriov in the pci_driver structure. For
> > >> > > PF drivers written in Rust, disabling SR-IOV on unbind() is mandatory.
> > >> > 
> > >> > Why? Could you explain the rationale behind this difference between C and
> > >> > Rust? Let me remind you that SR‑IOV devices which do not disable VFs do so
> > >> > for a practical and well‑established reason: maximizing hardware
> > >> > utilization.
> > >> 
> > >> Personally I think drivers doing this are wrong. That such a driver
> > >> bug was allowed to become UAPI is pretty bad. The rust approach is
> > >> better.
> > >
> > > We already had this discussion. I see this as a perfectly valid
> > > use-case.
> > 
> > Can you remind about a specific use-case for this please? (Ideally, one that
> > can't be solved otherwise.)
> 
> You create X VFs through sriov_configure, unbind PF, bind it to vfio
> instead and forward (X + 1) functions to different VMs.

No, illegal, and it doesn't even work right. When VFIO FLRs the PF it
will blow up the half baked SRIOV and break everything.

VFIO already has its own sriov_config support, the right flow is to
bind the PF to VFIO and then enable sriov and do your assignments.

Jason

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-03-04 16:45           ` Jason Gunthorpe
@ 2026-03-04 17:02             ` Leon Romanovsky
  2026-03-04 17:45               ` Jason Gunthorpe
  2026-03-04 17:50               ` Danilo Krummrich
  0 siblings, 2 replies; 21+ messages in thread
From: Leon Romanovsky @ 2026-03-04 17:02 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Danilo Krummrich, Peter Colberg, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Greg Kroah-Hartman, Dave Ertman, Ira Weiny, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng, linux-pci, rust-for-linux,
	linux-kernel, Alexandre Courbot, Alistair Popple, Joel Fernandes,
	John Hubbard, Zhi Wang, nouveau, dri-devel, linux-doc, linux-fpga,
	driver-core

On Wed, Mar 04, 2026 at 12:45:51PM -0400, Jason Gunthorpe wrote:
> On Wed, Mar 04, 2026 at 06:27:11PM +0200, Leon Romanovsky wrote:
> > On Wed, Mar 04, 2026 at 03:57:57PM +0100, Danilo Krummrich wrote:
> > > On Wed Mar 4, 2026 at 3:26 PM CET, Leon Romanovsky wrote:
> > > > On Wed, Mar 04, 2026 at 10:18:52AM -0400, Jason Gunthorpe wrote:
> > > >> On Wed, Mar 04, 2026 at 10:47:50AM +0200, Leon Romanovsky wrote:
> > > >> > On Tue, Mar 03, 2026 at 04:15:20PM -0500, Peter Colberg wrote:
> > > >> > > Add Rust abstractions for the Single Root I/O Virtualization (SR-IOV)
> > > >> > > capability of a PCI device. Provide a minimal set of wrappers for the
> > > >> > > SR-IOV C API to enable and disable SR-IOV for a device, and query if
> > > >> > > a PCI device is a Physical Function (PF) or Virtual Function (VF).
> > > >> > 
> > > >> > <...>
> > > >> > 
> > > >> > > For PF drivers written in C, disabling SR-IOV on remove() may be opted
> > > >> > > into by setting the flag managed_sriov in the pci_driver structure. For
> > > >> > > PF drivers written in Rust, disabling SR-IOV on unbind() is mandatory.
> > > >> > 
> > > >> > Why? Could you explain the rationale behind this difference between C and
> > > >> > Rust? Let me remind you that SR‑IOV devices which do not disable VFs do so
> > > >> > for a practical and well‑established reason: maximizing hardware
> > > >> > utilization.
> > > >> 
> > > >> Personally I think drivers doing this are wrong. That such a driver
> > > >> bug was allowed to become UAPI is pretty bad. The rust approach is
> > > >> better.
> > > >
> > > > We already had this discussion. I see this as a perfectly valid
> > > > use-case.
> > > 
> > > Can you remind about a specific use-case for this please? (Ideally, one that
> > > can't be solved otherwise.)
> > 
> > You create X VFs through sriov_configure, unbind PF, bind it to vfio
> > instead and forward (X + 1) functions to different VMs.
> 
> No, illegal, and it doesn't even work right. When VFIO FLRs the PF it
> will blow up the half baked SRIOV and break everything.

The FLR can be disabled. For example, PCI_DEV_FLAGS_NO_FLR_RESET flag
will do it.

> 
> VFIO already has its own sriov_config support, the right flow is to
> bind the PF to VFIO and then enable sriov and do your assignments.

VFIO started to support SR-IOV in 137e5531351d ("vfio/pci: Add
sriov_configure support"), which was added 8 years after VFIO core was
added cba3345cc494 ("vfio: VFIO core").

Thanks

> 
> Jason
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-03-04 17:02             ` Leon Romanovsky
@ 2026-03-04 17:45               ` Jason Gunthorpe
  2026-03-04 17:50               ` Danilo Krummrich
  1 sibling, 0 replies; 21+ messages in thread
From: Jason Gunthorpe @ 2026-03-04 17:45 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Danilo Krummrich, Peter Colberg, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Greg Kroah-Hartman, Dave Ertman, Ira Weiny, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng, linux-pci, rust-for-linux,
	linux-kernel, Alexandre Courbot, Alistair Popple, Joel Fernandes,
	John Hubbard, Zhi Wang, nouveau, dri-devel, linux-doc, linux-fpga,
	driver-core

On Wed, Mar 04, 2026 at 07:02:49PM +0200, Leon Romanovsky wrote:
> > No, illegal, and it doesn't even work right. When VFIO FLRs the PF it
> > will blow up the half baked SRIOV and break everything.
> 
> The FLR can be disabled. For example, PCI_DEV_FLAGS_NO_FLR_RESET flag
> will do it.

Well that would break all the security properties of VFIO.

> > VFIO already has its own sriov_config support, the right flow is to
> > bind the PF to VFIO and then enable sriov and do your assignments.
> 
> VFIO started to support SR-IOV in 137e5531351d ("vfio/pci: Add
> sriov_configure support"), which was added 8 years after VFIO core was
> added cba3345cc494 ("vfio: VFIO core").

Well, time to upgrade, I see no reason to allow Rust drivers to
further propogate these mistakes.

Jason

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-03-04 17:02             ` Leon Romanovsky
  2026-03-04 17:45               ` Jason Gunthorpe
@ 2026-03-04 17:50               ` Danilo Krummrich
  2026-03-04 18:30                 ` Leon Romanovsky
  1 sibling, 1 reply; 21+ messages in thread
From: Danilo Krummrich @ 2026-03-04 17:50 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Jason Gunthorpe, Peter Colberg, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Greg Kroah-Hartman, Dave Ertman, Ira Weiny, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng, linux-pci, rust-for-linux,
	linux-kernel, Alexandre Courbot, Alistair Popple, Joel Fernandes,
	John Hubbard, Zhi Wang, nouveau, dri-devel, linux-doc, linux-fpga,
	driver-core

On Wed Mar 4, 2026 at 6:02 PM CET, Leon Romanovsky wrote:
> On Wed, Mar 04, 2026 at 12:45:51PM -0400, Jason Gunthorpe wrote:
>> On Wed, Mar 04, 2026 at 06:27:11PM +0200, Leon Romanovsky wrote:
>> > On Wed, Mar 04, 2026 at 03:57:57PM +0100, Danilo Krummrich wrote:
>> > > On Wed Mar 4, 2026 at 3:26 PM CET, Leon Romanovsky wrote:
>> > > > On Wed, Mar 04, 2026 at 10:18:52AM -0400, Jason Gunthorpe wrote:
>> > > >> On Wed, Mar 04, 2026 at 10:47:50AM +0200, Leon Romanovsky wrote:
>> > > >> > On Tue, Mar 03, 2026 at 04:15:20PM -0500, Peter Colberg wrote:
>> > > >> > > Add Rust abstractions for the Single Root I/O Virtualization (SR-IOV)
>> > > >> > > capability of a PCI device. Provide a minimal set of wrappers for the
>> > > >> > > SR-IOV C API to enable and disable SR-IOV for a device, and query if
>> > > >> > > a PCI device is a Physical Function (PF) or Virtual Function (VF).
>> > > >> > 
>> > > >> > <...>
>> > > >> > 
>> > > >> > > For PF drivers written in C, disabling SR-IOV on remove() may be opted
>> > > >> > > into by setting the flag managed_sriov in the pci_driver structure. For
>> > > >> > > PF drivers written in Rust, disabling SR-IOV on unbind() is mandatory.
>> > > >> > 
>> > > >> > Why? Could you explain the rationale behind this difference between C and
>> > > >> > Rust? Let me remind you that SR‑IOV devices which do not disable VFs do so
>> > > >> > for a practical and well‑established reason: maximizing hardware
>> > > >> > utilization.
>> > > >> 
>> > > >> Personally I think drivers doing this are wrong. That such a driver
>> > > >> bug was allowed to become UAPI is pretty bad. The rust approach is
>> > > >> better.
>> > > >
>> > > > We already had this discussion. I see this as a perfectly valid
>> > > > use-case.
>> > > 
>> > > Can you remind about a specific use-case for this please? (Ideally, one that
>> > > can't be solved otherwise.)
>> > 
>> > You create X VFs through sriov_configure, unbind PF, bind it to vfio
>> > instead and forward (X + 1) functions to different VMs.
>> 
>> No, illegal, and it doesn't even work right. When VFIO FLRs the PF it
>> will blow up the half baked SRIOV and break everything.
>
> The FLR can be disabled. For example, PCI_DEV_FLAGS_NO_FLR_RESET flag
> will do it.

But this is a quirk and not a feature, no? So, we shouldn't use it as a baseline
for actual features.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-03-04 17:50               ` Danilo Krummrich
@ 2026-03-04 18:30                 ` Leon Romanovsky
  0 siblings, 0 replies; 21+ messages in thread
From: Leon Romanovsky @ 2026-03-04 18:30 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Jason Gunthorpe, Peter Colberg, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Greg Kroah-Hartman, Dave Ertman, Ira Weiny, David Airlie,
	Simona Vetter, Jonathan Corbet, Xu Yilun, Tom Rix, Moritz Fischer,
	Rafael J. Wysocki, Boqun Feng, linux-pci, rust-for-linux,
	linux-kernel, Alexandre Courbot, Alistair Popple, Joel Fernandes,
	John Hubbard, Zhi Wang, nouveau, dri-devel, linux-doc, linux-fpga,
	driver-core

On Wed, Mar 04, 2026 at 06:50:02PM +0100, Danilo Krummrich wrote:
> On Wed Mar 4, 2026 at 6:02 PM CET, Leon Romanovsky wrote:
> > On Wed, Mar 04, 2026 at 12:45:51PM -0400, Jason Gunthorpe wrote:
> >> On Wed, Mar 04, 2026 at 06:27:11PM +0200, Leon Romanovsky wrote:
> >> > On Wed, Mar 04, 2026 at 03:57:57PM +0100, Danilo Krummrich wrote:
> >> > > On Wed Mar 4, 2026 at 3:26 PM CET, Leon Romanovsky wrote:
> >> > > > On Wed, Mar 04, 2026 at 10:18:52AM -0400, Jason Gunthorpe wrote:
> >> > > >> On Wed, Mar 04, 2026 at 10:47:50AM +0200, Leon Romanovsky wrote:
> >> > > >> > On Tue, Mar 03, 2026 at 04:15:20PM -0500, Peter Colberg wrote:
> >> > > >> > > Add Rust abstractions for the Single Root I/O Virtualization (SR-IOV)
> >> > > >> > > capability of a PCI device. Provide a minimal set of wrappers for the
> >> > > >> > > SR-IOV C API to enable and disable SR-IOV for a device, and query if
> >> > > >> > > a PCI device is a Physical Function (PF) or Virtual Function (VF).
> >> > > >> > 
> >> > > >> > <...>
> >> > > >> > 
> >> > > >> > > For PF drivers written in C, disabling SR-IOV on remove() may be opted
> >> > > >> > > into by setting the flag managed_sriov in the pci_driver structure. For
> >> > > >> > > PF drivers written in Rust, disabling SR-IOV on unbind() is mandatory.
> >> > > >> > 
> >> > > >> > Why? Could you explain the rationale behind this difference between C and
> >> > > >> > Rust? Let me remind you that SR‑IOV devices which do not disable VFs do so
> >> > > >> > for a practical and well‑established reason: maximizing hardware
> >> > > >> > utilization.
> >> > > >> 
> >> > > >> Personally I think drivers doing this are wrong. That such a driver
> >> > > >> bug was allowed to become UAPI is pretty bad. The rust approach is
> >> > > >> better.
> >> > > >
> >> > > > We already had this discussion. I see this as a perfectly valid
> >> > > > use-case.
> >> > > 
> >> > > Can you remind about a specific use-case for this please? (Ideally, one that
> >> > > can't be solved otherwise.)
> >> > 
> >> > You create X VFs through sriov_configure, unbind PF, bind it to vfio
> >> > instead and forward (X + 1) functions to different VMs.
> >> 
> >> No, illegal, and it doesn't even work right. When VFIO FLRs the PF it
> >> will blow up the half baked SRIOV and break everything.
> >
> > The FLR can be disabled. For example, PCI_DEV_FLAGS_NO_FLR_RESET flag
> > will do it.
> 
> But this is a quirk and not a feature, no? So, we shouldn't use it as a baseline
> for actual features.

My point is slightly different. I was trying to explain the rationale for
preserving VFs after the PF is unbound, a design choice that predates the
introduction of the VFIO .srio_configure callback.

Thanks

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2026-03-04 18:30 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-03 21:15 [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
2026-03-03 21:15 ` [PATCH v3 01/10] PCI: add driver flag to opt into disabling SR-IOV on remove() Peter Colberg
2026-03-03 21:15 ` [PATCH v3 02/10] fpga: dfl-pci: set driver flag to disable " Peter Colberg
2026-03-03 21:15 ` [PATCH v3 03/10] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability Peter Colberg
2026-03-03 21:15 ` [PATCH v3 04/10] rust: pci: add vtable attribute to pci::Driver trait Peter Colberg
2026-03-03 21:15 ` [PATCH v3 05/10] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs Peter Colberg
2026-03-03 21:15 ` [PATCH v3 06/10] rust: pci: add is_virtfn(), to check for VFs Peter Colberg
2026-03-03 21:15 ` [PATCH v3 07/10] rust: pci: add is_physfn(), to check for PFs Peter Colberg
2026-03-03 21:15 ` [PATCH v3 08/10] rust: pci: add num_vf(), to return number of VFs Peter Colberg
2026-03-03 21:15 ` [PATCH v3 09/10] rust: pci: add physfn(), to return PF device for VF device Peter Colberg
2026-03-03 21:15 ` [PATCH v3 10/10] samples: rust: add SR-IOV driver sample Peter Colberg
2026-03-04  8:47 ` [PATCH v3 00/10] rust: pci: add abstractions for SR-IOV capability Leon Romanovsky
2026-03-04 14:18   ` Jason Gunthorpe
2026-03-04 14:26     ` Leon Romanovsky
2026-03-04 14:57       ` Danilo Krummrich
2026-03-04 16:27         ` Leon Romanovsky
2026-03-04 16:45           ` Jason Gunthorpe
2026-03-04 17:02             ` Leon Romanovsky
2026-03-04 17:45               ` Jason Gunthorpe
2026-03-04 17:50               ` Danilo Krummrich
2026-03-04 18:30                 ` Leon Romanovsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox