[PATCH v3 0/5] rust: samples: add an EDU PCI driver sample (MMIO + IRQ + DMA)

Maurice Hieronymus posted 5 patches 1 month, 2 weeks ago
MAINTAINERS                     |   2 +-
drivers/gpu/nova-core/driver.rs |   5 +-
rust/kernel/pci.rs              |  31 ++-
rust/kernel/pci/id.rs           |   2 +-
rust/kernel/sync/completion.rs  |  11 ++
samples/rust/Kconfig            |   8 +-
samples/rust/Makefile           |   2 +-
samples/rust/rust_driver_edu.rs | 421 ++++++++++++++++++++++++++++++++++++++++
samples/rust/rust_driver_pci.rs | 194 ------------------
9 files changed, 471 insertions(+), 205 deletions(-)
[PATCH v3 0/5] rust: samples: add an EDU PCI driver sample (MMIO + IRQ + DMA)
Posted by Maurice Hieronymus 1 month, 2 weeks ago
The Rust sample drivers currently exercise PCI facilities in isolation:
rust_driver_pci covers MMIO and rust_dma covers DMA, but there is no
single in-tree example that combines memory-mapped I/O, interrupts and
DMA in one driver.

This series adds one. It targets QEMU's `edu` device -- a small,
well-documented educational PCI device that supports exactly these three
facilities and ships with any recent QEMU (`-device edu`), so the sample
runs without special hardware.

The sample maps BAR0, reads the PCI configuration space, and runs a set
of MMIO self-tests (identification, liveness, factorial), allocates an
MSI vector and registers an IRQ handler, and performs a DMA round-trip
-- each stage waiting on a Completion that the IRQ handler signals.

As requested by Danilo in the v2 review, the sample replaces
rust_driver_pci, which it covers a superset of; the removal is the
first patch.

Prerequisites, that had to be implemented:

- pci: rework the device enabling API: replace enable_device_mem()
  with enable_device(), which returns a DeviceEnableGuard that
  disables the device again on drop, so the enable count stays
  balanced across unbind/rebind. This follows the design Danilo
  proposed in the review of the standalone patch [1], which this
  series absorbs.
- pci: make Vendor::from_raw() public, so a driver can match a device
  whose vendor ID has no symbolic name in pci_ids.h (QEMU's 0x1234),
  matching what C drivers already do.
- completion: add complete(), so a single Completion can be reused to
  wait for consecutive events (e.g. back-to-back DMA transfers).

The series is based on rust/rust-next and additionally depends on
Danilo's "rust: irq: make Registration compatible with lifetime-bound
drivers" [2], currently in linux-next.

Note: DeviceEnableGuard drops from a bound scope, so pci_disable_device()
can race the pci_dev bitfield word as discussed in [1]; that race
predates this series and is triggerable from sysfs today. The bitops
conversion is under way separately on linux-pci [3].

Tested with QEMU `-device edu`;

[1] https://lore.kernel.org/rust-for-linux/DJOEYVBS17MJ.1YD3TNGQBWHNK@kernel.org
[2] https://lore.kernel.org/r/20260719153631.559341-1-dakr@kernel.org
[3] https://lore.kernel.org/linux-pci/20260714-pci-dev-flags-v2-1-a1d7dc441cf3@mailbox.org/

Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
Changes in v3:
- Absorb the device enabling rework [1] into this series, redesigned
  around DeviceEnableGuard as proposed by Danilo; convert nova-core.
- Remove rust_driver_pci, replaced by this sample (Danilo).
- Add access to PCI configuration space (Danilo).
- Rebase on rust/rust-next on top of Danilo's irq Registration rework
  [2]; register the handler via pci::Device::request_irq().
- Use vertical import style.
- Link to v2: https://lore.kernel.org/r/20260620-b4-rust-pci-edu-driver-v2-0-6fd6684f2c14@mailbox.org

Changes in v2:
- pci: Vendor::from_raw(): collected Reviewed-by from Gary Guo;
  wrapped code identifiers in the commit message in backticks (Gary).
- pci: enable_device(): collected Reviewed-by from Fiona Behrens;
  made enable_device_mem() #[inline] and added a cross-reference to
  enable_device() in its docs (Fiona).
- completion: complete(): tightened the doc comment per Gary's review
  (emphasise "single", drop the internal-counter detail, drop the
  complete_all comparison).
- samples/edu: take &EduDriverData instead of &Arc<EduDriverData> in
  init()/test_irq()/test_dma() (Ewan Chorynski).
- samples/edu: simplify wait_until_compute_has_finished() to forward
  read_poll_timeout()'s error via inspect_err() instead of returning a
  hard-coded ETIMEDOUT (Ewan Chorynski / Miguel Ojeda).
- samples/edu: Rebased on rust/rust-next and adapt to the updated
  pci::Bar / device::Core lifetimes and pci::Driver::Data<'bound>, and
  obtain the BAR via into_devres().
- Link to v1: https://lore.kernel.org/r/20260614-b4-rust-pci-edu-driver-v1-0-e3f2471b595c@mailbox.org

---
Maurice Hieronymus (5):
      samples: rust: remove the rust_driver_pci sample
      rust: pci: rework device enabling API
      rust: pci: make Vendor::from_raw() public
      rust: completion: add complete()
      rust: samples: add EDU PCI driver sample

 MAINTAINERS                     |   2 +-
 drivers/gpu/nova-core/driver.rs |   5 +-
 rust/kernel/pci.rs              |  31 ++-
 rust/kernel/pci/id.rs           |   2 +-
 rust/kernel/sync/completion.rs  |  11 ++
 samples/rust/Kconfig            |   8 +-
 samples/rust/Makefile           |   2 +-
 samples/rust/rust_driver_edu.rs | 421 ++++++++++++++++++++++++++++++++++++++++
 samples/rust/rust_driver_pci.rs | 194 ------------------
 9 files changed, 471 insertions(+), 205 deletions(-)
---
base-commit: 643a7c306b8ce32743d4f94dd700c8588be37e66
change-id: 20260614-b4-rust-pci-edu-driver-3e50db2dda0f
prerequisite-message-id: <20260719153631.559341-1-dakr@kernel.org>
prerequisite-patch-id: 63224325d5ec73f06517bb35f8c366a086bbea19

Best regards,
-- 
Maurice Hieronymus <mhi@mailbox.org>