summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--rust/bindings/bindings_helper.h1
-rw-r--r--rust/kernel/cpu.rs30
-rw-r--r--rust/kernel/lib.rs1
4 files changed, 33 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 12cde55579a0..475abf72869c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6155,6 +6155,7 @@ F: include/linux/cpuhotplug.h
F: include/linux/smpboot.h
F: kernel/cpu.c
F: kernel/smpboot.*
+F: rust/kernel/cpu.rs
CPU IDLE TIME MANAGEMENT FRAMEWORK
M: "Rafael J. Wysocki" <rafael@kernel.org>
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index f53d6e1a21f2..ac92c67d2c38 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -11,6 +11,7 @@
#include <linux/blk_types.h>
#include <linux/blkdev.h>
#include <linux/clk.h>
+#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/cred.h>
#include <linux/device/faux.h>
diff --git a/rust/kernel/cpu.rs b/rust/kernel/cpu.rs
new file mode 100644
index 000000000000..10c5c3b25873
--- /dev/null
+++ b/rust/kernel/cpu.rs
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Generic CPU definitions.
+//!
+//! C header: [`include/linux/cpu.h`](srctree/include/linux/cpu.h)
+
+use crate::{bindings, device::Device, error::Result, prelude::ENODEV};
+
+/// Creates a new instance of CPU's device.
+///
+/// # Safety
+///
+/// Reference counting is not implemented for the CPU device in the C code. When a CPU is
+/// hot-unplugged, the corresponding CPU device is unregistered, but its associated memory
+/// is not freed.
+///
+/// Callers must ensure that the CPU device is not used after it has been unregistered.
+/// This can be achieved, for example, by registering a CPU hotplug notifier and removing
+/// any references to the CPU device within the notifier's callback.
+pub unsafe fn from_cpu(cpu: u32) -> Result<&'static Device> {
+ // SAFETY: It is safe to call `get_cpu_device()` for any CPU.
+ let ptr = unsafe { bindings::get_cpu_device(cpu) };
+ if ptr.is_null() {
+ return Err(ENODEV);
+ }
+
+ // SAFETY: The pointer returned by `get_cpu_device()`, if not `NULL`, is a valid pointer to
+ // a `struct device` and is never freed by the C code.
+ Ok(unsafe { Device::as_ref(ptr) })
+}
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 3fd7c17cbc06..de0a840fcc99 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -43,6 +43,7 @@ pub mod block;
#[doc(hidden)]
pub mod build_assert;
pub mod clk;
+pub mod cpu;
pub mod cpumask;
pub mod cred;
pub mod device;