* [PATCH 0/3] rust: Fix CFI type mismatches
@ 2026-10-19 23:34 Sami Tolvanen
2026-10-19 23:34 ` [PATCH 1/3] rust: irq: declare cfi_encoding for irqreturn Sami Tolvanen
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Sami Tolvanen @ 2026-10-19 23:34 UTC (permalink / raw)
To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, FUJITA Tomonori,
Frederic Weisbecker, Lyude Paul, Thomas Gleixner,
Anna-Maria Behnsen, John Stultz, Stephen Boyd, Abdiel Janulgue,
Robin Murphy
Cc: rust-for-linux, linux-kernel, driver-core, Sami Tolvanen
This series fixes a few CONFIG_CFI indirect call type mismatches that
I've run into while working on Tyr. If we're going to run into a lot
of these in future, perhaps we need a better solution than addressing
them one at a time?
Sami
---
base-commit: c03c1a14507dfaf8b856c2608f9ac216021fc222
change-id: 20261019-rust-cfi-fixes-bd898391df1d
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] rust: irq: declare cfi_encoding for irqreturn
2026-10-19 23:34 [PATCH 0/3] rust: Fix CFI type mismatches Sami Tolvanen
@ 2026-10-19 23:34 ` Sami Tolvanen
2026-10-19 23:34 ` [PATCH 2/3] rust: hrtimer: declare cfi_encoding for hrtimer_restart Sami Tolvanen
2026-10-19 23:34 ` [PATCH 3/3] rust: dma: declare cfi_encoding for dma_data_direction Sami Tolvanen
2 siblings, 0 replies; 4+ messages in thread
From: Sami Tolvanen @ 2026-10-19 23:34 UTC (permalink / raw)
To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, FUJITA Tomonori,
Frederic Weisbecker, Lyude Paul, Thomas Gleixner,
Anna-Maria Behnsen, John Stultz, Stephen Boyd, Abdiel Janulgue,
Robin Murphy
Cc: rust-for-linux, linux-kernel, driver-core, Sami Tolvanen
The IRQ callbacks return c_uint. C calls them through irq_handler_t,
which returns enum irqreturn. kCFI encodes enum types by name even with
integer normalization, so the type ids never match and every call fails
the CFI check.
Generate irqreturn as a newtype with a cfi_encoding, as is done for
lru_status, and return bindings::irqreturn_t from the callbacks.
Fixes: 0851d34a8cc3 ("rust: irq: add support for non-threaded IRQs and handlers")
Fixes: 135d40523244 ("rust: irq: add support for threaded IRQs and handlers")
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
---
rust/bindgen_parameters | 2 ++
rust/kernel/irq/request.rs | 28 +++++++++++++++++-----------
2 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/rust/bindgen_parameters b/rust/bindgen_parameters
index 8402b0c93545..5059cc74cb3c 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 irqreturn
+--with-attribute-custom-enum=irqreturn='#[cfi_encoding="9irqreturn"]'
--newtype-enum lru_status
--with-attribute-custom-enum=lru_status='#[cfi_encoding="10lru_status"]'
diff --git a/rust/kernel/irq/request.rs b/rust/kernel/irq/request.rs
index c1c6525a676a..1afa9fcaad1f 100644
--- a/rust/kernel/irq/request.rs
+++ b/rust/kernel/irq/request.rs
@@ -25,10 +25,10 @@
#[repr(u32)]
pub enum IrqReturn {
/// The interrupt was not from this device or was not handled.
- None = bindings::irqreturn_IRQ_NONE,
+ None = bindings::irqreturn::IRQ_NONE.0,
/// The interrupt was handled by this device.
- Handled = bindings::irqreturn_IRQ_HANDLED,
+ Handled = bindings::irqreturn::IRQ_HANDLED.0,
}
/// Callbacks for an IRQ handler.
@@ -240,25 +240,28 @@ fn drop(self: Pin<&mut Self>) {
/// # Safety
///
/// This function should be only used as the callback in `request_irq`.
-unsafe extern "C" fn handle_irq_callback<T: Handler>(_irq: i32, ptr: *mut c_void) -> c_uint {
+unsafe extern "C" fn handle_irq_callback<T: Handler>(
+ _irq: i32,
+ ptr: *mut c_void,
+) -> bindings::irqreturn_t {
let ptr = ptr.cast_const().cast::<Registration<'_, T>>();
// SAFETY: `ptr` is a pointer to `Registration<'_, T>` set in `Registration::new()`.
let registration = unsafe { &*ptr };
- T::handle(®istration.handler) as c_uint
+ bindings::irqreturn_t(T::handle(®istration.handler) as c_uint)
}
/// The value that can be returned from [`ThreadedHandler::handle`].
#[repr(u32)]
pub enum ThreadedIrqReturn {
/// The interrupt was not from this device or was not handled.
- None = bindings::irqreturn_IRQ_NONE,
+ None = bindings::irqreturn::IRQ_NONE.0,
/// The interrupt was handled by this device.
- Handled = bindings::irqreturn_IRQ_HANDLED,
+ Handled = bindings::irqreturn::IRQ_HANDLED.0,
/// The handler wants the handler thread to wake up.
- WakeThread = bindings::irqreturn_IRQ_WAKE_THREAD,
+ WakeThread = bindings::irqreturn::IRQ_WAKE_THREAD.0,
}
/// Callbacks for a threaded IRQ handler.
@@ -461,23 +464,26 @@ fn drop(self: Pin<&mut Self>) {
unsafe extern "C" fn handle_threaded_irq_callback<T: ThreadedHandler>(
_irq: i32,
ptr: *mut c_void,
-) -> c_uint {
+) -> bindings::irqreturn_t {
let ptr = ptr.cast_const().cast::<ThreadedRegistration<'_, T>>();
// SAFETY: `ptr` is a pointer to `ThreadedRegistration<'_, T>` set in
// `ThreadedRegistration::new()`.
let registration = unsafe { &*ptr };
- T::handle(®istration.handler) as c_uint
+ bindings::irqreturn_t(T::handle(®istration.handler) as c_uint)
}
/// # Safety
///
/// This function should be only used as the callback in `request_threaded_irq`.
-unsafe extern "C" fn thread_fn_callback<T: ThreadedHandler>(_irq: i32, ptr: *mut c_void) -> c_uint {
+unsafe extern "C" fn thread_fn_callback<T: ThreadedHandler>(
+ _irq: i32,
+ ptr: *mut c_void,
+) -> bindings::irqreturn_t {
let ptr = ptr.cast_const().cast::<ThreadedRegistration<'_, T>>();
// SAFETY: `ptr` is a pointer to `ThreadedRegistration<'_, T>` set in
// `ThreadedRegistration::new()`.
let registration = unsafe { &*ptr };
- T::handle_threaded(®istration.handler) as c_uint
+ bindings::irqreturn_t(T::handle_threaded(®istration.handler) as c_uint)
}
--
2.56.0.212.g129ede20d9-goog
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/3] rust: hrtimer: declare cfi_encoding for hrtimer_restart
2026-10-19 23:34 [PATCH 0/3] rust: Fix CFI type mismatches Sami Tolvanen
2026-10-19 23:34 ` [PATCH 1/3] rust: irq: declare cfi_encoding for irqreturn Sami Tolvanen
@ 2026-10-19 23:34 ` Sami Tolvanen
2026-10-19 23:34 ` [PATCH 3/3] rust: dma: declare cfi_encoding for dma_data_direction Sami Tolvanen
2 siblings, 0 replies; 4+ messages in thread
From: Sami Tolvanen @ 2026-10-19 23:34 UTC (permalink / raw)
To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, FUJITA Tomonori,
Frederic Weisbecker, Lyude Paul, Thomas Gleixner,
Anna-Maria Behnsen, John Stultz, Stephen Boyd, Abdiel Janulgue,
Robin Murphy
Cc: rust-for-linux, linux-kernel, driver-core, Sami Tolvanen
The hrtimer callbacks return bindings::hrtimer_restart, which bindgen
generates as c_uint. C calls them through hrtimer->function, which
returns enum hrtimer_restart. kCFI encodes enum types by name even with
integer normalization, so the type ids never match and every call fails
the CFI check.
Generate hrtimer_restart as a newtype with a cfi_encoding, as is done
for lru_status, and adapt HrTimerRestart to the newtype.
Fixes: 8a8afe9349fb ("rust: hrtimer: introduce hrtimer support")
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
---
rust/bindgen_parameters | 2 ++
rust/kernel/time/hrtimer.rs | 6 +++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/rust/bindgen_parameters b/rust/bindgen_parameters
index 5059cc74cb3c..6003d5127676 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 hrtimer_restart
+--with-attribute-custom-enum=hrtimer_restart='#[cfi_encoding="15hrtimer_restart"]'
--newtype-enum irqreturn
--with-attribute-custom-enum=irqreturn='#[cfi_encoding="9irqreturn"]'
--newtype-enum lru_status
diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs
index 2d7f1131a813..07344ed5fbd5 100644
--- a/rust/kernel/time/hrtimer.rs
+++ b/rust/kernel/time/hrtimer.rs
@@ -834,14 +834,14 @@ unsafe fn start(this: *const Self, expires: <Self::TimerMode as HrTimerMode>::Ex
#[repr(u32)]
pub enum HrTimerRestart {
/// Timer should not be restarted.
- NoRestart = bindings::hrtimer_restart_HRTIMER_NORESTART,
+ NoRestart = bindings::hrtimer_restart::HRTIMER_NORESTART.0,
/// Timer should be restarted.
- Restart = bindings::hrtimer_restart_HRTIMER_RESTART,
+ Restart = bindings::hrtimer_restart::HRTIMER_RESTART.0,
}
impl HrTimerRestart {
fn into_c(self) -> bindings::hrtimer_restart {
- self as bindings::hrtimer_restart
+ bindings::hrtimer_restart(self as c_uint)
}
}
--
2.56.0.212.g129ede20d9-goog
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 3/3] rust: dma: declare cfi_encoding for dma_data_direction
2026-10-19 23:34 [PATCH 0/3] rust: Fix CFI type mismatches Sami Tolvanen
2026-10-19 23:34 ` [PATCH 1/3] rust: irq: declare cfi_encoding for irqreturn Sami Tolvanen
2026-10-19 23:34 ` [PATCH 2/3] rust: hrtimer: declare cfi_encoding for hrtimer_restart Sami Tolvanen
@ 2026-10-19 23:34 ` Sami Tolvanen
2 siblings, 0 replies; 4+ messages in thread
From: Sami Tolvanen @ 2026-10-19 23:34 UTC (permalink / raw)
To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, FUJITA Tomonori,
Frederic Weisbecker, Lyude Paul, Thomas Gleixner,
Anna-Maria Behnsen, John Stultz, Stephen Boyd, Abdiel Janulgue,
Robin Murphy
Cc: rust-for-linux, linux-kernel, driver-core, Sami Tolvanen
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>
---
rust/bindgen_parameters | 2 ++
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 @@ const fn const_cast(val: bindings::dma_data_direction) -> u32 {
// 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 @@ const fn const_cast(val: bindings::dma_data_direction) -> u32 {
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,
+ }
}
}
--
2.56.0.212.g129ede20d9-goog
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-19 23:34 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-19 23:34 [PATCH 0/3] rust: Fix CFI type mismatches Sami Tolvanen
2026-10-19 23:34 ` [PATCH 1/3] rust: irq: declare cfi_encoding for irqreturn Sami Tolvanen
2026-10-19 23:34 ` [PATCH 2/3] rust: hrtimer: declare cfi_encoding for hrtimer_restart Sami Tolvanen
2026-10-19 23:34 ` [PATCH 3/3] rust: dma: declare cfi_encoding for dma_data_direction Sami Tolvanen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®