| 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 | |