Linux PCI subsystem development
 help / color / mirror / Atom feed
* [PATCH v4 0/7] samples: rust: add an EDU PCI driver sample (MMIO + IRQ + DMA)
@ 2026-11-04 23:05 Maurice Hieronymus
  2026-11-04 23:05 ` [PATCH v4 1/7] samples: rust: remove the rust_driver_pci sample Maurice Hieronymus
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Maurice Hieronymus @ 2026-11-04 23:05 UTC (permalink / raw)
  To: Danilo Krummrich, Bjorn Helgaas, Krzysztof Wilczyński,
	Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
	Onur Özkan, Lyude Paul, David Airlie, Simona Vetter
  Cc: John Hubbard, linux-pci, rust-for-linux, linux-kernel, nova-gpu,
	dri-devel, Maurice Hieronymus

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.
The IRQ and DMA tests wait on a `Completion` signalled by the IRQ
handler; the factorial test polls for completion.

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: keep `set_master()` on `Device<Core>` and require a borrowed
  `DeviceEnableGuard` for the same device, preserving callback
  synchronization while ensuring the device is enabled.
- pci: add PCI_VENDOR_ID_QEMU (0x1234) to pci_ids.h and expose it as
  Vendor::QEMU, so the sample can match the device.
- 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.

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`.

Not taken from the v3 review (Sashiko):

- The IRQ and DMA completion waits remain unbounded; missing
  interrupts can block probe.
- enable_device() uses pci_enable_device(), not
  pci_enable_device_mem(): it is the single enable API Danilo proposed,
  and enabling I/O decoding is harmless for memory-only devices.

[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 v4:
- Drop "rust: pci: make Vendor::from_raw() public" (and its R-b tags);
  instead add PCI_VENDOR_ID_QEMU to pci_ids.h and expose it as
  Vendor::QEMU (new patches 4-5) (Alice, John).
- New patch: pci: require a borrowed enable guard for the same device
  in `set_master()`, retaining `Device<Core>` callback synchronization;
  convert nova-core. This enforces enabling before bus-mastering
  (Danilo) while addressing the concurrency concern (Sashiko).
- pci: mark DeviceEnableGuard #[must_use] and enable_device() #[inline]
  (Sashiko, Fiona).
- completion: reference complete() from wait_for_completion()'s docs
  (Gary).
- samples/edu: turn init() and the test helpers into methods on
  EduDriverData; rename init() to selftest() (Danilo).
- samples/edu: initialize EduDriverData in a single try_pin_init!(),
  holding the IRQ vectors and registering the handler with
  irq::Registration::new() instead of pci::Device::request_irq(); run
  selftest() via pin_chain() (Danilo).
- samples/edu: make the magic and DMA base constants local to their
  users; check the magic via an IDENTIFICATION constant (Danilo).
- samples/edu: describe the DMA and test IRQ bits as fields of
  IRQ_STATUS/IRQ_RAISE/IRQ_ACK instead of a DMA_IRQ constant (Danilo).
- samples/edu: model the DMA registers as a struct accessed through
  io_project!()/io_write!().
- samples/edu: compare the liveness pattern via a Not impl on
  LIVENESS_CHECK (Danilo).
- samples/edu: replace `as` casts with safe casts (Danilo).
- samples/edu: return IrqReturn::None for interrupts that are not ours
  (Sashiko).
- samples/edu: depend on 64BIT for the 64-bit MMIO accesses (Sashiko).
- samples/edu: expand the commit message and Kconfig help to describe
  the sample's coverage, QEMU usage and the 64BIT requirement; mention
  the MAINTAINERS entry in the commit message (Sashiko).
- samples/edu: ack stale interrupts before registering the handler
  (Sashiko).
- samples/edu: spell out why the IRQ Registration is not leaked (Ewan).
- Drop the dependency on Danilo's irq Registration rework [2], now in
  mainline.
- Rebase on rust-next; adapt to register!() `base:`, Option<&IdInfo>
  in probe() and the Coherent read_val()/write_val() API.
- Link to v3: https://lore.kernel.org/r/20260812-b4-rust-pci-edu-driver-v3-0-5d0b5594e52b@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 (7):
      samples: rust: remove the rust_driver_pci sample
      rust: pci: rework device enabling API
      rust: pci: require an enable guard for `set_master()`
      PCI: Add QEMU vendor ID
      rust: pci: add Vendor::QEMU
      rust: completion: add complete()
      samples: rust: add EDU PCI driver sample

 MAINTAINERS                     |   2 +-
 drivers/gpu/nova-core/driver.rs |   9 +-
 include/linux/pci_ids.h         |   2 +
 rust/kernel/pci.rs              |  45 +++-
 rust/kernel/pci/id.rs           |   1 +
 rust/kernel/sync/completion.rs  |  13 +-
 samples/rust/Kconfig            |  14 +-
 samples/rust/Makefile           |   2 +-
 samples/rust/rust_driver_edu.rs | 475 ++++++++++++++++++++++++++++++++++++++++
 samples/rust/rust_driver_pci.rs | 198 -----------------
 10 files changed, 547 insertions(+), 214 deletions(-)
---
base-commit: d89e1d186ec9271bf78e62771779e9fc03bf0fc3
change-id: 20260614-b4-rust-pci-edu-driver-3e50db2dda0f

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


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

end of thread, other threads:[~2026-11-04 23:14 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 23:05 [PATCH v4 0/7] samples: rust: add an EDU PCI driver sample (MMIO + IRQ + DMA) Maurice Hieronymus
2026-11-04 23:05 ` [PATCH v4 1/7] samples: rust: remove the rust_driver_pci sample Maurice Hieronymus
2026-11-04 23:09   ` sashiko-bot
2026-11-04 23:05 ` [PATCH v4 2/7] rust: pci: rework device enabling API Maurice Hieronymus
2026-11-04 23:14   ` sashiko-bot
2026-11-04 23:05 ` [PATCH v4 3/7] rust: pci: require an enable guard for `set_master()` Maurice Hieronymus
2026-11-04 23:11   ` sashiko-bot
2026-11-04 23:05 ` [PATCH v4 4/7] PCI: Add QEMU vendor ID Maurice Hieronymus
2026-11-04 23:09   ` sashiko-bot
2026-11-04 23:05 ` [PATCH v4 5/7] rust: pci: add Vendor::QEMU Maurice Hieronymus
2026-11-04 23:09   ` sashiko-bot
2026-11-04 23:05 ` [PATCH v4 6/7] rust: completion: add complete() Maurice Hieronymus
2026-11-04 23:11   ` sashiko-bot
2026-11-04 23:05 ` [PATCH v4 7/7] samples: rust: add EDU PCI driver sample Maurice Hieronymus
2026-11-04 23:14   ` sashiko-bot

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