# Meeting 2024-01-31
<!-- Leave your topic starting with ### in the relevant sections below -->
## Critical
<!-- bugs, soundness issues, urgent patches/reviews etc. -->
## Status Reports
<!-- You want to report on something you are working on/request reviews.
Or you want to know the status of something someone else is doing -->
### Experiment changing FFI integer types
https://github.com/nbdd0121/linux/commit/b604a43db56f149a90084fa8aed7988a8066894b
```rust!
+/// Some assumptions about types that hold for all current kernel architectures.
+///
+/// Other code can rely on these. However, in such a case, the assertion should be written nearby
+/// as needed, even if these are here as a reference.
+mod assumptions {
+ use crate::{implies, static_assert};
+
+ // Very unlikely to ever change, even in future kernel architectures.
+ static_assert!(core::mem::size_of::<core::ffi::c_char>() == 1);
+ static_assert!(core::mem::size_of::<core::ffi::c_schar>() == 1);
+ static_assert!(core::mem::size_of::<core::ffi::c_uchar>() == 1);
+ static_assert!(core::mem::size_of::<core::ffi::c_short>() == 2);
+ static_assert!(core::mem::size_of::<core::ffi::c_ushort>() == 2);
+ static_assert!(core::mem::size_of::<core::ffi::c_int>() == 4);
+ static_assert!(core::mem::size_of::<core::ffi::c_uint>() == 4);
+ static_assert!(
+ core::mem::size_of::<core::ffi::c_long>() == core::mem::size_of::<core::ffi::c_ulong>()
+ );
+ static_assert!(
+ core::mem::size_of::<core::ffi::c_longlong>()
+ == core::mem::size_of::<core::ffi::c_ulonglong>()
+ );
+ static_assert!(
+ core::mem::size_of::<usize>() == 4
+ || core::mem::size_of::<usize>() == 8
+ || core::mem::size_of::<usize>() == 16
+ );
+
+ // It is undecided whether C's `long` will be 64-bits or 128-bits in future 128-bit kernel
+ // architectures. However, the kernel currently assumes `long` is the same size of a pointer,
+ // thus assume it here too, which helps with interoperability. This means that, in order to
+ // pick 64-bits in the future, it will likely require changes in both the C and Rust sides.
+ static_assert!(core::mem::size_of::<core::ffi::c_ulong>() == core::mem::size_of::<usize>());
+
+ // C's `long long` will likely be 128-bits in future 128-bit kernel architectures, thus new code
+ // should avoid assuming that it is always 64-bit (as it happens for all current architectures).
+ static_assert!(
+ core::mem::size_of::<core::ffi::c_longlong>() == 8
+ || core::mem::size_of::<core::ffi::c_longlong>() == 16
+ );
+
+ // In particular:
+ static_assert!(implies(
+ core::mem::size_of::<usize>() == 4,
+ core::mem::size_of::<core::ffi::c_longlong>() == 8
+ ));
+ static_assert!(implies(
+ core::mem::size_of::<usize>() == 8,
+ core::mem::size_of::<core::ffi::c_longlong>() == 8
+ ));
+ static_assert!(implies(
+ core::mem::size_of::<usize>() == 16,
+ core::mem::size_of::<core::ffi::c_longlong>() == 16
+ ));
+}
```
```diff
diff --git a/rust/Makefile b/rust/Makefile
index 543b37f6c77f..acce32f17a4a 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -330,7 +330,7 @@ bindgen_c_flags_final = $(bindgen_c_flags_lto) -D__BINDGEN__
quiet_cmd_bindgen = BINDGEN $@
cmd_bindgen = \
$(BINDGEN) $< $(bindgen_target_flags) \
- --use-core --with-derive-default --ctypes-prefix core::ffi --no-layout-tests \
+ --use-core --with-derive-default --ctypes-prefix ctypes --no-layout-tests \
--no-debug '.*' \
-o $@ -- $(bindgen_c_flags_final) -DMODULE \
$(bindgen_target_cflags) $(bindgen_target_extra)
@@ -450,8 +450,10 @@ $(obj)/bindings.o: $(src)/bindings/lib.rs \
$(obj)/bindings/bindings_helpers_generated.rs FORCE
$(call if_changed_dep,rustc_library)
+$(obj)/uapi.o: private rustc_target_flags = --extern bindings
$(obj)/uapi.o: $(src)/uapi/lib.rs \
$(obj)/compiler_builtins.o \
+ $(obj)/bindings.o \
$(obj)/uapi/uapi_generated.rs FORCE
$(call if_changed_dep,rustc_library)
diff --git a/rust/bindings/lib.rs b/rust/bindings/lib.rs
index 9bcbea04dac3..54ab1ff71bb4 100644
--- a/rust/bindings/lib.rs
+++ b/rust/bindings/lib.rs
@@ -24,10 +24,36 @@
unsafe_op_in_unsafe_fn
)]
+pub mod ctypes {
+ pub type c_void = core::ffi::c_void;
+
+ // Since commit 3bc753c06dd0 ("kbuild: treat char as always unsigned"), the kernel is compiled
+ // with `-funsigned-char` explicitly.
+ pub type c_char = u8;
+
+ pub type c_schar = i8;
+ pub type c_uchar = u8;
+
+ pub type c_short = i16;
+ pub type c_ushort = u16;
+
+ pub type c_int = i32;
+ pub type c_uint = u32;
+
+ // See `kernel::types::assumptions`.
+ pub type c_long = isize;
+ pub type c_ulong = usize;
+
+ // See `kernel::types::assumptions`.
+ pub type c_longlong = i64;
+ pub type c_ulonglong = u64;
+}
+
mod bindings_raw {
// Use glob import here to expose all helpers.
// Symbols defined within the module will take precedence to the glob import.
pub use super::bindings_helper::*;
+ use super::ctypes;
include!(concat!(
env!("OBJTREE"),
"/rust/bindings/bindings_generated.rs"
@@ -41,6 +67,7 @@ mod bindings_raw {
mod bindings_helper {
// Import the generated bindings for types.
use super::bindings_raw::*;
+ use super::ctypes;
include!(concat!(
env!("OBJTREE"),
"/rust/bindings/bindings_helpers_generated.rs"
diff --git a/rust/uapi/lib.rs b/rust/uapi/lib.rs
index 0caad902ba40..679f1d003633 100644
--- a/rust/uapi/lib.rs
+++ b/rust/uapi/lib.rs
@@ -23,4 +23,5 @@
unsafe_op_in_unsafe_fn
)]
+use bindings::ctypes;
include!(concat!(env!("OBJTREE"), "/rust/uapi/uapi_generated.rs"));
```
Gary: https://elixir.bootlin.com/linux/latest/source/include/uapi/asm-generic/posix_types.h#L63 Maybe we should change C code so that `size_t` is always `unsigned long`?
Want to change the typedef to avoid casts when compiling in 32-bit (so bindgen outputs usize for kernel size_t instead of u32).
## Discussion Questions
<!-- Anything that requires lengthy discussion/more general questions also fit here -->
### Discuss inheritance/subclassing pattern
DRM has requested we make a recommendation in relation to this discussion: https://hackmd.io/W_kJ1kRsS3mX8vpk5Cpbzg
## Miscellaneous
<!-- stuff that does not fit into other categories -->
### const_refs_to_static
Add [`const_refs_to_static`](https://github.com/rust-lang/rust/issues/119618) to [Rust unstable features needed for the kernel](https://github.com/Rust-for-Linux/linux/issues/2) to support storing pointer to owning module in `const struct` vtables:
```rust
const TABLE: bindings::block_device_operations = bindings::block_device_operations {
submit_bio: None,
open: None,
release: None,
ioctl: None,
compat_ioctl: None,
check_events: None,
unlock_native_capacity: None,
getgeo: None,
set_read_only: None,
swap_slot_free_notify: None,
report_zones: None,
devnode: None,
alternative_gpt_sector: None,
get_unique_id: None,
owner: core::ptr::null_mut(), // TODO: Set to THIS_MODULE <-- here
pr_ops: core::ptr::null_mut(),
free_disk: None,
poll_bio: None,
};
```
### Submitting patches with not upstream dependencies
Looking for the official guide