FAILED: patch "[PATCH] rust: irq: declare cfi_encoding for irqreturn" failed to apply to 6.18-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 01f3e6b4b1c8c1748e59ba53631ab1f5d9ad0ea4
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026110407-hydrated-decipher-a8a9@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 01f3e6b4b1c8c1748e59ba53631ab1f5d9ad0ea4 Mon Sep 17 00:00:00 2001
From: Sami Tolvanen <[email protected]>
Date: Mon, 19 Oct 2026 23:34:37 +0000
Subject: [PATCH] rust: irq: declare cfi_encoding for irqreturn
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.
rust/bindgen_parameters +2 -0
@@ -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"]'
rust/kernel/irq/request.rs +17 -11
@@ -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 ) }
Sasha Levin
maintainerPATCH 1/1 rust: irq: declare cfi_encoding for irqreturn
From: Sami Tolvanen <[email protected]>
[ Upstream commit 01f3e6b4b1c8c1748e59ba53631ab1f5d9ad0ea4 ]
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.
--- rust/Makefile | 3 ++- rust/bindgen_parameters | 3 +++ rust/bindings/lib.rs | 1 + rust/kernel/irq/request.rs | 22 +++++++++++----------- 4 files changed, 17 insertions(+), 12 deletions(-)
rust/Makefile +2 -1
@@ -367,7 +367,8 @@ quiet_cmd_bindgen = BINDGEN $@ $(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \ $(shell grep -Ev '^#|^$$' $(src)/bindgen_parameters) $(obj)/bindings/bindings_generated.rs: private bindgen_target_extra = ; \ - sed -Ei 's/pub const RUST_CONST_HELPER_([a-zA-Z0-9_]*)/pub const \1/g' $@ + sed -Ei 's/pub const RUST_CONST_HELPER_([a-zA-Z0-9_]*)/pub const \1/g' $@; \ + sed -Ei 's/^pub struct irqreturn\(/#[cfi_encoding="9irqreturn"]\n&/' $@ $(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \ $(src)/bindgen_parameters FORCE $(call if_changed_dep,bindgen)
rust/bindgen_parameters +3 -0
@@ -23,6 +23,9 @@ # warning. We don't need to peek into it anyway. --opaque-type spinlock +# enums that appear in indirect function calls should specify a cfi type +--newtype-enum irqreturn + # `seccomp`'s comment gets understood as a doctest --no-doc-comments
rust/bindings/lib.rs +1 -0
@@ -23,6 +23,7 @@ unreachable_pub, unsafe_op_in_unsafe_fn )] +#![feature(cfi_encoding)] #[allow(dead_code)] #[allow(clippy::as_underscore)]
rust/kernel/irq/request.rs +11 -11
@@ -20,10 +20,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.
@@ -275,7 +275,7 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {unsafe extern "C" fn handle_irq_callback <T :Handler + 'static>( _irq:i32 , ptr: *mut c_void , -) ->c_uint { +) -> bindings::irqreturn_t {// SAFETY: `ptr` is a pointer to `RegistrationInner` set in `Registration::new` let inner =unsafe { &*(ptras *const RegistrationInner ) };// SAFETY: `inner.handler` is a pointer to `T` set in `Registration::new`
@@ -284,20 +284,20 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {// callback is running implies that the device has not yet been unbound. let device =unsafe { inner.dev.as_bound () }; -T ::handle (handler, device)as c_uint + bindings::irqreturn_t (T ::handle (handler, device)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.
@@ -501,7 +501,7 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {unsafe extern "C" fn handle_threaded_irq_callback <T :ThreadedHandler + 'static>( _irq:i32 , ptr: *mut c_void , -) ->c_uint { +) -> bindings::irqreturn_t {// SAFETY: `ptr` is a pointer to `RegistrationInner` set in `ThreadedRegistration::new` let inner =unsafe { &*(ptras *const RegistrationInner ) };// SAFETY: `inner.handler` is a pointer to `T` set in `ThreadedRegistration::new`
@@ -510,7 +510,7 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {// callback is running implies that the device has not yet been unbound. let device =unsafe { inner.dev.as_bound () }; -T ::handle (handler, device)as c_uint + bindings::irqreturn_t (T ::handle (handler, device)as c_uint ) }/// # Safety
@@ -519,7 +519,7 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {unsafe extern "C" fn thread_fn_callback <T :ThreadedHandler + 'static>( _irq:i32 , ptr: *mut c_void , -) ->c_uint { +) -> bindings::irqreturn_t {// SAFETY: `ptr` is a pointer to `RegistrationInner` set in `ThreadedRegistration::new` let inner =unsafe { &*(ptras *const RegistrationInner ) };// SAFETY: `inner.handler` is a pointer to `T` set in `ThreadedRegistration::new`
@@ -528,5 +528,5 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {// callback is running implies that the device has not yet been unbound. let device =unsafe { inner.dev.as_bound () }; -T ::handle_threaded (handler, device)as c_uint + bindings::irqreturn_t (T ::handle_threaded (handler, device)as c_uint ) }
Signature · 1 line
2.53.0
Re: [PATCH 6.18.y] rust: irq: declare cfi_encoding for irqreturn
Quoted 4 lines · Sasha Levin
[ sashal: replaced bindgen's custom enum attribute option with sed post-processing to support older bindgen ]
+ sed -Ei 's/^pub struct irqreturn\(/#[cfi_encoding="9irqreturn"]\n&/' $@
Meh, not great, but it is what it is I guess :(
Should we send the other two, i.e. for dma and hrtimer? i.e. we had these:
FAILED: patch "[PATCH] rust: hrtimer: declare cfi_encoding forhrtimer_restart" failed to apply to 6.18-stable tree
FAILED: patch "[PATCH] rust: dma: declare cfi_encoding fordma_data_direction" failed to apply to 6.18-stable tree
FAILED: patch "[PATCH] rust: irq: declare cfi_encoding for
irqreturn" failed to apply to 6.18-stable tree
but I only see this one for irq (I imagine perhaps you sent this one to see whether the approach is OK first?). Do you want the other two to be sent on top of this one if so? I have them, and checked that the hashes match C's.
Then there were the 7.3 ones -- I will send those.
Thanks!
Cheers,
Miguel
Miguel Ojeda
maintainerPATCH 1/2 rust: hrtimer: declare cfi_encoding for hrtimer_restart
In reply to Sasha LevinFrom: Sami Tolvanen <[email protected]>
commit 39fe6892fd52faed6325ff7f13a92da01ab35727 upstream.
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.
[ Replaced bindgen's custom enum attribute option with sed
post-processing to support older bindgen. - Miguel ]
--- rust/Makefile | 1 + rust/bindgen_parameters | 1 + rust/kernel/time/hrtimer.rs | 6 +++--- 3 files changed, 5 insertions(+), 3 deletions(-)
rust/Makefile +1 -0
@@ -368,6 +368,7 @@ $(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \ $(shell grep -Ev '^#|^$$' $(src)/bindgen_parameters) $(obj)/bindings/bindings_generated.rs: private bindgen_target_extra = ; \ sed -Ei 's/pub const RUST_CONST_HELPER_([a-zA-Z0-9_]*)/pub const \1/g' $@; \ + sed -Ei 's/^pub struct hrtimer_restart\(/#[cfi_encoding="15hrtimer_restart"]\n&/' $@; \ sed -Ei 's/^pub struct irqreturn\(/#[cfi_encoding="9irqreturn"]\n&/' $@ $(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \ $(src)/bindgen_parameters FORCE
rust/bindgen_parameters +1 -0
@@ -24,6 +24,7 @@ --opaque-type spinlock # enums that appear in indirect function calls should specify a cfi type +--newtype-enum hrtimer_restart --newtype-enum irqreturn # `seccomp`'s comment gets understood as a doctest
rust/kernel/time/hrtimer.rs +3 -3
@@ -498,14 +498,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 { - selfas bindings::hrtimer_restart + bindings::hrtimer_restart (selfas c_uint ) } }
Signature · 1 line
2.56.0
Miguel Ojeda
maintainerPATCH 2/2 rust: dma: declare cfi_encoding for dma_data_direction
From: Sami Tolvanen <[email protected]>
commit 7d109178cd644268326cd31702ed46c7ac8bb300 upstream.
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.
[ Replaced bindgen's custom enum attribute option with sed
post-processing to support older bindgen. - Miguel ]
--- rust/Makefile | 1 + rust/bindgen_parameters | 1 + rust/kernel/dma.rs | 21 +++++++++++---------- 3 files changed, 13 insertions(+), 10 deletions(-)
rust/Makefile +1 -0
@@ -368,6 +368,7 @@ $(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \ $(shell grep -Ev '^#|^$$' $(src)/bindgen_parameters) $(obj)/bindings/bindings_generated.rs: private bindgen_target_extra = ; \ sed -Ei 's/pub const RUST_CONST_HELPER_([a-zA-Z0-9_]*)/pub const \1/g' $@; \ + sed -Ei 's/^pub struct dma_data_direction\(/#[cfi_encoding="18dma_data_direction"]\n&/' $@; \ sed -Ei 's/^pub struct hrtimer_restart\(/#[cfi_encoding="15hrtimer_restart"]\n&/' $@; \ sed -Ei 's/^pub struct irqreturn\(/#[cfi_encoding="9irqreturn"]\n&/' $@ $(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \
rust/bindgen_parameters +1 -0
@@ -24,6 +24,7 @@ --opaque-type spinlock # enums that appear in indirect function calls should specify a cfi type +--newtype-enum dma_data_direction --newtype-enum hrtimer_restart --newtype-enum irqreturn
rust/kernel/dma.rs +11 -10
@@ -267,25 +267,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 {
@@ -297,7 +297,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 = valas 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.
@@ -315,11 +315,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. - directionas 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 , + } } }
Signature · 1 line
2.56.0
Re: [PATCH 6.18.y 1/2] rust: hrtimer: declare cfi_encoding for hrtimer_restart
In reply to Miguel OjedaQuoted 1 line
[PATCH 6.18.y 1/2] rust: hrtimer: declare
cfi_encodingforhrtimer_restart
Queued the series for 6.18, thanks.
Signature · 2 lines
Thanks, Sasha