---
# System prepended metadata

title: Meeting  2024-01-31
tags: [meeting notes]

---

# 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 

