[PATCH v4 3/7] rust: pci: require an enable guard for `set_master()`
From: Maurice Hieronymus
Date: Wed Nov 04 2026 - 18:44:17 EST
Require a borrowed `DeviceEnableGuard` for the same device before enabling
bus-mastering. Check device identity so a guard for another device cannot
satisfy this requirement.
Keep `set_master()` on `Device<Core>` to retain callback synchronization:
the guard is shareable, while `pci_set_master()` modifies device state
without locking. Convert nova-core to pass its enable guard.
Link: https://lore.kernel.org/rust-for-linux/DLNQ5C9BTIAJ.1XEWLZ13TU1VF@xxxxxxxxxx
Suggested-by: Danilo Krummrich <dakr@xxxxxxxxxx>
Signed-off-by: Maurice Hieronymus <mhi@xxxxxxxxxxx>
---
drivers/gpu/nova-core/driver.rs | 2 +-
rust/kernel/pci.rs | 12 ++++++++++--
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs
index f0aebfe705ba..94f207c6078d 100644
--- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -107,7 +107,7 @@ fn probe<'bound>(
try_pin_init!(NovaCore {
_enable: {
let enable = pdev.enable_device()?;
- pdev.set_master();
+ pdev.set_master(&enable)?;
enable
},
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 75efd5c5ee97..20f45ca960cd 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -516,10 +516,18 @@ pub fn enable_device(&self) -> Result<DeviceEnableGuard<'_>> {
}
/// Enable bus-mastering for this device.
+ ///
+ /// Returns `EINVAL` if `enable` belongs to another device.
#[inline]
- pub fn set_master(&self) {
- // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`.
+ pub fn set_master(&self, enable: &DeviceEnableGuard<'_>) -> Result {
+ if self.as_raw() != enable.dev.as_raw() {
+ return Err(EINVAL);
+ }
+
+ // SAFETY: `self` is a valid device in core context, and `enable`
+ // keeps this device enabled for the duration of the call.
unsafe { bindings::pci_set_master(self.as_raw()) };
+ Ok(())
}
}
--
2.54.0