From nobody Tue Sep 29 08:47:52 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B66444307B7; Wed, 12 Aug 2026 11:18:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786533526; cv=none; b=XvEu3CtXjcfdTd28H4X5+6Zo2ZBs0Q6wi9t+8wyfKeOpxHUz2to3wdmUtcsDDzbnJf7lUt1RQ2Ljl81Yq5GCxdIwok4wcKWFcNwXbDMF0Hmrn3P/rAZo0CH21sKuwT2a+RExlxsgo0iV+ltnvFk0HZsCPZ9LLiviNcxVRiwHnrI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786533526; c=relaxed/simple; bh=7p37wPM2SYWZrby7/4ar5vmze6i5siIc7WjY4wUoJj8=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=XSUwjhM1afKaxTK8mLxsVAvEc+7BJqMvTJicJT8O2CSrDzdVOpwXEIlkitMEZ56FMxevIbNUREbP/apQ1dTsW53f2E8DaHJ6ilQvP+02ITPTRaJpAbsXAqsPiyYyDmCLGwfc2LNeKiqkmyUufeYUij6EmPk9/CHHuAugYt+pUHM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ZC3N4ANW; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1cFk4jEd; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ZC3N4ANW"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1cFk4jEd" Date: Wed, 12 Aug 2026 11:18:40 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1786533521; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YxtR+UopsF4rxcbTObkhouZnumOQzWZ0jCpp3vBXQBk=; b=ZC3N4ANWgNVRhw6tm0i1S5xPGI4PEPtwahaUgeVu6WpSoZvCMelWrG1QEf5m9fwpQ+GJwW zYpa/lWS0PPOBJQ2UaumxlguEpN0HkptGDmIwT9pXjqubPnfM5uo30Q3pJj3EQim9z5ueh elnC3UMg4Nm17Ex2t0eAFfyLU4YDhdkv4b38ISCdK+iINQjGH8sd/0vDnqdTrmzO6ICLyo NjyHwP7/haQmsSAnMorI3eVX5eEQV0241lWrN81SXkcsiwm3oOJccBoq01TzpU26C7rjjr qUQTjaqsq+may7POqCKb7VaU1vse2YFK43qfE6koBrhFfn/+q0ePYvl5AmC1bA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1786533522; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YxtR+UopsF4rxcbTObkhouZnumOQzWZ0jCpp3vBXQBk=; b=1cFk4jEdyNp5sw64UWd7MopymZsZ2io+KH5ZdaktW3LnL9kfiAKAdqnTRca/YznqogX7Lf kOQvukP6MrQMeACw== From: "tip-bot2 for Lyude Paul" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: locking/core] rust: Introduce interrupt module Cc: Lyude Paul , Boqun Feng , "Peter Zijlstra (Intel)" , Benno Lossin , Andreas Hindborg , Gary Guo , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20260807070218.27144-15-boqun@kernel.org> References: <20260807070218.27144-15-boqun@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <178653352036.442315.14955335172120634710.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the locking/core branch of tip: Commit-ID: c1f0451ec748f7a58a4e50bcb8f75bd89718be78 Gitweb: https://git.kernel.org/tip/c1f0451ec748f7a58a4e50bcb8f75bd89= 718be78 Author: Lyude Paul AuthorDate: Fri, 07 Aug 2026 00:02:11 -07:00 Committer: Peter Zijlstra CommitterDate: Mon, 10 Aug 2026 12:53:09 +02:00 rust: Introduce interrupt module This introduces a module for dealing with interrupt-disabled contexts, including the ability to enable and disable interrupts along with the ability to annotate functions as expecting that IRQs are already disabled on the local CPU. Signed-off-by: Lyude Paul Signed-off-by: Boqun Feng Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Benno Lossin Reviewed-by: Andreas Hindborg Reviewed-by: Gary Guo Link: https://patch.msgid.link/20260807070218.27144-15-boqun@kernel.org --- rust/helpers/helpers.c | 1 +- rust/helpers/interrupt.c | 13 ++++++- rust/helpers/sync.c | 5 ++- rust/kernel/interrupt.rs | 89 +++++++++++++++++++++++++++++++++++++++- rust/kernel/lib.rs | 1 +- 5 files changed, 109 insertions(+) create mode 100644 rust/helpers/interrupt.c create mode 100644 rust/kernel/interrupt.rs diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index 998e310..0d85b5e 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -65,6 +65,7 @@ #include "irq.c" #include "fs.c" #include "gpu.c" +#include "interrupt.c" #include "io.c" #include "jump_label.c" #include "kunit.c" diff --git a/rust/helpers/interrupt.c b/rust/helpers/interrupt.c new file mode 100644 index 0000000..6959549 --- /dev/null +++ b/rust/helpers/interrupt.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +__rust_helper void rust_helper_local_interrupt_disable(void) +{ + local_interrupt_disable(); +} + +__rust_helper void rust_helper_local_interrupt_enable(void) +{ + local_interrupt_enable(); +} diff --git a/rust/helpers/sync.c b/rust/helpers/sync.c index 82d6aff..4f474fe 100644 --- a/rust/helpers/sync.c +++ b/rust/helpers/sync.c @@ -11,3 +11,8 @@ __rust_helper void rust_helper_lockdep_unregister_key(str= uct lock_class_key *k) { lockdep_unregister_key(k); } + +__rust_helper void rust_helper_lockdep_assert_irqs_disabled(void) +{ + lockdep_assert_irqs_disabled(); +} diff --git a/rust/kernel/interrupt.rs b/rust/kernel/interrupt.rs new file mode 100644 index 0000000..a880ec3 --- /dev/null +++ b/rust/kernel/interrupt.rs @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Interrupt controls +//! +//! This module allows Rust code to annotate areas of code where local pro= cessor interrupts should +//! be disabled, along with actually disabling local processor interrupts. +//! +//! # =E2=9A=A0=EF=B8=8F Warning! =E2=9A=A0=EF=B8=8F +//! +//! The usage of this module can be more complicated than meets the eye, e= specially surrounding +//! [preemptible kernels]. It's recommended to take care when using the fu= nctions and types defined +//! here and familiarize yourself with the various documentation we have b= efore using them, along +//! with the various documents we link to here. +//! +//! # Reading material +//! +//! - [Software interrupts and realtime (LWN)](https://lwn.net/Articles/52= 0076) +//! +//! [preemptible kernels]: https://www.kernel.org/doc/html/latest/locking/= preempt-locking.html + +use crate::types::NotThreadSafe; + +/// A guard that represents local processor interrupt disablement on preem= ptible kernels. +/// +/// [`LocalInterruptDisabled`] is a guard type that represents that local = processor interrupts have +/// been disabled on a preemptible kernel. +/// +/// Certain functions take an immutable reference of [`LocalInterruptDisab= led`] in order to require +/// that they may only be run in local-interrupt-disabled contexts on pree= mptible kernels. +/// +/// This is a marker type; it has no size, and is simply used as a compile= -time guarantee that local +/// processor interrupts are disabled on preemptible kernels. Note that no= guarantees about the +/// state of interrupts are made by this type on non-preemptible kernels. +/// +/// # Invariants +/// +/// Local processor interrupts are disabled on preemptible kernels for as = long as an object of this +/// type exists. +pub struct LocalInterruptDisabled(NotThreadSafe); + +/// Disable local processor interrupts on a preemptible kernel. +/// +/// This function disables local processor interrupts on a preemptible ker= nel, and returns a +/// [`LocalInterruptDisabled`] token as proof of this. On non-preemptible = kernels, this function is +/// a no-op. +/// +/// **Usage of this function is discouraged** unless you are absolutely su= re you know what you are +/// doing, as kernel interfaces for Rust that deal with interrupt state wi= ll typically handle local +/// processor interrupt state management on their own and managing this by= hand is quite error +/// prone. +#[inline] +pub fn local_interrupt_disable() -> LocalInterruptDisabled { + // SAFETY: It's always safe to call `local_interrupt_disable()`. + unsafe { bindings::local_interrupt_disable() }; + + LocalInterruptDisabled(NotThreadSafe) +} + +impl Drop for LocalInterruptDisabled { + #[inline] + fn drop(&mut self) { + // SAFETY: Per type invariants, a `local_interrupt_disable()` must= be called to create this + // object, hence calling the corresponding `local_interrupt_enable= ()` is safe. + unsafe { bindings::local_interrupt_enable() }; + } +} + +impl LocalInterruptDisabled { + /// Assume that local processor interrupts are disabled on preemptible= kernels. + /// + /// This can be used for annotating code that is known to be run in co= ntexts where local + /// processor interrupts are disabled on preemptible kernels. It makes= no changes to the local + /// interrupt state on its own. + /// + /// # Safety + /// + /// For the whole life `'a`, local interrupts must be disabled on pree= mptible kernels. This + /// could be a context like, for example, an interrupt handler. + #[inline] + pub unsafe fn assume_disabled<'a>() -> &'a LocalInterruptDisabled { + const ASSUME_DISABLED: &LocalInterruptDisabled =3D &LocalInterrupt= Disabled(NotThreadSafe); + + // Confirm they're actually disabled if lockdep is available + // SAFETY: It's always safe to call `lockdep_assert_irqs_disabled(= )`. + unsafe { bindings::lockdep_assert_irqs_disabled() }; + + ASSUME_DISABLED + } +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 9512af7..2ee6c24 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -82,6 +82,7 @@ pub mod id_pool; pub mod impl_flags; pub mod init; pub mod interop; +pub mod interrupt; pub mod io; pub mod ioctl; pub mod iommu;