From 96609a1969f4ade45351ec368c65580c77592e8b Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Mon, 14 Apr 2025 15:18:08 +0200 Subject: samples: rust: add Rust auxiliary driver sample Add a sample Rust auxiliary driver based on a PCI driver for QEMU's "pci-testdev" device. The PCI driver only registers an auxiliary device, in order to make the corresponding auxiliary driver probe. Acked-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20250414131934.28418-6-dakr@kernel.org [ Use `ok_or()` when accessing auxiliary::Device::parent(). - Danilo ] Signed-off-by: Danilo Krummrich --- samples/rust/Kconfig | 12 ++++ samples/rust/Makefile | 1 + samples/rust/rust_driver_auxiliary.rs | 120 ++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 samples/rust/rust_driver_auxiliary.rs (limited to 'samples') diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig index cad52b7120b5..43cb72d72631 100644 --- a/samples/rust/Kconfig +++ b/samples/rust/Kconfig @@ -82,6 +82,18 @@ config SAMPLE_RUST_DRIVER_FAUX If unsure, say N. +config SAMPLE_RUST_DRIVER_AUXILIARY + tristate "Auxiliary Driver" + depends on AUXILIARY_BUS + depends on PCI + help + This option builds the Rust auxiliary driver sample. + + To compile this as a module, choose M here: + the module will be called rust_driver_auxiliary. + + If unsure, say N. + config SAMPLE_RUST_HOSTPROGS bool "Host programs" help diff --git a/samples/rust/Makefile b/samples/rust/Makefile index c6a2479f7d9c..6a466afd2a21 100644 --- a/samples/rust/Makefile +++ b/samples/rust/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_SAMPLE_RUST_DMA) += rust_dma.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_FAUX) += rust_driver_faux.o +obj-$(CONFIG_SAMPLE_RUST_DRIVER_AUXILIARY) += rust_driver_auxiliary.o rust_print-y := rust_print_main.o rust_print_events.o diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs new file mode 100644 index 000000000000..3e15e6d002bb --- /dev/null +++ b/samples/rust/rust_driver_auxiliary.rs @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Rust auxiliary driver sample (based on a PCI driver for QEMU's `pci-testdev`). +//! +//! To make this driver probe, QEMU must be run with `-device pci-testdev`. + +use kernel::{ + auxiliary, bindings, c_str, device::Core, driver, error::Error, pci, prelude::*, str::CStr, + InPlaceModule, +}; + +use pin_init::PinInit; + +const MODULE_NAME: &CStr = ::NAME; +const AUXILIARY_NAME: &CStr = c_str!("auxiliary"); + +struct AuxiliaryDriver; + +kernel::auxiliary_device_table!( + AUX_TABLE, + MODULE_AUX_TABLE, + ::IdInfo, + [(auxiliary::DeviceId::new(MODULE_NAME, AUXILIARY_NAME), ())] +); + +impl auxiliary::Driver for AuxiliaryDriver { + type IdInfo = (); + + const ID_TABLE: auxiliary::IdTable = &AUX_TABLE; + + fn probe(adev: &auxiliary::Device, _info: &Self::IdInfo) -> Result>> { + dev_info!( + adev.as_ref(), + "Probing auxiliary driver for auxiliary device with id={}\n", + adev.id() + ); + + ParentDriver::connect(adev)?; + + let this = KBox::new(Self, GFP_KERNEL)?; + + Ok(this.into()) + } +} + +struct ParentDriver { + _reg: [auxiliary::Registration; 2], +} + +kernel::pci_device_table!( + PCI_TABLE, + MODULE_PCI_TABLE, + ::IdInfo, + [( + pci::DeviceId::from_id(bindings::PCI_VENDOR_ID_REDHAT, 0x5), + () + )] +); + +impl pci::Driver for ParentDriver { + type IdInfo = (); + + const ID_TABLE: pci::IdTable = &PCI_TABLE; + + fn probe(pdev: &pci::Device, _info: &Self::IdInfo) -> Result>> { + let this = KBox::new( + Self { + _reg: [ + auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 0, MODULE_NAME)?, + auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 1, MODULE_NAME)?, + ], + }, + GFP_KERNEL, + )?; + + Ok(this.into()) + } +} + +impl ParentDriver { + fn connect(adev: &auxiliary::Device) -> Result<()> { + let parent = adev.parent().ok_or(EINVAL)?; + let pdev: &pci::Device = parent.try_into()?; + + dev_info!( + adev.as_ref(), + "Connect auxiliary {} with parent: VendorID={:#x}, DeviceID={:#x}\n", + adev.id(), + pdev.vendor_id(), + pdev.device_id() + ); + + Ok(()) + } +} + +#[pin_data] +struct SampleModule { + #[pin] + _pci_driver: driver::Registration>, + #[pin] + _aux_driver: driver::Registration>, +} + +impl InPlaceModule for SampleModule { + fn init(module: &'static kernel::ThisModule) -> impl PinInit { + try_pin_init!(Self { + _pci_driver <- driver::Registration::new(MODULE_NAME, module), + _aux_driver <- driver::Registration::new(MODULE_NAME, module), + }) + } +} + +module! { + type: SampleModule, + name: "rust_driver_auxiliary", + author: "Danilo Krummrich", + description: "Rust auxiliary driver", + license: "GPL v2", +} -- cgit v1.2.3-59-g8ed1b From 0c848b3adb45acc1722f94333e2a97bf1720e431 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Fri, 11 Apr 2025 21:09:39 +0900 Subject: samples: rust: convert PCI rust sample driver to use try_access_with() This method limits the scope of the revocable guard and is considered safer to use for most cases, so let's showcase it here. Reviewed-by: Benno Lossin Signed-off-by: Alexandre Courbot Acked-by: Miguel Ojeda Link: https://lore.kernel.org/r/20250411-try_with-v4-2-f470ac79e2e2@nvidia.com Signed-off-by: Danilo Krummrich --- samples/rust/rust_driver_pci.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'samples') diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs index 2bb260aebc9e..9ce3a7323a16 100644 --- a/samples/rust/rust_driver_pci.rs +++ b/samples/rust/rust_driver_pci.rs @@ -83,13 +83,12 @@ impl pci::Driver for SampleDriver { GFP_KERNEL, )?; - let bar = drvdata.bar.try_access().ok_or(ENXIO)?; + let res = drvdata + .bar + .try_access_with(|b| Self::testdev(info, b)) + .ok_or(ENXIO)??; - dev_info!( - pdev.as_ref(), - "pci-testdev data-match count: {}\n", - Self::testdev(info, &bar)? - ); + dev_info!(pdev.as_ref(), "pci-testdev data-match count: {}\n", res); Ok(drvdata.into()) } -- cgit v1.2.3-59-g8ed1b From b75a99e1077b12c5631fef7ac36970a89f6021f7 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Mon, 28 Apr 2025 16:00:29 +0200 Subject: samples: rust: pci: take advantage of Devres::access() For the I/O operations executed from the probe() method, take advantage of Devres::access(), avoiding the atomic check and RCU read lock required otherwise entirely. Reviewed-by: Alexandre Courbot Acked-by: Boqun Feng Reviewed-by: Joel Fernandes Link: https://lore.kernel.org/r/20250428140137.468709-4-dakr@kernel.org Signed-off-by: Danilo Krummrich --- samples/rust/rust_driver_pci.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'samples') diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs index 9ce3a7323a16..15147e4401b2 100644 --- a/samples/rust/rust_driver_pci.rs +++ b/samples/rust/rust_driver_pci.rs @@ -83,12 +83,12 @@ impl pci::Driver for SampleDriver { GFP_KERNEL, )?; - let res = drvdata - .bar - .try_access_with(|b| Self::testdev(info, b)) - .ok_or(ENXIO)??; - - dev_info!(pdev.as_ref(), "pci-testdev data-match count: {}\n", res); + let bar = drvdata.bar.access(pdev.as_ref())?; + dev_info!( + pdev.as_ref(), + "pci-testdev data-match count: {}\n", + Self::testdev(info, bar)? + ); Ok(drvdata.into()) } -- cgit v1.2.3-59-g8ed1b From 80a8bcc65290bc95c11accd875fb3dd19fc7287e Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Thu, 15 May 2025 17:23:18 +0900 Subject: samples: rust: select AUXILIARY_BUS instead of depending on it CONFIG_AUXILIARY_BUS cannot be enabled explicitly, and unless we select it we have no way to include it (and thus to enable the auxiliary driver sample) unless a driver happens to do it for us. Fixes: 96609a1969f4 ("samples: rust: add Rust auxiliary driver sample") Reviewed-by: Greg Kroah-Hartman Signed-off-by: Alexandre Courbot Link: https://lore.kernel.org/r/20250515-aux_bus-v2-1-47c70f96ae9b@nvidia.com Signed-off-by: Danilo Krummrich --- samples/rust/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'samples') diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig index 43cb72d72631..b1006ab4bc3c 100644 --- a/samples/rust/Kconfig +++ b/samples/rust/Kconfig @@ -84,8 +84,8 @@ config SAMPLE_RUST_DRIVER_FAUX config SAMPLE_RUST_DRIVER_AUXILIARY tristate "Auxiliary Driver" - depends on AUXILIARY_BUS depends on PCI + select AUXILIARY_BUS help This option builds the Rust auxiliary driver sample. -- cgit v1.2.3-59-g8ed1b