From 10bb7f09e346f152d2627e0b3619c402d64a50e9 Mon Sep 17 00:00:00 2001 From: Abhinav Ananthu Date: Fri, 13 Jun 2025 15:48:16 +0530 Subject: rust: cpufreq: Ensure C ABI compatibility in all unsafe Update all `unsafe extern "C"` callback functions in the cpufreq module to use `kernel::ffi` types (`c_int`, `c_uint`, etc.) instead of Rust-native types like `i32`, `u32`, or `usize`. This change ensures that all Rust callbacks have signatures that are ABI-compatible with their corresponding C counterparts, which is critical for FFI correctness and safety. Suggested-by: Miguel Ojeda Link: https://github.com/Rust-for-Linux/linux/issues/1170 Signed-off-by: Abhinav Ananthu Signed-off-by: Viresh Kumar --- rust/kernel/cpufreq.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'rust') diff --git a/rust/kernel/cpufreq.rs b/rust/kernel/cpufreq.rs index 11b03e9d7e89..481a6d2dc362 100644 --- a/rust/kernel/cpufreq.rs +++ b/rust/kernel/cpufreq.rs @@ -1207,8 +1207,8 @@ impl Registration { /// - The pointer arguments must be valid pointers. unsafe extern "C" fn target_callback( ptr: *mut bindings::cpufreq_policy, - target_freq: u32, - relation: u32, + target_freq: c_uint, + relation: c_uint, ) -> kernel::ffi::c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the @@ -1226,7 +1226,7 @@ impl Registration { /// - The pointer arguments must be valid pointers. unsafe extern "C" fn target_index_callback( ptr: *mut bindings::cpufreq_policy, - index: u32, + index: c_uint, ) -> kernel::ffi::c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the @@ -1249,7 +1249,7 @@ impl Registration { /// - The pointer arguments must be valid pointers. unsafe extern "C" fn fast_switch_callback( ptr: *mut bindings::cpufreq_policy, - target_freq: u32, + target_freq: c_uint, ) -> kernel::ffi::c_uint { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1263,10 +1263,10 @@ impl Registration { /// /// - This function may only be called from the cpufreq C infrastructure. unsafe extern "C" fn adjust_perf_callback( - cpu: u32, - min_perf: usize, - target_perf: usize, - capacity: usize, + cpu: c_uint, + min_perf: c_ulong, + target_perf: c_ulong, + capacity: c_ulong, ) { // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number. let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) }; @@ -1284,7 +1284,7 @@ impl Registration { /// - The pointer arguments must be valid pointers. unsafe extern "C" fn get_intermediate_callback( ptr: *mut bindings::cpufreq_policy, - index: u32, + index: c_uint, ) -> kernel::ffi::c_uint { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1305,7 +1305,7 @@ impl Registration { /// - The pointer arguments must be valid pointers. unsafe extern "C" fn target_intermediate_callback( ptr: *mut bindings::cpufreq_policy, - index: u32, + index: c_uint, ) -> kernel::ffi::c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the @@ -1325,7 +1325,7 @@ impl Registration { /// # Safety /// /// - This function may only be called from the cpufreq C infrastructure. - unsafe extern "C" fn get_callback(cpu: u32) -> kernel::ffi::c_uint { + unsafe extern "C" fn get_callback(cpu: c_uint) -> kernel::ffi::c_uint { // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number. let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) }; @@ -1351,7 +1351,7 @@ impl Registration { /// /// - This function may only be called from the cpufreq C infrastructure. /// - The pointer arguments must be valid pointers. - unsafe extern "C" fn bios_limit_callback(cpu: i32, limit: *mut u32) -> kernel::ffi::c_int { + unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> kernel::ffi::c_int { // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number. let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) }; @@ -1371,7 +1371,7 @@ impl Registration { /// - The pointer arguments must be valid pointers. unsafe extern "C" fn set_boost_callback( ptr: *mut bindings::cpufreq_policy, - state: i32, + state: c_int, ) -> kernel::ffi::c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the -- cgit v1.2.3 From b0a86fb0b27f1ae944a6b0a1a9187c332bb2773e Mon Sep 17 00:00:00 2001 From: Abhinav Ananthu Date: Fri, 20 Jun 2025 14:22:30 +0530 Subject: rust: cpufreq: use c_ types from kernel prelude Update cpufreq FFI callback signatures to use `c_int` from the `kernel::prelude`, rather than accessing it explicitly through `kernel::ffi::c_int`. Although these types are defined in the `ffi` crate, they are re-exported via `kernel::prelude`. This aligns with the Rust-for-Linux coding guidelines and ensures proper C ABI compatibility across platforms. Signed-off-by: Abhinav Ananthu Suggested-by: Viresh Kumar Reviewed-by: Alice Ryhl [ Viresh: Fixed rustfmtcheck errors ] Signed-off-by: Viresh Kumar --- rust/kernel/cpufreq.rs | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) (limited to 'rust') diff --git a/rust/kernel/cpufreq.rs b/rust/kernel/cpufreq.rs index 481a6d2dc362..d6a14239f4ba 100644 --- a/rust/kernel/cpufreq.rs +++ b/rust/kernel/cpufreq.rs @@ -1061,7 +1061,7 @@ impl Registration { /// /// - This function may only be called from the cpufreq C infrastructure. /// - The pointer arguments must be valid pointers. - unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int { + unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1094,7 +1094,7 @@ impl Registration { /// /// - This function may only be called from the cpufreq C infrastructure. /// - The pointer arguments must be valid pointers. - unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int { + unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1109,9 +1109,7 @@ impl Registration { /// /// - This function may only be called from the cpufreq C infrastructure. /// - The pointer arguments must be valid pointers. - unsafe extern "C" fn offline_callback( - ptr: *mut bindings::cpufreq_policy, - ) -> kernel::ffi::c_int { + unsafe extern "C" fn offline_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1126,9 +1124,7 @@ impl Registration { /// /// - This function may only be called from the cpufreq C infrastructure. /// - The pointer arguments must be valid pointers. - unsafe extern "C" fn suspend_callback( - ptr: *mut bindings::cpufreq_policy, - ) -> kernel::ffi::c_int { + unsafe extern "C" fn suspend_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1143,7 +1139,7 @@ impl Registration { /// /// - This function may only be called from the cpufreq C infrastructure. /// - The pointer arguments must be valid pointers. - unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int { + unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1171,9 +1167,7 @@ impl Registration { /// /// - This function may only be called from the cpufreq C infrastructure. /// - The pointer arguments must be valid pointers. - unsafe extern "C" fn verify_callback( - ptr: *mut bindings::cpufreq_policy_data, - ) -> kernel::ffi::c_int { + unsafe extern "C" fn verify_callback(ptr: *mut bindings::cpufreq_policy_data) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1188,9 +1182,7 @@ impl Registration { /// /// - This function may only be called from the cpufreq C infrastructure. /// - The pointer arguments must be valid pointers. - unsafe extern "C" fn setpolicy_callback( - ptr: *mut bindings::cpufreq_policy, - ) -> kernel::ffi::c_int { + unsafe extern "C" fn setpolicy_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1209,7 +1201,7 @@ impl Registration { ptr: *mut bindings::cpufreq_policy, target_freq: c_uint, relation: c_uint, - ) -> kernel::ffi::c_int { + ) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1227,7 +1219,7 @@ impl Registration { unsafe extern "C" fn target_index_callback( ptr: *mut bindings::cpufreq_policy, index: c_uint, - ) -> kernel::ffi::c_int { + ) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1250,7 +1242,7 @@ impl Registration { unsafe extern "C" fn fast_switch_callback( ptr: *mut bindings::cpufreq_policy, target_freq: c_uint, - ) -> kernel::ffi::c_uint { + ) -> c_uint { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. let policy = unsafe { Policy::from_raw_mut(ptr) }; @@ -1285,7 +1277,7 @@ impl Registration { unsafe extern "C" fn get_intermediate_callback( ptr: *mut bindings::cpufreq_policy, index: c_uint, - ) -> kernel::ffi::c_uint { + ) -> c_uint { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. let policy = unsafe { Policy::from_raw_mut(ptr) }; @@ -1306,7 +1298,7 @@ impl Registration { unsafe extern "C" fn target_intermediate_callback( ptr: *mut bindings::cpufreq_policy, index: c_uint, - ) -> kernel::ffi::c_int { + ) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. @@ -1325,7 +1317,7 @@ impl Registration { /// # Safety /// /// - This function may only be called from the cpufreq C infrastructure. - unsafe extern "C" fn get_callback(cpu: c_uint) -> kernel::ffi::c_uint { + unsafe extern "C" fn get_callback(cpu: c_uint) -> c_uint { // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number. let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) }; @@ -1351,7 +1343,7 @@ impl Registration { /// /// - This function may only be called from the cpufreq C infrastructure. /// - The pointer arguments must be valid pointers. - unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> kernel::ffi::c_int { + unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> c_int { // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number. let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) }; @@ -1372,7 +1364,7 @@ impl Registration { unsafe extern "C" fn set_boost_callback( ptr: *mut bindings::cpufreq_policy, state: c_int, - ) -> kernel::ffi::c_int { + ) -> c_int { from_result(|| { // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the // lifetime of `policy`. -- cgit v1.2.3 From 22679d807dea5c065d8019acfce48f20e87ba5ca Mon Sep 17 00:00:00 2001 From: Abhinav Ananthu Date: Fri, 20 Jun 2025 15:29:21 +0530 Subject: rust: opp: use c_* types via kernel prelude Update OPP FFI callback signatures to use `c_int` from the `kernel::prelude`, instead of accessing it via `kernel::ffi::c_int`. Although these types are defined in a crate named `ffi`, they are re-exported via the `kernel::prelude` and should be used from there. This aligns with the Rust-for-Linux coding guidelines and ensures ABI correctness when interfacing with C code. Suggested-by: Viresh Kumar Signed-off-by: Abhinav Ananthu Signed-off-by: Viresh Kumar --- rust/kernel/opp.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'rust') diff --git a/rust/kernel/opp.rs b/rust/kernel/opp.rs index a566fc3e7dcb..846583da9a2f 100644 --- a/rust/kernel/opp.rs +++ b/rust/kernel/opp.rs @@ -514,9 +514,9 @@ impl Config { dev: *mut bindings::device, opp_table: *mut bindings::opp_table, opp: *mut bindings::dev_pm_opp, - _data: *mut kernel::ffi::c_void, + _data: *mut c_void, scaling_down: bool, - ) -> kernel::ffi::c_int { + ) -> c_int { from_result(|| { // SAFETY: 'dev' is guaranteed by the C code to be valid. let dev = unsafe { Device::get_device(dev) }; @@ -540,8 +540,8 @@ impl Config { old_opp: *mut bindings::dev_pm_opp, new_opp: *mut bindings::dev_pm_opp, regulators: *mut *mut bindings::regulator, - count: kernel::ffi::c_uint, - ) -> kernel::ffi::c_int { + count: c_uint, + ) -> c_int { from_result(|| { // SAFETY: 'dev' is guaranteed by the C code to be valid. let dev = unsafe { Device::get_device(dev) }; -- cgit v1.2.3 From a507f8230d60d7e21aac390ee83eb625cb6021d9 Mon Sep 17 00:00:00 2001 From: Ritvik Gupta Date: Mon, 14 Jul 2025 00:32:44 +0530 Subject: rust: cpumask: Replace `MaybeUninit` and `mem::zeroed` with `Opaque` APIs Replace the following unsafe initializations: 1. `MaybeUninit::uninit().assume_init()` with `Opaque::uninit()` 2. `core::mem::zeroed()` with `Opaque::zeroed()` Suggested-by: Benno Lossin Link: https://github.com/Rust-for-Linux/linux/issues/1178 Suggested-by: Alice Ryhl Link: https://lore.kernel.org/rust-for-linux/CAH5fLgj0OoCn56OkNUmiPQ=RAVa_VmS-yMZ4TNBSpGPNtZ5D0A@mail.gmail.com/ Reviewed-by: Benno Lossin Reviewed-by: Alice Ryhl Signed-off-by: Ritvik Gupta Signed-off-by: Viresh Kumar --- rust/kernel/cpumask.rs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'rust') diff --git a/rust/kernel/cpumask.rs b/rust/kernel/cpumask.rs index 19c607709b5f..e07f8ff5e3fd 100644 --- a/rust/kernel/cpumask.rs +++ b/rust/kernel/cpumask.rs @@ -14,9 +14,6 @@ use crate::{ #[cfg(CONFIG_CPUMASK_OFFSTACK)] use core::ptr::{self, NonNull}; -#[cfg(not(CONFIG_CPUMASK_OFFSTACK))] -use core::mem::MaybeUninit; - use core::ops::{Deref, DerefMut}; /// A CPU Mask. @@ -239,10 +236,7 @@ impl CpumaskVar { }, #[cfg(not(CONFIG_CPUMASK_OFFSTACK))] - // SAFETY: FFI type is valid to be zero-initialized. - // - // INVARIANT: The associated memory is freed when the `CpumaskVar` goes out of scope. - mask: unsafe { core::mem::zeroed() }, + mask: Cpumask(Opaque::zeroed()), }) } @@ -266,10 +260,7 @@ impl CpumaskVar { NonNull::new(ptr.cast()).ok_or(AllocError)? }, #[cfg(not(CONFIG_CPUMASK_OFFSTACK))] - // SAFETY: Guaranteed by the safety requirements of the function. - // - // INVARIANT: The associated memory is freed when the `CpumaskVar` goes out of scope. - mask: unsafe { MaybeUninit::uninit().assume_init() }, + mask: Cpumask(Opaque::uninit()), }) } -- cgit v1.2.3