lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241018055125.2784186-3-boqun.feng@gmail.com>
Date: Thu, 17 Oct 2024 22:51:21 -0700
From: Boqun Feng <boqun.feng@...il.com>
To: "Thomas Gleixner" <tglx@...utronix.de>
Cc: Dirk Behme <dirk.behme@...il.com>,
	Lyude Paul <lyude@...hat.com>,
	rust-for-linux@...r.kernel.org,
	Danilo Krummrich <dakr@...hat.com>,
	airlied@...hat.com,
	Ingo Molnar <mingo@...hat.com>,
	will@...nel.org,
	Waiman Long <longman@...hat.com>,
	Peter Zijlstra <peterz@...radead.org>,
	linux-kernel@...r.kernel.org,
	Miguel Ojeda <ojeda@...nel.org>,
	Alex Gaynor <alex.gaynor@...il.com>,
	wedsonaf@...il.com,
	Gary Guo <gary@...yguo.net>,
	Björn Roy Baron <bjorn3_gh@...tonmail.com>,
	Benno Lossin <benno.lossin@...ton.me>,
	Andreas Hindborg <a.hindborg@...sung.com>,
	aliceryhl@...gle.com,
	Trevor Gross <tmgross@...ch.edu>,
	Boqun Feng <boqun.feng@...il.com>
Subject: [POC 2/6] rust: Introduce interrupt module

From: Lyude Paul <lyude@...hat.com>

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.

[Boqun: This is based on Lyude's work on interrupt disable abstraction,
I port to the new local_interrupt_disable() mechanism to make it work
as a guard type. I cannot even take the credit of this design, since
Lyude also brought up the same idea in zulip. Anyway, this is only for
POC purpose, and of course all bugs are mine]

Co-Developed-by: Lyude Paul <lyude@...hat.com>
Signed-off-by: Lyude Paul <lyude@...hat.com>
Signed-off-by: Boqun Feng <boqun.feng@...il.com>
---
 rust/helpers/helpers.c   |  1 +
 rust/helpers/interrupt.c | 18 +++++++++++
 rust/kernel/interrupt.rs | 64 ++++++++++++++++++++++++++++++++++++++++
 rust/kernel/lib.rs       |  1 +
 4 files changed, 84 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 30f40149f3a9..f6e5b33eaff8 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -12,6 +12,7 @@
 #include "build_assert.c"
 #include "build_bug.c"
 #include "err.c"
+#include "interrupt.c"
 #include "kunit.c"
 #include "mutex.c"
 #include "page.c"
diff --git a/rust/helpers/interrupt.c b/rust/helpers/interrupt.c
new file mode 100644
index 000000000000..e58da42916da
--- /dev/null
+++ b/rust/helpers/interrupt.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/irqflags.h>
+
+void rust_helper_local_interrupt_disable(void)
+{
+	local_interrupt_disable();
+}
+
+void rust_helper_local_interrupt_enable(void)
+{
+	local_interrupt_enable();
+}
+
+bool rust_helper_irqs_disabled(void)
+{
+	return irqs_disabled();
+}
diff --git a/rust/kernel/interrupt.rs b/rust/kernel/interrupt.rs
new file mode 100644
index 000000000000..fe5a36877538
--- /dev/null
+++ b/rust/kernel/interrupt.rs
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Interrupt controls
+//!
+//! This module allows Rust code to control processor interrupts. [`with_interrupt_disabled()`] may be
+//! used for nested disables of interrupts, whereas [`InterruptDisabled`] can be used for annotating code
+//! that requires interrupts to be disabled.
+
+use bindings;
+use core::marker::*;
+
+/// XXX: Temporarily definition for NotThreadSafe
+pub type NotThreadSafe = PhantomData<*mut ()>;
+
+/// XXX: Temporarily const for NotThreadSafe
+#[allow(non_upper_case_globals)]
+pub const NotThreadSafe: NotThreadSafe = PhantomData;
+
+/// A guard that represent interrupt disable protection.
+///
+/// [`InterruptDisabled`] is a guard type that represent interrupts have been disabled. Certain
+/// functions take an immutable reference of [`InterruptDisabled`] in order to require that they may
+/// only be run in interrupt-disabled contexts.
+///
+/// This is a marker type; it has no size, and is simply used as a compile-time guarantee that
+/// interrupts are disabled where required.
+///
+/// This token can be created by [`with_interrupt_disabled`]. See [`with_interrupt_disabled`] for examples and
+/// further information.
+///
+/// # Invariants
+///
+/// Interrupts are disabled with `local_interrupt_disable()` when an object of this type exists.
+pub struct InterruptDisabled(NotThreadSafe);
+
+/// Disable interrupts.
+pub fn interrupt_disable() -> InterruptDisabled {
+    // SAFETY: It's always safe to call `local_interrupt_disable()`.
+    unsafe { bindings::local_interrupt_disable() };
+
+    InterruptDisabled(NotThreadSafe)
+}
+
+impl Drop for InterruptDisabled {
+    fn drop(&mut self) {
+        // SAFETY: Per type invariants, a `local_interrupt_disable()` must be called to create this
+        // object, hence call the corresponding `local_interrupt_enable()` is safe.
+        unsafe { bindings::local_interrupt_enable() };
+    }
+}
+
+impl InterruptDisabled {
+    const ASSUME_INTERRUPT_DISABLED: &'static InterruptDisabled = &InterruptDisabled(NotThreadSafe);
+
+    /// Assume that interrupts are disabled.
+    ///
+    /// # Safety
+    ///
+    /// For the whole life `'a`, interrupts must be considered disabled, for example an interrupt
+    /// handler.
+    pub unsafe fn assume_interrupt_disabled<'a>() -> &'a InterruptDisabled {
+        Self::ASSUME_INTERRUPT_DISABLED
+    }
+}
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index b5f4b3ce6b48..56ff464b7905 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -35,6 +35,7 @@
 #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)]
 pub mod firmware;
 pub mod init;
+pub mod interrupt;
 pub mod ioctl;
 #[cfg(CONFIG_KUNIT)]
 pub mod kunit;
-- 
2.45.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ