public inbox for linux-doc@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability
@ 2026-02-05 20:59 Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 01/10] PCI: add driver flag to opt into disabling SR-IOV on remove() Peter Colberg
                   ` (10 more replies)
  0 siblings, 11 replies; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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 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: c5048ddee936ca5ce0aeb79172ce512130779d31
change-id: 20251026-rust-pci-sriov-ca8f501b2ae3

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


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

* [PATCH v2 01/10] PCI: add driver flag to opt into disabling SR-IOV on remove()
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
@ 2026-02-05 20:59 ` Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 02/10] fpga: dfl-pci: set driver flag to disable " Peter Colberg
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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 00784a60ba80bb55ff2790d8f87e15a90c652a24..5b6ed251b4b1e940ec5781bb10dd5c58d3609fc8 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -1011,20 +1011,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 7c2d9d59625868886d61d8d4045d656ee0165776..e44593c67d147cd70d2d1a8a436a26857b0e446a 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -462,6 +462,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);
 		/*
@@ -475,8 +476,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 0e67014aa0013a7086c3a45d576d4b1ca2bb159f..53692e138ed347bfcf6d5923ddd418e9860399d7 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -826,6 +826,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);
@@ -860,6 +861,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 b5cc0c2b99065d4a1ee4581275362e79726a2145..768a02b12ff73aeb4dc3dc33fcca7c46b524c3c0 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -997,6 +997,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;
@@ -1015,6 +1022,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.52.0


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

* [PATCH v2 02/10] fpga: dfl-pci: set driver flag to disable SR-IOV on remove()
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 01/10] PCI: add driver flag to opt into disabling SR-IOV on remove() Peter Colberg
@ 2026-02-05 20:59 ` Peter Colberg
  2026-02-26  6:59   ` Xu Yilun
  2026-02-05 20:59 ` [PATCH v2 03/10] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability Peter Colberg
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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 602807d6afcc09af9e1d53368b41460ef86545d8..7965c307f9b79bdd2c2c3277d519ab2c4e701797 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.52.0


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

* [PATCH v2 03/10] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 01/10] PCI: add driver flag to opt into disabling SR-IOV on remove() Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 02/10] fpga: dfl-pci: set driver flag to disable " Peter Colberg
@ 2026-02-05 20:59 ` Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 04/10] rust: pci: add vtable attribute to pci::Driver trait Peter Colberg
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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.52.0


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

* [PATCH v2 04/10] rust: pci: add vtable attribute to pci::Driver trait
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (2 preceding siblings ...)
  2026-02-05 20:59 ` [PATCH v2 03/10] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability Peter Colberg
@ 2026-02-05 20:59 ` Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 05/10] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs Peter Colberg
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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 b8b0cc0f2d93599358c8cd6562d23c27e4654a87..3944077adf550ac91422ca1cb235365b8502586e 100644
--- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -65,6 +65,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 c20961f168356c6bbe0faefc0079d7a90b013684..67a17f4b4657b5f91a4fc603ca7025478d79df2d 100644
--- a/samples/rust/rust_driver_auxiliary.rs
+++ b/samples/rust/rust_driver_auxiliary.rs
@@ -66,6 +66,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 4dfb8a6a47077d2c565b09f7c7822f7f5e2641c8..fe4db08d42a74abb5865c75968249b58bedc01fd 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.52.0


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

* [PATCH v2 05/10] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (3 preceding siblings ...)
  2026-02-05 20:59 ` [PATCH v2 04/10] rust: pci: add vtable attribute to pci::Driver trait Peter Colberg
@ 2026-02-05 20:59 ` Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 06/10] rust: pci: add is_virtfn(), to check for VFs Peter Colberg
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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.52.0


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

* [PATCH v2 06/10] rust: pci: add is_virtfn(), to check for VFs
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (4 preceding siblings ...)
  2026-02-05 20:59 ` [PATCH v2 05/10] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs Peter Colberg
@ 2026-02-05 20:59 ` Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 07/10] rust: pci: add is_physfn(), to check for PFs Peter Colberg
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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.52.0


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

* [PATCH v2 07/10] rust: pci: add is_physfn(), to check for PFs
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (5 preceding siblings ...)
  2026-02-05 20:59 ` [PATCH v2 06/10] rust: pci: add is_virtfn(), to check for VFs Peter Colberg
@ 2026-02-05 20:59 ` Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 08/10] rust: pci: add num_vf(), to return number of VFs Peter Colberg
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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.52.0


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

* [PATCH v2 08/10] rust: pci: add num_vf(), to return number of VFs
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (6 preceding siblings ...)
  2026-02-05 20:59 ` [PATCH v2 07/10] rust: pci: add is_physfn(), to check for PFs Peter Colberg
@ 2026-02-05 20:59 ` Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 09/10] rust: pci: add physfn(), to return PF device for VF device Peter Colberg
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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.52.0


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

* [PATCH v2 09/10] rust: pci: add physfn(), to return PF device for VF device
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (7 preceding siblings ...)
  2026-02-05 20:59 ` [PATCH v2 08/10] rust: pci: add num_vf(), to return number of VFs Peter Colberg
@ 2026-02-05 20:59 ` Peter Colberg
  2026-02-05 20:59 ` [PATCH v2 10/10] samples: rust: add SR-IOV driver sample Peter Colberg
  2026-02-06  7:45 ` [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Dirk Behme
  10 siblings, 0 replies; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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 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.52.0


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

* [PATCH v2 10/10] samples: rust: add SR-IOV driver sample
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (8 preceding siblings ...)
  2026-02-05 20:59 ` [PATCH v2 09/10] rust: pci: add physfn(), to return PF device for VF device Peter Colberg
@ 2026-02-05 20:59 ` Peter Colberg
  2026-02-16  8:27   ` Dirk Behme
  2026-02-06  7:45 ` [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Dirk Behme
  10 siblings, 1 reply; 16+ messages in thread
From: Peter Colberg @ 2026-02-05 20:59 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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
  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 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 b277baee5eb6725b3a5126cefb6eef6190b02413..96dffd777c24473063baaeda017f64b15e8c0ab9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20242,6 +20242,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..84d057629c7b03d743179a4e05ccc092f814bf6b
--- /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.as_ref(),
+                "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.as_ref(),
+                    "Parent device is PF (PCI ID: {}, 0x{:x}).\n",
+                    physfn.vendor_id(),
+                    physfn.device_id()
+                );
+
+                dev_info!(
+                    pdev.as_ref(),
+                    "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.as_ref(),
+                "Disable SR-IOV (PCI ID: {}, 0x{:x}).\n",
+                pdev.vendor_id(),
+                pdev.device_id()
+            );
+            pdev.disable_sriov();
+        } else {
+            dev_info!(
+                pdev.as_ref(),
+                "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.as_ref(), "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.52.0


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

* Re: [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-02-05 20:59 [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Peter Colberg
                   ` (9 preceding siblings ...)
  2026-02-05 20:59 ` [PATCH v2 10/10] samples: rust: add SR-IOV driver sample Peter Colberg
@ 2026-02-06  7:45 ` Dirk Behme
  2026-02-06 10:47   ` Danilo Krummrich
  10 siblings, 1 reply; 16+ messages in thread
From: Dirk Behme @ 2026-02-06  7:45 UTC (permalink / raw)
  To: Peter Colberg, Danilo Krummrich, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	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, Zhi Wang,
	Zijing Zhang
  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, Jason Gunthorpe

On 05.02.2026 21:59, 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).
> 
> 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 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

Would it make sense to somehow align / coordinate / stack this with the 
work from Zhi Wang (and Zijing Zhang)

https://lore.kernel.org/rust-for-linux/20260126215957.541180-3-zhiw@nvidia.com/

? Or is this completely orthogonal?

Best regards

Dirk



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

* Re: [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability
  2026-02-06  7:45 ` [PATCH v2 00/10] rust: pci: add abstractions for SR-IOV capability Dirk Behme
@ 2026-02-06 10:47   ` Danilo Krummrich
  0 siblings, 0 replies; 16+ messages in thread
From: Danilo Krummrich @ 2026-02-06 10:47 UTC (permalink / raw)
  To: Dirk Behme
  Cc: Peter Colberg, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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, Zhi Wang, Zijing Zhang,
	linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
	Alistair Popple, Joel Fernandes, John Hubbard, nouveau, dri-devel,
	linux-doc, linux-fpga, driver-core, Jason Gunthorpe

On Fri Feb 6, 2026 at 8:45 AM CET, Dirk Behme wrote:
> Or is this completely orthogonal?

Yes, this is orthogonal.

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

* Re: [PATCH v2 10/10] samples: rust: add SR-IOV driver sample
  2026-02-05 20:59 ` [PATCH v2 10/10] samples: rust: add SR-IOV driver sample Peter Colberg
@ 2026-02-16  8:27   ` Dirk Behme
  2026-02-18  2:03     ` Peter Colberg
  0 siblings, 1 reply; 16+ messages in thread
From: Dirk Behme @ 2026-02-16  8:27 UTC (permalink / raw)
  To: Peter Colberg, Danilo Krummrich, Bjorn Helgaas,
	Krzysztof Wilczyński, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	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
  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, Jason Gunthorpe

Hi Peter,

On 05.02.2026 21:59, Peter Colberg wrote:
> 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 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/samples/rust/rust_driver_sriov.rs b/samples/rust/rust_driver_sriov.rs
> new file mode 100644
> index 0000000000000000000000000000000000000000..84d057629c7b03d743179a4e05ccc092f814bf6b
> --- /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.as_ref(),

The `as_ref()` in the `dev_*()` prints can be dropped. Example:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/samples/rust/rust_driver_pci.rs?id=600de1c008b2302b56d69ff27d12a9d8d14892ac

Best regards

Dirk

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

* Re: [PATCH v2 10/10] samples: rust: add SR-IOV driver sample
  2026-02-16  8:27   ` Dirk Behme
@ 2026-02-18  2:03     ` Peter Colberg
  0 siblings, 0 replies; 16+ messages in thread
From: Peter Colberg @ 2026-02-18  2:03 UTC (permalink / raw)
  To: Dirk Behme
  Cc: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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, 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

Hi Dirk,

On Mon, Feb 16, 2026 at 09:27:44AM +0100, Dirk Behme wrote:
> Hi Peter,
> 
> On 05.02.2026 21:59, Peter Colberg wrote:
> > 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 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/samples/rust/rust_driver_sriov.rs b/samples/rust/rust_driver_sriov.rs
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..84d057629c7b03d743179a4e05ccc092f814bf6b
> > --- /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.as_ref(),
> 
> The `as_ref()` in the `dev_*()` prints can be dropped. Example:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/samples/rust/rust_driver_pci.rs?id=600de1c008b2302b56d69ff27d12a9d8d14892ac

Thank you for the pointer, dropped in v3.

Peter

> 
> Best regards
> 
> Dirk
> 


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

* Re: [PATCH v2 02/10] fpga: dfl-pci: set driver flag to disable SR-IOV on remove()
  2026-02-05 20:59 ` [PATCH v2 02/10] fpga: dfl-pci: set driver flag to disable " Peter Colberg
@ 2026-02-26  6:59   ` Xu Yilun
  0 siblings, 0 replies; 16+ messages in thread
From: Xu Yilun @ 2026-02-26  6:59 UTC (permalink / raw)
  To: Peter Colberg
  Cc: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, 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, 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 Thu, Feb 05, 2026 at 03:59:49PM -0500, Peter Colberg wrote:
> 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().

I think it makes much clearer demonstration if you split the unrelated
changes out.

> 
> 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 602807d6afcc09af9e1d53368b41460ef86545d8..7965c307f9b79bdd2c2c3277d519ab2c4e701797 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.52.0
> 
> 

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

end of thread, other threads:[~2026-02-26  7:18 UTC | newest]

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

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