* [PATCH 1/8] rust: pci: add is_virtfn(), to check for VFs
2025-11-19 22:19 [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Peter Colberg
@ 2025-11-19 22:19 ` Peter Colberg
2025-11-21 3:00 ` kernel test robot
2025-11-19 22:19 ` [PATCH 2/8] rust: pci: add is_physfn(), to check for PFs Peter Colberg
` (7 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Peter Colberg @ 2025-11-19 22:19 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
Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang,
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>
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
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 | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 82e128431f080fde78a06dc5c284ab12739e747e..c20b8daeb7aadbef9f6ecfc48c972436efac9a08 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -409,6 +409,12 @@ 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).
+ 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.51.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* Re: [PATCH 1/8] rust: pci: add is_virtfn(), to check for VFs
2025-11-19 22:19 ` [PATCH 1/8] rust: pci: add is_virtfn(), to check for VFs Peter Colberg
@ 2025-11-21 3:00 ` kernel test robot
2025-11-21 18:27 ` Peter Colberg
0 siblings, 1 reply; 31+ messages in thread
From: kernel test robot @ 2025-11-21 3:00 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
Cc: llvm, oe-kbuild-all, linux-pci, rust-for-linux, linux-kernel,
Alexandre Courbot, Alistair Popple, Joel Fernandes, John Hubbard,
Zhi Wang, Peter Colberg, Jason Gunthorpe
Hi Peter,
kernel test robot noticed the following build errors:
[auto build test ERROR on e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559]
url: https://github.com/intel-lab-lkp/linux/commits/Peter-Colberg/rust-pci-add-is_virtfn-to-check-for-VFs/20251120-062302
base: e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559
patch link: https://lore.kernel.org/r/20251119-rust-pci-sriov-v1-1-883a94599a97%40redhat.com
patch subject: [PATCH 1/8] rust: pci: add is_virtfn(), to check for VFs
config: um-randconfig-001-20251121 (https://download.01.org/0day-ci/archive/20251121/202511211008.jgLuTcrQ-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9e9fe08b16ea2c4d9867fb4974edf2a3776d6ece)
rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251121/202511211008.jgLuTcrQ-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511211008.jgLuTcrQ-lkp@intel.com/
All errors (new ones prefixed by >>):
>> error[E0599]: no method named `is_virtfn` found for struct `bindings::pci_dev` in the current scope
--> rust/kernel/pci.rs:415:35
|
415 | unsafe { (*self.as_raw()).is_virtfn() != 0 }
| ^^^^^^^^^ method not found in `pci_dev`
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 1/8] rust: pci: add is_virtfn(), to check for VFs
2025-11-21 3:00 ` kernel test robot
@ 2025-11-21 18:27 ` Peter Colberg
0 siblings, 0 replies; 31+ messages in thread
From: Peter Colberg @ 2025-11-21 18:27 UTC (permalink / raw)
To: kernel test robot
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, llvm,
oe-kbuild-all, linux-pci, rust-for-linux, linux-kernel,
Alexandre Courbot, Alistair Popple, Joel Fernandes, John Hubbard,
Zhi Wang, Jason Gunthorpe
On Fri, Nov 21, 2025 at 11:00:32AM +0800, kernel test robot wrote:
> Hi Peter,
>
> kernel test robot noticed the following build errors:
This appears to be a generic issue with UML, unrelated to this series.
https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/CONFIG_UML.20maybe.20broken.3F/with/558611169
Thanks,
Peter
>
> [auto build test ERROR on e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Peter-Colberg/rust-pci-add-is_virtfn-to-check-for-VFs/20251120-062302
> base: e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559
> patch link: https://lore.kernel.org/r/20251119-rust-pci-sriov-v1-1-883a94599a97%40redhat.com
> patch subject: [PATCH 1/8] rust: pci: add is_virtfn(), to check for VFs
> config: um-randconfig-001-20251121 (https://download.01.org/0day-ci/archive/20251121/202511211008.jgLuTcrQ-lkp@intel.com/config)
> compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9e9fe08b16ea2c4d9867fb4974edf2a3776d6ece)
> rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251121/202511211008.jgLuTcrQ-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202511211008.jgLuTcrQ-lkp@intel.com/
>
> All errors (new ones prefixed by >>):
>
> >> error[E0599]: no method named `is_virtfn` found for struct `bindings::pci_dev` in the current scope
> --> rust/kernel/pci.rs:415:35
> |
> 415 | unsafe { (*self.as_raw()).is_virtfn() != 0 }
> | ^^^^^^^^^ method not found in `pci_dev`
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 2/8] rust: pci: add is_physfn(), to check for PFs
2025-11-19 22:19 [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Peter Colberg
2025-11-19 22:19 ` [PATCH 1/8] rust: pci: add is_virtfn(), to check for VFs Peter Colberg
@ 2025-11-19 22:19 ` Peter Colberg
2025-11-21 4:35 ` kernel test robot
2025-11-19 22:19 ` [PATCH 3/8] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability Peter Colberg
` (6 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Peter Colberg @ 2025-11-19 22:19 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
Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang,
Peter Colberg, Jason Gunthorpe
Add a method to check if a PCI device is a Physical Function (PF).
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
rust/kernel/pci.rs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index c20b8daeb7aadbef9f6ecfc48c972436efac9a08..814990d386708fe2ac652ccaa674c10a6cf390cb 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -409,6 +409,12 @@ 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 (VF).
+ 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).
pub fn is_virtfn(&self) -> bool {
// SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`.
--
2.51.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* Re: [PATCH 2/8] rust: pci: add is_physfn(), to check for PFs
2025-11-19 22:19 ` [PATCH 2/8] rust: pci: add is_physfn(), to check for PFs Peter Colberg
@ 2025-11-21 4:35 ` kernel test robot
0 siblings, 0 replies; 31+ messages in thread
From: kernel test robot @ 2025-11-21 4:35 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
Cc: llvm, oe-kbuild-all, linux-pci, rust-for-linux, linux-kernel,
Alexandre Courbot, Alistair Popple, Joel Fernandes, John Hubbard,
Zhi Wang, Peter Colberg, Jason Gunthorpe
Hi Peter,
kernel test robot noticed the following build errors:
[auto build test ERROR on e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559]
url: https://github.com/intel-lab-lkp/linux/commits/Peter-Colberg/rust-pci-add-is_virtfn-to-check-for-VFs/20251120-062302
base: e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559
patch link: https://lore.kernel.org/r/20251119-rust-pci-sriov-v1-2-883a94599a97%40redhat.com
patch subject: [PATCH 2/8] rust: pci: add is_physfn(), to check for PFs
config: um-randconfig-001-20251121 (https://download.01.org/0day-ci/archive/20251121/202511211257.8KOIldMM-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9e9fe08b16ea2c4d9867fb4974edf2a3776d6ece)
rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251121/202511211257.8KOIldMM-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511211257.8KOIldMM-lkp@intel.com/
All errors (new ones prefixed by >>):
>> error[E0599]: no method named `is_physfn` found for struct `bindings::pci_dev` in the current scope
--> rust/kernel/pci.rs:415:35
|
415 | unsafe { (*self.as_raw()).is_physfn() != 0 }
| ^^^^^^^^^ method not found in `pci_dev`
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 3/8] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability
2025-11-19 22:19 [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Peter Colberg
2025-11-19 22:19 ` [PATCH 1/8] rust: pci: add is_virtfn(), to check for VFs Peter Colberg
2025-11-19 22:19 ` [PATCH 2/8] rust: pci: add is_physfn(), to check for PFs Peter Colberg
@ 2025-11-19 22:19 ` Peter Colberg
2025-11-21 23:28 ` Jason Gunthorpe
2025-11-19 22:19 ` [PATCH 4/8] rust: pci: add num_vf(), to return number of VFs Peter Colberg
` (5 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Peter Colberg @ 2025-11-19 22:19 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
Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang,
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.
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
rust/kernel/pci.rs | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 814990d386708fe2ac652ccaa674c10a6cf390cb..556a01ed9bc3b1300a3340a3d2383e08ceacbfe5 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -454,6 +454,36 @@ 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.
+ let ret = unsafe { bindings::pci_enable_sriov(self.as_raw(), nr_virtfn) };
+ if ret != 0 {
+ return Err(crate::error::Error::from_errno(ret));
+ }
+ Ok(())
+ }
+
+ /// 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.
+ unsafe { bindings::pci_disable_sriov(self.as_raw()) };
+ }
}
// SAFETY: `pci::Device` is a transparent wrapper of `struct pci_dev`.
--
2.51.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* Re: [PATCH 3/8] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability
2025-11-19 22:19 ` [PATCH 3/8] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability Peter Colberg
@ 2025-11-21 23:28 ` Jason Gunthorpe
0 siblings, 0 replies; 31+ messages in thread
From: Jason Gunthorpe @ 2025-11-21 23:28 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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang
On Wed, Nov 19, 2025 at 05:19:07PM -0500, Peter Colberg wrote:
> 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.
>
> Suggested-by: Danilo Krummrich <dakr@kernel.org>
> Signed-off-by: Peter Colberg <pcolberg@redhat.com>
> ---
> rust/kernel/pci.rs | 30 ++++++++++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
>
> diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
> index 814990d386708fe2ac652ccaa674c10a6cf390cb..556a01ed9bc3b1300a3340a3d2383e08ceacbfe5 100644
> --- a/rust/kernel/pci.rs
> +++ b/rust/kernel/pci.rs
> @@ -454,6 +454,36 @@ 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.
> + let ret = unsafe { bindings::pci_enable_sriov(self.as_raw(), nr_virtfn) };
> + if ret != 0 {
> + return Err(crate::error::Error::from_errno(ret));
> + }
> + Ok(())
> + }
> +
> + /// 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.
> + unsafe { bindings::pci_disable_sriov(self.as_raw()) };
> + }
Both these functions should only be called on bound devices - the
safety statement should call it out, does the code require it?
Also per my other email SRIOV should be disabled before a driver can
be unbound, this patch should take care of it to not introduce an
dangerous enable_sriov().
Jason
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 4/8] rust: pci: add num_vf(), to return number of VFs
2025-11-19 22:19 [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Peter Colberg
` (2 preceding siblings ...)
2025-11-19 22:19 ` [PATCH 3/8] rust: pci: add {enable,disable}_sriov(), to control SR-IOV capability Peter Colberg
@ 2025-11-19 22:19 ` Peter Colberg
2025-11-19 22:19 ` [PATCH 5/8] rust: pci: add vtable attribute to pci::Driver trait Peter Colberg
` (4 subsequent siblings)
8 siblings, 0 replies; 31+ messages in thread
From: Peter Colberg @ 2025-11-19 22:19 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
Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang,
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 556a01ed9bc3b1300a3340a3d2383e08ceacbfe5..edb2bd41c8a14c8cfc421b26cda4dc84f75b546d 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -421,6 +421,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.51.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PATCH 5/8] rust: pci: add vtable attribute to pci::Driver trait
2025-11-19 22:19 [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Peter Colberg
` (3 preceding siblings ...)
2025-11-19 22:19 ` [PATCH 4/8] rust: pci: add num_vf(), to return number of VFs Peter Colberg
@ 2025-11-19 22:19 ` Peter Colberg
2025-11-19 22:19 ` [PATCH 6/8] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs Peter Colberg
` (3 subsequent siblings)
8 siblings, 0 replies; 31+ messages in thread
From: Peter Colberg @ 2025-11-19 22:19 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
Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang,
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>
---
rust/kernel/pci.rs | 1 +
samples/rust/rust_dma.rs | 1 +
samples/rust/rust_driver_auxiliary.rs | 1 +
samples/rust/rust_driver_pci.rs | 1 +
4 files changed, 4 insertions(+)
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index edb2bd41c8a14c8cfc421b26cda4dc84f75b546d..24dda12f6402098a1a323f3b5aae884201b26d89 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -275,6 +275,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 f53bce2a73e3bb619372798c33bc3f13e580fdfc..96aa906984d8a40c5270bb2a7bcf9650a41b7c9e 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 5761ea314f447643b8023b05ab7e92b60e6a1e17..23488fa6179fcc8c7a44df949d5eeeb1b132bd2d 100644
--- a/samples/rust/rust_driver_auxiliary.rs
+++ b/samples/rust/rust_driver_auxiliary.rs
@@ -64,6 +64,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 5823787bea8ec3e9a38ab3e4941f6c88d70e00b4..400db907e061a6a782b1cfebe9e5744815cc2843 100644
--- a/samples/rust/rust_driver_pci.rs
+++ b/samples/rust/rust_driver_pci.rs
@@ -60,6 +60,7 @@ fn testdev(index: &TestIndex, bar: &Bar0) -> Result<u32> {
}
}
+#[vtable]
impl pci::Driver for SampleDriver {
type IdInfo = TestIndex;
--
2.51.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [PATCH 6/8] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs
2025-11-19 22:19 [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Peter Colberg
` (4 preceding siblings ...)
2025-11-19 22:19 ` [PATCH 5/8] rust: pci: add vtable attribute to pci::Driver trait Peter Colberg
@ 2025-11-19 22:19 ` Peter Colberg
2025-11-21 6:00 ` kernel test robot
2025-11-19 22:19 ` [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device Peter Colberg
` (2 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Peter Colberg @ 2025-11-19 22:19 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
Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang,
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 | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 24dda12f6402098a1a323f3b5aae884201b26d89..f9054c52a3bdff2c42273366a4058d943ee5fd76 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -66,6 +66,10 @@ 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();
+ #[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 `RegType`.
@@ -118,6 +122,20 @@ extern "C" fn remove_callback(pdev: *mut bindings::pci_dev) {
T::unbind(pdev, data.as_ref());
}
+
+ #[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.
@@ -307,6 +325,39 @@ 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.
+ ///
+ /// 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.51.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* Re: [PATCH 6/8] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs
2025-11-19 22:19 ` [PATCH 6/8] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs Peter Colberg
@ 2025-11-21 6:00 ` kernel test robot
0 siblings, 0 replies; 31+ messages in thread
From: kernel test robot @ 2025-11-21 6:00 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
Cc: llvm, oe-kbuild-all, linux-pci, rust-for-linux, linux-kernel,
Alexandre Courbot, Alistair Popple, Joel Fernandes, John Hubbard,
Zhi Wang, Peter Colberg, Jason Gunthorpe
Hi Peter,
kernel test robot noticed the following build errors:
[auto build test ERROR on e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559]
url: https://github.com/intel-lab-lkp/linux/commits/Peter-Colberg/rust-pci-add-is_virtfn-to-check-for-VFs/20251120-062302
base: e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559
patch link: https://lore.kernel.org/r/20251119-rust-pci-sriov-v1-6-883a94599a97%40redhat.com
patch subject: [PATCH 6/8] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs
config: um-randconfig-001-20251121 (https://download.01.org/0day-ci/archive/20251121/202511211317.FkJsCIc0-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9e9fe08b16ea2c4d9867fb4974edf2a3776d6ece)
rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251121/202511211317.FkJsCIc0-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511211317.FkJsCIc0-lkp@intel.com/
All errors (new ones prefixed by >>):
>> error[E0609]: no field `sriov_configure` on type `pci_driver`
--> rust/kernel/pci.rs:71:31
|
71 | (*pdrv.get()).sriov_configure = Some(Self::sriov_configure_callback);
| ^^^^^^^^^^^^^^^ unknown field
|
= note: available field is: `_address`
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-19 22:19 [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Peter Colberg
` (5 preceding siblings ...)
2025-11-19 22:19 ` [PATCH 6/8] rust: pci: add bus callback sriov_configure(), to control SR-IOV from sysfs Peter Colberg
@ 2025-11-19 22:19 ` Peter Colberg
2025-11-21 7:57 ` kernel test robot
2025-11-21 23:26 ` Jason Gunthorpe
2025-11-19 22:19 ` [PATCH 8/8] samples: rust: add SR-IOV driver sample Peter Colberg
2025-11-20 6:32 ` [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Zhi Wang
8 siblings, 2 replies; 31+ messages in thread
From: Peter Colberg @ 2025-11-19 22:19 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
Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang,
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.
When a device with enabled VFs is unbound from a driver, invoke the
sriov_configure() callback to disable SR-IOV before the unbind()
callback. To ensure the guarantee is upheld, call disable_sriov()
to remove all VF devices if the driver has not done so already.
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Peter Colberg <pcolberg@redhat.com>
---
rust/kernel/pci.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index f9054c52a3bdff2c42273366a4058d943ee5fd76..d6cc5d7e7cd7a3b6e451c0ff5aea044b89c6774a 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -120,6 +120,19 @@ extern "C" fn remove_callback(pdev: *mut bindings::pci_dev) {
// and stored a `Pin<KBox<T>>`.
let data = unsafe { pdev.as_ref().drvdata_obtain::<T>() };
+ // Always disable SR-IOV before `unbind()` to guarantee that when a VF device is bound
+ // to a driver, the underlying PF device is bound to a driver, too.
+ #[cfg(CONFIG_PCI_IOV)]
+ {
+ // First, allow the driver to gracefully disable SR-IOV by itself.
+ if T::HAS_SRIOV_CONFIGURE && pdev.num_vf() != 0 {
+ let _ = T::sriov_configure(pdev, 0);
+ }
+ // Then, forcibly disable SR-IOV if the driver has not done so already,
+ // to uphold the guarantee with regard to driver binding described above.
+ pdev.disable_sriov();
+ }
+
T::unbind(pdev, data.as_ref());
}
@@ -332,6 +345,11 @@ fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) {
/// [`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.
///
@@ -500,6 +518,35 @@ 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>`.
+ ///
+ /// ```
+ /// let pf_pdev = vf_pdev.physfn()?;
+ /// let pf_drvdata = pf_pdev.as_ref().drvdata::<MyDriver>()?;
+ /// ```
+ #[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 self.is_virtfn() is `true`.
+ //
+ // `physfn` may be cast to a `Device<device::Bound>` since `pci::Driver::remove()` calls
+ // `disable_sriov()` to remove all VF devices, which guarantees that the underlying
+ // PF device is always bound to a driver when the VF device is bound to a driver.
+ Ok(unsafe { &*(*self.as_raw()).__bindgen_anon_1.physfn.cast() })
+ }
+}
+
impl Device<device::Core> {
/// Enable memory resources for this device.
pub fn enable_device_mem(&self) -> Result {
--
2.51.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* Re: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-19 22:19 ` [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device Peter Colberg
@ 2025-11-21 7:57 ` kernel test robot
2025-11-21 23:26 ` Jason Gunthorpe
1 sibling, 0 replies; 31+ messages in thread
From: kernel test robot @ 2025-11-21 7:57 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
Cc: llvm, oe-kbuild-all, linux-pci, rust-for-linux, linux-kernel,
Alexandre Courbot, Alistair Popple, Joel Fernandes, John Hubbard,
Zhi Wang, Peter Colberg, Jason Gunthorpe
Hi Peter,
kernel test robot noticed the following build errors:
[auto build test ERROR on e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559]
url: https://github.com/intel-lab-lkp/linux/commits/Peter-Colberg/rust-pci-add-is_virtfn-to-check-for-VFs/20251120-062302
base: e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559
patch link: https://lore.kernel.org/r/20251119-rust-pci-sriov-v1-7-883a94599a97%40redhat.com
patch subject: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
config: um-randconfig-001-20251121 (https://download.01.org/0day-ci/archive/20251121/202511211511.hUcSTiSF-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9e9fe08b16ea2c4d9867fb4974edf2a3776d6ece)
rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251121/202511211511.hUcSTiSF-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511211511.hUcSTiSF-lkp@intel.com/
All errors (new ones prefixed by >>):
>> error[E0609]: no field `__bindgen_anon_1` on type `bindings::pci_dev`
--> rust/kernel/pci.rs:546:40
|
546 | Ok(unsafe { &*(*self.as_raw()).__bindgen_anon_1.physfn.cast() })
| ^^^^^^^^^^^^^^^^ unknown field
|
= note: available field is: `_address`
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-19 22:19 ` [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device Peter Colberg
2025-11-21 7:57 ` kernel test robot
@ 2025-11-21 23:26 ` Jason Gunthorpe
2025-11-22 10:23 ` Danilo Krummrich
1 sibling, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2025-11-21 23:26 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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang
On Wed, Nov 19, 2025 at 05:19:11PM -0500, Peter Colberg wrote:
> 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.
You can't do this as an absolutely statement from rust code alone,
this statement is confused.
> When a device with enabled VFs is unbound from a driver, invoke the
> sriov_configure() callback to disable SR-IOV before the unbind()
> callback. To ensure the guarantee is upheld, call disable_sriov()
> to remove all VF devices if the driver has not done so already.
This doesn't seem like it should be in this patch.
Good drivers using the PCI APIs should be calling pci_disable_sriov()
during their unbind.
The prior patch #3 should not have added "safe" bindings for
enable_sriov that allow this lifetime rule to be violated.
> + #[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 self.is_virtfn() is `true`.
> + //
> + // `physfn` may be cast to a `Device<device::Bound>` since `pci::Driver::remove()` calls
> + // `disable_sriov()` to remove all VF devices, which guarantees that the underlying
> + // PF device is always bound to a driver when the VF device is bound to a driver.
Wrong safety statement. There are drivers that don't call
disable_sriov(). You need to also check that the driver attached to
the PF is actually working properly.
I do not like to see this attempt to open code the tricky login of
pci_iov_get_pf_drvdata() in rust without understanding the issues :(
Jason
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-21 23:26 ` Jason Gunthorpe
@ 2025-11-22 10:23 ` Danilo Krummrich
2025-11-22 16:16 ` Jason Gunthorpe
0 siblings, 1 reply; 31+ messages in thread
From: Danilo Krummrich @ 2025-11-22 10:23 UTC (permalink / raw)
To: Jason Gunthorpe
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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang
On Sat Nov 22, 2025 at 12:26 PM NZDT, Jason Gunthorpe wrote:
> On Wed, Nov 19, 2025 at 05:19:11PM -0500, Peter Colberg wrote:
>> 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.
>
> You can't do this as an absolutely statement from rust code alone,
> this statement is confused.
Indeed! However, I'd like to see that we actually provide this guarantee from
the C PCI code.
So far I haven't heard a convincing reason for not providing this guarantee. The
only reason not to guarantee this I have heard is that some PF drivers only
enable SR-IOV and hence could be unloaded afterwards. However, I think there is
no strong reason to do so.
What I would like to see is that we unbind VF drivers when the PF driver is
unbound in general, analogous to what we are guaranteed by the auxiliary bus.
>> + #[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 self.is_virtfn() is `true`.
>> + //
>> + // `physfn` may be cast to a `Device<device::Bound>` since `pci::Driver::remove()` calls
>> + // `disable_sriov()` to remove all VF devices, which guarantees that the underlying
>> + // PF device is always bound to a driver when the VF device is bound to a driver.
>
> Wrong safety statement. There are drivers that don't call
> disable_sriov(). You need to also check that the driver attached to
> the PF is actually working properly.
Indeed, with this patch, only Rust drivers provide this guarantee of the VF
being bound when the PF is bound.
> I do not like to see this attempt to open code the tricky login of
> pci_iov_get_pf_drvdata() in rust without understanding the issues :(
I discussed this with Peter in advance (thanks Peter for your work on this
topic!), and as mentioned above I'd like to see this series to propose that we
always guarantee that a VF is bound when the corresponding PF is bound.
With this, the above code will be correct and a driver can use the generic
infrastructure to:
1) Call pci::Device<Bound>::physfn() returning a Result<pci::Device<Bound>>
2) Grab the driver's device private data from the returned Device<Bound>
Note that 2) (i.e. accessing the driver's device private data with
Device::drvdata() [1]) ensures that the device is actually bound (drvdata() is
only implemented for Device<Bound>) and that the returned type actually matches
the type of the object that has been stored.
Since we always need those two checks when accessing a driver's device private
data, it is already done in the generic drvdata() accessor.
Therefore the only additional guarantee we have to give is that VF bound implies
PF bound. Otherwise physfn() would need to be unsafe and the driver would need
to promise that this is the case. From there on drvdata() already does the other
checks as mentioned.
I suggest to have a look at [2] for an example with how this turns out with the
auxiliary bus [2][3], since in the end it's the same problem, i.e. an auxiliary
driver calling into its parent, except that the auxiliary bus already guarantees
that the parent is bound when the child is bound.
Given that, there is no value in using pci_iov_get_pf_drvdata(), in Rust you'd
just call
// `vfdev` must be a `pci::Device<Bound>` for `physfn()` to be
// available; `pfdev` will therefore be a `pci::Device<Bound>` too
// (assuming we provide the guarantee for this, otherwise this would
// need to be unsafe).
let pfdev = vfdev.phyfn();
// `FooData` is the type of the PF drvier's device private data. The
// call to `drvdata()` will fail with an error of the asserted type is
// wrong.
let drvdata = pfdev.drvdata::<FooData>()?;
So, if we'd provide a Rust accessor for the PF's device driver data, we'd
implement it like above, because Device::drvdata() is already safe. If we want
pci::Device::pf_drvdata() to be safe, we'd otherwise need to do all the checks
Device::drvdata() already does again before we call into
pci_iov_get_pf_drvdata().
(Note that I'm currently travelling, hence I might not be as responsive as
usual. I'm travelling until after LPC; I plan to take a detailed look at this
series in the week of the conference).
[1] https://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git/tree/rust/kernel/device.rs?h=driver-core-next#n313
[2] https://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git/tree/samples/rust/rust_driver_auxiliary.rs?h=driver-core-next#n81
[3] https://lore.kernel.org/all/20251020223516.241050-1-dakr@kernel.org/
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-22 10:23 ` Danilo Krummrich
@ 2025-11-22 16:16 ` Jason Gunthorpe
2025-11-22 18:57 ` Leon Romanovsky
2025-11-22 22:43 ` Danilo Krummrich
0 siblings, 2 replies; 31+ messages in thread
From: Jason Gunthorpe @ 2025-11-22 16:16 UTC (permalink / raw)
To: Danilo Krummrich
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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang
On Sat, Nov 22, 2025 at 11:23:16PM +1300, Danilo Krummrich wrote:
> So far I haven't heard a convincing reason for not providing this guarantee. The
> only reason not to guarantee this I have heard is that some PF drivers only
> enable SR-IOV and hence could be unloaded afterwards. However, I think there is
> no strong reason to do so.
I know some people have work flows around this. I think they are
wrong. When we "fixed" mlx5 a while back there was some pushback and
some weird things did stop working.
So while I support this goal, I don't know if enough people will
agree..
> With this, the above code will be correct and a driver can use the generic
> infrastructure to:
>
> 1) Call pci::Device<Bound>::physfn() returning a Result<pci::Device<Bound>>
> 2) Grab the driver's device private data from the returned Device<Bound>
>
> Note that 2) (i.e. accessing the driver's device private data with
> Device::drvdata() [1]) ensures that the device is actually bound (drvdata() is
> only implemented for Device<Bound>) and that the returned type actually matches
> the type of the object that has been stored.
This is what the core helper does, with the twist that it "validates"
the PF driver is working right by checking its driver binding..
> I suggest to have a look at [2] for an example with how this turns out with the
> auxiliary bus [2][3], since in the end it's the same problem, i.e. an auxiliary
> driver calling into its parent, except that the auxiliary bus already guarantees
> that the parent is bound when the child is bound.
Aux bus is a little different because it should be used in a way where
there are stronger guarantees about what the parent is. Ie the aux bus
names should be unique and limited to the type of parent.
> So, if we'd provide a Rust accessor for the PF's device driver data, we'd
> implement it like above, because Device::drvdata() is already safe. If we want
> pci::Device::pf_drvdata() to be safe, we'd otherwise need to do all the checks
> Device::drvdata() already does again before we call into
> pci_iov_get_pf_drvdata().
I think to make progress along this line you need to still somehow
validate that the PF driver is working right, either by checking that
the driver is bound to a rust driver somehow or using the same
approach as the core helper.
I'm not sure the idea to force all drivers to do disable sriov is
going to be easy, and I'd rather see rust bindings progress without
opening such a topic..
Jason
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-22 16:16 ` Jason Gunthorpe
@ 2025-11-22 18:57 ` Leon Romanovsky
2025-11-22 22:26 ` Danilo Krummrich
2025-11-22 22:43 ` Danilo Krummrich
1 sibling, 1 reply; 31+ messages in thread
From: Leon Romanovsky @ 2025-11-22 18:57 UTC (permalink / raw)
To: Jason Gunthorpe, Danilo Krummrich
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, linux-pci,
rust-for-linux, linux-kernel, Alexandre Courbot, Alistair Popple,
Joel Fernandes, John Hubbard, Zhi Wang
On Sat, Nov 22, 2025 at 12:16:15PM -0400, Jason Gunthorpe wrote:
> On Sat, Nov 22, 2025 at 11:23:16PM +1300, Danilo Krummrich wrote:
> > So far I haven't heard a convincing reason for not providing this guarantee. The
> > only reason not to guarantee this I have heard is that some PF drivers only
> > enable SR-IOV and hence could be unloaded afterwards. However, I think there is
> > no strong reason to do so.
>
> I know some people have work flows around this. I think they are
> wrong. When we "fixed" mlx5 a while back there was some pushback and
> some weird things did stop working.
I don't think that this is correct. The main use case for keeping VFs,
while unloading PF driver is to allow reuse this PF for VFIO too. It is
very natural and common flow for "real" SR-IOV devices which present all
PF/VFs as truly separate devices.
The pushback for mlx5 was related to change in eswitch mode and not to
driver unload. In very corner case, mlx5 kept VFs to protect change in
netdevs.
>
> So while I support this goal, I don't know if enough people will
> agree..
I don't see that Bjorn is CCed here, so it is unclear to whom Danilo
talked to get rationale for this new behaviour.
>
> > With this, the above code will be correct and a driver can use the generic
> > infrastructure to:
> >
> > 1) Call pci::Device<Bound>::physfn() returning a Result<pci::Device<Bound>>
> > 2) Grab the driver's device private data from the returned Device<Bound>
> >
> > Note that 2) (i.e. accessing the driver's device private data with
> > Device::drvdata() [1]) ensures that the device is actually bound (drvdata() is
> > only implemented for Device<Bound>) and that the returned type actually matches
> > the type of the object that has been stored.
>
> This is what the core helper does, with the twist that it "validates"
> the PF driver is working right by checking its driver binding..
>
> > I suggest to have a look at [2] for an example with how this turns out with the
> > auxiliary bus [2][3], since in the end it's the same problem, i.e. an auxiliary
> > driver calling into its parent, except that the auxiliary bus already guarantees
> > that the parent is bound when the child is bound.
>
> Aux bus is a little different because it should be used in a way where
> there are stronger guarantees about what the parent is. Ie the aux bus
> names should be unique and limited to the type of parent.
Right, aux bus is completely unrelated to real physical PCI bus.
Thanks
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-22 18:57 ` Leon Romanovsky
@ 2025-11-22 22:26 ` Danilo Krummrich
2025-11-23 6:34 ` Leon Romanovsky
0 siblings, 1 reply; 31+ messages in thread
From: Danilo Krummrich @ 2025-11-22 22:26 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Jason Gunthorpe, 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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang
On Sun Nov 23, 2025 at 7:57 AM NZDT, Leon Romanovsky wrote:
> On Sat, Nov 22, 2025 at 12:16:15PM -0400, Jason Gunthorpe wrote:
>> On Sat, Nov 22, 2025 at 11:23:16PM +1300, Danilo Krummrich wrote:
>> > So far I haven't heard a convincing reason for not providing this guarantee. The
>> > only reason not to guarantee this I have heard is that some PF drivers only
>> > enable SR-IOV and hence could be unloaded afterwards. However, I think there is
>> > no strong reason to do so.
>>
>> I know some people have work flows around this. I think they are
>> wrong. When we "fixed" mlx5 a while back there was some pushback and
>> some weird things did stop working.
>
> I don't think that this is correct. The main use case for keeping VFs,
> while unloading PF driver is to allow reuse this PF for VFIO too. It is
> very natural and common flow for "real" SR-IOV devices which present all
> PF/VFs as truly separate devices.
That sounds a bit odd to me, what exactly do you mean with "reuse the PF for
VFIO"? What do you do with the PF after driver unload instead? Load another
driver? If so, why separate ones?
>> So while I support this goal, I don't know if enough people will
>> agree..
>
> I don't see that Bjorn is CCed here, so it is unclear to whom Danilo
> talked to get rationale for this new behaviour.
Not sure what you mean, Bjorn is CC'd on the whole series and hence also this
conversation.
Otherwise, my proposal to guarantee that the PF is bound as long as the VF(s)
are bound stems from the corresponding beneficial lifecycle implications for the
driver model (some more on this below).
>> > With this, the above code will be correct and a driver can use the generic
>> > infrastructure to:
>> >
>> > 1) Call pci::Device<Bound>::physfn() returning a Result<pci::Device<Bound>>
>> > 2) Grab the driver's device private data from the returned Device<Bound>
>> >
>> > Note that 2) (i.e. accessing the driver's device private data with
>> > Device::drvdata() [1]) ensures that the device is actually bound (drvdata() is
>> > only implemented for Device<Bound>) and that the returned type actually matches
>> > the type of the object that has been stored.
>>
>> This is what the core helper does, with the twist that it "validates"
>> the PF driver is working right by checking its driver binding..
>>
>> > I suggest to have a look at [2] for an example with how this turns out with the
>> > auxiliary bus [2][3], since in the end it's the same problem, i.e. an auxiliary
>> > driver calling into its parent, except that the auxiliary bus already guarantees
>> > that the parent is bound when the child is bound.
>>
>> Aux bus is a little different because it should be used in a way where
>> there are stronger guarantees about what the parent is. Ie the aux bus
>> names should be unique and limited to the type of parent.
>
> Right, aux bus is completely unrelated to real physical PCI bus.
Of course the auxiliary and the PCI bus are fundamentally different busses,
*but* they also have commonalities: the driver lifecycle requirements drivers
have to deal with are the same.
For instance, if you call from an auxiliary driver into the parent driver to let
the parent driver do some work on behalf, the auxiliary driver has to guarantee
that the parent device is guranteed to remain bound for the duration of the
call, otherwise the parent driver can't call dev_get_drvdata() without risking a
UAF, since a concurrent unbind might free the parent driver's device private
data.
The same is true for PCI when a VF driver calls into the PF driver to do some
work on behalf. The VF driver has to make sure that the PF driver remains bound
for the whole duration of the call for the exact same reasons.
I.e. it is a common driver lifecycle pattern for interactions between drivers in
general.
As for Rust specifically, we can actually model such driver lifecycle patterns
with the type system and with that do a lot of the driver lifecycle checks (that
drivers love to ignore :) even at compile time, such that your code doesn't even
compile when you violate the driver lifecycle rules.
For the auxiliary bus that's already the case and I'd love to get to this point
with PF <-> VF interactions (in Rust) as well.
I hope this helps.
- Danilo
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-22 22:26 ` Danilo Krummrich
@ 2025-11-23 6:34 ` Leon Romanovsky
2025-11-23 10:07 ` Danilo Krummrich
0 siblings, 1 reply; 31+ messages in thread
From: Leon Romanovsky @ 2025-11-23 6:34 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Jason Gunthorpe, 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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang
On Sun, Nov 23, 2025 at 11:26:52AM +1300, Danilo Krummrich wrote:
> On Sun Nov 23, 2025 at 7:57 AM NZDT, Leon Romanovsky wrote:
> > On Sat, Nov 22, 2025 at 12:16:15PM -0400, Jason Gunthorpe wrote:
> >> On Sat, Nov 22, 2025 at 11:23:16PM +1300, Danilo Krummrich wrote:
> >> > So far I haven't heard a convincing reason for not providing this guarantee. The
> >> > only reason not to guarantee this I have heard is that some PF drivers only
> >> > enable SR-IOV and hence could be unloaded afterwards. However, I think there is
> >> > no strong reason to do so.
> >>
> >> I know some people have work flows around this. I think they are
> >> wrong. When we "fixed" mlx5 a while back there was some pushback and
> >> some weird things did stop working.
> >
> > I don't think that this is correct. The main use case for keeping VFs,
> > while unloading PF driver is to allow reuse this PF for VFIO too. It is
> > very natural and common flow for "real" SR-IOV devices which present all
> > PF/VFs as truly separate devices.
>
> That sounds a bit odd to me, what exactly do you mean with "reuse the PF for
> VFIO"? What do you do with the PF after driver unload instead? Load another
> driver? If so, why separate ones?
One of the main use cases for SR-IOV is to provide to VM users/customers
devices with performance and security promises as physical ones. In this
case, the VMs are created through PF and not bound to any driver. Once
customer/user requests VM, that VF is bound to vfio-pci driver and
attached to that VM.
In many cases, PF is unbound too from its original driver and attached
to some other VM. It allows for these VM providers to maximize
utilization of their SR-IOV devices.
At least in PCI spec 6.0.1, it stays clearly that PF can be attached to SI (VM in spec language).
"Physical Function (PF) - A PF is a PCIe Function that supports the SR-IOV Extended Capability
and is accessible to an SR-PCIM, a VI, or an SI."
>
> >> So while I support this goal, I don't know if enough people will
> >> agree..
> >
> > I don't see that Bjorn is CCed here, so it is unclear to whom Danilo
> > talked to get rationale for this new behaviour.
>
> Not sure what you mean, Bjorn is CC'd on the whole series and hence also this
> conversation.
>
> Otherwise, my proposal to guarantee that the PF is bound as long as the VF(s)
> are bound stems from the corresponding beneficial lifecycle implications for the
> driver model (some more on this below).
>
> >> > With this, the above code will be correct and a driver can use the generic
> >> > infrastructure to:
> >> >
> >> > 1) Call pci::Device<Bound>::physfn() returning a Result<pci::Device<Bound>>
> >> > 2) Grab the driver's device private data from the returned Device<Bound>
> >> >
> >> > Note that 2) (i.e. accessing the driver's device private data with
> >> > Device::drvdata() [1]) ensures that the device is actually bound (drvdata() is
> >> > only implemented for Device<Bound>) and that the returned type actually matches
> >> > the type of the object that has been stored.
> >>
> >> This is what the core helper does, with the twist that it "validates"
> >> the PF driver is working right by checking its driver binding..
> >>
> >> > I suggest to have a look at [2] for an example with how this turns out with the
> >> > auxiliary bus [2][3], since in the end it's the same problem, i.e. an auxiliary
> >> > driver calling into its parent, except that the auxiliary bus already guarantees
> >> > that the parent is bound when the child is bound.
> >>
> >> Aux bus is a little different because it should be used in a way where
> >> there are stronger guarantees about what the parent is. Ie the aux bus
> >> names should be unique and limited to the type of parent.
> >
> > Right, aux bus is completely unrelated to real physical PCI bus.
>
> Of course the auxiliary and the PCI bus are fundamentally different busses,
> *but* they also have commonalities: the driver lifecycle requirements drivers
> have to deal with are the same.
>
> For instance, if you call from an auxiliary driver into the parent driver to let
> the parent driver do some work on behalf, the auxiliary driver has to guarantee
> that the parent device is guranteed to remain bound for the duration of the
> call, otherwise the parent driver can't call dev_get_drvdata() without risking a
> UAF, since a concurrent unbind might free the parent driver's device private
> data.
>
> The same is true for PCI when a VF driver calls into the PF driver to do some
> work on behalf. The VF driver has to make sure that the PF driver remains bound
> for the whole duration of the call for the exact same reasons.
And this section is not entirely correct. It is one of the possible
usages of PF. In many devices, PF and its VFs are independent and don't
communicate through kernel at all. There is no need for VF to have PF be
bounded to its original driver.
>
> I.e. it is a common driver lifecycle pattern for interactions between drivers in
> general.
And it is not true as well. In case you need to interact between
devices/drivers, it is up to the caller to ensure that this driver isn't
unloaded.
>
> As for Rust specifically, we can actually model such driver lifecycle patterns
> with the type system and with that do a lot of the driver lifecycle checks (that
> drivers love to ignore :) even at compile time, such that your code doesn't even
> compile when you violate the driver lifecycle rules.
>
> For the auxiliary bus that's already the case and I'd love to get to this point
> with PF <-> VF interactions (in Rust) as well.
It is absolutely correct thing to do for auxbus. It is very questionable for SR-IOV.
>
> I hope this helps.
Thanks
>
> - Danilo
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-23 6:34 ` Leon Romanovsky
@ 2025-11-23 10:07 ` Danilo Krummrich
2025-11-23 11:18 ` Leon Romanovsky
0 siblings, 1 reply; 31+ messages in thread
From: Danilo Krummrich @ 2025-11-23 10:07 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Jason Gunthorpe, 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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang
On Sun Nov 23, 2025 at 7:34 PM NZDT, Leon Romanovsky wrote:
> On Sun, Nov 23, 2025 at 11:26:52AM +1300, Danilo Krummrich wrote:
>> On Sun Nov 23, 2025 at 7:57 AM NZDT, Leon Romanovsky wrote:
>> > On Sat, Nov 22, 2025 at 12:16:15PM -0400, Jason Gunthorpe wrote:
>> >> On Sat, Nov 22, 2025 at 11:23:16PM +1300, Danilo Krummrich wrote:
>> >> > So far I haven't heard a convincing reason for not providing this guarantee. The
>> >> > only reason not to guarantee this I have heard is that some PF drivers only
>> >> > enable SR-IOV and hence could be unloaded afterwards. However, I think there is
>> >> > no strong reason to do so.
>> >>
>> >> I know some people have work flows around this. I think they are
>> >> wrong. When we "fixed" mlx5 a while back there was some pushback and
>> >> some weird things did stop working.
>> >
>> > I don't think that this is correct. The main use case for keeping VFs,
>> > while unloading PF driver is to allow reuse this PF for VFIO too. It is
>> > very natural and common flow for "real" SR-IOV devices which present all
>> > PF/VFs as truly separate devices.
>>
>> That sounds a bit odd to me, what exactly do you mean with "reuse the PF for
>> VFIO"? What do you do with the PF after driver unload instead? Load another
>> driver? If so, why separate ones?
>
> One of the main use cases for SR-IOV is to provide to VM users/customers
> devices with performance and security promises as physical ones. In this
> case, the VMs are created through PF and not bound to any driver. Once
> customer/user requests VM, that VF is bound to vfio-pci driver and
> attached to that VM.
>
> In many cases, PF is unbound too from its original driver and attached
> to some other VM. It allows for these VM providers to maximize
> utilization of their SR-IOV devices.
>
> At least in PCI spec 6.0.1, it stays clearly that PF can be attached to SI (VM in spec language).
> "Physical Function (PF) - A PF is a PCIe Function that supports the SR-IOV Extended Capability
> and is accessible to an SR-PCIM, a VI, or an SI."
Hm, that's possible, but do we have cases of this in practice where we bind and
unbind the same PF multiple times, pass it to different VMs, etc.?
In any case, what we can always do is what I propose in [1], i.e. add a bool to
struct pci_driver that indicates whether the VFs should be unbound when the PF
is unbound, such that we can uphold the guarantee of VF bound implies PF bound
at least conditionally.
[1] https://lore.kernel.org/all/DEFL4TG0WX1C.2GLH4417EPU3V@kernel.org/
>> >> So while I support this goal, I don't know if enough people will
>> >> agree..
>> >
>> > I don't see that Bjorn is CCed here, so it is unclear to whom Danilo
>> > talked to get rationale for this new behaviour.
>>
>> Not sure what you mean, Bjorn is CC'd on the whole series and hence also this
>> conversation.
>>
>> Otherwise, my proposal to guarantee that the PF is bound as long as the VF(s)
>> are bound stems from the corresponding beneficial lifecycle implications for the
>> driver model (some more on this below).
>>
>> >> > With this, the above code will be correct and a driver can use the generic
>> >> > infrastructure to:
>> >> >
>> >> > 1) Call pci::Device<Bound>::physfn() returning a Result<pci::Device<Bound>>
>> >> > 2) Grab the driver's device private data from the returned Device<Bound>
>> >> >
>> >> > Note that 2) (i.e. accessing the driver's device private data with
>> >> > Device::drvdata() [1]) ensures that the device is actually bound (drvdata() is
>> >> > only implemented for Device<Bound>) and that the returned type actually matches
>> >> > the type of the object that has been stored.
>> >>
>> >> This is what the core helper does, with the twist that it "validates"
>> >> the PF driver is working right by checking its driver binding..
>> >>
>> >> > I suggest to have a look at [2] for an example with how this turns out with the
>> >> > auxiliary bus [2][3], since in the end it's the same problem, i.e. an auxiliary
>> >> > driver calling into its parent, except that the auxiliary bus already guarantees
>> >> > that the parent is bound when the child is bound.
>> >>
>> >> Aux bus is a little different because it should be used in a way where
>> >> there are stronger guarantees about what the parent is. Ie the aux bus
>> >> names should be unique and limited to the type of parent.
>> >
>> > Right, aux bus is completely unrelated to real physical PCI bus.
>>
>> Of course the auxiliary and the PCI bus are fundamentally different busses,
>> *but* they also have commonalities: the driver lifecycle requirements drivers
>> have to deal with are the same.
>>
>> For instance, if you call from an auxiliary driver into the parent driver to let
>> the parent driver do some work on behalf, the auxiliary driver has to guarantee
>> that the parent device is guranteed to remain bound for the duration of the
>> call, otherwise the parent driver can't call dev_get_drvdata() without risking a
>> UAF, since a concurrent unbind might free the parent driver's device private
>> data.
>>
>> The same is true for PCI when a VF driver calls into the PF driver to do some
>> work on behalf. The VF driver has to make sure that the PF driver remains bound
>> for the whole duration of the call for the exact same reasons.
>
> And this section is not entirely correct. It is one of the possible
> usages of PF. In many devices, PF and its VFs are independent and don't
> communicate through kernel at all. There is no need for VF to have PF be
> bounded to its original driver.
Of course -- similarly there might be cases where an auxiliary driver might not
cummunicate with its parent, but that's not the case I'm referring to above.
>
>>
>> I.e. it is a common driver lifecycle pattern for interactions between drivers in
>> general.
>
> And it is not true as well. In case you need to interact between
> devices/drivers, it is up to the caller to ensure that this driver isn't
> unloaded.
You're mixing two things here. The driver model lifecycle requires that if
driver A calls into driver B - where B accesses its device private data - that B
is bound for the full duration of the call.
This is true for any such interaction, the question of who is responsible to
uphold this guarantee, e.g. the bus layer or the driver itself is orthogonal.
Whenever possible, it's best to let the bus layer uphold the guarantee though,
since it's one pitfall less a driver can fall into.
>>
>> As for Rust specifically, we can actually model such driver lifecycle patterns
>> with the type system and with that do a lot of the driver lifecycle checks (that
>> drivers love to ignore :) even at compile time, such that your code doesn't even
>> compile when you violate the driver lifecycle rules.
>>
>> For the auxiliary bus that's already the case and I'd love to get to this point
>> with PF <-> VF interactions (in Rust) as well.
>
> It is absolutely correct thing to do for auxbus. It is very questionable for SR-IOV.
At least conditionally (as proposed above), it's an improvement for cases where
there is PF <-> VF interactions, i.e. why let drivers take care if the bus can
already do it for them.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-23 10:07 ` Danilo Krummrich
@ 2025-11-23 11:18 ` Leon Romanovsky
0 siblings, 0 replies; 31+ messages in thread
From: Leon Romanovsky @ 2025-11-23 11:18 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Jason Gunthorpe, 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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang
On Sun, Nov 23, 2025 at 11:07:47PM +1300, Danilo Krummrich wrote:
> On Sun Nov 23, 2025 at 7:34 PM NZDT, Leon Romanovsky wrote:
> > On Sun, Nov 23, 2025 at 11:26:52AM +1300, Danilo Krummrich wrote:
> >> On Sun Nov 23, 2025 at 7:57 AM NZDT, Leon Romanovsky wrote:
> >> > On Sat, Nov 22, 2025 at 12:16:15PM -0400, Jason Gunthorpe wrote:
> >> >> On Sat, Nov 22, 2025 at 11:23:16PM +1300, Danilo Krummrich wrote:
> >> >> > So far I haven't heard a convincing reason for not providing this guarantee. The
> >> >> > only reason not to guarantee this I have heard is that some PF drivers only
> >> >> > enable SR-IOV and hence could be unloaded afterwards. However, I think there is
> >> >> > no strong reason to do so.
> >> >>
> >> >> I know some people have work flows around this. I think they are
> >> >> wrong. When we "fixed" mlx5 a while back there was some pushback and
> >> >> some weird things did stop working.
> >> >
> >> > I don't think that this is correct. The main use case for keeping VFs,
> >> > while unloading PF driver is to allow reuse this PF for VFIO too. It is
> >> > very natural and common flow for "real" SR-IOV devices which present all
> >> > PF/VFs as truly separate devices.
> >>
> >> That sounds a bit odd to me, what exactly do you mean with "reuse the PF for
> >> VFIO"? What do you do with the PF after driver unload instead? Load another
> >> driver? If so, why separate ones?
> >
> > One of the main use cases for SR-IOV is to provide to VM users/customers
> > devices with performance and security promises as physical ones. In this
> > case, the VMs are created through PF and not bound to any driver. Once
> > customer/user requests VM, that VF is bound to vfio-pci driver and
> > attached to that VM.
> >
> > In many cases, PF is unbound too from its original driver and attached
> > to some other VM. It allows for these VM providers to maximize
> > utilization of their SR-IOV devices.
> >
> > At least in PCI spec 6.0.1, it stays clearly that PF can be attached to SI (VM in spec language).
> > "Physical Function (PF) - A PF is a PCIe Function that supports the SR-IOV Extended Capability
> > and is accessible to an SR-PCIM, a VI, or an SI."
>
> Hm, that's possible, but do we have cases of this in practice where we bind and
> unbind the same PF multiple times, pass it to different VMs, etc.?
It is very common case, when the goal is to maximize hardware utilization.
>
> In any case, what we can always do is what I propose in [1], i.e. add a bool to
> struct pci_driver that indicates whether the VFs should be unbound when the PF
> is unbound, such that we can uphold the guarantee of VF bound implies PF bound
> at least conditionally.
>
> [1] https://lore.kernel.org/all/DEFL4TG0WX1C.2GLH4417EPU3V@kernel.org/
>
> >> >> So while I support this goal, I don't know if enough people will
> >> >> agree..
> >> >
> >> > I don't see that Bjorn is CCed here, so it is unclear to whom Danilo
> >> > talked to get rationale for this new behaviour.
> >>
> >> Not sure what you mean, Bjorn is CC'd on the whole series and hence also this
> >> conversation.
> >>
> >> Otherwise, my proposal to guarantee that the PF is bound as long as the VF(s)
> >> are bound stems from the corresponding beneficial lifecycle implications for the
> >> driver model (some more on this below).
> >>
> >> >> > With this, the above code will be correct and a driver can use the generic
> >> >> > infrastructure to:
> >> >> >
> >> >> > 1) Call pci::Device<Bound>::physfn() returning a Result<pci::Device<Bound>>
> >> >> > 2) Grab the driver's device private data from the returned Device<Bound>
> >> >> >
> >> >> > Note that 2) (i.e. accessing the driver's device private data with
> >> >> > Device::drvdata() [1]) ensures that the device is actually bound (drvdata() is
> >> >> > only implemented for Device<Bound>) and that the returned type actually matches
> >> >> > the type of the object that has been stored.
> >> >>
> >> >> This is what the core helper does, with the twist that it "validates"
> >> >> the PF driver is working right by checking its driver binding..
> >> >>
> >> >> > I suggest to have a look at [2] for an example with how this turns out with the
> >> >> > auxiliary bus [2][3], since in the end it's the same problem, i.e. an auxiliary
> >> >> > driver calling into its parent, except that the auxiliary bus already guarantees
> >> >> > that the parent is bound when the child is bound.
> >> >>
> >> >> Aux bus is a little different because it should be used in a way where
> >> >> there are stronger guarantees about what the parent is. Ie the aux bus
> >> >> names should be unique and limited to the type of parent.
> >> >
> >> > Right, aux bus is completely unrelated to real physical PCI bus.
> >>
> >> Of course the auxiliary and the PCI bus are fundamentally different busses,
> >> *but* they also have commonalities: the driver lifecycle requirements drivers
> >> have to deal with are the same.
> >>
> >> For instance, if you call from an auxiliary driver into the parent driver to let
> >> the parent driver do some work on behalf, the auxiliary driver has to guarantee
> >> that the parent device is guranteed to remain bound for the duration of the
> >> call, otherwise the parent driver can't call dev_get_drvdata() without risking a
> >> UAF, since a concurrent unbind might free the parent driver's device private
> >> data.
> >>
> >> The same is true for PCI when a VF driver calls into the PF driver to do some
> >> work on behalf. The VF driver has to make sure that the PF driver remains bound
> >> for the whole duration of the call for the exact same reasons.
> >
> > And this section is not entirely correct. It is one of the possible
> > usages of PF. In many devices, PF and its VFs are independent and don't
> > communicate through kernel at all. There is no need for VF to have PF be
> > bounded to its original driver.
>
> Of course -- similarly there might be cases where an auxiliary driver might not
> cummunicate with its parent, but that's not the case I'm referring to above.
Not really. Auxbus is a logical in-kernel separation of one physical device.
The promise is that parent auxdevice is tied to its children. It was done
intentionally to make sure that children don't outlive their parent.
It is not the case for SR-IOV.
>
> >
> >>
> >> I.e. it is a common driver lifecycle pattern for interactions between drivers in
> >> general.
> >
> > And it is not true as well. In case you need to interact between
> > devices/drivers, it is up to the caller to ensure that this driver isn't
> > unloaded.
>
> You're mixing two things here. The driver model lifecycle requires that if
> driver A calls into driver B - where B accesses its device private data - that B
> is bound for the full duration of the call.
I'm aware of this, and we are not talking about driver model. Whole
discussion is "if PF can be unbound, while VFs exist". The answer is yes, it can,
both from PCI spec perspective and from operational one.
>
> This is true for any such interaction, the question of who is responsible to
> uphold this guarantee, e.g. the bus layer or the driver itself is orthogonal.
>
> Whenever possible, it's best to let the bus layer uphold the guarantee though,
> since it's one pitfall less a driver can fall into.
>
> >>
> >> As for Rust specifically, we can actually model such driver lifecycle patterns
> >> with the type system and with that do a lot of the driver lifecycle checks (that
> >> drivers love to ignore :) even at compile time, such that your code doesn't even
> >> compile when you violate the driver lifecycle rules.
> >>
> >> For the auxiliary bus that's already the case and I'd love to get to this point
> >> with PF <-> VF interactions (in Rust) as well.
> >
> > It is absolutely correct thing to do for auxbus. It is very questionable for SR-IOV.
>
> At least conditionally (as proposed above), it's an improvement for cases where
> there is PF <-> VF interactions, i.e. why let drivers take care if the bus can
> already do it for them.
I'm not against some opt-in/opt-out solution. I'm against "one size fits
all" proposal, where PF is tied to its original driver as long as VFs
exist.
Thanks
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device
2025-11-22 16:16 ` Jason Gunthorpe
2025-11-22 18:57 ` Leon Romanovsky
@ 2025-11-22 22:43 ` Danilo Krummrich
1 sibling, 0 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-11-22 22:43 UTC (permalink / raw)
To: Jason Gunthorpe
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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang
On Sun Nov 23, 2025 at 5:16 AM NZDT, Jason Gunthorpe wrote:
> I think to make progress along this line you need to still somehow
> validate that the PF driver is working right, either by checking that
> the driver is bound to a rust driver somehow or using the same
> approach as the core helper.
Do you refer to the
if (pf_dev->driver != pf_driver)
check? If so, that's (in a slightly different form) already part of the generic
Device::drvdata() accessor.
> I'm not sure the idea to force all drivers to do disable sriov is
> going to be easy, and I'd rather see rust bindings progress without
> opening such a topic..
I'm sorry, I should have mentioned what I actually propose:
My idea would be to provide a bool in struct pci_driver, which, if set,
guarantees that all VFs are unbound when the PF is unbound.
With this bool being set, the PCI bus can provide the guarantee that VF bound
implies PF bound; the Rust accessor can then leverage this guarantee.
This can also be leveraged by the C code, where we could have a separate
accessor that checks the bool rather than askes the driver to promise that the
PF is bound, which pci_iov_get_pf_drvdata() does.
(Although I have to admit that without the additional type system capabilities
we have in Rust, it is not that big of an improvement.)
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 8/8] samples: rust: add SR-IOV driver sample
2025-11-19 22:19 [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Peter Colberg
` (6 preceding siblings ...)
2025-11-19 22:19 ` [PATCH 7/8] rust: pci: add physfn(), to return PF device for VF device Peter Colberg
@ 2025-11-19 22:19 ` Peter Colberg
2025-11-20 6:41 ` Zhi Wang
2025-11-20 6:32 ` [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Zhi Wang
8 siblings, 1 reply; 31+ messages in thread
From: Peter Colberg @ 2025-11-19 22:19 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
Cc: linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Zhi Wang,
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>
---
MAINTAINERS | 1 +
samples/rust/Kconfig | 11 ++++
samples/rust/Makefile | 1 +
samples/rust/rust_driver_sriov.rs | 107 ++++++++++++++++++++++++++++++++++++++
4 files changed, 120 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index b71ea515240a4c5db6d932efce5183386f3a3f79..f2b00c6d9feca43443d3618da32dce2c6ab8c569 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19945,6 +19945,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 b66bed5d3f36d20302bf586dfdb002d39ed9796e..b6154b6cd91f1d733f05b7529f67a79fe032b50c 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 && BROKEN
diff --git a/samples/rust/Makefile b/samples/rust/Makefile
index f65885d1d62bf406b0db13121ef3e5b09829cfbc..a4c12c1200949d0233e08a34e86cea1ff72d0ad7 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..a60d58d00a2d24883ddcb7236e525c448ae86b4f
--- /dev/null
+++ b/samples/rust/rust_driver_sriov.rs
@@ -0,0 +1,107 @@
+// 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};
+
+#[pin_data(PinnedDrop)]
+struct SampleDriver {
+ pdev: ARef<pci::Device>,
+}
+
+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()?;
+ assert!(physfn.is_physfn());
+ dev_info!(
+ pdev.as_ref(),
+ "Parent device is PF (PCI ID: {}, 0x{:x}).\n",
+ physfn.vendor_id(),
+ physfn.device_id()
+ );
+ }
+
+ pdev.enable_device_mem()?;
+ pdev.set_master();
+
+ Ok(try_pin_init!(Self { pdev: pdev.into() }))
+ })
+ }
+
+ 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.51.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* Re: [PATCH 8/8] samples: rust: add SR-IOV driver sample
2025-11-19 22:19 ` [PATCH 8/8] samples: rust: add SR-IOV driver sample Peter Colberg
@ 2025-11-20 6:41 ` Zhi Wang
2025-11-20 15:49 ` Peter Colberg
0 siblings, 1 reply; 31+ messages in thread
From: Zhi Wang @ 2025-11-20 6:41 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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Jason Gunthorpe
On Wed, 19 Nov 2025 17:19:12 -0500
Peter Colberg <pcolberg@redhat.com> 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.
>
snip
> +
> + 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)?;
> + }
> +
IMO, it would be nice to simply demostrate how to reach the driver data
structure (struct SampleDriver) and its members (I think accessing one
dummy member in the SampleDriver is good enough, not something fancy),
which I believe quite many of the drivers need to do so and they can
take this as the kernel recommended approach instead of inventing
something new differently. :)
Z.
> + 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",
> +}
>
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 8/8] samples: rust: add SR-IOV driver sample
2025-11-20 6:41 ` Zhi Wang
@ 2025-11-20 15:49 ` Peter Colberg
0 siblings, 0 replies; 31+ messages in thread
From: Peter Colberg @ 2025-11-20 15:49 UTC (permalink / raw)
To: Zhi Wang
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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Jason Gunthorpe
On Thu, Nov 20, 2025 at 08:41:32AM +0200, Zhi Wang wrote:
> On Wed, 19 Nov 2025 17:19:12 -0500
> Peter Colberg <pcolberg@redhat.com> 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.
> >
>
> snip
>
> > +
> > + 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)?;
> > + }
> > +
>
> IMO, it would be nice to simply demostrate how to reach the driver data
> structure (struct SampleDriver) and its members (I think accessing one
> dummy member in the SampleDriver is good enough, not something fancy),
> which I believe quite many of the drivers need to do so and they can
> take this as the kernel recommended approach instead of inventing
> something new differently. :)
Thanks for the suggestion. I added a `private` member to SampleDriver,
similar to the rust_driver_auxiliary sample, and extended the VF-only
path of probe() to demonstrate how to reach the driver data of the PF
device from a VF device.
Peter
>
> Z.
>
> > + 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",
> > +}
> >
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability
2025-11-19 22:19 [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Peter Colberg
` (7 preceding siblings ...)
2025-11-19 22:19 ` [PATCH 8/8] samples: rust: add SR-IOV driver sample Peter Colberg
@ 2025-11-20 6:32 ` Zhi Wang
2025-11-20 15:03 ` Peter Colberg
8 siblings, 1 reply; 31+ messages in thread
From: Zhi Wang @ 2025-11-20 6:32 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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Jason Gunthorpe
On Wed, 19 Nov 2025 17:19:04 -0500
Peter Colberg <pcolberg@redhat.com> wrote:
Hi Peter:
Thanks for the patches. :) I will test them with nova-core and come back
with Tested-bys.
Nit: Let's use "kernel vertical" styles on imports. [1]
[1] https://lore.kernel.org/all/20251105120352.77603-1-dakr@kernel.org/
> 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 unbind()
> callback. To ensure the guarantee is upheld, call disable_sriov()
> to remove all VF devices if the driver has not done so already.
>
> 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].
>
> 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
> [3].
>
> [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://www.qemu.org/docs/master/system/devices/igb.html
>
> Signed-off-by: Peter Colberg <pcolberg@redhat.com>
> ---
> John Hubbard (1):
> rust: pci: add is_virtfn(), to check for VFs
>
> Peter Colberg (7):
> rust: pci: add is_physfn(), to check for PFs
> rust: pci: add {enable,disable}_sriov(), to control SR-IOV
> capability rust: pci: add num_vf(), to return number of VFs
> 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 physfn(), to return PF device for VF
> device samples: rust: add SR-IOV driver sample
>
> MAINTAINERS | 1 +
> rust/kernel/pci.rs | 148
> ++++++++++++++++++++++++++++++++++ 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 | 107 ++++++++++++++++++++++++
> 8 files changed, 271 insertions(+)
> ---
> base-commit: e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559
> change-id: 20251026-rust-pci-sriov-ca8f501b2ae3
>
> Best regards,
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability
2025-11-20 6:32 ` [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability Zhi Wang
@ 2025-11-20 15:03 ` Peter Colberg
2025-11-20 18:34 ` Zhi Wang
0 siblings, 1 reply; 31+ messages in thread
From: Peter Colberg @ 2025-11-20 15:03 UTC (permalink / raw)
To: Zhi Wang
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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Jason Gunthorpe
On Thu, Nov 20, 2025 at 08:32:13AM +0200, Zhi Wang wrote:
> On Wed, 19 Nov 2025 17:19:04 -0500
> Peter Colberg <pcolberg@redhat.com> wrote:
>
> Hi Peter:
>
> Thanks for the patches. :) I will test them with nova-core and come back
> with Tested-bys.
Perfect, thanks Zhi.
> Nit: Let's use "kernel vertical" styles on imports. [1]
>
> [1] https://lore.kernel.org/all/20251105120352.77603-1-dakr@kernel.org/
Thanks, done for patch "samples: rust: add SR-IOV driver sample".
Peter
>
> > 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 unbind()
> > callback. To ensure the guarantee is upheld, call disable_sriov()
> > to remove all VF devices if the driver has not done so already.
> >
> > 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].
> >
> > 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
> > [3].
> >
> > [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://www.qemu.org/docs/master/system/devices/igb.html
> >
> > Signed-off-by: Peter Colberg <pcolberg@redhat.com>
> > ---
> > John Hubbard (1):
> > rust: pci: add is_virtfn(), to check for VFs
> >
> > Peter Colberg (7):
> > rust: pci: add is_physfn(), to check for PFs
> > rust: pci: add {enable,disable}_sriov(), to control SR-IOV
> > capability rust: pci: add num_vf(), to return number of VFs
> > 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 physfn(), to return PF device for VF
> > device samples: rust: add SR-IOV driver sample
> >
> > MAINTAINERS | 1 +
> > rust/kernel/pci.rs | 148
> > ++++++++++++++++++++++++++++++++++ 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 | 107 ++++++++++++++++++++++++
> > 8 files changed, 271 insertions(+)
> > ---
> > base-commit: e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559
> > change-id: 20251026-rust-pci-sriov-ca8f501b2ae3
> >
> > Best regards,
>
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability
2025-11-20 15:03 ` Peter Colberg
@ 2025-11-20 18:34 ` Zhi Wang
2025-11-20 21:16 ` Zhi Wang
2025-11-21 17:05 ` Peter Colberg
0 siblings, 2 replies; 31+ messages in thread
From: Zhi Wang @ 2025-11-20 18:34 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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Jason Gunthorpe
On Thu, 20 Nov 2025 10:03:45 -0500
Peter Colberg <pcolberg@redhat.com> wrote:
Hi Peter:
I met some errors when compiling on driver-core-next branch, you can
fix those in the next spin.
Fixes:
diff --git a/drivers/gpu/nova-core/driver.rs
b/drivers/gpu/nova-core/driver.rs index ca0d5f8ad54b..730e745cad63
100644 --- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -49,6 +49,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 d6cc5d7e7cd7..2d68db076f92 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -292,6 +292,7 @@ macro_rules! pci_device_table {
/// ]
/// );
///
+/// #[vtable]
/// impl pci::Driver for MyDriver {
/// type IdInfo = ();
/// const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
The code in the examples should be able to compile.
You can enable doctest by:
CONFIG_RUST_KERNEL_DOCTESTS=y
Then:
impl Device<device::Bound> {
/// Returns the Physical Function (PF) device for a Virtual
Function (VF) device. ///
/// # Examples
///
snip
/// ```
/// let pf_pdev = vf_pdev.physfn()?;
/// let pf_drvdata = pf_pdev.as_ref().drvdata::<MyDriver>()?;
I saw this part is not able to be compiled.^
Z.
> On Thu, Nov 20, 2025 at 08:32:13AM +0200, Zhi Wang wrote:
> > On Wed, 19 Nov 2025 17:19:04 -0500
> > Peter Colberg <pcolberg@redhat.com> wrote:
> >
> > Hi Peter:
> >
> > Thanks for the patches. :) I will test them with nova-core and come
> > back with Tested-bys.
>
> Perfect, thanks Zhi.
>
> > Nit: Let's use "kernel vertical" styles on imports. [1]
> >
> > [1]
> > https://lore.kernel.org/all/20251105120352.77603-1-dakr@kernel.org/
>
> Thanks, done for patch "samples: rust: add SR-IOV driver sample".
>
> Peter
>
> >
> > > 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
> > > unbind() callback. To ensure the guarantee is upheld, call
> > > disable_sriov() to remove all VF devices if the driver has not
> > > done so already.
> > >
> > > 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].
> > >
> > > 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 [3].
> > >
> > > [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://www.qemu.org/docs/master/system/devices/igb.html
> > >
> > > Signed-off-by: Peter Colberg <pcolberg@redhat.com>
> > > ---
> > > John Hubbard (1):
> > > rust: pci: add is_virtfn(), to check for VFs
> > >
> > > Peter Colberg (7):
> > > rust: pci: add is_physfn(), to check for PFs
> > > rust: pci: add {enable,disable}_sriov(), to control SR-IOV
> > > capability rust: pci: add num_vf(), to return number of VFs
> > > 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 physfn(), to return PF device
> > > for VF device samples: rust: add SR-IOV driver sample
> > >
> > > MAINTAINERS | 1 +
> > > rust/kernel/pci.rs | 148
> > > ++++++++++++++++++++++++++++++++++ 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 | 107
> > > ++++++++++++++++++++++++ 8 files changed, 271 insertions(+)
> > > ---
> > > base-commit: e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559
> > > change-id: 20251026-rust-pci-sriov-ca8f501b2ae3
> > >
> > > Best regards,
> >
>
>
^ permalink raw reply related [flat|nested] 31+ messages in thread* Re: [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability
2025-11-20 18:34 ` Zhi Wang
@ 2025-11-20 21:16 ` Zhi Wang
2025-11-21 17:05 ` Peter Colberg
1 sibling, 0 replies; 31+ messages in thread
From: Zhi Wang @ 2025-11-20 21:16 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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Jason Gunthorpe
On Thu, 20 Nov 2025 20:34:44 +0200
Zhi Wang <zhiw@nvidia.com> wrote:
I tested the patches on a L4, they are working perfectly. :) Though we
can't bootstrap a vGPU and actually poke the VF so far, but VF
enabling/disabling works without problem.
[ 97.447502] NovaCore 0000:b6:00.0: Enable SR-IOV (PCI ID: NVIDIA, 0x27b8).
[ 97.549467] pci 0000:b6:00.4: [10de:27b8] type 00 class 0x030200 PCIe Endpoint
[ 97.549499] pci 0000:b6:00.4: enabling Extended Tags
[ 97.549570] pci 0000:b6:00.4: Enabling HDA controller
[ 97.549894] pci 0000:b6:00.4: Adding to iommu group 88
[ 97.550649] NovaCore 0000:b6:00.4: enabling device (0000 -> 0002)
[ 97.550745] NovaCore 0000:b6:00.4: probe with driver NovaCore failed with error -22
[ 117.248723] NovaCore 0000:b6:00.0: Disable SR-IOV (PCI ID: NVIDIA, 0x27b8).
The repo I am using can be found here:
https://github.com/zhiwang-nvidia/nova-core/tree/rust-for-linux/test-sriov-on-nova-core
Will test them again on the next spin. :)
Z.
> On Thu, 20 Nov 2025 10:03:45 -0500
> Peter Colberg <pcolberg@redhat.com> wrote:
>
> Hi Peter:
>
> I met some errors when compiling on driver-core-next branch, you can
> fix those in the next spin.
>
> Fixes:
>
> diff --git a/drivers/gpu/nova-core/driver.rs
> b/drivers/gpu/nova-core/driver.rs index ca0d5f8ad54b..730e745cad63
> 100644 --- a/drivers/gpu/nova-core/driver.rs
> +++ b/drivers/gpu/nova-core/driver.rs
> @@ -49,6 +49,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 d6cc5d7e7cd7..2d68db076f92 100644
> --- a/rust/kernel/pci.rs
> +++ b/rust/kernel/pci.rs
> @@ -292,6 +292,7 @@ macro_rules! pci_device_table {
> /// ]
> /// );
> ///
> +/// #[vtable]
> /// impl pci::Driver for MyDriver {
> /// type IdInfo = ();
> /// const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
>
> The code in the examples should be able to compile.
>
> You can enable doctest by:
>
> CONFIG_RUST_KERNEL_DOCTESTS=y
>
> Then:
>
> impl Device<device::Bound> {
> /// Returns the Physical Function (PF) device for a Virtual
> Function (VF) device. ///
> /// # Examples
> ///
>
> snip
>
> /// ```
> /// let pf_pdev = vf_pdev.physfn()?;
> /// let pf_drvdata = pf_pdev.as_ref().drvdata::<MyDriver>()?;
>
> I saw this part is not able to be compiled.^
>
> Z.
>
> > On Thu, Nov 20, 2025 at 08:32:13AM +0200, Zhi Wang wrote:
> > > On Wed, 19 Nov 2025 17:19:04 -0500
> > > Peter Colberg <pcolberg@redhat.com> wrote:
> > >
> > > Hi Peter:
> > >
> > > Thanks for the patches. :) I will test them with nova-core and
> > > come back with Tested-bys.
> >
> > Perfect, thanks Zhi.
> >
> > > Nit: Let's use "kernel vertical" styles on imports. [1]
> > >
> > > [1]
> > > https://lore.kernel.org/all/20251105120352.77603-1-dakr@kernel.org/
> >
> > Thanks, done for patch "samples: rust: add SR-IOV driver sample".
> >
> > Peter
> >
> > >
> > > > 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
> > > > unbind() callback. To ensure the guarantee is upheld, call
> > > > disable_sriov() to remove all VF devices if the driver has not
> > > > done so already.
> > > >
> > > > 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].
> > > >
> > > > 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 [3].
> > > >
> > > > [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://www.qemu.org/docs/master/system/devices/igb.html
> > > >
> > > > Signed-off-by: Peter Colberg <pcolberg@redhat.com>
> > > > ---
> > > > John Hubbard (1):
> > > > rust: pci: add is_virtfn(), to check for VFs
> > > >
> > > > Peter Colberg (7):
> > > > rust: pci: add is_physfn(), to check for PFs
> > > > rust: pci: add {enable,disable}_sriov(), to control SR-IOV
> > > > capability rust: pci: add num_vf(), to return number of VFs
> > > > 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 physfn(), to return PF device
> > > > for VF device samples: rust: add SR-IOV driver sample
> > > >
> > > > MAINTAINERS | 1 +
> > > > rust/kernel/pci.rs | 148
> > > > ++++++++++++++++++++++++++++++++++ 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 | 107
> > > > ++++++++++++++++++++++++ 8 files changed, 271 insertions(+)
> > > > ---
> > > > base-commit: e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559
> > > > change-id: 20251026-rust-pci-sriov-ca8f501b2ae3
> > > >
> > > > Best regards,
> > >
> >
> >
>
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 0/8] rust: pci: add abstractions for SR-IOV capability
2025-11-20 18:34 ` Zhi Wang
2025-11-20 21:16 ` Zhi Wang
@ 2025-11-21 17:05 ` Peter Colberg
1 sibling, 0 replies; 31+ messages in thread
From: Peter Colberg @ 2025-11-21 17:05 UTC (permalink / raw)
To: Zhi Wang
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,
linux-pci, rust-for-linux, linux-kernel, Alexandre Courbot,
Alistair Popple, Joel Fernandes, John Hubbard, Jason Gunthorpe
On Thu, Nov 20, 2025 at 08:34:44PM +0200, Zhi Wang wrote:
> On Thu, 20 Nov 2025 10:03:45 -0500
> Peter Colberg <pcolberg@redhat.com> wrote:
>
> Hi Peter:
>
> I met some errors when compiling on driver-core-next branch, you can
> fix those in the next spin.
>
> Fixes:
>
> diff --git a/drivers/gpu/nova-core/driver.rs
> b/drivers/gpu/nova-core/driver.rs index ca0d5f8ad54b..730e745cad63
> 100644 --- a/drivers/gpu/nova-core/driver.rs
> +++ b/drivers/gpu/nova-core/driver.rs
> @@ -49,6 +49,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 d6cc5d7e7cd7..2d68db076f92 100644
> --- a/rust/kernel/pci.rs
> +++ b/rust/kernel/pci.rs
> @@ -292,6 +292,7 @@ macro_rules! pci_device_table {
> /// ]
> /// );
> ///
> +/// #[vtable]
> /// impl pci::Driver for MyDriver {
> /// type IdInfo = ();
> /// const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
>
> The code in the examples should be able to compile.
>
> You can enable doctest by:
>
> CONFIG_RUST_KERNEL_DOCTESTS=y
>
> Then:
>
> impl Device<device::Bound> {
> /// Returns the Physical Function (PF) device for a Virtual
> Function (VF) device. ///
> /// # Examples
> ///
>
> snip
>
> /// ```
> /// let pf_pdev = vf_pdev.physfn()?;
> /// let pf_drvdata = pf_pdev.as_ref().drvdata::<MyDriver>()?;
>
> I saw this part is not able to be compiled.^
Thanks Zhi, I applied all fixes.
Peter
>
> Z.
>
> > On Thu, Nov 20, 2025 at 08:32:13AM +0200, Zhi Wang wrote:
> > > On Wed, 19 Nov 2025 17:19:04 -0500
> > > Peter Colberg <pcolberg@redhat.com> wrote:
> > >
> > > Hi Peter:
> > >
> > > Thanks for the patches. :) I will test them with nova-core and come
> > > back with Tested-bys.
> >
> > Perfect, thanks Zhi.
> >
> > > Nit: Let's use "kernel vertical" styles on imports. [1]
> > >
> > > [1]
> > > https://lore.kernel.org/all/20251105120352.77603-1-dakr@kernel.org/
> >
> > Thanks, done for patch "samples: rust: add SR-IOV driver sample".
> >
> > Peter
> >
> > >
> > > > 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
> > > > unbind() callback. To ensure the guarantee is upheld, call
> > > > disable_sriov() to remove all VF devices if the driver has not
> > > > done so already.
> > > >
> > > > 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].
> > > >
> > > > 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 [3].
> > > >
> > > > [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://www.qemu.org/docs/master/system/devices/igb.html
> > > >
> > > > Signed-off-by: Peter Colberg <pcolberg@redhat.com>
> > > > ---
> > > > John Hubbard (1):
> > > > rust: pci: add is_virtfn(), to check for VFs
> > > >
> > > > Peter Colberg (7):
> > > > rust: pci: add is_physfn(), to check for PFs
> > > > rust: pci: add {enable,disable}_sriov(), to control SR-IOV
> > > > capability rust: pci: add num_vf(), to return number of VFs
> > > > 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 physfn(), to return PF device
> > > > for VF device samples: rust: add SR-IOV driver sample
> > > >
> > > > MAINTAINERS | 1 +
> > > > rust/kernel/pci.rs | 148
> > > > ++++++++++++++++++++++++++++++++++ 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 | 107
> > > > ++++++++++++++++++++++++ 8 files changed, 271 insertions(+)
> > > > ---
> > > > base-commit: e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559
> > > > change-id: 20251026-rust-pci-sriov-ca8f501b2ae3
> > > >
> > > > Best regards,
> > >
> >
> >
>
^ permalink raw reply [flat|nested] 31+ messages in thread