Skip to content

Commit dfcbb0c

Browse files
nbdd0121ojeda
authored andcommitted
rust: map long to isize and char to u8
The following FFI types are replaced compared to `core::ffi`: 1. `char` type is now always mapped to `u8`, since kernel uses `-funsigned-char` on the C code. `core::ffi` maps it to platform default ABI, which can be either signed or unsigned. 2. `long` is now always mapped to `isize`. It's very common in the kernel to use `long` to represent a pointer-sized integer, and in fact `intptr_t` is a typedef of `long` in the kernel. Enforce this mapping rather than mapping to `i32/i64` depending on platform can save us a lot of unnecessary casts. Signed-off-by: Gary Guo <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Moved `uaccess` changes from the next commit, since they were irrefutable patterns that Rust >= 1.82.0 warns about. Reworded slightly and reformatted a few documentation comments. Rebased on top of `rust-next`. - Miguel ] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent d072acd commit dfcbb0c

File tree

4 files changed

+45
-26
lines changed

4 files changed

+45
-26
lines changed

Diff for: rust/ffi.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,39 @@
1010
1111
#![no_std]
1212

13-
pub use core::ffi::*;
13+
macro_rules! alias {
14+
($($name:ident = $ty:ty;)*) => {$(
15+
#[allow(non_camel_case_types, missing_docs)]
16+
pub type $name = $ty;
17+
18+
// Check size compatibility with `core`.
19+
const _: () = assert!(
20+
core::mem::size_of::<$name>() == core::mem::size_of::<core::ffi::$name>()
21+
);
22+
)*}
23+
}
24+
25+
alias! {
26+
// `core::ffi::c_char` is either `i8` or `u8` depending on architecture. In the kernel, we use
27+
// `-funsigned-char` so it's always mapped to `u8`.
28+
c_char = u8;
29+
30+
c_schar = i8;
31+
c_uchar = u8;
32+
33+
c_short = i16;
34+
c_ushort = u16;
35+
36+
c_int = i32;
37+
c_uint = u32;
38+
39+
// In the kernel, `intptr_t` is defined to be `long` in all platforms, so we can map the type to
40+
// `isize`.
41+
c_long = isize;
42+
c_ulong = usize;
43+
44+
c_longlong = i64;
45+
c_ulonglong = u64;
46+
}
47+
48+
pub use core::ffi::c_void;

Diff for: rust/kernel/error.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,8 @@ impl Error {
153153

154154
/// Returns the error encoded as a pointer.
155155
pub fn to_ptr<T>(self) -> *mut T {
156-
#[cfg_attr(target_pointer_width = "32", allow(clippy::useless_conversion))]
157156
// SAFETY: `self.0` is a valid error due to its invariant.
158-
unsafe {
159-
bindings::ERR_PTR(self.0.get().into()) as *mut _
160-
}
157+
unsafe { bindings::ERR_PTR(self.0.get() as _) as *mut _ }
161158
}
162159

163160
/// Returns a string representing the error, if one exists.

Diff for: rust/kernel/firmware.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use core::ptr::NonNull;
1212
/// One of the following: `bindings::request_firmware`, `bindings::firmware_request_nowarn`,
1313
/// `bindings::firmware_request_platform`, `bindings::request_firmware_direct`.
1414
struct FwFunc(
15-
unsafe extern "C" fn(*mut *const bindings::firmware, *const i8, *mut bindings::device) -> i32,
15+
unsafe extern "C" fn(*mut *const bindings::firmware, *const u8, *mut bindings::device) -> i32,
1616
);
1717

1818
impl FwFunc {

Diff for: rust/kernel/uaccess.rs

+7-20
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
alloc::Flags,
99
bindings,
1010
error::Result,
11-
ffi::{c_ulong, c_void},
11+
ffi::c_void,
1212
prelude::*,
1313
transmute::{AsBytes, FromBytes},
1414
};
@@ -224,13 +224,9 @@ impl UserSliceReader {
224224
if len > self.length {
225225
return Err(EFAULT);
226226
}
227-
let Ok(len_ulong) = c_ulong::try_from(len) else {
228-
return Err(EFAULT);
229-
};
230-
// SAFETY: `out_ptr` points into a mutable slice of length `len_ulong`, so we may write
227+
// SAFETY: `out_ptr` points into a mutable slice of length `len`, so we may write
231228
// that many bytes to it.
232-
let res =
233-
unsafe { bindings::copy_from_user(out_ptr, self.ptr as *const c_void, len_ulong) };
229+
let res = unsafe { bindings::copy_from_user(out_ptr, self.ptr as *const c_void, len) };
234230
if res != 0 {
235231
return Err(EFAULT);
236232
}
@@ -259,9 +255,6 @@ impl UserSliceReader {
259255
if len > self.length {
260256
return Err(EFAULT);
261257
}
262-
let Ok(len_ulong) = c_ulong::try_from(len) else {
263-
return Err(EFAULT);
264-
};
265258
let mut out: MaybeUninit<T> = MaybeUninit::uninit();
266259
// SAFETY: The local variable `out` is valid for writing `size_of::<T>()` bytes.
267260
//
@@ -272,7 +265,7 @@ impl UserSliceReader {
272265
bindings::_copy_from_user(
273266
out.as_mut_ptr().cast::<c_void>(),
274267
self.ptr as *const c_void,
275-
len_ulong,
268+
len,
276269
)
277270
};
278271
if res != 0 {
@@ -335,12 +328,9 @@ impl UserSliceWriter {
335328
if len > self.length {
336329
return Err(EFAULT);
337330
}
338-
let Ok(len_ulong) = c_ulong::try_from(len) else {
339-
return Err(EFAULT);
340-
};
341-
// SAFETY: `data_ptr` points into an immutable slice of length `len_ulong`, so we may read
331+
// SAFETY: `data_ptr` points into an immutable slice of length `len`, so we may read
342332
// that many bytes from it.
343-
let res = unsafe { bindings::copy_to_user(self.ptr as *mut c_void, data_ptr, len_ulong) };
333+
let res = unsafe { bindings::copy_to_user(self.ptr as *mut c_void, data_ptr, len) };
344334
if res != 0 {
345335
return Err(EFAULT);
346336
}
@@ -359,9 +349,6 @@ impl UserSliceWriter {
359349
if len > self.length {
360350
return Err(EFAULT);
361351
}
362-
let Ok(len_ulong) = c_ulong::try_from(len) else {
363-
return Err(EFAULT);
364-
};
365352
// SAFETY: The reference points to a value of type `T`, so it is valid for reading
366353
// `size_of::<T>()` bytes.
367354
//
@@ -372,7 +359,7 @@ impl UserSliceWriter {
372359
bindings::_copy_to_user(
373360
self.ptr as *mut c_void,
374361
(value as *const T).cast::<c_void>(),
375-
len_ulong,
362+
len,
376363
)
377364
};
378365
if res != 0 {

0 commit comments

Comments
 (0)