* [PATCH 0/9] Implement "Bound" device context
@ 2025-03-31 20:27 Danilo Krummrich
2025-03-31 20:27 ` [PATCH 1/9] rust: device: implement impl_device_context_deref! Danilo Krummrich
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Danilo Krummrich @ 2025-03-31 20:27 UTC (permalink / raw)
To: bhelgaas, gregkh, rafael, abdiel.janulgue
Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin,
a.hindborg, aliceryhl, tmgross, daniel.almeida, robin.murphy,
linux-pci, rust-for-linux, linux-kernel, Danilo Krummrich
Currently, we do not ensure that APIs that require a bound device instance can
only be called with a bound device.
Examples of such APIs are Devres, dma::CoherentAllocation and
pci::Device::iomap_region().
This patch series introduces the "Bound" device context such that we can ensure
to only ever pass a bound device to APIs that require this precondition.
In order to get there, we need some prerequisites:
(1) Implement macros to consistently derive Deref implementations for the
different device contexts. For instance, Device<Core> can be dereferenced to
Device<Bound>, since all device references we get from "core" bus callbacks
are guaranteed to be from a bound device. Device<Bound> can always be
dereferenced to Device (i.e. Device<Normal>), since the "Normal" device
context has no specific requirements.
(2) Implement device context support for the generic Device type. Some APIs such
as Devres and dma::CoherentAllocation work with generic devices.
(3) Preserve device context generics in bus specific device' AsRef
implementation, such that we can derive the device context when converting
from a bus specific device reference to a generic device reference.
With this, Devres::new(), for instance, can take a &Device<Bound> argument and
hence ensure that it can't be called with a Device reference that is not
guaranteed to be bound to a driver.
This patch series is based on driver-core-next (with rust-next merged into it);
a branch containing the commits can be found in [1]. It is targeting v6.16-rc1.
[1] https://web.git.kernel.org/pub/scm/linux/kernel/git/dakr/linux.git/log/?h=rust/device-bound
Danilo Krummrich (9):
rust: device: implement impl_device_context_deref!
rust: device: implement impl_device_context_into_aref!
rust: device: implement device context for Device
rust: platform: preserve device context in AsRef
rust: pci: preserve device context in AsRef
rust: device: implement Bound device context
rust: pci: move iomap_region() to impl Device<Bound>
rust: devres: require a bound device
rust: dma: require a bound device
rust/kernel/device.rs | 71 +++++++++++++++++++++++++++++++++++++++--
rust/kernel/devres.rs | 17 ++++------
rust/kernel/dma.rs | 14 ++++----
rust/kernel/pci.rs | 31 ++++++------------
rust/kernel/platform.rs | 30 ++++-------------
5 files changed, 98 insertions(+), 65 deletions(-)
--
2.49.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/9] rust: device: implement impl_device_context_deref!
2025-03-31 20:27 [PATCH 0/9] Implement "Bound" device context Danilo Krummrich
@ 2025-03-31 20:27 ` Danilo Krummrich
2025-03-31 20:27 ` [PATCH 2/9] rust: device: implement impl_device_context_into_aref! Danilo Krummrich
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2025-03-31 20:27 UTC (permalink / raw)
To: bhelgaas, gregkh, rafael, abdiel.janulgue
Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin,
a.hindborg, aliceryhl, tmgross, daniel.almeida, robin.murphy,
linux-pci, rust-for-linux, linux-kernel, Danilo Krummrich
The Deref hierarchy for device context generics is the same for every
(bus specific) device.
Implement those with a generic macro to avoid duplicated boiler plate
code and ensure the correct Deref hierarchy for every device
implementation.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/device.rs | 29 +++++++++++++++++++++++++++++
rust/kernel/pci.rs | 14 +-------------
rust/kernel/platform.rs | 15 +--------------
3 files changed, 31 insertions(+), 27 deletions(-)
diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index 21b343a1dc4d..e3ab8980270e 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -235,6 +235,35 @@ impl Sealed for super::Normal {}
impl DeviceContext for Core {}
impl DeviceContext for Normal {}
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __impl_device_context_deref {
+ ($src:ty, $dst:ty, $device:tt) => {
+ impl core::ops::Deref for $device<$src> {
+ type Target = $device<$dst>;
+
+ fn deref(&self) -> &Self::Target {
+ let ptr: *const Self = self;
+
+ // CAST: `Device<Ctx: DeviceContext>` types are transparent to each other.
+ let ptr = ptr.cast::<Self::Target>();
+
+ // SAFETY: `ptr` was derived from `&self`.
+ unsafe { &*ptr }
+ }
+ }
+ };
+}
+
+/// Implement [`core::ops::Deref`] traits for allowed [`DeviceContext`] conversions of a (bus
+/// specific) device.
+#[macro_export]
+macro_rules! impl_device_context_deref {
+ ($device:tt) => {
+ kernel::__impl_device_context_deref!($crate::device::Core, $crate::device::Normal, $device);
+ };
+}
+
#[doc(hidden)]
#[macro_export]
macro_rules! dev_printk {
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index c97d6d470b28..0e735409bfc4 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -422,19 +422,7 @@ pub fn set_master(&self) {
}
}
-impl Deref for Device<device::Core> {
- type Target = Device;
-
- fn deref(&self) -> &Self::Target {
- let ptr: *const Self = self;
-
- // CAST: `Device<Ctx>` is a transparent wrapper of `Opaque<bindings::pci_dev>`.
- let ptr = ptr.cast::<Device>();
-
- // SAFETY: `ptr` was derived from `&self`.
- unsafe { &*ptr }
- }
-}
+kernel::impl_device_context_deref!(Device);
impl From<&Device<device::Core>> for ARef<Device> {
fn from(dev: &Device<device::Core>) -> Self {
diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
index 4917cb34e2fe..9268e1edca9b 100644
--- a/rust/kernel/platform.rs
+++ b/rust/kernel/platform.rs
@@ -16,7 +16,6 @@
use core::{
marker::PhantomData,
- ops::Deref,
ptr::{addr_of_mut, NonNull},
};
@@ -190,19 +189,7 @@ fn as_raw(&self) -> *mut bindings::platform_device {
}
}
-impl Deref for Device<device::Core> {
- type Target = Device;
-
- fn deref(&self) -> &Self::Target {
- let ptr: *const Self = self;
-
- // CAST: `Device<Ctx>` is a transparent wrapper of `Opaque<bindings::platform_device>`.
- let ptr = ptr.cast::<Device>();
-
- // SAFETY: `ptr` was derived from `&self`.
- unsafe { &*ptr }
- }
-}
+kernel::impl_device_context_deref!(Device);
impl From<&Device<device::Core>> for ARef<Device> {
fn from(dev: &Device<device::Core>) -> Self {
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/9] rust: device: implement impl_device_context_into_aref!
2025-03-31 20:27 [PATCH 0/9] Implement "Bound" device context Danilo Krummrich
2025-03-31 20:27 ` [PATCH 1/9] rust: device: implement impl_device_context_deref! Danilo Krummrich
@ 2025-03-31 20:27 ` Danilo Krummrich
2025-03-31 20:27 ` [PATCH 3/9] rust: device: implement device context for Device Danilo Krummrich
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2025-03-31 20:27 UTC (permalink / raw)
To: bhelgaas, gregkh, rafael, abdiel.janulgue
Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin,
a.hindborg, aliceryhl, tmgross, daniel.almeida, robin.murphy,
linux-pci, rust-for-linux, linux-kernel, Danilo Krummrich
Implement a macro to implement all From conversions of a certain device
to ARef<Device>.
This avoids unnecessary boiler plate code for every device
implementation.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/device.rs | 21 +++++++++++++++++++++
rust/kernel/pci.rs | 7 +------
rust/kernel/platform.rs | 9 ++-------
3 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index e3ab8980270e..68652ba62b02 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -264,6 +264,27 @@ macro_rules! impl_device_context_deref {
};
}
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __impl_device_context_into_aref {
+ ($src:ty, $device:tt) => {
+ impl core::convert::From<&$device<$src>> for $crate::types::ARef<$device> {
+ fn from(dev: &$device<$src>) -> Self {
+ (&**dev).into()
+ }
+ }
+ };
+}
+
+/// Implement [`core::convert::From`], such that all `&Device<Ctx>` can be converted to an
+/// `ARef<Device>`.
+#[macro_export]
+macro_rules! impl_device_context_into_aref {
+ ($device:tt) => {
+ kernel::__impl_device_context_into_aref!($crate::device::Core, $device);
+ };
+}
+
#[doc(hidden)]
#[macro_export]
macro_rules! dev_printk {
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 0e735409bfc4..e235aa23c63a 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -423,12 +423,7 @@ pub fn set_master(&self) {
}
kernel::impl_device_context_deref!(Device);
-
-impl From<&Device<device::Core>> for ARef<Device> {
- fn from(dev: &Device<device::Core>) -> Self {
- (&**dev).into()
- }
-}
+kernel::impl_device_context_into_aref!(Device);
// SAFETY: Instances of `Device` are always reference-counted.
unsafe impl crate::types::AlwaysRefCounted for Device {
diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
index 9268e1edca9b..9133490ea4c9 100644
--- a/rust/kernel/platform.rs
+++ b/rust/kernel/platform.rs
@@ -10,7 +10,7 @@
of,
prelude::*,
str::CStr,
- types::{ARef, ForeignOwnable, Opaque},
+ types::{ForeignOwnable, Opaque},
ThisModule,
};
@@ -190,12 +190,7 @@ fn as_raw(&self) -> *mut bindings::platform_device {
}
kernel::impl_device_context_deref!(Device);
-
-impl From<&Device<device::Core>> for ARef<Device> {
- fn from(dev: &Device<device::Core>) -> Self {
- (&**dev).into()
- }
-}
+kernel::impl_device_context_into_aref!(Device);
// SAFETY: Instances of `Device` are always reference-counted.
unsafe impl crate::types::AlwaysRefCounted for Device {
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/9] rust: device: implement device context for Device
2025-03-31 20:27 [PATCH 0/9] Implement "Bound" device context Danilo Krummrich
2025-03-31 20:27 ` [PATCH 1/9] rust: device: implement impl_device_context_deref! Danilo Krummrich
2025-03-31 20:27 ` [PATCH 2/9] rust: device: implement impl_device_context_into_aref! Danilo Krummrich
@ 2025-03-31 20:27 ` Danilo Krummrich
2025-03-31 20:27 ` [PATCH 4/9] rust: platform: preserve device context in AsRef Danilo Krummrich
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2025-03-31 20:27 UTC (permalink / raw)
To: bhelgaas, gregkh, rafael, abdiel.janulgue
Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin,
a.hindborg, aliceryhl, tmgross, daniel.almeida, robin.murphy,
linux-pci, rust-for-linux, linux-kernel, Danilo Krummrich
Analogous to bus specific device, implement the DeviceContext generic
for generic devices.
This is used for APIs that work with generic devices (such as Devres) to
evaluate the device' context.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/device.rs | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index 68652ba62b02..2d98e650376e 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -9,7 +9,7 @@
str::CStr,
types::{ARef, Opaque},
};
-use core::{fmt, ptr};
+use core::{fmt, marker::PhantomData, ptr};
#[cfg(CONFIG_PRINTK)]
use crate::c_str;
@@ -42,7 +42,7 @@
/// `bindings::device::release` is valid to be called from any thread, hence `ARef<Device>` can be
/// dropped from any thread.
#[repr(transparent)]
-pub struct Device(Opaque<bindings::device>);
+pub struct Device<Ctx: DeviceContext = Normal>(Opaque<bindings::device>, PhantomData<Ctx>);
impl Device {
/// Creates a new reference-counted abstraction instance of an existing `struct device` pointer.
@@ -59,7 +59,9 @@ pub unsafe fn get_device(ptr: *mut bindings::device) -> ARef<Self> {
// SAFETY: By the safety requirements ptr is valid
unsafe { Self::as_ref(ptr) }.into()
}
+}
+impl<Ctx: DeviceContext> Device<Ctx> {
/// Obtain the raw `struct device *`.
pub(crate) fn as_raw(&self) -> *mut bindings::device {
self.0.get()
@@ -189,6 +191,9 @@ pub fn property_present(&self, name: &CStr) -> bool {
}
}
+kernel::impl_device_context_deref!(Device);
+kernel::impl_device_context_into_aref!(Device);
+
// SAFETY: Instances of `Device` are always reference-counted.
unsafe impl crate::types::AlwaysRefCounted for Device {
fn inc_ref(&self) {
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/9] rust: platform: preserve device context in AsRef
2025-03-31 20:27 [PATCH 0/9] Implement "Bound" device context Danilo Krummrich
` (2 preceding siblings ...)
2025-03-31 20:27 ` [PATCH 3/9] rust: device: implement device context for Device Danilo Krummrich
@ 2025-03-31 20:27 ` Danilo Krummrich
2025-03-31 20:27 ` [PATCH 5/9] rust: pci: " Danilo Krummrich
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2025-03-31 20:27 UTC (permalink / raw)
To: bhelgaas, gregkh, rafael, abdiel.janulgue
Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin,
a.hindborg, aliceryhl, tmgross, daniel.almeida, robin.murphy,
linux-pci, rust-for-linux, linux-kernel, Danilo Krummrich
Since device::Device has a generic over its context, preserve this
device context in AsRef.
For instance, when calling platform::Device<Core> the new AsRef
implementation returns device::Device<Core>.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/platform.rs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
index 9133490ea4c9..fa07f895af3a 100644
--- a/rust/kernel/platform.rs
+++ b/rust/kernel/platform.rs
@@ -183,7 +183,7 @@ pub struct Device<Ctx: device::DeviceContext = device::Normal>(
PhantomData<Ctx>,
);
-impl Device {
+impl<Ctx: device::DeviceContext> Device<Ctx> {
fn as_raw(&self) -> *mut bindings::platform_device {
self.0.get()
}
@@ -205,8 +205,8 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
-impl AsRef<device::Device> for Device {
- fn as_ref(&self) -> &device::Device {
+impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
+ fn as_ref(&self) -> &device::Device<Ctx> {
// SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
// `struct platform_device`.
let dev = unsafe { addr_of_mut!((*self.as_raw()).dev) };
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/9] rust: pci: preserve device context in AsRef
2025-03-31 20:27 [PATCH 0/9] Implement "Bound" device context Danilo Krummrich
` (3 preceding siblings ...)
2025-03-31 20:27 ` [PATCH 4/9] rust: platform: preserve device context in AsRef Danilo Krummrich
@ 2025-03-31 20:27 ` Danilo Krummrich
2025-03-31 20:27 ` [PATCH 6/9] rust: device: implement Bound device context Danilo Krummrich
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2025-03-31 20:27 UTC (permalink / raw)
To: bhelgaas, gregkh, rafael, abdiel.janulgue
Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin,
a.hindborg, aliceryhl, tmgross, daniel.almeida, robin.murphy,
linux-pci, rust-for-linux, linux-kernel, Danilo Krummrich
Since device::Device has a generic over its context, preserve this
device context in AsRef.
For instance, when calling pci::Device<Core> the new AsRef implementation
returns device::Device<Core>.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/pci.rs | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index e235aa23c63a..de140cce13cf 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -360,11 +360,13 @@ fn deref(&self) -> &Self::Target {
}
}
-impl Device {
+impl<Ctx: device::DeviceContext> Device<Ctx> {
fn as_raw(&self) -> *mut bindings::pci_dev {
self.0.get()
}
+}
+impl Device {
/// Returns the PCI vendor ID.
pub fn vendor_id(&self) -> u16 {
// SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`.
@@ -438,8 +440,8 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
-impl AsRef<device::Device> for Device {
- fn as_ref(&self) -> &device::Device {
+impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
+ fn as_ref(&self) -> &device::Device<Ctx> {
// SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
// `struct pci_dev`.
let dev = unsafe { addr_of_mut!((*self.as_raw()).dev) };
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/9] rust: device: implement Bound device context
2025-03-31 20:27 [PATCH 0/9] Implement "Bound" device context Danilo Krummrich
` (4 preceding siblings ...)
2025-03-31 20:27 ` [PATCH 5/9] rust: pci: " Danilo Krummrich
@ 2025-03-31 20:27 ` Danilo Krummrich
2025-03-31 20:28 ` [PATCH 7/9] rust: pci: move iomap_region() to impl Device<Bound> Danilo Krummrich
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2025-03-31 20:27 UTC (permalink / raw)
To: bhelgaas, gregkh, rafael, abdiel.janulgue
Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin,
a.hindborg, aliceryhl, tmgross, daniel.almeida, robin.murphy,
linux-pci, rust-for-linux, linux-kernel, Danilo Krummrich
The Bound device context indicates that a device is bound to a driver.
It must be used for APIs that require the device to be bound, such as
Devres or dma::CoherentAllocation.
Implement Bound and add the corresponding Deref hierarchy, as well as the
corresponding ARef conversion for this device context.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/device.rs | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index 2d98e650376e..a7da1519439d 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -230,13 +230,19 @@ pub trait DeviceContext: private::Sealed {}
/// any of the bus callbacks, such as `probe()`.
pub struct Core;
+/// The [`Bound`] context is the context of a bus specific device reference when it is guranteed to
+/// be bound for the duration of its lifetime.
+pub struct Bound;
+
mod private {
pub trait Sealed {}
+ impl Sealed for super::Bound {}
impl Sealed for super::Core {}
impl Sealed for super::Normal {}
}
+impl DeviceContext for Bound {}
impl DeviceContext for Core {}
impl DeviceContext for Normal {}
@@ -265,7 +271,12 @@ fn deref(&self) -> &Self::Target {
#[macro_export]
macro_rules! impl_device_context_deref {
($device:tt) => {
- kernel::__impl_device_context_deref!($crate::device::Core, $crate::device::Normal, $device);
+ kernel::__impl_device_context_deref!($crate::device::Core, $crate::device::Bound, $device);
+ kernel::__impl_device_context_deref!(
+ $crate::device::Bound,
+ $crate::device::Normal,
+ $device
+ );
};
}
@@ -287,6 +298,7 @@ fn from(dev: &$device<$src>) -> Self {
macro_rules! impl_device_context_into_aref {
($device:tt) => {
kernel::__impl_device_context_into_aref!($crate::device::Core, $device);
+ kernel::__impl_device_context_into_aref!($crate::device::Bound, $device);
};
}
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/9] rust: pci: move iomap_region() to impl Device<Bound>
2025-03-31 20:27 [PATCH 0/9] Implement "Bound" device context Danilo Krummrich
` (5 preceding siblings ...)
2025-03-31 20:27 ` [PATCH 6/9] rust: device: implement Bound device context Danilo Krummrich
@ 2025-03-31 20:28 ` Danilo Krummrich
2025-03-31 20:28 ` [PATCH 8/9] rust: devres: require a bound device Danilo Krummrich
2025-03-31 20:28 ` [PATCH 9/9] rust: dma: " Danilo Krummrich
8 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2025-03-31 20:28 UTC (permalink / raw)
To: bhelgaas, gregkh, rafael, abdiel.janulgue
Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin,
a.hindborg, aliceryhl, tmgross, daniel.almeida, robin.murphy,
linux-pci, rust-for-linux, linux-kernel, Danilo Krummrich
Require the Bound device context to be able to call iomap_region() and
iomap_region_sized(). Creating I/O mapping requires the device to be
bound.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/pci.rs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index de140cce13cf..b93bf57d2b54 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -390,7 +390,9 @@ pub fn resource_len(&self, bar: u32) -> Result<bindings::resource_size_t> {
// - by its type invariant `self.as_raw` is always a valid pointer to a `struct pci_dev`.
Ok(unsafe { bindings::pci_resource_len(self.as_raw(), bar.try_into()?) })
}
+}
+impl Device<device::Bound> {
/// Mapps an entire PCI-BAR after performing a region-request on it. I/O operation bound checks
/// can be performed on compile time for offsets (plus the requested type size) < SIZE.
pub fn iomap_region_sized<const SIZE: usize>(
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 8/9] rust: devres: require a bound device
2025-03-31 20:27 [PATCH 0/9] Implement "Bound" device context Danilo Krummrich
` (6 preceding siblings ...)
2025-03-31 20:28 ` [PATCH 7/9] rust: pci: move iomap_region() to impl Device<Bound> Danilo Krummrich
@ 2025-03-31 20:28 ` Danilo Krummrich
2025-03-31 20:28 ` [PATCH 9/9] rust: dma: " Danilo Krummrich
8 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2025-03-31 20:28 UTC (permalink / raw)
To: bhelgaas, gregkh, rafael, abdiel.janulgue
Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin,
a.hindborg, aliceryhl, tmgross, daniel.almeida, robin.murphy,
linux-pci, rust-for-linux, linux-kernel, Danilo Krummrich
Require the Bound device context to be able to a new Devres container.
This ensures that we can't register devres callbacks for unbound
devices.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/devres.rs | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
index ddb1ce4a78d9..1e58f5d22044 100644
--- a/rust/kernel/devres.rs
+++ b/rust/kernel/devres.rs
@@ -8,7 +8,7 @@
use crate::{
alloc::Flags,
bindings,
- device::Device,
+ device::{Bound, Device},
error::{Error, Result},
ffi::c_void,
prelude::*,
@@ -45,7 +45,7 @@ struct DevresInner<T> {
/// # Example
///
/// ```no_run
-/// # use kernel::{bindings, c_str, device::Device, devres::Devres, io::{Io, IoRaw}};
+/// # use kernel::{bindings, c_str, device::{Bound, Device}, devres::Devres, io::{Io, IoRaw}};
/// # use core::ops::Deref;
///
/// // See also [`pci::Bar`] for a real example.
@@ -83,13 +83,10 @@ struct DevresInner<T> {
/// unsafe { Io::from_raw(&self.0) }
/// }
/// }
-/// # fn no_run() -> Result<(), Error> {
-/// # // SAFETY: Invalid usage; just for the example to get an `ARef<Device>` instance.
-/// # let dev = unsafe { Device::get_device(core::ptr::null_mut()) };
-///
+/// # fn no_run(dev: &Device<Bound>) -> Result<(), Error> {
/// // SAFETY: Invalid usage for example purposes.
/// let iomem = unsafe { IoMem::<{ core::mem::size_of::<u32>() }>::new(0xBAAAAAAD)? };
-/// let devres = Devres::new(&dev, iomem, GFP_KERNEL)?;
+/// let devres = Devres::new(dev, iomem, GFP_KERNEL)?;
///
/// let res = devres.try_access().ok_or(ENXIO)?;
/// res.write8(0x42, 0x0);
@@ -99,7 +96,7 @@ struct DevresInner<T> {
pub struct Devres<T>(Arc<DevresInner<T>>);
impl<T> DevresInner<T> {
- fn new(dev: &Device, data: T, flags: Flags) -> Result<Arc<DevresInner<T>>> {
+ fn new(dev: &Device<Bound>, data: T, flags: Flags) -> Result<Arc<DevresInner<T>>> {
let inner = Arc::pin_init(
pin_init!( DevresInner {
dev: dev.into(),
@@ -171,7 +168,7 @@ fn remove_action(this: &Arc<Self>) {
impl<T> Devres<T> {
/// Creates a new [`Devres`] instance of the given `data`. The `data` encapsulated within the
/// returned `Devres` instance' `data` will be revoked once the device is detached.
- pub fn new(dev: &Device, data: T, flags: Flags) -> Result<Self> {
+ pub fn new(dev: &Device<Bound>, data: T, flags: Flags) -> Result<Self> {
let inner = DevresInner::new(dev, data, flags)?;
Ok(Devres(inner))
@@ -179,7 +176,7 @@ pub fn new(dev: &Device, data: T, flags: Flags) -> Result<Self> {
/// Same as [`Devres::new`], but does not return a `Devres` instance. Instead the given `data`
/// is owned by devres and will be revoked / dropped, once the device is detached.
- pub fn new_foreign_owned(dev: &Device, data: T, flags: Flags) -> Result {
+ pub fn new_foreign_owned(dev: &Device<Bound>, data: T, flags: Flags) -> Result {
let _ = DevresInner::new(dev, data, flags)?;
Ok(())
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 9/9] rust: dma: require a bound device
2025-03-31 20:27 [PATCH 0/9] Implement "Bound" device context Danilo Krummrich
` (7 preceding siblings ...)
2025-03-31 20:28 ` [PATCH 8/9] rust: devres: require a bound device Danilo Krummrich
@ 2025-03-31 20:28 ` Danilo Krummrich
8 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2025-03-31 20:28 UTC (permalink / raw)
To: bhelgaas, gregkh, rafael, abdiel.janulgue
Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin,
a.hindborg, aliceryhl, tmgross, daniel.almeida, robin.murphy,
linux-pci, rust-for-linux, linux-kernel, Danilo Krummrich
Require the Bound device context to be able to create new
dma::CoherentAllocation instances.
DMA memory allocations are only valid to be created for bound devices.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/dma.rs | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index 8cdc76043ee7..605e01e35715 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -6,7 +6,7 @@
use crate::{
bindings, build_assert,
- device::Device,
+ device::{Bound, Device},
error::code::*,
error::Result,
transmute::{AsBytes, FromBytes},
@@ -22,10 +22,10 @@
/// # Examples
///
/// ```
-/// use kernel::device::Device;
+/// # use kernel::device::{Bound, Device};
/// use kernel::dma::{attrs::*, CoherentAllocation};
///
-/// # fn test(dev: &Device) -> Result {
+/// # fn test(dev: &Device<Bound>) -> Result {
/// let attribs = DMA_ATTR_FORCE_CONTIGUOUS | DMA_ATTR_NO_WARN;
/// let c: CoherentAllocation<u64> =
/// CoherentAllocation::alloc_attrs(dev, 4, GFP_KERNEL, attribs)?;
@@ -143,16 +143,16 @@ impl<T: AsBytes + FromBytes> CoherentAllocation<T> {
/// # Examples
///
/// ```
- /// use kernel::device::Device;
+ /// # use kernel::device::{Bound, Device};
/// use kernel::dma::{attrs::*, CoherentAllocation};
///
- /// # fn test(dev: &Device) -> Result {
+ /// # fn test(dev: &Device<Bound>) -> Result {
/// let c: CoherentAllocation<u64> =
/// CoherentAllocation::alloc_attrs(dev, 4, GFP_KERNEL, DMA_ATTR_NO_WARN)?;
/// # Ok::<(), Error>(()) }
/// ```
pub fn alloc_attrs(
- dev: &Device,
+ dev: &Device<Bound>,
count: usize,
gfp_flags: kernel::alloc::Flags,
dma_attrs: Attrs,
@@ -194,7 +194,7 @@ pub fn alloc_attrs(
/// Performs the same functionality as [`CoherentAllocation::alloc_attrs`], except the
/// `dma_attrs` is 0 by default.
pub fn alloc_coherent(
- dev: &Device,
+ dev: &Device<Bound>,
count: usize,
gfp_flags: kernel::alloc::Flags,
) -> Result<CoherentAllocation<T>> {
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-03-31 20:29 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-31 20:27 [PATCH 0/9] Implement "Bound" device context Danilo Krummrich
2025-03-31 20:27 ` [PATCH 1/9] rust: device: implement impl_device_context_deref! Danilo Krummrich
2025-03-31 20:27 ` [PATCH 2/9] rust: device: implement impl_device_context_into_aref! Danilo Krummrich
2025-03-31 20:27 ` [PATCH 3/9] rust: device: implement device context for Device Danilo Krummrich
2025-03-31 20:27 ` [PATCH 4/9] rust: platform: preserve device context in AsRef Danilo Krummrich
2025-03-31 20:27 ` [PATCH 5/9] rust: pci: " Danilo Krummrich
2025-03-31 20:27 ` [PATCH 6/9] rust: device: implement Bound device context Danilo Krummrich
2025-03-31 20:28 ` [PATCH 7/9] rust: pci: move iomap_region() to impl Device<Bound> Danilo Krummrich
2025-03-31 20:28 ` [PATCH 8/9] rust: devres: require a bound device Danilo Krummrich
2025-03-31 20:28 ` [PATCH 9/9] rust: dma: " Danilo Krummrich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).