xref: /linux/rust/kernel/cpu.rs (revision b74710eaff314d6afe4fb0bbe9bc7657bf226fd4)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Generic CPU definitions.
4 //!
5 //! C header: [`include/linux/cpu.h`](srctree/include/linux/cpu.h)
6 
7 use crate::{bindings, device::Device, error::Result, prelude::ENODEV};
8 
9 /// Creates a new instance of CPU's device.
10 ///
11 /// # Safety
12 ///
13 /// Reference counting is not implemented for the CPU device in the C code. When a CPU is
14 /// hot-unplugged, the corresponding CPU device is unregistered, but its associated memory
15 /// is not freed.
16 ///
17 /// Callers must ensure that the CPU device is not used after it has been unregistered.
18 /// This can be achieved, for example, by registering a CPU hotplug notifier and removing
19 /// any references to the CPU device within the notifier's callback.
20 pub unsafe fn from_cpu(cpu: u32) -> Result<&'static Device> {
21     // SAFETY: It is safe to call `get_cpu_device()` for any CPU.
22     let ptr = unsafe { bindings::get_cpu_device(cpu) };
23     if ptr.is_null() {
24         return Err(ENODEV);
25     }
26 
27     // SAFETY: The pointer returned by `get_cpu_device()`, if not `NULL`, is a valid pointer to
28     // a `struct device` and is never freed by the C code.
29     Ok(unsafe { Device::as_ref(ptr) })
30 }
31