diff options
| author | Sami Tolvanen <samitolvanen@google.com> | 2026-10-19 23:34:39 +0000 |
|---|---|---|
| committer | Miguel Ojeda <ojeda@kernel.org> | 2026-10-22 15:36:01 +0200 |
| commit | 7d109178cd644268326cd31702ed46c7ac8bb300 (patch) | |
| tree | 57575644d2801995773d227c64ce3160a7bd4fe8 /rust | |
| parent | 39fe6892fd52faed6325ff7f13a92da01ab35727 (diff) | |
rust: dma: declare cfi_encoding for dma_data_direction
bindgen generates bindings::dma_data_direction as an integer by default,
while C callback tables such as dma_buf_ops declare the parameter as
enum dma_data_direction. kCFI encodes enum types by name even with
integer normalization, so the type ids would not match when C calls into
a Rust callback taking bindings::dma_data_direction.
Generate dma_data_direction as a newtype with a cfi_encoding, as is done
for lru_status, and convert DataDirection through the newtype's
constants.
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Cc: stable@vger.kernel.org
Fixes: c2437c43cfb1 ("rust: dma: implement DataDirection")
Link: https://patch.msgid.link/20261019-rust-cfi-fixes-v1-3-9503472ba738@google.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/bindgen_parameters | 2 | ||||
| -rw-r--r-- | rust/kernel/dma.rs | 21 |
2 files changed, 13 insertions, 10 deletions
diff --git a/rust/bindgen_parameters b/rust/bindgen_parameters index 6003d5127676..8577e7663e02 100644 --- a/rust/bindgen_parameters +++ b/rust/bindgen_parameters @@ -27,6 +27,8 @@ --opaque-type spinlock # enums that appear in indirect function calls should specify a cfi type +--newtype-enum dma_data_direction +--with-attribute-custom-enum=dma_data_direction='#[cfi_encoding="18dma_data_direction"]' --newtype-enum hrtimer_restart --with-attribute-custom-enum=hrtimer_restart='#[cfi_encoding="15hrtimer_restart"]' --newtype-enum irqreturn diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs index 2ce09f8e90c6..2ec5fe7d56bc 100644 --- a/rust/kernel/dma.rs +++ b/rust/kernel/dma.rs @@ -310,25 +310,25 @@ pub enum DataDirection { /// /// This is used when the buffer can be both read from and written to by the device. /// The cache for the corresponding memory region is both flushed and invalidated. - Bidirectional = Self::const_cast(bindings::dma_data_direction_DMA_BIDIRECTIONAL), + Bidirectional = Self::const_cast(bindings::dma_data_direction::DMA_BIDIRECTIONAL), /// The DMA mapping is for data transfer from memory to the device (write). /// /// The CPU has prepared data in the buffer, and the device will read it. /// The cache for the corresponding memory region is flushed before device access. - ToDevice = Self::const_cast(bindings::dma_data_direction_DMA_TO_DEVICE), + ToDevice = Self::const_cast(bindings::dma_data_direction::DMA_TO_DEVICE), /// The DMA mapping is for data transfer from the device to memory (read). /// /// The device will write data into the buffer for the CPU to read. /// The cache for the corresponding memory region is invalidated before CPU access. - FromDevice = Self::const_cast(bindings::dma_data_direction_DMA_FROM_DEVICE), + FromDevice = Self::const_cast(bindings::dma_data_direction::DMA_FROM_DEVICE), /// The DMA mapping is not for data transfer. /// /// This is primarily for debugging purposes. With this direction, the DMA mapping API /// will not perform any cache coherency operations. - None = Self::const_cast(bindings::dma_data_direction_DMA_NONE), + None = Self::const_cast(bindings::dma_data_direction::DMA_NONE), } impl DataDirection { @@ -340,7 +340,7 @@ impl DataDirection { // CAST: The C standard allows compilers to choose different integer types for enums. // To safely check the value, we cast it to a wide signed integer type (`i128`) // which can hold any standard C integer enum type without truncation. - let wide_val = val as i128; + let wide_val = val.0 as i128; // Check if the value is outside the valid range for the target type `u32`. // CAST: `u32::MAX` is cast to `i128` to match the type of `wide_val` for the comparison. @@ -358,11 +358,12 @@ impl DataDirection { impl From<DataDirection> for bindings::dma_data_direction { /// Returns the raw representation of [`enum dma_data_direction`]. fn from(direction: DataDirection) -> Self { - // CAST: `direction as u32` gets the underlying representation of our `#[repr(u32)]` enum. - // The subsequent cast to `Self` (the bindgen type) assumes the C enum is compatible - // with the enum variants of `DataDirection`, which is a valid assumption given our - // compile-time checks. - direction as u32 as Self + match direction { + DataDirection::Bidirectional => Self::DMA_BIDIRECTIONAL, + DataDirection::ToDevice => Self::DMA_TO_DEVICE, + DataDirection::FromDevice => Self::DMA_FROM_DEVICE, + DataDirection::None => Self::DMA_NONE, + } } } |
