* [PATCH 7.2.y] rust: irq: pass RegistrationInner as cookie to request_irq
@ 2026-10-07 6:01 Alice Ryhl
2026-10-07 6:28 ` Patch "rust: irq: pass RegistrationInner as cookie to request_irq" has been added to the 7.2-stable tree gregkh
0 siblings, 1 reply; 2+ messages in thread
From: Alice Ryhl @ 2026-10-07 6:01 UTC (permalink / raw)
To: stable, Greg Kroah-Hartman, Sasha Levin, Danilo Krummrich,
Daniel Almeida
Cc: Alexandre Courbot, Andreas Hindborg, Benno Lossin,
Björn Roy Baron, Boqun Feng, Boris Brezillon, Eliot Courtney,
Gary Guo, Markus Probst, Miguel Ojeda, Onur Özkan,
Rafael J. Wysocki, Tamir Duberstein, Trevor Gross, driver-core,
rust-for-linux, linux-kernel, Alice Ryhl
With commit ba268514ea14 ("rust: devres: fix race condition due to
nesting"), Devres::new() returns Result<Self> by value instead of
initializing in-place via PinInit. Because request_irq() is called
inside Devres::new(), registration.inner is still uninitialized when the
IRQ is enabled, so accessing registration.inner.device() in the IRQ
callback can read uninitialized memory.
Fix this by storing the Device and handler pointer in RegistrationInner
and passing RegistrationInner as the IRQ cookie after its fields are
initialized.
This is not needed in mainline because commit 98c63ce4d760 ("rust: irq:
make Registration compatible with lifetime-bound drivers") removed
Devres from irq::Registration and moved request_irq() after all fields
are initialized.
Fixes: 29e16fcd67ee ("rust: irq: add &Device<Bound> argument to irq callbacks")
Fixes: ba268514ea14 ("rust: devres: fix race condition due to nesting")
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
This is the 7.2 version of:
https://lore.kernel.org/all/20261005-devres-6-18-backport-v1-5-06dcf0e592d5@google.com/
---
rust/kernel/irq/request.rs | 89 ++++++++++++++++++++++++++++------------------
1 file changed, 54 insertions(+), 35 deletions(-)
diff --git a/rust/kernel/irq/request.rs b/rust/kernel/irq/request.rs
index f425fe12f7c8..d84a32ff0f7c 100644
--- a/rust/kernel/irq/request.rs
+++ b/rust/kernel/irq/request.rs
@@ -14,7 +14,7 @@
use crate::irq::flags::Flags;
use crate::prelude::*;
use crate::str::CStr;
-use crate::sync::Arc;
+use crate::sync::{aref::ARef, Arc};
/// The value that can be returned from a [`Handler`] or a [`ThreadedHandler`].
#[repr(u32)]
@@ -54,13 +54,18 @@ fn handle(&self, device: &Device<Bound>) -> IrqReturn {
/// # Invariants
///
/// - `self.irq` is the same as the one passed to `request_{threaded}_irq`.
-/// - `cookie` was passed to `request_{threaded}_irq` as the cookie. It is guaranteed to be unique
+/// - `&self` was passed to `request_{threaded}_irq` as the cookie. It is guaranteed to be unique
/// by the type system, since each call to `new` will return a different instance of
/// `Registration`.
+/// - `self.handler` points to a valid instance of the handler `T` that lives at least until
+/// `Self::drop` completes.
#[pin_data(PinnedDrop)]
struct RegistrationInner {
irq: u32,
- cookie: *mut c_void,
+ dev: ARef<Device>,
+ handler: *const c_void,
+ #[pin]
+ _pin: PhantomPinned,
}
impl RegistrationInner {
@@ -77,18 +82,22 @@ fn drop(self: Pin<&mut Self>) {
//
// Safe as per the invariants of `RegistrationInner` and:
//
- // - The containing struct is `!Unpin` and was initialized using
+ // - `RegistrationInner` is `!Unpin` and was initialized using
// pin-init, so it occupied the same memory location for the entirety of
// its lifetime.
//
// Notice that this will block until all handlers finish executing,
// i.e.: at no point will &self be invalid while the handler is running.
- unsafe { bindings::free_irq(self.irq, self.cookie) };
+ unsafe {
+ bindings::free_irq(
+ self.irq,
+ core::ptr::from_mut::<Self>(self.get_unchecked_mut()).cast::<c_void>(),
+ )
+ };
}
}
-// SAFETY: We only use `inner` on drop, which called at most once with no
-// concurrent access.
+// SAFETY: `RegistrationInner` has no interior mutability and `handler` points to a `Sync` handler.
unsafe impl Sync for RegistrationInner {}
// SAFETY: It is safe to send `RegistrationInner` across threads.
@@ -179,7 +188,7 @@ pub fn irq(&self) -> u32 {
///
/// # Invariants
///
-/// * We own an irq handler whose cookie is a pointer to `Self`.
+/// * We own an irq handler whose cookie is a pointer to `Self::inner`.
#[pin_data]
pub struct Registration<T: Handler> {
#[pin]
@@ -206,10 +215,13 @@ pub fn new<'a>(
handler <- handler,
inner <- Devres::new(
request.dev,
- try_pin_init!(RegistrationInner {
- // INVARIANT: `this` is a valid pointer to the `Registration` instance
- cookie: this.as_ptr().cast::<c_void>(),
- irq: {
+ try_pin_init!(&inner_this in RegistrationInner {
+ irq: request.irq,
+ dev: request.dev.into(),
+ // SAFETY: `this` is a valid pointer to the `Registration` instance.
+ handler: unsafe { &raw const (*this.as_ptr()).handler }.cast(),
+ _pin: PhantomPinned,
+ _: {
// SAFETY:
// - The callbacks are valid for use with request_irq.
// - If this succeeds, the slot is guaranteed to be valid until the
@@ -224,11 +236,10 @@ pub fn new<'a>(
Some(handle_irq_callback::<T>),
flags.into_inner(),
name.as_char_ptr(),
- this.as_ptr().cast::<c_void>(),
+ inner_this.as_ptr().cast::<c_void>(),
)
})?;
- request.irq
- }
+ },
})
),
_pin: PhantomPinned,
@@ -261,13 +272,15 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {
///
/// 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 {
- // SAFETY: `ptr` is a pointer to `Registration<T>` set in `Registration::new`
- let registration = unsafe { &*(ptr as *const Registration<T>) };
+ // SAFETY: `ptr` is a pointer to `RegistrationInner` set in `Registration::new`
+ let inner = unsafe { &*(ptr as *const RegistrationInner) };
+ // SAFETY: `inner.handler` is a pointer to `T` set in `Registration::new`
+ let handler = unsafe { &*inner.handler.cast::<T>() };
// SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq
// callback is running implies that the device has not yet been unbound.
- let device = unsafe { registration.inner.device().as_bound() };
+ let device = unsafe { inner.dev.as_bound() };
- T::handle(®istration.handler, device) as c_uint
+ T::handle(handler, device) as c_uint
}
/// The value that can be returned from [`ThreadedHandler::handle`].
@@ -396,7 +409,7 @@ fn handle_threaded(&self, device: &Device<Bound>) -> IrqReturn {
///
/// # Invariants
///
-/// * We own an irq handler whose cookie is a pointer to `Self`.
+/// * We own an irq handler whose cookie is a pointer to `Self::inner`.
#[pin_data]
pub struct ThreadedRegistration<T: ThreadedHandler> {
#[pin]
@@ -423,10 +436,13 @@ pub fn new<'a>(
handler <- handler,
inner <- Devres::new(
request.dev,
- try_pin_init!(RegistrationInner {
- // INVARIANT: `this` is a valid pointer to the `ThreadedRegistration` instance.
- cookie: this.as_ptr().cast::<c_void>(),
- irq: {
+ try_pin_init!(&inner_this in RegistrationInner {
+ irq: request.irq,
+ dev: request.dev.into(),
+ // SAFETY: `this` is a valid pointer to the `ThreadedRegistration` instance.
+ handler: unsafe { &raw const (*this.as_ptr()).handler }.cast(),
+ _pin: PhantomPinned,
+ _: {
// SAFETY:
// - The callbacks are valid for use with request_threaded_irq.
// - If this succeeds, the slot is guaranteed to be valid until the
@@ -442,11 +458,10 @@ pub fn new<'a>(
Some(thread_fn_callback::<T>),
flags.into_inner(),
name.as_char_ptr(),
- this.as_ptr().cast::<c_void>(),
+ inner_this.as_ptr().cast::<c_void>(),
)
})?;
- request.irq
- }
+ },
})
),
_pin: PhantomPinned,
@@ -482,24 +497,28 @@ pub fn synchronize(&self, dev: &Device<Bound>) -> Result {
_irq: i32,
ptr: *mut c_void,
) -> c_uint {
- // SAFETY: `ptr` is a pointer to `ThreadedRegistration<T>` set in `ThreadedRegistration::new`
- let registration = unsafe { &*(ptr as *const ThreadedRegistration<T>) };
+ // SAFETY: `ptr` is a pointer to `RegistrationInner` set in `ThreadedRegistration::new`
+ let inner = unsafe { &*(ptr as *const RegistrationInner) };
+ // SAFETY: `inner.handler` is a pointer to `T` set in `ThreadedRegistration::new`
+ let handler = unsafe { &*inner.handler.cast::<T>() };
// SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq
// callback is running implies that the device has not yet been unbound.
- let device = unsafe { registration.inner.device().as_bound() };
+ let device = unsafe { inner.dev.as_bound() };
- T::handle(®istration.handler, device) as c_uint
+ T::handle(handler, device) 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 {
- // SAFETY: `ptr` is a pointer to `ThreadedRegistration<T>` set in `ThreadedRegistration::new`
- let registration = unsafe { &*(ptr as *const ThreadedRegistration<T>) };
+ // SAFETY: `ptr` is a pointer to `RegistrationInner` set in `ThreadedRegistration::new`
+ let inner = unsafe { &*(ptr as *const RegistrationInner) };
+ // SAFETY: `inner.handler` is a pointer to `T` set in `ThreadedRegistration::new`
+ let handler = unsafe { &*inner.handler.cast::<T>() };
// SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq
// callback is running implies that the device has not yet been unbound.
- let device = unsafe { registration.inner.device().as_bound() };
+ let device = unsafe { inner.dev.as_bound() };
- T::handle_threaded(®istration.handler, device) as c_uint
+ T::handle_threaded(handler, device) as c_uint
}
---
base-commit: 5fce161649b4d779d1b76d9fcd52dc77779774b8
change-id: 20261006-irq-7-2-backport-117b7044b052
Best regards,
--
Alice Ryhl <aliceryhl@google.com>
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Patch "rust: irq: pass RegistrationInner as cookie to request_irq" has been added to the 7.2-stable tree
2026-10-07 6:01 [PATCH 7.2.y] rust: irq: pass RegistrationInner as cookie to request_irq Alice Ryhl
@ 2026-10-07 6:28 ` gregkh
0 siblings, 0 replies; 2+ messages in thread
From: gregkh @ 2026-10-07 6:28 UTC (permalink / raw)
To: a.hindborg, acourbot, aliceryhl, bjorn3_gh, boqun,
boris.brezillon, dakr, daniel.almeida, driver-core, ecourtney,
gary, gregkh, lossin, markus.probst, ojeda, rafael, sashal,
tamird, tmgross, work
Cc: stable-commits
This is a note to let you know that I've just added the patch titled
rust: irq: pass RegistrationInner as cookie to request_irq
to the 7.2-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
rust-irq-pass-registrationinner-as-cookie-to-request_irq.patch
and it can be found in the queue-7.2 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
From aliceryhl@google.com Wed Oct 7 08:24:34 2026
From: Alice Ryhl <aliceryhl@google.com>
Date: Wed, 07 Oct 2026 06:01:58 +0000
Subject: rust: irq: pass RegistrationInner as cookie to request_irq
To: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, Danilo Krummrich <dakr@kernel.org>, Daniel Almeida <daniel.almeida@collabora.com>
Cc: "Alexandre Courbot" <acourbot@nvidia.com>, "Andreas Hindborg" <a.hindborg@kernel.org>, "Benno Lossin" <lossin@kernel.org>, "Björn Roy Baron" <bjorn3_gh@protonmail.com>, "Boqun Feng" <boqun@kernel.org>, "Boris Brezillon" <boris.brezillon@collabora.com>, "Eliot Courtney" <ecourtney@nvidia.com>, "Gary Guo" <gary@garyguo.net>, "Markus Probst" <markus.probst@posteo.de>, "Miguel Ojeda" <ojeda@kernel.org>, "Onur Özkan" <work@onurozkan.dev>, "Rafael J. Wysocki" <rafael@kernel.org>, "Tamir Duberstein" <tamird@kernel.org>, "Trevor Gross" <tmgross@umich.edu>, driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, "Alice Ryhl" <aliceryhl@google.com>
Message-ID: <20261007-irq-7-2-backport-v1-1-183f514f2aac@google.com>
From: Alice Ryhl <aliceryhl@google.com>
With commit ba268514ea14 ("rust: devres: fix race condition due to
nesting"), Devres::new() returns Result<Self> by value instead of
initializing in-place via PinInit. Because request_irq() is called
inside Devres::new(), registration.inner is still uninitialized when the
IRQ is enabled, so accessing registration.inner.device() in the IRQ
callback can read uninitialized memory.
Fix this by storing the Device and handler pointer in RegistrationInner
and passing RegistrationInner as the IRQ cookie after its fields are
initialized.
This is not needed in mainline because commit 98c63ce4d760 ("rust: irq:
make Registration compatible with lifetime-bound drivers") removed
Devres from irq::Registration and moved request_irq() after all fields
are initialized.
Fixes: 29e16fcd67ee ("rust: irq: add &Device<Bound> argument to irq callbacks")
Fixes: ba268514ea14 ("rust: devres: fix race condition due to nesting")
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
rust/kernel/irq/request.rs | 89 +++++++++++++++++++++++++++------------------
1 file changed, 54 insertions(+), 35 deletions(-)
--- a/rust/kernel/irq/request.rs
+++ b/rust/kernel/irq/request.rs
@@ -14,7 +14,7 @@ use crate::error::to_result;
use crate::irq::flags::Flags;
use crate::prelude::*;
use crate::str::CStr;
-use crate::sync::Arc;
+use crate::sync::{aref::ARef, Arc};
/// The value that can be returned from a [`Handler`] or a [`ThreadedHandler`].
#[repr(u32)]
@@ -54,13 +54,18 @@ impl<T: ?Sized + Handler, A: Allocator +
/// # Invariants
///
/// - `self.irq` is the same as the one passed to `request_{threaded}_irq`.
-/// - `cookie` was passed to `request_{threaded}_irq` as the cookie. It is guaranteed to be unique
+/// - `&self` was passed to `request_{threaded}_irq` as the cookie. It is guaranteed to be unique
/// by the type system, since each call to `new` will return a different instance of
/// `Registration`.
+/// - `self.handler` points to a valid instance of the handler `T` that lives at least until
+/// `Self::drop` completes.
#[pin_data(PinnedDrop)]
struct RegistrationInner {
irq: u32,
- cookie: *mut c_void,
+ dev: ARef<Device>,
+ handler: *const c_void,
+ #[pin]
+ _pin: PhantomPinned,
}
impl RegistrationInner {
@@ -77,18 +82,22 @@ impl PinnedDrop for RegistrationInner {
//
// Safe as per the invariants of `RegistrationInner` and:
//
- // - The containing struct is `!Unpin` and was initialized using
+ // - `RegistrationInner` is `!Unpin` and was initialized using
// pin-init, so it occupied the same memory location for the entirety of
// its lifetime.
//
// Notice that this will block until all handlers finish executing,
// i.e.: at no point will &self be invalid while the handler is running.
- unsafe { bindings::free_irq(self.irq, self.cookie) };
+ unsafe {
+ bindings::free_irq(
+ self.irq,
+ core::ptr::from_mut::<Self>(self.get_unchecked_mut()).cast::<c_void>(),
+ )
+ };
}
}
-// SAFETY: We only use `inner` on drop, which called at most once with no
-// concurrent access.
+// SAFETY: `RegistrationInner` has no interior mutability and `handler` points to a `Sync` handler.
unsafe impl Sync for RegistrationInner {}
// SAFETY: It is safe to send `RegistrationInner` across threads.
@@ -179,7 +188,7 @@ impl<'a> IrqRequest<'a> {
///
/// # Invariants
///
-/// * We own an irq handler whose cookie is a pointer to `Self`.
+/// * We own an irq handler whose cookie is a pointer to `Self::inner`.
#[pin_data]
pub struct Registration<T: Handler> {
#[pin]
@@ -206,10 +215,13 @@ impl<T: Handler> Registration<T> {
handler <- handler,
inner <- Devres::new(
request.dev,
- try_pin_init!(RegistrationInner {
- // INVARIANT: `this` is a valid pointer to the `Registration` instance
- cookie: this.as_ptr().cast::<c_void>(),
- irq: {
+ try_pin_init!(&inner_this in RegistrationInner {
+ irq: request.irq,
+ dev: request.dev.into(),
+ // SAFETY: `this` is a valid pointer to the `Registration` instance.
+ handler: unsafe { &raw const (*this.as_ptr()).handler }.cast(),
+ _pin: PhantomPinned,
+ _: {
// SAFETY:
// - The callbacks are valid for use with request_irq.
// - If this succeeds, the slot is guaranteed to be valid until the
@@ -224,11 +236,10 @@ impl<T: Handler> Registration<T> {
Some(handle_irq_callback::<T>),
flags.into_inner(),
name.as_char_ptr(),
- this.as_ptr().cast::<c_void>(),
+ inner_this.as_ptr().cast::<c_void>(),
)
})?;
- request.irq
- }
+ },
})
),
_pin: PhantomPinned,
@@ -261,13 +272,15 @@ impl<T: Handler> Registration<T> {
///
/// 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 {
- // SAFETY: `ptr` is a pointer to `Registration<T>` set in `Registration::new`
- let registration = unsafe { &*(ptr as *const Registration<T>) };
+ // SAFETY: `ptr` is a pointer to `RegistrationInner` set in `Registration::new`
+ let inner = unsafe { &*(ptr as *const RegistrationInner) };
+ // SAFETY: `inner.handler` is a pointer to `T` set in `Registration::new`
+ let handler = unsafe { &*inner.handler.cast::<T>() };
// SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq
// callback is running implies that the device has not yet been unbound.
- let device = unsafe { registration.inner.device().as_bound() };
+ let device = unsafe { inner.dev.as_bound() };
- T::handle(®istration.handler, device) as c_uint
+ T::handle(handler, device) as c_uint
}
/// The value that can be returned from [`ThreadedHandler::handle`].
@@ -396,7 +409,7 @@ impl<T: ?Sized + ThreadedHandler, A: All
///
/// # Invariants
///
-/// * We own an irq handler whose cookie is a pointer to `Self`.
+/// * We own an irq handler whose cookie is a pointer to `Self::inner`.
#[pin_data]
pub struct ThreadedRegistration<T: ThreadedHandler> {
#[pin]
@@ -423,10 +436,13 @@ impl<T: ThreadedHandler> ThreadedRegistr
handler <- handler,
inner <- Devres::new(
request.dev,
- try_pin_init!(RegistrationInner {
- // INVARIANT: `this` is a valid pointer to the `ThreadedRegistration` instance.
- cookie: this.as_ptr().cast::<c_void>(),
- irq: {
+ try_pin_init!(&inner_this in RegistrationInner {
+ irq: request.irq,
+ dev: request.dev.into(),
+ // SAFETY: `this` is a valid pointer to the `ThreadedRegistration` instance.
+ handler: unsafe { &raw const (*this.as_ptr()).handler }.cast(),
+ _pin: PhantomPinned,
+ _: {
// SAFETY:
// - The callbacks are valid for use with request_threaded_irq.
// - If this succeeds, the slot is guaranteed to be valid until the
@@ -442,11 +458,10 @@ impl<T: ThreadedHandler> ThreadedRegistr
Some(thread_fn_callback::<T>),
flags.into_inner(),
name.as_char_ptr(),
- this.as_ptr().cast::<c_void>(),
+ inner_this.as_ptr().cast::<c_void>(),
)
})?;
- request.irq
- }
+ },
})
),
_pin: PhantomPinned,
@@ -482,24 +497,28 @@ unsafe extern "C" fn handle_threaded_irq
_irq: i32,
ptr: *mut c_void,
) -> c_uint {
- // SAFETY: `ptr` is a pointer to `ThreadedRegistration<T>` set in `ThreadedRegistration::new`
- let registration = unsafe { &*(ptr as *const ThreadedRegistration<T>) };
+ // SAFETY: `ptr` is a pointer to `RegistrationInner` set in `ThreadedRegistration::new`
+ let inner = unsafe { &*(ptr as *const RegistrationInner) };
+ // SAFETY: `inner.handler` is a pointer to `T` set in `ThreadedRegistration::new`
+ let handler = unsafe { &*inner.handler.cast::<T>() };
// SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq
// callback is running implies that the device has not yet been unbound.
- let device = unsafe { registration.inner.device().as_bound() };
+ let device = unsafe { inner.dev.as_bound() };
- T::handle(®istration.handler, device) as c_uint
+ T::handle(handler, device) 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 {
- // SAFETY: `ptr` is a pointer to `ThreadedRegistration<T>` set in `ThreadedRegistration::new`
- let registration = unsafe { &*(ptr as *const ThreadedRegistration<T>) };
+ // SAFETY: `ptr` is a pointer to `RegistrationInner` set in `ThreadedRegistration::new`
+ let inner = unsafe { &*(ptr as *const RegistrationInner) };
+ // SAFETY: `inner.handler` is a pointer to `T` set in `ThreadedRegistration::new`
+ let handler = unsafe { &*inner.handler.cast::<T>() };
// SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq
// callback is running implies that the device has not yet been unbound.
- let device = unsafe { registration.inner.device().as_bound() };
+ let device = unsafe { inner.dev.as_bound() };
- T::handle_threaded(®istration.handler, device) as c_uint
+ T::handle_threaded(handler, device) as c_uint
}
Patches currently in stable-queue which might be from aliceryhl@google.com are
queue-7.2/rust_binder-cancel-deferred-work-items-in-thread-exit.patch
queue-7.2/rust-irq-pass-registrationinner-as-cookie-to-request_irq.patch
queue-7.2/rust_binder-reschedule-node-refcount-update-on-thread-exit.patch
queue-7.2/binder-fix-leaked-fd-fixups-on-tf_update_txn-supersede.patch
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-07 6:28 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-07 6:01 [PATCH 7.2.y] rust: irq: pass RegistrationInner as cookie to request_irq Alice Ryhl
2026-10-07 6:28 ` Patch "rust: irq: pass RegistrationInner as cookie to request_irq" has been added to the 7.2-stable tree gregkh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox