History

Merge tag 'rust-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux

Pull rust updates from Miguel Ojeda: "Toolchain and infrastructure: - Derive 'Zeroable' for all structs and unions generated by 'bindgen' where possible and corresponding cleanups. To do so, add the 'pin-init' crate as a dependency to 'bindings' and 'uapi'. It also includes its first use in the 'cpufreq' module, with more to come in the next cycle. - Add warning to the 'rustdoc' target to detect broken 'srctree/' links and fix existing cases. - Remove support for unused (since v6.16) host '#[test]'s, simplifying the 'rusttest' target. Tests should generally run within KUnit. 'kernel' crate: - Add 'ptr' module with a new 'Alignment' type, which is always a power of two and is used to validate that a given value is a valid alignment and to perform masking and alignment operations: // Checked at build time. assert_eq!(Alignment::new::<16>().as_usize(), 16); // Checked at runtime. assert_eq!(Alignment::new_checked(15), None); assert_eq!(Alignment::of::<u8>().log2(), 0); assert_eq!(0x25u8.align_down(Alignment::new::<0x10>()), 0x20); assert_eq!(0x5u8.align_up(Alignment::new::<0x10>()), Some(0x10)); assert_eq!(u8::MAX.align_up(Alignment::new::<0x10>()), None); It also includes its first use in Nova. - Add 'core::mem::{align,size}_of{,_val}' to the prelude, matching Rust 1.80.0. - Keep going with the steps on our migration to the standard library 'core::ffi::CStr' type (use 'kernel::{fmt, prelude::fmt!}' and use upstream method names). - 'error' module: improve 'Error::from_errno' and 'to_result' documentation, including examples/tests. - 'sync' module: extend 'aref' submodule documentation now that it exists, and more updates to complete the ongoing move of 'ARef' and 'AlwaysRefCounted' to 'sync::aref'. - 'list' module: add an example/test for 'ListLinksSelfPtr' usage. - 'alloc' module: - Implement 'Box::pin_slice()', which constructs a pinned slice of elements. - Provide information about the minimum alignment guarantees of 'Kmalloc', 'Vmalloc' and 'KVmalloc'. - Take minimum alignment guarantees of allocators for 'ForeignOwnable' into account. - Remove the 'allocator_test' (including 'Cmalloc'). - Add doctest for 'Vec::as_slice()'. - Constify various methods. - 'time' module: - Add methods on 'HrTimer' that can only be called with exclusive access to an unarmed timer, or from timer callback context. - Add arithmetic operations to 'Instant' and 'Delta'. - Add a few convenience and access methods to 'HrTimer' and 'Instant'. 'macros' crate: - Reduce collections in 'quote!' macro. And a few other cleanups and improvements" * tag 'rust-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (58 commits) gpu: nova-core: use Alignment for alignment-related operations rust: add `Alignment` type rust: macros: reduce collections in `quote!` macro rust: acpi: use `core::ffi::CStr` method names rust: of: use `core::ffi::CStr` method names rust: net: use `core::ffi::CStr` method names rust: miscdevice: use `core::ffi::CStr` method names rust: kunit: use `core::ffi::CStr` method names rust: firmware: use `core::ffi::CStr` method names rust: drm: use `core::ffi::CStr` method names rust: cpufreq: use `core::ffi::CStr` method names rust: configfs: use `core::ffi::CStr` method names rust: auxiliary: use `core::ffi::CStr` method names drm/panic: use `core::ffi::CStr` method names rust: device: use `kernel::{fmt,prelude::fmt!}` rust: sync: use `kernel::{fmt,prelude::fmt!}` rust: seq_file: use `kernel::{fmt,prelude::fmt!}` rust: kunit: use `kernel::{fmt,prelude::fmt!}` rust: file: use `kernel::{fmt,prelude::fmt!}` rust: device: use `kernel::{fmt,prelude::fmt!}` ...

Linus Torvalds committed 1 year ago

Commit f4e0ff72 parents ae28ed4 f3f6b3661 files · +1054 −315Browse files

Unified · Split

61 files
  1. Documentation/gpu/nova/core/todo.rst +0 −1
  2. drivers/block/rnull.rs +1 −1
  3. drivers/gpu/drm/drm_panic_qr.rs +1 −1
  4. drivers/gpu/nova-core/fb.rs +3 −3
  5. drivers/gpu/nova-core/gpu.rs +1 −2
  6. drivers/gpu/nova-core/regs/macros.rs +3 −3
  7. drivers/gpu/nova-core/vbios.rs +2 −2
  8. rust/Makefile +15 −14
  9. rust/bindgen_parameters +5 −0
  10. rust/bindings/bindings_helper.h +1 −0
  11. rust/bindings/lib.rs +8 −0
  12. rust/kernel/acpi.rs +2 −5
  13. rust/kernel/alloc.rs +8 −7
  14. rust/kernel/alloc/allocator.rs +8 −0
  15. rust/kernel/alloc/allocator_test.rs +0 −124
  16. rust/kernel/alloc/kbox.rs +87 −5
  17. rust/kernel/alloc/kvec.rs +17 −7
  18. rust/kernel/alloc/kvec/errors.rs +1 −1
  19. rust/kernel/alloc/layout.rs +1 −1
  20. rust/kernel/auxiliary.rs +2 −2
  21. rust/kernel/block/mq.rs +1 −1
  22. rust/kernel/block/mq/gen_disk.rs +2 −2
  23. rust/kernel/block/mq/raw_writer.rs +1 −2
  24. rust/kernel/configfs.rs +2 −2
  25. rust/kernel/cpu.rs +1 −0
  26. rust/kernel/cpufreq.rs +2 −4
  27. rust/kernel/device.rs +3 −3
  28. rust/kernel/device/property.rs +12 −11
  29. rust/kernel/dma.rs +1 −1
  30. rust/kernel/drm/device.rs +3 −3
  31. rust/kernel/drm/driver.rs +1 −1
  32. rust/kernel/drm/file.rs +1 −1
  33. rust/kernel/drm/gem/mod.rs +1 −1
  34. rust/kernel/drm/ioctl.rs +1 −1
  35. rust/kernel/error.rs +59 −7
  36. rust/kernel/firmware.rs +1 −1
  37. rust/kernel/fs/file.rs +3 −2
  38. rust/kernel/kunit.rs +7 −7
  39. rust/kernel/lib.rs +4 −1
  40. rust/kernel/list.rs +120 −0
  41. rust/kernel/miscdevice.rs +1 −1
  42. rust/kernel/net/phy.rs +1 −1
  43. rust/kernel/of.rs +1 −1
  44. rust/kernel/prelude.rs +4 −1
  45. rust/kernel/ptr.rs +228 −0
  46. rust/kernel/seq_file.rs +3 −3
  47. rust/kernel/sync/arc.rs +4 −4
  48. rust/kernel/sync/aref.rs +16 −1
  49. rust/kernel/task.rs +4 −3
  50. rust/kernel/time.rs +162 −1
  51. rust/kernel/time/hrtimer.rs +149 −3
  52. rust/kernel/time/hrtimer/arc.rs +8 −1
  53. rust/kernel/time/hrtimer/pin.rs +8 −1
  54. rust/kernel/time/hrtimer/pin_mut.rs +9 −3
  55. rust/kernel/time/hrtimer/tbox.rs +8 −1
  56. rust/macros/quote.rs +49 −55
  57. rust/uapi/lib.rs +2 −0
  58. samples/rust/rust_configfs.rs +1 −1
  59. samples/rust/rust_dma.rs +1 −1
  60. scripts/generate_rust_analyzer.py +2 −2
  61. scripts/rustdoc_test_gen.rs +1 −1
Documentation/gpu/nova/core/todo.rst+0−1
@@ -147,7 +147,6 @@ Numerical operations [NUMM] · 146 unmodified lines
147147 Nova uses integer operations that are not part of the standard library (or not
148148 implemented in an optimized way for the kernel). These include:
149149
150−- Aligning up and down to a power of two,
151150 - The "Find Last Set Bit" (`fls` function of the C part of the kernel)
152151 operation.
153152
drivers/block/rnull.rs+1−1
@@ -51,7 +51,7 @@ impl kernel::InPlaceModule for NullBlkModule { · 50 unmodified lines
5151 .logical_block_size(4096)?
5252 .physical_block_size(4096)?
5353 .rotational(false)
54− .build(format_args!("rnullb{}", 0), tagset)
54+ .build(fmt!("rnullb{}", 0), tagset)
5555 })();
5656
5757 try_pin_init!(Self {
drivers/gpu/drm/drm_panic_qr.rs+1−1
@@ -968,7 +968,7 @@ pub unsafe extern "C" fn drm_panic_qr_generate( · 967 unmodified lines
968968 // nul-terminated string.
969969 let url_cstr: &CStr = unsafe { CStr::from_char_ptr(url) };
970970 let segments = &[
971− &Segment::Binary(url_cstr.as_bytes()),
971+ &Segment::Binary(url_cstr.to_bytes()),
972972 &Segment::Numeric(&data_slice[0..data_len]),
973973 ];
974974 match EncodedMsg::new(segments, tmp_slice) {
drivers/gpu/nova-core/fb.rs+3−3
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 use core::ops::Range;
44
55 use kernel::prelude::*;
6+use kernel::ptr::{Alignable, Alignment};
67 use kernel::sizes::*;
78 use kernel::types::ARef;
89 use kernel::{dev_warn, device};
@@ -130,10 +131,9 @@ impl FbLayout { · 121 unmodified lines
130131 };
131132
132133 let frts = {
133− const FRTS_DOWN_ALIGN: u64 = SZ_128K as u64;
134+ const FRTS_DOWN_ALIGN: Alignment = Alignment::new::<SZ_128K>();
134135 const FRTS_SIZE: u64 = SZ_1M as u64;
135− // TODO[NUMM]: replace with `align_down` once it lands.
136− let frts_base = (vga_workspace.start & !(FRTS_DOWN_ALIGN - 1)) - FRTS_SIZE;
136+ let frts_base = vga_workspace.start.align_down(FRTS_DOWN_ALIGN) - FRTS_SIZE;
137137
138138 frts_base..frts_base + FRTS_SIZE
139139 };
drivers/gpu/nova-core/gpu.rs+1−2
@@ -1,6 +1,6 @@
11 // SPDX-License-Identifier: GPL-2.0
22
3−use kernel::{device, devres::Devres, error::code::*, pci, prelude::*, sync::Arc};
3+use kernel::{device, devres::Devres, error::code::*, fmt, pci, prelude::*, sync::Arc};
44
55 use crate::driver::Bar0;
66 use crate::falcon::{gsp::Gsp, sec2::Sec2, Falcon};
@@ -12,7 +12,6 @@ use crate::gfw; · 5 unmodified lines
1212 use crate::regs;
1313 use crate::util;
1414 use crate::vbios::Vbios;
15−use core::fmt;
1615
1716 macro_rules! define_chipset {
1817 ({ $($variant:ident = $value:expr),* $(,)* }) =>
drivers/gpu/nova-core/regs/macros.rs+3−3
@@ -149,10 +149,10 @@ macro_rules! register { · 148 unmodified lines
149149
150150 // TODO[REGA]: display the raw hex value, then the value of all the fields. This requires
151151 // matching the fields, which will complexify the syntax considerably...
152− impl ::core::fmt::Debug for $name {
153− fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
152+ impl ::kernel::fmt::Debug for $name {
153+ fn fmt(&self, f: &mut ::kernel::fmt::Formatter<'_>) -> ::kernel::fmt::Result {
154154 f.debug_tuple(stringify!($name))
155− .field(&format_args!("0x{0:x}", &self.0))
155+ .field(&::kernel::prelude::fmt!("0x{0:x}", &self.0))
156156 .finish()
157157 }
158158 }
drivers/gpu/nova-core/vbios.rs+2−2
@@ -10,6 +10,7 @@ use kernel::device; · 9 unmodified lines
1010 use kernel::error::Result;
1111 use kernel::pci;
1212 use kernel::prelude::*;
13+use kernel::ptr::{Alignable, Alignment};
1314
1415 /// The offset of the VBIOS ROM in the BAR0 space.
1516 const ROM_OFFSET: usize = 0x300000;
@@ -177,8 +178,7 @@ impl<'a> Iterator for VbiosIterator<'a> { · 161 unmodified lines
177178
178179 // Advance to next image (aligned to 512 bytes).
179180 self.current_offset += image_size;
180− // TODO[NUMM]: replace with `align_up` once it lands.
181− self.current_offset = self.current_offset.next_multiple_of(512);
181+ self.current_offset = self.current_offset.align_up(Alignment::new::<512>())?;
182182
183183 Some(Ok(full_image))
184184 }
rust/Makefile+15−14
@@ -98,6 +98,12 @@ quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< · 97 unmodified lines
9898 # and then retouch the generated files.
9999 rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \
100100 rustdoc-kernel rustdoc-pin_init
101+ $(Q)grep -Ehro '<a href="srctree/([^"]+)"' $(rustdoc_output) | \
102+ cut -d'"' -f2 | cut -d/ -f2- | while read f; do \
103+ if [ ! -e "$(srctree)/$$f" ]; then \
104+ echo "warning: srctree/ link to $$f does not exist"; \
105+ fi \
106+ done
101107 $(Q)cp $(srctree)/Documentation/images/logo.svg $(rustdoc_output)/static.files/
102108 $(Q)cp $(srctree)/Documentation/images/COPYING-logo $(rustdoc_output)/static.files/
103109 $(Q)find $(rustdoc_output) -name '*.html' -type f -print0 | xargs -0 sed -Ei \
@@ -193,12 +199,12 @@ rusttestlib-kernel: $(src)/kernel/lib.rs rusttestlib-bindings rusttestlib-uapi \ · 89 unmodified lines
193199 $(obj)/bindings.o FORCE
194200 +$(call if_changed,rustc_test_library)
195201
196−rusttestlib-bindings: private rustc_target_flags = --extern ffi
197−rusttestlib-bindings: $(src)/bindings/lib.rs rusttestlib-ffi FORCE
202+rusttestlib-bindings: private rustc_target_flags = --extern ffi --extern pin_init
203+rusttestlib-bindings: $(src)/bindings/lib.rs rusttestlib-ffi rusttestlib-pin_init FORCE
198204 +$(call if_changed,rustc_test_library)
199205
200−rusttestlib-uapi: private rustc_target_flags = --extern ffi
201−rusttestlib-uapi: $(src)/uapi/lib.rs rusttestlib-ffi FORCE
206+rusttestlib-uapi: private rustc_target_flags = --extern ffi --extern pin_init
207+rusttestlib-uapi: $(src)/uapi/lib.rs rusttestlib-ffi rusttestlib-pin_init FORCE
202208 +$(call if_changed,rustc_test_library)
203209
204210 quiet_cmd_rustdoc_test = RUSTDOC T $<
@@ -248,7 +254,7 @@ quiet_cmd_rustc_test = $(RUSTC_OR_CLIPPY_QUIET) T $< · 43 unmodified lines
248254 $(objtree)/$(obj)/test/$(subst rusttest-,,$@) $(rust_test_quiet) \
249255 $(rustc_test_run_flags)
250256
251−rusttest: rusttest-macros rusttest-kernel
257+rusttest: rusttest-macros
252258
253259 rusttest-macros: private rustc_target_flags = --extern proc_macro \
254260 --extern macros --extern kernel --extern pin_init
@@ -258,13 +264,6 @@ rusttest-macros: $(src)/macros/lib.rs \ · 3 unmodified lines
258264 +$(call if_changed,rustc_test)
259265 +$(call if_changed,rustdoc_test)
260266
261−rusttest-kernel: private rustc_target_flags = --extern ffi --extern pin_init \
262− --extern build_error --extern macros --extern bindings --extern uapi
263−rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-ffi rusttestlib-kernel \
264− rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \
265− rusttestlib-uapi rusttestlib-pin_init FORCE
266− +$(call if_changed,rustc_test)
267−
268267 ifdef CONFIG_CC_IS_CLANG
269268 bindgen_c_flags = $(c_flags)
270269 else
@@ -531,17 +530,19 @@ $(obj)/ffi.o: private skip_gendwarfksyms = 1 · 260 unmodified lines
531530 $(obj)/ffi.o: $(src)/ffi.rs $(obj)/compiler_builtins.o FORCE
532531 +$(call if_changed_rule,rustc_library)
533532
534−$(obj)/bindings.o: private rustc_target_flags = --extern ffi
533+$(obj)/bindings.o: private rustc_target_flags = --extern ffi --extern pin_init
535534 $(obj)/bindings.o: $(src)/bindings/lib.rs \
536535 $(obj)/ffi.o \
536+ $(obj)/pin_init.o \
537537 $(obj)/bindings/bindings_generated.rs \
538538 $(obj)/bindings/bindings_helpers_generated.rs FORCE
539539 +$(call if_changed_rule,rustc_library)
540540
541−$(obj)/uapi.o: private rustc_target_flags = --extern ffi
541+$(obj)/uapi.o: private rustc_target_flags = --extern ffi --extern pin_init
542542 $(obj)/uapi.o: private skip_gendwarfksyms = 1
543543 $(obj)/uapi.o: $(src)/uapi/lib.rs \
544544 $(obj)/ffi.o \
545+ $(obj)/pin_init.o \
545546 $(obj)/uapi/uapi_generated.rs FORCE
546547 +$(call if_changed_rule,rustc_library)
547548
rust/bindgen_parameters+5−0
@@ -34,3 +34,8 @@ · 33 unmodified lines
3434 # We use const helpers to aid bindgen, to avoid conflicts when constants are
3535 # recognized, block generation of the non-helper constants.
3636 --blocklist-item ARCH_SLAB_MINALIGN
37+--blocklist-item ARCH_KMALLOC_MINALIGN
38+
39+# Structs should implement `Zeroable` when all of their fields do.
40+--with-derive-custom-struct .*=MaybeZeroable
41+--with-derive-custom-union .*=MaybeZeroable
rust/bindings/bindings_helper.h+1−0
@@ -84,6 +84,7 @@ · 83 unmodified lines
8484
8585 /* `bindgen` gets confused at certain things. */
8686 const size_t RUST_CONST_HELPER_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN;
87+const size_t RUST_CONST_HELPER_ARCH_KMALLOC_MINALIGN = ARCH_KMALLOC_MINALIGN;
8788 const size_t RUST_CONST_HELPER_PAGE_SIZE = PAGE_SIZE;
8889 const gfp_t RUST_CONST_HELPER_GFP_ATOMIC = GFP_ATOMIC;
8990 const gfp_t RUST_CONST_HELPER_GFP_KERNEL = GFP_KERNEL;
rust/bindings/lib.rs+8−0
@@ -31,11 +31,19 @@ · 30 unmodified lines
3131 #[allow(clippy::undocumented_unsafe_blocks)]
3232 #[cfg_attr(CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES, allow(unnecessary_transmutes))]
3333 mod bindings_raw {
34+ use pin_init::{MaybeZeroable, Zeroable};
35+
3436 // Manual definition for blocklisted types.
3537 type __kernel_size_t = usize;
3638 type __kernel_ssize_t = isize;
3739 type __kernel_ptrdiff_t = isize;
3840
41+ // `bindgen` doesn't automatically do this, see
42+ // <https://github.com/rust-lang/rust-bindgen/issues/3196>
43+ //
44+ // SAFETY: `__BindgenBitfieldUnit<Storage>` is a newtype around `Storage`.
45+ unsafe impl<Storage> Zeroable for __BindgenBitfieldUnit<Storage> where Storage: Zeroable {}
46+
3947 // Use glob import here to expose all helpers.
4048 // Symbols defined within the module will take precedence to the glob import.
4149 pub use super::bindings_helper::*;
rust/kernel/acpi.rs+2−5
@@ -37,11 +37,8 @@ impl DeviceId { · 36 unmodified lines
3737 /// Create a new device id from an ACPI 'id' string.
3838 #[inline(always)]
3939 pub const fn new(id: &'static CStr) -> Self {
40− build_assert!(
41− id.len_with_nul() <= Self::ACPI_ID_LEN,
42− "ID exceeds 16 bytes"
43− );
44− let src = id.as_bytes_with_nul();
40+ let src = id.to_bytes_with_nul();
41+ build_assert!(src.len() <= Self::ACPI_ID_LEN, "ID exceeds 16 bytes");
4542 // Replace with `bindings::acpi_device_id::default()` once stabilized for `const`.
4643 // SAFETY: FFI type is valid to be zero-initialized.
4744 let mut acpi: bindings::acpi_device_id = unsafe { core::mem::zeroed() };
rust/kernel/alloc.rs+8−7
@@ -2,18 +2,11 @@ · 1 unmodified line
22
33 //! Implementation of the kernel's memory allocation infrastructure.
44
5−#[cfg(not(any(test, testlib)))]
65 pub mod allocator;
76 pub mod kbox;
87 pub mod kvec;
98 pub mod layout;
109
11−#[cfg(any(test, testlib))]
12−pub mod allocator_test;
13−
14−#[cfg(any(test, testlib))]
15−pub use self::allocator_test as allocator;
16−
1710 pub use self::kbox::Box;
1811 pub use self::kbox::KBox;
1912 pub use self::kbox::KVBox;
@@ -137,6 +130,14 @@ pub mod flags { · 117 unmodified lines
137130 /// - Implementers must ensure that all trait functions abide by the guarantees documented in the
138131 /// `# Guarantees` sections.
139132 pub unsafe trait Allocator {
133+ /// The minimum alignment satisfied by all allocations from this allocator.
134+ ///
135+ /// # Guarantees
136+ ///
137+ /// Any pointer allocated by this allocator is guaranteed to be aligned to `MIN_ALIGN` even if
138+ /// the requested layout has a smaller alignment.
139+ const MIN_ALIGN: usize;
140+
140141 /// Allocate memory based on `layout` and `flags`.
141142 ///
142143 /// On success, returns a buffer represented as `NonNull<[u8]>` that satisfies the layout
rust/kernel/alloc/allocator.rs+8−0
@@ -17,6 +17,8 @@ use crate::alloc::{AllocError, Allocator}; · 16 unmodified lines
1717 use crate::bindings;
1818 use crate::pr_warn;
1919
20+const ARCH_KMALLOC_MINALIGN: usize = bindings::ARCH_KMALLOC_MINALIGN;
21+
2022 /// The contiguous kernel allocator.
2123 ///
2224 /// `Kmalloc` is typically used for physically contiguous allocations up to page size, but also
@@ -128,6 +130,8 @@ impl Kmalloc { · 105 unmodified lines
128130 // - passing a pointer to a valid memory allocation is OK,
129131 // - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same.
130132 unsafe impl Allocator for Kmalloc {
133+ const MIN_ALIGN: usize = ARCH_KMALLOC_MINALIGN;
134+
131135 #[inline]
132136 unsafe fn realloc(
133137 ptr: Option<NonNull<u8>>,
@@ -147,6 +151,8 @@ unsafe impl Allocator for Kmalloc { · 13 unmodified lines
147151 // - passing a pointer to a valid memory allocation is OK,
148152 // - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same.
149153 unsafe impl Allocator for Vmalloc {
154+ const MIN_ALIGN: usize = kernel::page::PAGE_SIZE;
155+
150156 #[inline]
151157 unsafe fn realloc(
152158 ptr: Option<NonNull<u8>>,
@@ -171,6 +177,8 @@ unsafe impl Allocator for Vmalloc { · 18 unmodified lines
171177 // - passing a pointer to a valid memory allocation is OK,
172178 // - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same.
173179 unsafe impl Allocator for KVmalloc {
180+ const MIN_ALIGN: usize = ARCH_KMALLOC_MINALIGN;
181+
174182 #[inline]
175183 unsafe fn realloc(
176184 ptr: Option<NonNull<u8>>,
rust/kernel/alloc/allocator_test.rs+0−124
@@ -1,124 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−
3−//! So far the kernel's `Box` and `Vec` types can't be used by userspace test cases, since all users
4−//! of those types (e.g. `CString`) use kernel allocators for instantiation.
5−//!
6−//! In order to allow userspace test cases to make use of such types as well, implement the
7−//! `Cmalloc` allocator within the `allocator_test` module and type alias all kernel allocators to
8−//! `Cmalloc`. The `Cmalloc` allocator uses libc's `realloc()` function as allocator backend.
9−
10−#![allow(missing_docs)]
11−
12−use super::{flags::*, AllocError, Allocator, Flags};
13−use core::alloc::Layout;
14−use core::cmp;
15−use core::ptr;
16−use core::ptr::NonNull;
17−
18−/// The userspace allocator based on libc.
19−pub struct Cmalloc;
20−
21−pub type Kmalloc = Cmalloc;
22−pub type Vmalloc = Kmalloc;
23−pub type KVmalloc = Kmalloc;
24−
25−impl Cmalloc {
26− /// Returns a [`Layout`] that makes [`Kmalloc`] fulfill the requested size and alignment of
27− /// `layout`.
28− pub fn aligned_layout(layout: Layout) -> Layout {
29− // Note that `layout.size()` (after padding) is guaranteed to be a multiple of
30− // `layout.align()` which together with the slab guarantees means that `Kmalloc` will return
31− // a properly aligned object (see comments in `kmalloc()` for more information).
32− layout.pad_to_align()
33− }
34−}
35−
36−extern "C" {
37− #[link_name = "aligned_alloc"]
38− fn libc_aligned_alloc(align: usize, size: usize) -> *mut crate::ffi::c_void;
39−
40− #[link_name = "free"]
41− fn libc_free(ptr: *mut crate::ffi::c_void);
42−}
43−
44−// SAFETY:
45−// - memory remains valid until it is explicitly freed,
46−// - passing a pointer to a valid memory allocation created by this `Allocator` is always OK,
47−// - `realloc` provides the guarantees as provided in the `# Guarantees` section.
48−unsafe impl Allocator for Cmalloc {
49− unsafe fn realloc(
50− ptr: Option<NonNull<u8>>,
51− layout: Layout,
52− old_layout: Layout,
53− flags: Flags,
54− ) -> Result<NonNull<[u8]>, AllocError> {
55− let src = match ptr {
56− Some(src) => {
57− if old_layout.size() == 0 {
58− ptr::null_mut()
59− } else {
60− src.as_ptr()
61− }
62− }
63− None => ptr::null_mut(),
64− };
65−
66− if layout.size() == 0 {
67− // SAFETY: `src` is either NULL or was previously allocated with this `Allocator`
68− unsafe { libc_free(src.cast()) };
69−
70− return Ok(NonNull::slice_from_raw_parts(
71− crate::alloc::dangling_from_layout(layout),
72− 0,
73− ));
74− }
75−
76− // ISO C (ISO/IEC 9899:2011) defines `aligned_alloc`:
77− //
78− // > The value of alignment shall be a valid alignment supported by the implementation
79− // [...].
80− //
81− // As an example of the "supported by the implementation" requirement, POSIX.1-2001 (IEEE
82− // 1003.1-2001) defines `posix_memalign`:
83− //
84− // > The value of alignment shall be a power of two multiple of sizeof (void *).
85− //
86− // and POSIX-based implementations of `aligned_alloc` inherit this requirement. At the time
87− // of writing, this is known to be the case on macOS (but not in glibc).
88− //
89− // Satisfy the stricter requirement to avoid spurious test failures on some platforms.
90− let min_align = core::mem::size_of::<*const crate::ffi::c_void>();
91− let layout = layout.align_to(min_align).map_err(|_| AllocError)?;
92− let layout = layout.pad_to_align();
93−
94− // SAFETY: Returns either NULL or a pointer to a memory allocation that satisfies or
95− // exceeds the given size and alignment requirements.
96− let dst = unsafe { libc_aligned_alloc(layout.align(), layout.size()) }.cast::<u8>();
97− let dst = NonNull::new(dst).ok_or(AllocError)?;
98−
99− if flags.contains(__GFP_ZERO) {
100− // SAFETY: The preceding calls to `libc_aligned_alloc` and `NonNull::new`
101− // guarantee that `dst` points to memory of at least `layout.size()` bytes.
102− unsafe { dst.as_ptr().write_bytes(0, layout.size()) };
103− }
104−
105− if !src.is_null() {
106− // SAFETY:
107− // - `src` has previously been allocated with this `Allocator`; `dst` has just been
108− // newly allocated, hence the memory regions do not overlap.
109− // - both` src` and `dst` are properly aligned and valid for reads and writes
110− unsafe {
111− ptr::copy_nonoverlapping(
112− src,
113− dst.as_ptr(),
114− cmp::min(layout.size(), old_layout.size()),
115− )
116− };
117− }
118−
119− // SAFETY: `src` is either NULL or was previously allocated with this `Allocator`
120− unsafe { libc_free(src.cast()) };
121−
122− Ok(NonNull::slice_from_raw_parts(dst, layout.size()))
123− }
124−}
rust/kernel/alloc/kbox.rs+87−5
@@ -7,7 +7,6 @@ use super::allocator::{KVmalloc, Kmalloc, Vmalloc}; · 6 unmodified lines
77 use super::{AllocError, Allocator, Flags};
88 use core::alloc::Layout;
99 use core::borrow::{Borrow, BorrowMut};
10−use core::fmt;
1110 use core::marker::PhantomData;
1211 use core::mem::ManuallyDrop;
1312 use core::mem::MaybeUninit;
@@ -17,6 +16,7 @@ use core::ptr::NonNull; · 3 unmodified lines
1716 use core::result::Result;
1817
1918 use crate::ffi::c_void;
19+use crate::fmt;
2020 use crate::init::InPlaceInit;
2121 use crate::types::ForeignOwnable;
2222 use pin_init::{InPlaceWrite, Init, PinInit, ZeroableOption};
@@ -290,6 +290,83 @@ where · 267 unmodified lines
290290 Ok(Self::new(x, flags)?.into())
291291 }
292292
293+ /// Construct a pinned slice of elements `Pin<Box<[T], A>>`.
294+ ///
295+ /// This is a convenient means for creation of e.g. slices of structrures containing spinlocks
296+ /// or mutexes.
297+ ///
298+ /// # Examples
299+ ///
300+ /// ```
301+ /// use kernel::sync::{new_spinlock, SpinLock};
302+ ///
303+ /// struct Inner {
304+ /// a: u32,
305+ /// b: u32,
306+ /// }
307+ ///
308+ /// #[pin_data]
309+ /// struct Example {
310+ /// c: u32,
311+ /// #[pin]
312+ /// d: SpinLock<Inner>,
313+ /// }
314+ ///
315+ /// impl Example {
316+ /// fn new() -> impl PinInit<Self, Error> {
317+ /// try_pin_init!(Self {
318+ /// c: 10,
319+ /// d <- new_spinlock!(Inner { a: 20, b: 30 }),
320+ /// })
321+ /// }
322+ /// }
323+ ///
324+ /// // Allocate a boxed slice of 10 `Example`s.
325+ /// let s = KBox::pin_slice(
326+ /// | _i | Example::new(),
327+ /// 10,
328+ /// GFP_KERNEL
329+ /// )?;
330+ ///
331+ /// assert_eq!(s[5].c, 10);
332+ /// assert_eq!(s[3].d.lock().a, 20);
333+ /// # Ok::<(), Error>(())
334+ /// ```
335+ pub fn pin_slice<Func, Item, E>(
336+ mut init: Func,
337+ len: usize,
338+ flags: Flags,
339+ ) -> Result<Pin<Box<[T], A>>, E>
340+ where
341+ Func: FnMut(usize) -> Item,
342+ Item: PinInit<T, E>,
343+ E: From<AllocError>,
344+ {
345+ let mut buffer = super::Vec::<T, A>::with_capacity(len, flags)?;
346+ for i in 0..len {
347+ let ptr = buffer.spare_capacity_mut().as_mut_ptr().cast();
348+ // SAFETY:
349+ // - `ptr` is a valid pointer to uninitialized memory.
350+ // - `ptr` is not used if an error is returned.
351+ // - `ptr` won't be moved until it is dropped, i.e. it is pinned.
352+ unsafe { init(i).__pinned_init(ptr)? };
353+
354+ // SAFETY:
355+ // - `i + 1 <= len`, hence we don't exceed the capacity, due to the call to
356+ // `with_capacity()` above.
357+ // - The new value at index buffer.len() + 1 is the only element being added here, and
358+ // it has been initialized above by `init(i).__pinned_init(ptr)`.
359+ unsafe { buffer.inc_len(1) };
360+ }
361+
362+ let (ptr, _, _) = buffer.into_raw_parts();
363+ let slice = core::ptr::slice_from_raw_parts_mut(ptr, len);
364+
365+ // SAFETY: `slice` points to an allocation allocated with `A` (`buffer`) and holds a valid
366+ // `[T]`.
367+ Ok(Pin::from(unsafe { Box::from_raw(slice) }))
368+ }
369+
293370 /// Convert a [`Box<T,A>`] to a [`Pin<Box<T,A>>`]. If `T` does not implement
294371 /// [`Unpin`], then `x` will be pinned in memory and can't be moved.
295372 pub fn into_pin(this: Self) -> Pin<Self> {
@@ -401,12 +478,17 @@ where · 105 unmodified lines
401478 }
402479
403480 // SAFETY: The pointer returned by `into_foreign` comes from a well aligned
404−// pointer to `T`.
481+// pointer to `T` allocated by `A`.
405482 unsafe impl<T: 'static, A> ForeignOwnable for Box<T, A>
406483 where
407484 A: Allocator,
408485 {
409− const FOREIGN_ALIGN: usize = core::mem::align_of::<T>();
486+ const FOREIGN_ALIGN: usize = if core::mem::align_of::<T>() < A::MIN_ALIGN {
487+ A::MIN_ALIGN
488+ } else {
489+ core::mem::align_of::<T>()
490+ };
491+
410492 type Borrowed<'a> = &'a T;
411493 type BorrowedMut<'a> = &'a mut T;
412494
@@ -435,12 +517,12 @@ where · 22 unmodified lines
435517 }
436518
437519 // SAFETY: The pointer returned by `into_foreign` comes from a well aligned
438−// pointer to `T`.
520+// pointer to `T` allocated by `A`.
439521 unsafe impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
440522 where
441523 A: Allocator,
442524 {
443− const FOREIGN_ALIGN: usize = core::mem::align_of::<T>();
525+ const FOREIGN_ALIGN: usize = <Box<T, A> as ForeignOwnable>::FOREIGN_ALIGN;
444526 type Borrowed<'a> = Pin<&'a T>;
445527 type BorrowedMut<'a> = Pin<&'a mut T>;
446528
rust/kernel/alloc/kvec.rs+17−7
@@ -7,9 +7,9 @@ use super::{ · 6 unmodified lines
77 layout::ArrayLayout,
88 AllocError, Allocator, Box, Flags,
99 };
10+use crate::fmt;
1011 use core::{
1112 borrow::{Borrow, BorrowMut},
12− fmt,
1313 marker::PhantomData,
1414 mem::{ManuallyDrop, MaybeUninit},
1515 ops::Deref,
@@ -175,7 +175,7 @@ where · 159 unmodified lines
175175
176176 /// Returns the number of elements that can be stored within the vector without allocating
177177 /// additional memory.
178− pub fn capacity(&self) -> usize {
178+ pub const fn capacity(&self) -> usize {
179179 if const { Self::is_zst() } {
180180 usize::MAX
181181 } else {
@@ -185,7 +185,7 @@ where · 3 unmodified lines
185185
186186 /// Returns the number of elements stored within the vector.
187187 #[inline]
188− pub fn len(&self) -> usize {
188+ pub const fn len(&self) -> usize {
189189 self.len
190190 }
191191
@@ -196,7 +196,7 @@ where · 4 unmodified lines
196196 /// - `additional` must be less than or equal to `self.capacity - self.len`.
197197 /// - All elements within the interval [`self.len`,`self.len + additional`) must be initialized.
198198 #[inline]
199− pub unsafe fn inc_len(&mut self, additional: usize) {
199+ pub const unsafe fn inc_len(&mut self, additional: usize) {
200200 // Guaranteed by the type invariant to never underflow.
201201 debug_assert!(additional <= self.capacity() - self.len());
202202 // INVARIANT: By the safety requirements of this method this represents the exact number of
@@ -224,6 +224,16 @@ where · 21 unmodified lines
224224 }
225225
226226 /// Returns a slice of the entire vector.
227+ ///
228+ /// # Examples
229+ ///
230+ /// ```
231+ /// let mut v = KVec::new();
232+ /// v.push(1, GFP_KERNEL)?;
233+ /// v.push(2, GFP_KERNEL)?;
234+ /// assert_eq!(v.as_slice(), &[1, 2]);
235+ /// # Ok::<(), Error>(())
236+ /// ```
227237 #[inline]
228238 pub fn as_slice(&self) -> &[T] {
229239 self
@@ -245,7 +255,7 @@ where · 15 unmodified lines
245255 /// Returns a raw pointer to the vector's backing buffer, or, if `T` is a ZST, a dangling raw
246256 /// pointer.
247257 #[inline]
248− pub fn as_ptr(&self) -> *const T {
258+ pub const fn as_ptr(&self) -> *const T {
249259 self.ptr.as_ptr()
250260 }
251261
@@ -261,7 +271,7 @@ where · 9 unmodified lines
261271 /// assert!(!v.is_empty());
262272 /// ```
263273 #[inline]
264− pub fn is_empty(&self) -> bool {
274+ pub const fn is_empty(&self) -> bool {
265275 self.len() == 0
266276 }
267277
@@ -1294,7 +1304,7 @@ impl<'vec, T> Drop for DrainAll<'vec, T> { · 1026 unmodified lines
12941304 }
12951305 }
12961306
1297−#[macros::kunit_tests(rust_kvec_kunit)]
1307+#[macros::kunit_tests(rust_kvec)]
12981308 mod tests {
12991309 use super::*;
13001310 use crate::prelude::*;
rust/kernel/alloc/kvec/errors.rs+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
22
33 //! Errors for the [`Vec`] type.
44
5−use core::fmt::{self, Debug, Formatter};
5+use kernel::fmt::{self, Debug, Formatter};
66 use kernel::prelude::*;
77
88 /// Error type for [`Vec::push_within_capacity`].
rust/kernel/alloc/layout.rs+1−1
@@ -80,7 +80,7 @@ impl<T> ArrayLayout<T> { · 79 unmodified lines
8080 /// # Safety
8181 ///
8282 /// `len` must be a value, for which `len * size_of::<T>() <= isize::MAX` is true.
83− pub unsafe fn new_unchecked(len: usize) -> Self {
83+ pub const unsafe fn new_unchecked(len: usize) -> Self {
8484 // INVARIANT: By the safety requirements of this function
8585 // `len * size_of::<T>() <= isize::MAX`.
8686 Self {
rust/kernel/auxiliary.rs+2−2
@@ -105,8 +105,8 @@ pub struct DeviceId(bindings::auxiliary_device_id); · 104 unmodified lines
105105 impl DeviceId {
106106 /// Create a new [`DeviceId`] from name.
107107 pub const fn new(modname: &'static CStr, name: &'static CStr) -> Self {
108− let name = name.as_bytes_with_nul();
109− let modname = modname.as_bytes_with_nul();
108+ let name = name.to_bytes_with_nul();
109+ let modname = modname.to_bytes_with_nul();
110110
111111 // TODO: Replace with `bindings::auxiliary_device_id::default()` once stabilized for
112112 // `const`.
rust/kernel/block/mq.rs+1−1
@@ -82,7 +82,7 @@ · 81 unmodified lines
8282 //! Arc::pin_init(TagSet::new(1, 256, 1), flags::GFP_KERNEL)?;
8383 //! let mut disk = gen_disk::GenDiskBuilder::new()
8484 //! .capacity_sectors(4096)
85−//! .build(format_args!("myblk"), tagset)?;
85+//! .build(fmt!("myblk"), tagset)?;
8686 //!
8787 //! # Ok::<(), kernel::error::Error>(())
8888 //! ```
rust/kernel/block/mq/gen_disk.rs+2−2
@@ -3,12 +3,12 @@ · 2 unmodified lines
33 //! Generic disk abstraction.
44 //!
55 //! C header: [`include/linux/blkdev.h`](srctree/include/linux/blkdev.h)
6−//! C header: [`include/linux/blk_mq.h`](srctree/include/linux/blk_mq.h)
6+//! C header: [`include/linux/blk-mq.h`](srctree/include/linux/blk-mq.h)
77
88 use crate::block::mq::{raw_writer::RawWriter, Operations, TagSet};
9+use crate::fmt::{self, Write};
910 use crate::{bindings, error::from_err_ptr, error::Result, sync::Arc};
1011 use crate::{error, static_lock_class};
11−use core::fmt::{self, Write};
1212
1313 /// A builder for [`GenDisk`].
1414 ///
rust/kernel/block/mq/raw_writer.rs+1−2
@@ -1,8 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0
22
3−use core::fmt::{self, Write};
4−
53 use crate::error::Result;
4+use crate::fmt::{self, Write};
65 use crate::prelude::EINVAL;
76
87 /// A mutable reference to a byte buffer where a string can be written into.
rust/kernel/configfs.rs+2−2
@@ -263,7 +263,7 @@ impl<Data> Group<Data> { · 262 unmodified lines
263263 try_pin_init!(Self {
264264 group <- pin_init::init_zeroed().chain(|v: &mut Opaque<bindings::config_group>| {
265265 let place = v.get();
266− let name = name.as_bytes_with_nul().as_ptr();
266+ let name = name.to_bytes_with_nul().as_ptr();
267267 // SAFETY: It is safe to initialize a group once it has been zeroed.
268268 unsafe {
269269 bindings::config_group_init_type_name(place, name.cast(), item_type.as_ptr())
@@ -613,7 +613,7 @@ where · 343 unmodified lines
613613 pub const fn new(name: &'static CStr) -> Self {
614614 Self {
615615 attribute: Opaque::new(bindings::configfs_attribute {
616− ca_name: name.as_char_ptr(),
616+ ca_name: crate::str::as_char_ptr_in_const_context(name),
617617 ca_owner: core::ptr::null_mut(),
618618 ca_mode: 0o660,
619619 show: Some(Self::show),
rust/kernel/cpu.rs+1−0
@@ -109,6 +109,7 @@ impl CpuId { · 108 unmodified lines
109109 /// unexpectedly due to preemption or CPU migration. It should only be
110110 /// used when the context ensures that the task remains on the same CPU
111111 /// or the users could use a stale (yet valid) CPU ID.
112+ #[inline]
112113 pub fn current() -> Self {
113114 // SAFETY: raw_smp_processor_id() always returns a valid CPU ID.
114115 unsafe { Self::from_u32_unchecked(bindings::raw_smp_processor_id()) }
rust/kernel/cpufreq.rs+2−4
@@ -27,7 +27,6 @@ use crate::clk::Clk; · 26 unmodified lines
2727 use core::{
2828 cell::UnsafeCell,
2929 marker::PhantomData,
30− mem::MaybeUninit,
3130 ops::{Deref, DerefMut},
3231 pin::Pin,
3332 ptr,
@@ -1013,12 +1012,11 @@ impl<T: Driver> Registration<T> { · 979 unmodified lines
10131012 } else {
10141013 None
10151014 },
1016− // SAFETY: All zeros is a valid value for `bindings::cpufreq_driver`.
1017− ..unsafe { MaybeUninit::zeroed().assume_init() }
1015+ ..pin_init::zeroed()
10181016 };
10191017
10201018 const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] {
1021− let src = name.as_bytes_with_nul();
1019+ let src = name.to_bytes_with_nul();
10221020 let mut dst = [0; CPUFREQ_NAME_LEN];
10231021
10241022 build_assert!(src.len() <= CPUFREQ_NAME_LEN);
rust/kernel/device.rs+3−3
@@ -5,10 +5,10 @@ · 4 unmodified lines
55 //! C header: [`include/linux/device.h`](srctree/include/linux/device.h)
66
77 use crate::{
8− bindings,
8+ bindings, fmt,
99 types::{ARef, ForeignOwnable, Opaque},
1010 };
11−use core::{fmt, marker::PhantomData, ptr};
11+use core::{marker::PhantomData, ptr};
1212
1313 #[cfg(CONFIG_PRINTK)]
1414 use crate::c_str;
@@ -596,7 +596,7 @@ macro_rules! impl_device_context_into_aref { · 581 unmodified lines
596596 macro_rules! dev_printk {
597597 ($method:ident, $dev:expr, $($f:tt)*) => {
598598 {
599− ($dev).$method(::core::format_args!($($f)*));
599+ ($dev).$method($crate::prelude::fmt!($($f)*));
600600 }
601601 }
602602 }
rust/kernel/device/property.rs+12−11
@@ -11,6 +11,7 @@ use crate::{ · 10 unmodified lines
1111 alloc::KVec,
1212 bindings,
1313 error::{to_result, Result},
14+ fmt,
1415 prelude::*,
1516 str::{CStr, CString},
1617 types::{ARef, Opaque},
@@ -68,16 +69,16 @@ impl FwNode { · 51 unmodified lines
6869 unsafe { bindings::is_of_node(self.as_raw()) }
6970 }
7071
71− /// Returns an object that implements [`Display`](core::fmt::Display) for
72+ /// Returns an object that implements [`Display`](fmt::Display) for
7273 /// printing the name of a node.
7374 ///
7475 /// This is an alternative to the default `Display` implementation, which
7576 /// prints the full path.
76− pub fn display_name(&self) -> impl core::fmt::Display + '_ {
77+ pub fn display_name(&self) -> impl fmt::Display + '_ {
7778 struct FwNodeDisplayName<'a>(&'a FwNode);
7879
79− impl core::fmt::Display for FwNodeDisplayName<'_> {
80− fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
80+ impl fmt::Display for FwNodeDisplayName<'_> {
81+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8182 // SAFETY: `self` is valid by its type invariant.
8283 let name = unsafe { bindings::fwnode_get_name(self.0.as_raw()) };
8384 if name.is_null() {
@@ -87,7 +88,7 @@ impl FwNode { · 3 unmodified lines
8788 // - `fwnode_get_name` returns null or a valid C string.
8889 // - `name` was checked to be non-null.
8990 let name = unsafe { CStr::from_char_ptr(name) };
90− write!(f, "{name}")
91+ fmt::Display::fmt(name, f)
9192 }
9293 }
9394
@@ -351,8 +352,8 @@ impl FwNodeReferenceArgs { · 257 unmodified lines
351352 }
352353 }
353354
354−impl core::fmt::Debug for FwNodeReferenceArgs {
355− fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
355+impl fmt::Debug for FwNodeReferenceArgs {
356+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
356357 write!(f, "{:?}", self.as_slice())
357358 }
358359 }
@@ -377,8 +378,8 @@ enum Node<'a> { · 18 unmodified lines
377378 Owned(ARef<FwNode>),
378379 }
379380
380−impl core::fmt::Display for FwNode {
381− fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
381+impl fmt::Display for FwNode {
382+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
382383 // The logic here is the same as the one in lib/vsprintf.c
383384 // (fwnode_full_name_string).
384385
@@ -413,9 +414,9 @@ impl core::fmt::Display for FwNode { · 28 unmodified lines
413414 // SAFETY: `fwnode_get_name_prefix` returns null or a
414415 // valid C string.
415416 let prefix = unsafe { CStr::from_char_ptr(prefix) };
416− write!(f, "{prefix}")?;
417+ fmt::Display::fmt(prefix, f)?;
417418 }
418− write!(f, "{}", fwnode.display_name())?;
419+ fmt::Display::fmt(&fwnode.display_name(), f)?;
419420 }
420421
421422 Ok(())
rust/kernel/dma.rs+1−1
@@ -9,8 +9,8 @@ use crate::{ · 8 unmodified lines
99 device::{Bound, Core},
1010 error::{to_result, Result},
1111 prelude::*,
12+ sync::aref::ARef,
1213 transmute::{AsBytes, FromBytes},
13− types::ARef,
1414 };
1515
1616 /// Trait to be implemented by DMA capable bus devices.
rust/kernel/drm/device.rs+3−3
@@ -2,7 +2,7 @@ · 1 unmodified line
22
33 //! DRM device.
44 //!
5−//! C header: [`include/linux/drm/drm_device.h`](srctree/include/linux/drm/drm_device.h)
5+//! C header: [`include/drm/drm_device.h`](srctree/include/drm/drm_device.h)
66
77 use crate::{
88 alloc::allocator::Kmalloc,
@@ -82,8 +82,8 @@ impl<T: drm::Driver> Device<T> { · 73 unmodified lines
8282 major: T::INFO.major,
8383 minor: T::INFO.minor,
8484 patchlevel: T::INFO.patchlevel,
85− name: T::INFO.name.as_char_ptr().cast_mut(),
86− desc: T::INFO.desc.as_char_ptr().cast_mut(),
85+ name: crate::str::as_char_ptr_in_const_context(T::INFO.name).cast_mut(),
86+ desc: crate::str::as_char_ptr_in_const_context(T::INFO.desc).cast_mut(),
8787
8888 driver_features: drm::driver::FEAT_GEM,
8989 ioctls: T::IOCTLS.as_ptr(),
rust/kernel/drm/driver.rs+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
22
33 //! DRM driver core.
44 //!
5−//! C header: [`include/linux/drm/drm_drv.h`](srctree/include/linux/drm/drm_drv.h)
5+//! C header: [`include/drm/drm_drv.h`](srctree/include/drm/drm_drv.h)
66
77 use crate::{
88 bindings, device, devres, drm,
rust/kernel/drm/file.rs+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
22
33 //! DRM File objects.
44 //!
5−//! C header: [`include/linux/drm/drm_file.h`](srctree/include/linux/drm/drm_file.h)
5+//! C header: [`include/drm/drm_file.h`](srctree/include/drm/drm_file.h)
66
77 use crate::{bindings, drm, error::Result, prelude::*, types::Opaque};
88 use core::marker::PhantomData;
rust/kernel/drm/gem/mod.rs+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
22
33 //! DRM GEM API
44 //!
5−//! C header: [`include/linux/drm/drm_gem.h`](srctree/include/linux/drm/drm_gem.h)
5+//! C header: [`include/drm/drm_gem.h`](srctree/include/drm/drm_gem.h)
66
77 use crate::{
88 alloc::flags::*,
rust/kernel/drm/ioctl.rs+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
22
33 //! DRM IOCTL definitions.
44 //!
5−//! C header: [`include/linux/drm/drm_ioctl.h`](srctree/include/linux/drm/drm_ioctl.h)
5+//! C header: [`include/drm/drm_ioctl.h`](srctree/include/drm/drm_ioctl.h)
66
77 use crate::ioctl;
88
rust/kernel/error.rs+59−7
@@ -2,7 +2,9 @@ · 1 unmodified line
22
33 //! Kernel errors.
44 //!
5−//! C header: [`include/uapi/asm-generic/errno-base.h`](srctree/include/uapi/asm-generic/errno-base.h)
5+//! C header: [`include/uapi/asm-generic/errno-base.h`](srctree/include/uapi/asm-generic/errno-base.h)\
6+//! C header: [`include/uapi/asm-generic/errno.h`](srctree/include/uapi/asm-generic/errno.h)\
7+//! C header: [`include/linux/errno.h`](srctree/include/linux/errno.h)
68
79 use crate::{
810 alloc::{layout::LayoutError, AllocError},
@@ -101,8 +103,23 @@ pub struct Error(NonZeroI32); · 92 unmodified lines
101103 impl Error {
102104 /// Creates an [`Error`] from a kernel error code.
103105 ///
104− /// It is a bug to pass an out-of-range `errno`. `EINVAL` would
105− /// be returned in such a case.
106+ /// `errno` must be within error code range (i.e. `>= -MAX_ERRNO && < 0`).
107+ ///
108+ /// It is a bug to pass an out-of-range `errno`. [`code::EINVAL`] is returned in such a case.
109+ ///
110+ /// # Examples
111+ ///
112+ /// ```
113+ /// assert_eq!(Error::from_errno(-1), EPERM);
114+ /// assert_eq!(Error::from_errno(-2), ENOENT);
115+ /// ```
116+ ///
117+ /// The following calls are considered a bug:
118+ ///
119+ /// ```
120+ /// assert_eq!(Error::from_errno(0), EINVAL);
121+ /// assert_eq!(Error::from_errno(-1000000), EINVAL);
122+ /// ```
106123 pub fn from_errno(errno: crate::ffi::c_int) -> Error {
107124 if let Some(error) = Self::try_from_errno(errno) {
108125 error
@@ -158,7 +175,7 @@ impl Error { · 49 unmodified lines
158175 }
159176
160177 /// Returns a string representing the error, if one exists.
161− #[cfg(not(any(test, testlib)))]
178+ #[cfg(not(testlib))]
162179 pub fn name(&self) -> Option<&'static CStr> {
163180 // SAFETY: Just an FFI call, there are no extra safety requirements.
164181 let ptr = unsafe { bindings::errname(-self.0.get()) };
@@ -175,7 +192,7 @@ impl Error { · 10 unmodified lines
175192 /// When `testlib` is configured, this always returns `None` to avoid the dependency on a
176193 /// kernel function so that tests that use this (e.g., by calling [`Result::unwrap`]) can still
177194 /// run in userspace.
178− #[cfg(any(test, testlib))]
195+ #[cfg(testlib)]
179196 pub fn name(&self) -> Option<&'static CStr> {
180197 None
181198 }
@@ -375,8 +392,43 @@ impl From<core::convert::Infallible> for Error { · 193 unmodified lines
375392 /// [Rust documentation]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html
376393 pub type Result<T = (), E = Error> = core::result::Result<T, E>;
377394
378−/// Converts an integer as returned by a C kernel function to an error if it's negative, and
379−/// `Ok(())` otherwise.
395+/// Converts an integer as returned by a C kernel function to a [`Result`].
396+///
397+/// If the integer is negative, an [`Err`] with an [`Error`] as given by [`Error::from_errno`] is
398+/// returned. This means the integer must be `>= -MAX_ERRNO`.
399+///
400+/// Otherwise, it returns [`Ok`].
401+///
402+/// It is a bug to pass an out-of-range negative integer. `Err(EINVAL)` is returned in such a case.
403+///
404+/// # Examples
405+///
406+/// This function may be used to easily perform early returns with the [`?`] operator when working
407+/// with C APIs within Rust abstractions:
408+///
409+/// ```
410+/// # use kernel::error::to_result;
411+/// # mod bindings {
412+/// # #![expect(clippy::missing_safety_doc)]
413+/// # use kernel::prelude::*;
414+/// # pub(super) unsafe fn f1() -> c_int { 0 }
415+/// # pub(super) unsafe fn f2() -> c_int { EINVAL.to_errno() }
416+/// # }
417+/// fn f() -> Result {
418+/// // SAFETY: ...
419+/// to_result(unsafe { bindings::f1() })?;
420+///
421+/// // SAFETY: ...
422+/// to_result(unsafe { bindings::f2() })?;
423+///
424+/// // ...
425+///
426+/// Ok(())
427+/// }
428+/// # assert_eq!(f(), Err(EINVAL));
429+/// ```
430+///
431+/// [`?`]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator
380432 pub fn to_result(err: crate::ffi::c_int) -> Result {
381433 if err < 0 {
382434 Err(Error::from_errno(err))
rust/kernel/firmware.rs+1−1
@@ -291,7 +291,7 @@ impl<const N: usize> ModInfoBuilder<N> { · 290 unmodified lines
291291 let module_name = this.module_name;
292292
293293 if !this.module_name.is_empty() {
294− this = this.push_internal(module_name.as_bytes_with_nul());
294+ this = this.push_internal(module_name.to_bytes_with_nul());
295295
296296 if N != 0 {
297297 // Re-use the space taken by the NULL terminator and swap it with the '.' separator.
rust/kernel/fs/file.rs+3−2
@@ -11,6 +11,7 @@ use crate::{ · 10 unmodified lines
1111 bindings,
1212 cred::Credential,
1313 error::{code::*, to_result, Error, Result},
14+ fmt,
1415 sync::aref::{ARef, AlwaysRefCounted},
1516 types::{NotThreadSafe, Opaque},
1617 };
@@ -460,8 +461,8 @@ impl From<BadFdError> for Error { · 443 unmodified lines
460461 }
461462 }
462463
463−impl core::fmt::Debug for BadFdError {
464− fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
464+impl fmt::Debug for BadFdError {
465+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
465466 f.pad("EBADF")
466467 }
467468 }
rust/kernel/kunit.rs+7−7
@@ -6,8 +6,8 @@ · 5 unmodified lines
66 //!
77 //! Reference: <https://docs.kernel.org/dev-tools/kunit/index.html>
88
9+use crate::fmt;
910 use crate::prelude::*;
10−use core::fmt;
1111
1212 #[cfg(CONFIG_PRINTK)]
1313 use crate::c_str;
@@ -74,14 +74,14 @@ macro_rules! kunit_assert { · 60 unmodified lines
7474 // mistake (it is hidden to prevent that).
7575 //
7676 // This mimics KUnit's failed assertion format.
77− $crate::kunit::err(format_args!(
77+ $crate::kunit::err($crate::prelude::fmt!(
7878 " # {}: ASSERTION FAILED at {FILE}:{LINE}\n",
7979 $name
8080 ));
81− $crate::kunit::err(format_args!(
81+ $crate::kunit::err($crate::prelude::fmt!(
8282 " Expected {CONDITION} to be true, but is false\n"
8383 ));
84− $crate::kunit::err(format_args!(
84+ $crate::kunit::err($crate::prelude::fmt!(
8585 " Failure not reported to KUnit since this is a non-KUnit task\n"
8686 ));
8787 break 'out;
@@ -102,12 +102,12 @@ macro_rules! kunit_assert { · 14 unmodified lines
102102 unsafe impl Sync for UnaryAssert {}
103103
104104 static LOCATION: Location = Location($crate::bindings::kunit_loc {
105− file: FILE.as_char_ptr(),
105+ file: $crate::str::as_char_ptr_in_const_context(FILE),
106106 line: LINE,
107107 });
108108 static ASSERTION: UnaryAssert = UnaryAssert($crate::bindings::kunit_unary_assert {
109109 assert: $crate::bindings::kunit_assert {},
110− condition: CONDITION.as_char_ptr(),
110+ condition: $crate::str::as_char_ptr_in_const_context(CONDITION),
111111 expected_true: true,
112112 });
113113
@@ -202,7 +202,7 @@ pub const fn kunit_case( · 88 unmodified lines
202202 ) -> kernel::bindings::kunit_case {
203203 kernel::bindings::kunit_case {
204204 run_case: Some(run_case),
205− name: name.as_char_ptr(),
205+ name: kernel::str::as_char_ptr_in_const_context(name),
206206 attr: kernel::bindings::kunit_attributes {
207207 speed: kernel::bindings::kunit_speed_KUNIT_SPEED_NORMAL,
208208 },
rust/kernel/lib.rs+4−1
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 // the unstable features in use.
1818 //
1919 // Stable since Rust 1.79.0.
20+#![feature(generic_nonzero)]
2021 #![feature(inline_const)]
2122 //
2223 // Stable since Rust 1.81.0.
@@ -28,6 +29,7 @@ · 5 unmodified lines
2829 // Stable since Rust 1.83.0.
2930 #![feature(const_maybe_uninit_as_mut_ptr)]
3031 #![feature(const_mut_refs)]
32+#![feature(const_option)]
3133 #![feature(const_ptr_write)]
3234 #![feature(const_refs_to_cell)]
3335 //
@@ -110,6 +112,7 @@ pub mod pid_namespace; · 76 unmodified lines
110112 pub mod platform;
111113 pub mod prelude;
112114 pub mod print;
115+pub mod ptr;
113116 pub mod rbtree;
114117 pub mod regulator;
115118 pub mod revocable;
@@ -206,7 +209,7 @@ impl ThisModule { · 90 unmodified lines
206209 }
207210 }
208211
209−#[cfg(not(any(testlib, test)))]
212+#[cfg(not(testlib))]
210213 #[panic_handler]
211214 fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
212215 pr_emerg!("{}\n", info);
rust/kernel/list.rs+120−0
@@ -38,6 +38,8 @@ pub use self::arc_field::{define_list_arc_field_getter, ListArcField}; · 37 unmodified lines
3838 ///
3939 /// # Examples
4040 ///
41+/// Use [`ListLinks`] as the type of the intrusive field.
42+///
4143 /// ```
4244 /// use kernel::list::*;
4345 ///
@@ -140,6 +142,124 @@ pub use self::arc_field::{define_list_arc_field_getter, ListArcField}; · 96 unmodified lines
140142 /// }
141143 /// # Result::<(), Error>::Ok(())
142144 /// ```
145+///
146+/// Use [`ListLinksSelfPtr`] as the type of the intrusive field. This allows a list of trait object
147+/// type.
148+///
149+/// ```
150+/// use kernel::list::*;
151+///
152+/// trait Foo {
153+/// fn foo(&self) -> (&'static str, i32);
154+/// }
155+///
156+/// #[pin_data]
157+/// struct DTWrap<T: ?Sized> {
158+/// #[pin]
159+/// links: ListLinksSelfPtr<DTWrap<dyn Foo>>,
160+/// value: T,
161+/// }
162+///
163+/// impl<T> DTWrap<T> {
164+/// fn new(value: T) -> Result<ListArc<Self>> {
165+/// ListArc::pin_init(try_pin_init!(Self {
166+/// value,
167+/// links <- ListLinksSelfPtr::new(),
168+/// }), GFP_KERNEL)
169+/// }
170+/// }
171+///
172+/// impl_list_arc_safe! {
173+/// impl{T: ?Sized} ListArcSafe<0> for DTWrap<T> { untracked; }
174+/// }
175+/// impl_list_item! {
176+/// impl ListItem<0> for DTWrap<dyn Foo> { using ListLinksSelfPtr { self.links }; }
177+/// }
178+///
179+/// // Create a new empty list.
180+/// let mut list = List::<DTWrap<dyn Foo>>::new();
181+/// {
182+/// assert!(list.is_empty());
183+/// }
184+///
185+/// struct A(i32);
186+/// // `A` returns the inner value for `foo`.
187+/// impl Foo for A { fn foo(&self) -> (&'static str, i32) { ("a", self.0) } }
188+///
189+/// struct B;
190+/// // `B` always returns 42.
191+/// impl Foo for B { fn foo(&self) -> (&'static str, i32) { ("b", 42) } }
192+///
193+/// // Insert 3 element using `push_back()`.
194+/// list.push_back(DTWrap::new(A(15))?);
195+/// list.push_back(DTWrap::new(A(32))?);
196+/// list.push_back(DTWrap::new(B)?);
197+///
198+/// // Iterate over the list to verify the nodes were inserted correctly.
199+/// // [A(15), A(32), B]
200+/// {
201+/// let mut iter = list.iter();
202+/// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 15));
203+/// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 32));
204+/// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
205+/// assert!(iter.next().is_none());
206+///
207+/// // Verify the length of the list.
208+/// assert_eq!(list.iter().count(), 3);
209+/// }
210+///
211+/// // Pop the items from the list using `pop_back()` and verify the content.
212+/// {
213+/// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("b", 42));
214+/// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 32));
215+/// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 15));
216+/// }
217+///
218+/// // Insert 3 elements using `push_front()`.
219+/// list.push_front(DTWrap::new(A(15))?);
220+/// list.push_front(DTWrap::new(A(32))?);
221+/// list.push_front(DTWrap::new(B)?);
222+///
223+/// // Iterate over the list to verify the nodes were inserted correctly.
224+/// // [B, A(32), A(15)]
225+/// {
226+/// let mut iter = list.iter();
227+/// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
228+/// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 32));
229+/// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 15));
230+/// assert!(iter.next().is_none());
231+///
232+/// // Verify the length of the list.
233+/// assert_eq!(list.iter().count(), 3);
234+/// }
235+///
236+/// // Pop the items from the list using `pop_front()` and verify the content.
237+/// {
238+/// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 15));
239+/// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 32));
240+/// }
241+///
242+/// // Push `list2` to `list` through `push_all_back()`.
243+/// // list: [B]
244+/// // list2: [B, A(25)]
245+/// {
246+/// let mut list2 = List::<DTWrap<dyn Foo>>::new();
247+/// list2.push_back(DTWrap::new(B)?);
248+/// list2.push_back(DTWrap::new(A(25))?);
249+///
250+/// list.push_all_back(&mut list2);
251+///
252+/// // list: [B, B, A(25)]
253+/// // list2: []
254+/// let mut iter = list.iter();
255+/// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
256+/// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
257+/// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 25));
258+/// assert!(iter.next().is_none());
259+/// assert!(list2.is_empty());
260+/// }
261+/// # Result::<(), Error>::Ok(())
262+/// ```
143263 pub struct List<T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
144264 first: *mut ListLinksFields,
145265 _ty: PhantomData<ListArc<T, ID>>,
rust/kernel/miscdevice.rs+1−1
@@ -34,7 +34,7 @@ impl MiscDeviceOptions { · 33 unmodified lines
3434 // SAFETY: All zeros is valid for this C type.
3535 let mut result: bindings::miscdevice = unsafe { MaybeUninit::zeroed().assume_init() };
3636 result.minor = bindings::MISC_DYNAMIC_MINOR as ffi::c_int;
37− result.name = self.name.as_char_ptr();
37+ result.name = crate::str::as_char_ptr_in_const_context(self.name);
3838 result.fops = MiscdeviceVTable::<T>::build();
3939 result
4040 }
rust/kernel/net/phy.rs+1−1
@@ -497,7 +497,7 @@ unsafe impl Sync for DriverVTable {} · 496 unmodified lines
497497 pub const fn create_phy_driver<T: Driver>() -> DriverVTable {
498498 // INVARIANT: All the fields of `struct phy_driver` are initialized properly.
499499 DriverVTable(Opaque::new(bindings::phy_driver {
500− name: T::NAME.as_char_ptr().cast_mut(),
500+ name: crate::str::as_char_ptr_in_const_context(T::NAME).cast_mut(),
501501 flags: T::FLAGS,
502502 phy_id: T::PHY_DEVICE_ID.id(),
503503 phy_id_mask: T::PHY_DEVICE_ID.mask_as_int(),
rust/kernel/of.rs+1−1
@@ -34,7 +34,7 @@ unsafe impl RawDeviceIdIndex for DeviceId { · 33 unmodified lines
3434 impl DeviceId {
3535 /// Create a new device id from an OF 'compatible' string.
3636 pub const fn new(compatible: &'static CStr) -> Self {
37− let src = compatible.as_bytes_with_nul();
37+ let src = compatible.to_bytes_with_nul();
3838 // Replace with `bindings::of_device_id::default()` once stabilized for `const`.
3939 // SAFETY: FFI type is valid to be zero-initialized.
4040 let mut of: bindings::of_device_id = unsafe { core::mem::zeroed() };
rust/kernel/prelude.rs+4−1
@@ -12,7 +12,10 @@ · 11 unmodified lines
1212 //! ```
1313
1414 #[doc(no_inline)]
15−pub use core::pin::Pin;
15+pub use core::{
16+ mem::{align_of, align_of_val, size_of, size_of_val},
17+ pin::Pin,
18+};
1619
1720 pub use ::ffi::{
1821 c_char, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint, c_ulong, c_ulonglong,
rust/kernel/ptr.rs+228−0
@@ -0,0 +1,228 @@
1+// SPDX-License-Identifier: GPL-2.0
2+
3+//! Types and functions to work with pointers and addresses.
4+
5+use core::fmt::Debug;
6+use core::mem::align_of;
7+use core::num::NonZero;
8+
9+use crate::build_assert;
10+
11+/// Type representing an alignment, which is always a power of two.
12+///
13+/// It is used to validate that a given value is a valid alignment, and to perform masking and
14+/// alignment operations.
15+///
16+/// This is a temporary substitute for the [`Alignment`] nightly type from the standard library,
17+/// and to be eventually replaced by it.
18+///
19+/// [`Alignment`]: https://github.com/rust-lang/rust/issues/102070
20+///
21+/// # Invariants
22+///
23+/// An alignment is always a power of two.
24+#[repr(transparent)]
25+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
26+pub struct Alignment(NonZero<usize>);
27+
28+impl Alignment {
29+ /// Validates that `ALIGN` is a power of two at build-time, and returns an [`Alignment`] of the
30+ /// same value.
31+ ///
32+ /// A build error is triggered if `ALIGN` is not a power of two.
33+ ///
34+ /// # Examples
35+ ///
36+ /// ```
37+ /// use kernel::ptr::Alignment;
38+ ///
39+ /// let v = Alignment::new::<16>();
40+ /// assert_eq!(v.as_usize(), 16);
41+ /// ```
42+ #[inline(always)]
43+ pub const fn new<const ALIGN: usize>() -> Self {
44+ build_assert!(
45+ ALIGN.is_power_of_two(),
46+ "Provided alignment is not a power of two."
47+ );
48+
49+ // INVARIANT: `align` is a power of two.
50+ // SAFETY: `align` is a power of two, and thus non-zero.
51+ Self(unsafe { NonZero::new_unchecked(ALIGN) })
52+ }
53+
54+ /// Validates that `align` is a power of two at runtime, and returns an
55+ /// [`Alignment`] of the same value.
56+ ///
57+ /// Returns [`None`] if `align` is not a power of two.
58+ ///
59+ /// # Examples
60+ ///
61+ /// ```
62+ /// use kernel::ptr::Alignment;
63+ ///
64+ /// assert_eq!(Alignment::new_checked(16), Some(Alignment::new::<16>()));
65+ /// assert_eq!(Alignment::new_checked(15), None);
66+ /// assert_eq!(Alignment::new_checked(1), Some(Alignment::new::<1>()));
67+ /// assert_eq!(Alignment::new_checked(0), None);
68+ /// ```
69+ #[inline(always)]
70+ pub const fn new_checked(align: usize) -> Option<Self> {
71+ if align.is_power_of_two() {
72+ // INVARIANT: `align` is a power of two.
73+ // SAFETY: `align` is a power of two, and thus non-zero.
74+ Some(Self(unsafe { NonZero::new_unchecked(align) }))
75+ } else {
76+ None
77+ }
78+ }
79+
80+ /// Returns the alignment of `T`.
81+ ///
82+ /// This is equivalent to [`align_of`], but with the return value provided as an [`Alignment`].
83+ #[inline(always)]
84+ pub const fn of<T>() -> Self {
85+ #![allow(clippy::incompatible_msrv)]
86+ // This cannot panic since alignments are always powers of two.
87+ //
88+ // We unfortunately cannot use `new` as it would require the `generic_const_exprs` feature.
89+ const { Alignment::new_checked(align_of::<T>()).unwrap() }
90+ }
91+
92+ /// Returns this alignment as a [`usize`].
93+ ///
94+ /// It is guaranteed to be a power of two.
95+ ///
96+ /// # Examples
97+ ///
98+ /// ```
99+ /// use kernel::ptr::Alignment;
100+ ///
101+ /// assert_eq!(Alignment::new::<16>().as_usize(), 16);
102+ /// ```
103+ #[inline(always)]
104+ pub const fn as_usize(self) -> usize {
105+ self.as_nonzero().get()
106+ }
107+
108+ /// Returns this alignment as a [`NonZero`].
109+ ///
110+ /// It is guaranteed to be a power of two.
111+ ///
112+ /// # Examples
113+ ///
114+ /// ```
115+ /// use kernel::ptr::Alignment;
116+ ///
117+ /// assert_eq!(Alignment::new::<16>().as_nonzero().get(), 16);
118+ /// ```
119+ #[inline(always)]
120+ pub const fn as_nonzero(self) -> NonZero<usize> {
121+ // Allow the compiler to know that the value is indeed a power of two. This can help
122+ // optimize some operations down the line, like e.g. replacing divisions by bit shifts.
123+ if !self.0.is_power_of_two() {
124+ // SAFETY: Per the invariants, `self.0` is always a power of two so this block will
125+ // never be reached.
126+ unsafe { core::hint::unreachable_unchecked() }
127+ }
128+ self.0
129+ }
130+
131+ /// Returns the base-2 logarithm of the alignment.
132+ ///
133+ /// # Examples
134+ ///
135+ /// ```
136+ /// use kernel::ptr::Alignment;
137+ ///
138+ /// assert_eq!(Alignment::of::<u8>().log2(), 0);
139+ /// assert_eq!(Alignment::new::<16>().log2(), 4);
140+ /// ```
141+ #[inline(always)]
142+ pub const fn log2(self) -> u32 {
143+ self.0.ilog2()
144+ }
145+
146+ /// Returns the mask for this alignment.
147+ ///
148+ /// This is equivalent to `!(self.as_usize() - 1)`.
149+ ///
150+ /// # Examples
151+ ///
152+ /// ```
153+ /// use kernel::ptr::Alignment;
154+ ///
155+ /// assert_eq!(Alignment::new::<0x10>().mask(), !0xf);
156+ /// ```
157+ #[inline(always)]
158+ pub const fn mask(self) -> usize {
159+ // No underflow can occur as the alignment is guaranteed to be a power of two, and thus is
160+ // non-zero.
161+ !(self.as_usize() - 1)
162+ }
163+}
164+
165+/// Trait for items that can be aligned against an [`Alignment`].
166+pub trait Alignable: Sized {
167+ /// Aligns `self` down to `alignment`.
168+ ///
169+ /// # Examples
170+ ///
171+ /// ```
172+ /// use kernel::ptr::{Alignable, Alignment};
173+ ///
174+ /// assert_eq!(0x2f_usize.align_down(Alignment::new::<0x10>()), 0x20);
175+ /// assert_eq!(0x30usize.align_down(Alignment::new::<0x10>()), 0x30);
176+ /// assert_eq!(0xf0u8.align_down(Alignment::new::<0x1000>()), 0x0);
177+ /// ```
178+ fn align_down(self, alignment: Alignment) -> Self;
179+
180+ /// Aligns `self` up to `alignment`, returning `None` if aligning would result in an overflow.
181+ ///
182+ /// # Examples
183+ ///
184+ /// ```
185+ /// use kernel::ptr::{Alignable, Alignment};
186+ ///
187+ /// assert_eq!(0x4fusize.align_up(Alignment::new::<0x10>()), Some(0x50));
188+ /// assert_eq!(0x40usize.align_up(Alignment::new::<0x10>()), Some(0x40));
189+ /// assert_eq!(0x0usize.align_up(Alignment::new::<0x10>()), Some(0x0));
190+ /// assert_eq!(u8::MAX.align_up(Alignment::new::<0x10>()), None);
191+ /// assert_eq!(0x10u8.align_up(Alignment::new::<0x100>()), None);
192+ /// assert_eq!(0x0u8.align_up(Alignment::new::<0x100>()), Some(0x0));
193+ /// ```
194+ fn align_up(self, alignment: Alignment) -> Option<Self>;
195+}
196+
197+/// Implement [`Alignable`] for unsigned integer types.
198+macro_rules! impl_alignable_uint {
199+ ($($t:ty),*) => {
200+ $(
201+ impl Alignable for $t {
202+ #[inline(always)]
203+ fn align_down(self, alignment: Alignment) -> Self {
204+ // The operands of `&` need to be of the same type so convert the alignment to
205+ // `Self`. This means we need to compute the mask ourselves.
206+ ::core::num::NonZero::<Self>::try_from(alignment.as_nonzero())
207+ .map(|align| self & !(align.get() - 1))
208+ // An alignment larger than `Self` always aligns down to `0`.
209+ .unwrap_or(0)
210+ }
211+
212+ #[inline(always)]
213+ fn align_up(self, alignment: Alignment) -> Option<Self> {
214+ let aligned_down = self.align_down(alignment);
215+ if self == aligned_down {
216+ Some(aligned_down)
217+ } else {
218+ Self::try_from(alignment.as_usize())
219+ .ok()
220+ .and_then(|align| aligned_down.checked_add(align))
221+ }
222+ }
223+ }
224+ )*
225+ };
226+}
227+
228+impl_alignable_uint!(u8, u16, u32, u64, usize);
rust/kernel/seq_file.rs+3−3
@@ -4,7 +4,7 @@ · 3 unmodified lines
44 //!
55 //! C header: [`include/linux/seq_file.h`](srctree/include/linux/seq_file.h)
66
7−use crate::{bindings, c_str, types::NotThreadSafe, types::Opaque};
7+use crate::{bindings, c_str, fmt, types::NotThreadSafe, types::Opaque};
88
99 /// A utility for generating the contents of a seq file.
1010 #[repr(transparent)]
@@ -31,7 +31,7 @@ impl SeqFile { · 20 unmodified lines
3131
3232 /// Used by the [`seq_print`] macro.
3333 #[inline]
34− pub fn call_printf(&self, args: core::fmt::Arguments<'_>) {
34+ pub fn call_printf(&self, args: fmt::Arguments<'_>) {
3535 // SAFETY: Passing a void pointer to `Arguments` is valid for `%pA`.
3636 unsafe {
3737 bindings::seq_printf(
@@ -47,7 +47,7 @@ impl SeqFile { · 9 unmodified lines
4747 #[macro_export]
4848 macro_rules! seq_print {
4949 ($m:expr, $($arg:tt)+) => (
50− $m.call_printf(format_args!($($arg)+))
50+ $m.call_printf($crate::prelude::fmt!($($arg)+))
5151 );
5252 }
5353 pub use seq_print;
rust/kernel/sync/arc.rs+4−4
@@ -19,6 +19,7 @@ · 18 unmodified lines
1919 use crate::{
2020 alloc::{AllocError, Flags, KBox},
2121 ffi::c_void,
22+ fmt,
2223 init::InPlaceInit,
2324 sync::Refcount,
2425 try_init,
@@ -27,7 +28,6 @@ use crate::{ · 2 unmodified lines
2728 use core::{
2829 alloc::Layout,
2930 borrow::{Borrow, BorrowMut},
30− fmt,
3131 marker::PhantomData,
3232 mem::{ManuallyDrop, MaybeUninit},
3333 ops::{Deref, DerefMut},
@@ -367,10 +367,10 @@ impl<T: ?Sized> Arc<T> { · 333 unmodified lines
367367 }
368368 }
369369
370−// SAFETY: The pointer returned by `into_foreign` comes from a well aligned
371−// pointer to `ArcInner<T>`.
370+// SAFETY: The pointer returned by `into_foreign` was originally allocated as an
371+// `KBox<ArcInner<T>>`, so that type is what determines the alignment.
372372 unsafe impl<T: 'static> ForeignOwnable for Arc<T> {
373− const FOREIGN_ALIGN: usize = core::mem::align_of::<ArcInner<T>>();
373+ const FOREIGN_ALIGN: usize = <KBox<ArcInner<T>> as ForeignOwnable>::FOREIGN_ALIGN;
374374
375375 type Borrowed<'a> = ArcBorrow<'a, T>;
376376 type BorrowedMut<'a> = Self::Borrowed<'a>;
rust/kernel/sync/aref.rs+16−1
@@ -1,6 +1,21 @@
11 // SPDX-License-Identifier: GPL-2.0
22
33 //! Internal reference counting support.
4+//!
5+//! Many C types already have their own reference counting mechanism (e.g. by storing a
6+//! `refcount_t`). This module provides support for directly using their internal reference count
7+//! from Rust; instead of making users have to use an additional Rust-reference count in the form of
8+//! [`Arc`].
9+//!
10+//! The smart pointer [`ARef<T>`] acts similarly to [`Arc<T>`] in that it holds a refcount on the
11+//! underlying object, but this refcount is internal to the object. It essentially is a Rust
12+//! implementation of the `get_` and `put_` pattern used in C for reference counting.
13+//!
14+//! To make use of [`ARef<MyType>`], `MyType` needs to implement [`AlwaysRefCounted`]. It is a trait
15+//! for accessing the internal reference count of an object of the `MyType` type.
16+//!
17+//! [`Arc`]: crate::sync::Arc
18+//! [`Arc<T>`]: crate::sync::Arc
419
520 use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull};
621
@@ -97,7 +112,7 @@ impl<T: AlwaysRefCounted> ARef<T> { · 90 unmodified lines
97112 ///
98113 /// ```
99114 /// use core::ptr::NonNull;
100− /// use kernel::types::{ARef, AlwaysRefCounted};
115+ /// use kernel::sync::aref::{ARef, AlwaysRefCounted};
101116 ///
102117 /// struct Empty {}
103118 ///
rust/kernel/task.rs+4−3
@@ -9,7 +9,8 @@ use crate::{ · 8 unmodified lines
99 ffi::{c_int, c_long, c_uint},
1010 mm::MmWithUser,
1111 pid_namespace::PidNamespace,
12− types::{ARef, NotThreadSafe, Opaque},
12+ sync::aref::ARef,
13+ types::{NotThreadSafe, Opaque},
1314 };
1415 use core::{
1516 cmp::{Eq, PartialEq},
@@ -76,7 +77,7 @@ macro_rules! current { · 60 unmodified lines
7677 /// incremented when creating `State` and decremented when it is dropped:
7778 ///
7879 /// ```
79−/// use kernel::{task::Task, types::ARef};
80+/// use kernel::{task::Task, sync::aref::ARef};
8081 ///
8182 /// struct State {
8283 /// creator: ARef<Task>,
@@ -347,7 +348,7 @@ impl CurrentTask { · 264 unmodified lines
347348 }
348349
349350 // SAFETY: The type invariants guarantee that `Task` is always refcounted.
350−unsafe impl crate::types::AlwaysRefCounted for Task {
351+unsafe impl crate::sync::aref::AlwaysRefCounted for Task {
351352 #[inline]
352353 fn inc_ref(&self) {
353354 // SAFETY: The existence of a shared reference means that the refcount is nonzero.
rust/kernel/time.rs+162−1
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525 //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h).
2626
2727 use core::marker::PhantomData;
28+use core::ops;
2829
2930 pub mod delay;
3031 pub mod hrtimer;
@@ -200,9 +201,31 @@ impl<C: ClockSource> Instant<C> { · 169 unmodified lines
200201 pub(crate) fn as_nanos(&self) -> i64 {
201202 self.inner
202203 }
204+
205+ /// Create an [`Instant`] from a `ktime_t` without checking if it is non-negative.
206+ ///
207+ /// # Panics
208+ ///
209+ /// On debug builds, this function will panic if `ktime` is not in the range from 0 to
210+ /// `KTIME_MAX`.
211+ ///
212+ /// # Safety
213+ ///
214+ /// The caller promises that `ktime` is in the range from 0 to `KTIME_MAX`.
215+ #[inline]
216+ pub(crate) unsafe fn from_ktime(ktime: bindings::ktime_t) -> Self {
217+ debug_assert!(ktime >= 0);
218+
219+ // INVARIANT: Our safety contract ensures that `ktime` is in the range from 0 to
220+ // `KTIME_MAX`.
221+ Self {
222+ inner: ktime,
223+ _c: PhantomData,
224+ }
225+ }
203226 }
204227
205−impl<C: ClockSource> core::ops::Sub for Instant<C> {
228+impl<C: ClockSource> ops::Sub for Instant<C> {
206229 type Output = Delta;
207230
208231 // By the type invariant, it never overflows.
@@ -214,6 +237,46 @@ impl<C: ClockSource> core::ops::Sub for Instant<C> { · 5 unmodified lines
214237 }
215238 }
216239
240+impl<T: ClockSource> ops::Add<Delta> for Instant<T> {
241+ type Output = Self;
242+
243+ #[inline]
244+ fn add(self, rhs: Delta) -> Self::Output {
245+ // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
246+ // (e.g. go above `KTIME_MAX`)
247+ let res = self.inner + rhs.nanos;
248+
249+ // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
250+ #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
251+ assert!(res >= 0);
252+
253+ Self {
254+ inner: res,
255+ _c: PhantomData,
256+ }
257+ }
258+}
259+
260+impl<T: ClockSource> ops::Sub<Delta> for Instant<T> {
261+ type Output = Self;
262+
263+ #[inline]
264+ fn sub(self, rhs: Delta) -> Self::Output {
265+ // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
266+ // (e.g. go above `KTIME_MAX`)
267+ let res = self.inner - rhs.nanos;
268+
269+ // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
270+ #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
271+ assert!(res >= 0);
272+
273+ Self {
274+ inner: res,
275+ _c: PhantomData,
276+ }
277+ }
278+}
279+
217280 /// A span of time.
218281 ///
219282 /// This struct represents a span of time, with its value stored as nanoseconds.
@@ -224,6 +287,78 @@ pub struct Delta { · 4 unmodified lines
224287 nanos: i64,
225288 }
226289
290+impl ops::Add for Delta {
291+ type Output = Self;
292+
293+ #[inline]
294+ fn add(self, rhs: Self) -> Self {
295+ Self {
296+ nanos: self.nanos + rhs.nanos,
297+ }
298+ }
299+}
300+
301+impl ops::AddAssign for Delta {
302+ #[inline]
303+ fn add_assign(&mut self, rhs: Self) {
304+ self.nanos += rhs.nanos;
305+ }
306+}
307+
308+impl ops::Sub for Delta {
309+ type Output = Self;
310+
311+ #[inline]
312+ fn sub(self, rhs: Self) -> Self::Output {
313+ Self {
314+ nanos: self.nanos - rhs.nanos,
315+ }
316+ }
317+}
318+
319+impl ops::SubAssign for Delta {
320+ #[inline]
321+ fn sub_assign(&mut self, rhs: Self) {
322+ self.nanos -= rhs.nanos;
323+ }
324+}
325+
326+impl ops::Mul<i64> for Delta {
327+ type Output = Self;
328+
329+ #[inline]
330+ fn mul(self, rhs: i64) -> Self::Output {
331+ Self {
332+ nanos: self.nanos * rhs,
333+ }
334+ }
335+}
336+
337+impl ops::MulAssign<i64> for Delta {
338+ #[inline]
339+ fn mul_assign(&mut self, rhs: i64) {
340+ self.nanos *= rhs;
341+ }
342+}
343+
344+impl ops::Div for Delta {
345+ type Output = i64;
346+
347+ #[inline]
348+ fn div(self, rhs: Self) -> Self::Output {
349+ #[cfg(CONFIG_64BIT)]
350+ {
351+ self.nanos / rhs.nanos
352+ }
353+
354+ #[cfg(not(CONFIG_64BIT))]
355+ {
356+ // SAFETY: This function is always safe to call regardless of the input values
357+ unsafe { bindings::div64_s64(self.nanos, rhs.nanos) }
358+ }
359+ }
360+}
361+
227362 impl Delta {
228363 /// A span of time equal to zero.
229364 pub const ZERO: Self = Self { nanos: 0 };
@@ -312,4 +447,30 @@ impl Delta { · 82 unmodified lines
312447 bindings::ktime_to_ms(self.as_nanos())
313448 }
314449 }
450+
451+ /// Return `self % dividend` where `dividend` is in nanoseconds.
452+ ///
453+ /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is
454+ /// limited to 32 bit dividends.
455+ #[inline]
456+ pub fn rem_nanos(self, dividend: i32) -> Self {
457+ #[cfg(CONFIG_64BIT)]
458+ {
459+ Self {
460+ nanos: self.as_nanos() % i64::from(dividend),
461+ }
462+ }
463+
464+ #[cfg(not(CONFIG_64BIT))]
465+ {
466+ let mut rem = 0;
467+
468+ // SAFETY: `rem` is in the stack, so we can always provide a valid pointer to it.
469+ unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) };
470+
471+ Self {
472+ nanos: i64::from(rem),
473+ }
474+ }
475+ }
315476 }
rust/kernel/time/hrtimer.rs+149−3
@@ -69,9 +69,14 @@ · 68 unmodified lines
6969
7070 use super::{ClockSource, Delta, Instant};
7171 use crate::{prelude::*, types::Opaque};
72−use core::marker::PhantomData;
72+use core::{marker::PhantomData, ptr::NonNull};
7373 use pin_init::PinInit;
7474
75+/// A type-alias to refer to the [`Instant<C>`] for a given `T` from [`HrTimer<T>`].
76+///
77+/// Where `C` is the [`ClockSource`] of the [`HrTimer`].
78+pub type HrTimerInstant<T> = Instant<<<T as HasHrTimer<T>>::TimerMode as HrTimerMode>::Clock>;
79+
7580 /// A timer backed by a C `struct hrtimer`.
7681 ///
7782 /// # Invariants
@@ -163,6 +168,84 @@ impl<T> HrTimer<T> { · 85 unmodified lines
163168 // handled on the C side.
164169 unsafe { bindings::hrtimer_cancel(c_timer_ptr) != 0 }
165170 }
171+
172+ /// Forward the timer expiry for a given timer pointer.
173+ ///
174+ /// # Safety
175+ ///
176+ /// - `self_ptr` must point to a valid `Self`.
177+ /// - The caller must either have exclusive access to the data pointed at by `self_ptr`, or be
178+ /// within the context of the timer callback.
179+ #[inline]
180+ unsafe fn raw_forward(self_ptr: *mut Self, now: HrTimerInstant<T>, interval: Delta) -> u64
181+ where
182+ T: HasHrTimer<T>,
183+ {
184+ // SAFETY:
185+ // * The C API requirements for this function are fulfilled by our safety contract.
186+ // * `self_ptr` is guaranteed to point to a valid `Self` via our safety contract
187+ unsafe {
188+ bindings::hrtimer_forward(Self::raw_get(self_ptr), now.as_nanos(), interval.as_nanos())
189+ }
190+ }
191+
192+ /// Conditionally forward the timer.
193+ ///
194+ /// If the timer expires after `now`, this function does nothing and returns 0. If the timer
195+ /// expired at or before `now`, this function forwards the timer by `interval` until the timer
196+ /// expires after `now` and then returns the number of times the timer was forwarded by
197+ /// `interval`.
198+ ///
199+ /// This function is mainly useful for timer types which can provide exclusive access to the
200+ /// timer when the timer is not running. For forwarding the timer from within the timer callback
201+ /// context, see [`HrTimerCallbackContext::forward()`].
202+ ///
203+ /// Returns the number of overruns that occurred as a result of the timer expiry change.
204+ pub fn forward(self: Pin<&mut Self>, now: HrTimerInstant<T>, interval: Delta) -> u64
205+ where
206+ T: HasHrTimer<T>,
207+ {
208+ // SAFETY: `raw_forward` does not move `Self`
209+ let this = unsafe { self.get_unchecked_mut() };
210+
211+ // SAFETY: By existence of `Pin<&mut Self>`, the pointer passed to `raw_forward` points to a
212+ // valid `Self` that we have exclusive access to.
213+ unsafe { Self::raw_forward(this, now, interval) }
214+ }
215+
216+ /// Conditionally forward the timer.
217+ ///
218+ /// This is a variant of [`forward()`](Self::forward) that uses an interval after the current
219+ /// time of the base clock for the [`HrTimer`].
220+ pub fn forward_now(self: Pin<&mut Self>, interval: Delta) -> u64
221+ where
222+ T: HasHrTimer<T>,
223+ {
224+ self.forward(HrTimerInstant::<T>::now(), interval)
225+ }
226+
227+ /// Return the time expiry for this [`HrTimer`].
228+ ///
229+ /// This value should only be used as a snapshot, as the actual expiry time could change after
230+ /// this function is called.
231+ pub fn expires(&self) -> HrTimerInstant<T>
232+ where
233+ T: HasHrTimer<T>,
234+ {
235+ // SAFETY: `self` is an immutable reference and thus always points to a valid `HrTimer`.
236+ let c_timer_ptr = unsafe { HrTimer::raw_get(self) };
237+
238+ // SAFETY:
239+ // - Timers cannot have negative ktime_t values as their expiration time.
240+ // - There's no actual locking here, a racy read is fine and expected
241+ unsafe {
242+ Instant::from_ktime(
243+ // This `read_volatile` is intended to correspond to a READ_ONCE call.
244+ // FIXME(read_once): Replace with `read_once` when available on the Rust side.
245+ core::ptr::read_volatile(&raw const ((*c_timer_ptr).node.expires)),
246+ )
247+ }
248+ }
166249 }
167250
168251 /// Implemented by pointer types that point to structs that contain a [`HrTimer`].
@@ -300,9 +383,13 @@ pub trait HrTimerCallback { · 131 unmodified lines
300383 type Pointer<'a>: RawHrTimerCallback;
301384
302385 /// Called by the timer logic when the timer fires.
303− fn run(this: <Self::Pointer<'_> as RawHrTimerCallback>::CallbackTarget<'_>) -> HrTimerRestart
386+ fn run(
387+ this: <Self::Pointer<'_> as RawHrTimerCallback>::CallbackTarget<'_>,
388+ ctx: HrTimerCallbackContext<'_, Self>,
389+ ) -> HrTimerRestart
304390 where
305− Self: Sized;
391+ Self: Sized,
392+ Self: HasHrTimer<Self>;
306393 }
307394
308395 /// A handle representing a potentially running timer.
@@ -324,6 +411,8 @@ pub unsafe trait HrTimerHandle { · 15 unmodified lines
324411 /// Note that the timer might be started by a concurrent start operation. If
325412 /// so, the timer might not be in the **stopped** state when this function
326413 /// returns.
414+ ///
415+ /// Returns `true` if the timer was running.
327416 fn cancel(&mut self) -> bool;
328417 }
329418
@@ -585,6 +674,63 @@ impl<C: ClockSource> HrTimerMode for RelativePinnedHardMode<C> { · 255 unmodified lines
585674 type Expires = Delta;
586675 }
587676
677+/// Privileged smart-pointer for a [`HrTimer`] callback context.
678+///
679+/// Many [`HrTimer`] methods can only be called in two situations:
680+///
681+/// * When the caller has exclusive access to the `HrTimer` and the `HrTimer` is guaranteed not to
682+/// be running.
683+/// * From within the context of an `HrTimer`'s callback method.
684+///
685+/// This type provides access to said methods from within a timer callback context.
686+///
687+/// # Invariants
688+///
689+/// * The existence of this type means the caller is currently within the callback for an
690+/// [`HrTimer`].
691+/// * `self.0` always points to a live instance of [`HrTimer<T>`].
692+pub struct HrTimerCallbackContext<'a, T: HasHrTimer<T>>(NonNull<HrTimer<T>>, PhantomData<&'a ()>);
693+
694+impl<'a, T: HasHrTimer<T>> HrTimerCallbackContext<'a, T> {
695+ /// Create a new [`HrTimerCallbackContext`].
696+ ///
697+ /// # Safety
698+ ///
699+ /// This function relies on the caller being within the context of a timer callback, so it must
700+ /// not be used anywhere except for within implementations of [`RawHrTimerCallback::run`]. The
701+ /// caller promises that `timer` points to a valid initialized instance of
702+ /// [`bindings::hrtimer`].
703+ ///
704+ /// The returned `Self` must not outlive the function context of [`RawHrTimerCallback::run`]
705+ /// where this function is called.
706+ pub(crate) unsafe fn from_raw(timer: *mut HrTimer<T>) -> Self {
707+ // SAFETY: The caller guarantees `timer` is a valid pointer to an initialized
708+ // `bindings::hrtimer`
709+ // INVARIANT: Our safety contract ensures that we're within the context of a timer callback
710+ // and that `timer` points to a live instance of `HrTimer<T>`.
711+ Self(unsafe { NonNull::new_unchecked(timer) }, PhantomData)
712+ }
713+
714+ /// Conditionally forward the timer.
715+ ///
716+ /// This function is identical to [`HrTimer::forward()`] except that it may only be used from
717+ /// within the context of a [`HrTimer`] callback.
718+ pub fn forward(&mut self, now: HrTimerInstant<T>, interval: Delta) -> u64 {
719+ // SAFETY:
720+ // - We are guaranteed to be within the context of a timer callback by our type invariants
721+ // - By our type invariants, `self.0` always points to a valid `HrTimer<T>`
722+ unsafe { HrTimer::<T>::raw_forward(self.0.as_ptr(), now, interval) }
723+ }
724+
725+ /// Conditionally forward the timer.
726+ ///
727+ /// This is a variant of [`HrTimerCallbackContext::forward()`] that uses an interval after the
728+ /// current time of the base clock for the [`HrTimer`].
729+ pub fn forward_now(&mut self, duration: Delta) -> u64 {
730+ self.forward(HrTimerInstant::<T>::now(), duration)
731+ }
732+}
733+
588734 /// Use to implement the [`HasHrTimer<T>`] trait.
589735 ///
590736 /// See [`module`] documentation for an example.
rust/kernel/time/hrtimer/arc.rs+8−1
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 use super::HasHrTimer;
44 use super::HrTimer;
55 use super::HrTimerCallback;
6+use super::HrTimerCallbackContext;
67 use super::HrTimerHandle;
78 use super::HrTimerMode;
89 use super::HrTimerPointer;
@@ -99,6 +100,12 @@ where · 90 unmodified lines
99100 // allocation from other `Arc` clones.
100101 let receiver = unsafe { ArcBorrow::from_raw(data_ptr) };
101102
102− T::run(receiver).into_c()
103+ // SAFETY:
104+ // - By C API contract `timer_ptr` is the pointer that we passed when queuing the timer, so
105+ // it is a valid pointer to a `HrTimer<T>` embedded in a `T`.
106+ // - We are within `RawHrTimerCallback::run`
107+ let context = unsafe { HrTimerCallbackContext::from_raw(timer_ptr) };
108+
109+ T::run(receiver, context).into_c()
103110 }
104111 }
rust/kernel/time/hrtimer/pin.rs+8−1
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 use super::HasHrTimer;
44 use super::HrTimer;
55 use super::HrTimerCallback;
6+use super::HrTimerCallbackContext;
67 use super::HrTimerHandle;
78 use super::HrTimerMode;
89 use super::RawHrTimerCallback;
@@ -103,6 +104,12 @@ where · 94 unmodified lines
103104 // here.
104105 let receiver_pin = unsafe { Pin::new_unchecked(receiver_ref) };
105106
106− T::run(receiver_pin).into_c()
107+ // SAFETY:
108+ // - By C API contract `timer_ptr` is the pointer that we passed when queuing the timer, so
109+ // it is a valid pointer to a `HrTimer<T>` embedded in a `T`.
110+ // - We are within `RawHrTimerCallback::run`
111+ let context = unsafe { HrTimerCallbackContext::from_raw(timer_ptr) };
112+
113+ T::run(receiver_pin, context).into_c()
107114 }
108115 }
rust/kernel/time/hrtimer/pin_mut.rs+9−3
@@ -1,8 +1,8 @@
11 // SPDX-License-Identifier: GPL-2.0
22
33 use super::{
4− HasHrTimer, HrTimer, HrTimerCallback, HrTimerHandle, HrTimerMode, RawHrTimerCallback,
5− UnsafeHrTimerPointer,
4+ HasHrTimer, HrTimer, HrTimerCallback, HrTimerCallbackContext, HrTimerHandle, HrTimerMode,
5+ RawHrTimerCallback, UnsafeHrTimerPointer,
66 };
77 use core::{marker::PhantomData, pin::Pin, ptr::NonNull};
88
@@ -107,6 +107,12 @@ where · 98 unmodified lines
107107 // here.
108108 let receiver_pin = unsafe { Pin::new_unchecked(receiver_ref) };
109109
110− T::run(receiver_pin).into_c()
110+ // SAFETY:
111+ // - By C API contract `timer_ptr` is the pointer that we passed when queuing the timer, so
112+ // it is a valid pointer to a `HrTimer<T>` embedded in a `T`.
113+ // - We are within `RawHrTimerCallback::run`
114+ let context = unsafe { HrTimerCallbackContext::from_raw(timer_ptr) };
115+
116+ T::run(receiver_pin, context).into_c()
111117 }
112118 }
rust/kernel/time/hrtimer/tbox.rs+8−1
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 use super::HasHrTimer;
44 use super::HrTimer;
55 use super::HrTimerCallback;
6+use super::HrTimerCallbackContext;
67 use super::HrTimerHandle;
78 use super::HrTimerMode;
89 use super::HrTimerPointer;
@@ -119,6 +120,12 @@ where · 110 unmodified lines
119120 // `data_ptr` exist.
120121 let data_mut_ref = unsafe { Pin::new_unchecked(&mut *data_ptr) };
121122
122− T::run(data_mut_ref).into_c()
123+ // SAFETY:
124+ // - By C API contract `timer_ptr` is the pointer that we passed when queuing the timer, so
125+ // it is a valid pointer to a `HrTimer<T>` embedded in a `T`.
126+ // - We are within `RawHrTimerCallback::run`
127+ let context = unsafe { HrTimerCallbackContext::from_raw(timer_ptr) };
128+
129+ T::run(data_mut_ref, context).into_c()
123130 }
124131 }
rust/macros/quote.rs+49−55
@@ -2,7 +2,6 @@ · 1 unmodified line
22
33 use proc_macro::{TokenStream, TokenTree};
44
5−#[allow(dead_code)]
65 pub(crate) trait ToTokens {
76 fn to_tokens(&self, tokens: &mut TokenStream);
87 }
@@ -47,121 +46,116 @@ impl ToTokens for TokenStream { · 38 unmodified lines
4746 /// `quote` crate but provides only just enough functionality needed by the current `macros` crate.
4847 macro_rules! quote_spanned {
4948 ($span:expr => $($tt:tt)*) => {{
50− let mut tokens: ::std::vec::Vec<::proc_macro::TokenTree>;
51− #[allow(clippy::vec_init_then_push)]
49+ let mut tokens = ::proc_macro::TokenStream::new();
5250 {
53− tokens = ::std::vec::Vec::new();
5451 let span = $span;
5552 quote_spanned!(@proc tokens span $($tt)*);
5653 }
57− ::proc_macro::TokenStream::from_iter(tokens)
54+ tokens
5855 }};
5956 (@proc $v:ident $span:ident) => {};
6057 (@proc $v:ident $span:ident #$id:ident $($tt:tt)*) => {
61− let mut ts = ::proc_macro::TokenStream::new();
62− $crate::quote::ToTokens::to_tokens(&$id, &mut ts);
63− $v.extend(ts);
58+ $crate::quote::ToTokens::to_tokens(&$id, &mut $v);
6459 quote_spanned!(@proc $v $span $($tt)*);
6560 };
6661 (@proc $v:ident $span:ident #(#$id:ident)* $($tt:tt)*) => {
6762 for token in $id {
68− let mut ts = ::proc_macro::TokenStream::new();
69− $crate::quote::ToTokens::to_tokens(&token, &mut ts);
70− $v.extend(ts);
63+ $crate::quote::ToTokens::to_tokens(&token, &mut $v);
7164 }
7265 quote_spanned!(@proc $v $span $($tt)*);
7366 };
7467 (@proc $v:ident $span:ident ( $($inner:tt)* ) $($tt:tt)*) => {
7568 #[allow(unused_mut)]
76− let mut tokens = ::std::vec::Vec::<::proc_macro::TokenTree>::new();
69+ let mut tokens = ::proc_macro::TokenStream::new();
7770 quote_spanned!(@proc tokens $span $($inner)*);
78− $v.push(::proc_macro::TokenTree::Group(::proc_macro::Group::new(
71+ $v.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new(
7972 ::proc_macro::Delimiter::Parenthesis,
80− ::proc_macro::TokenStream::from_iter(tokens)
81− )));
73+ tokens,
74+ ))]);
8275 quote_spanned!(@proc $v $span $($tt)*);
8376 };
8477 (@proc $v:ident $span:ident [ $($inner:tt)* ] $($tt:tt)*) => {
85− let mut tokens = ::std::vec::Vec::new();
78+ let mut tokens = ::proc_macro::TokenStream::new();
8679 quote_spanned!(@proc tokens $span $($inner)*);
87− $v.push(::proc_macro::TokenTree::Group(::proc_macro::Group::new(
80+ $v.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new(
8881 ::proc_macro::Delimiter::Bracket,
89− ::proc_macro::TokenStream::from_iter(tokens)
90− )));
82+ tokens,
83+ ))]);
9184 quote_spanned!(@proc $v $span $($tt)*);
9285 };
9386 (@proc $v:ident $span:ident { $($inner:tt)* } $($tt:tt)*) => {
94− let mut tokens = ::std::vec::Vec::new();
87+ let mut tokens = ::proc_macro::TokenStream::new();
9588 quote_spanned!(@proc tokens $span $($inner)*);
96− $v.push(::proc_macro::TokenTree::Group(::proc_macro::Group::new(
89+ $v.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new(
9790 ::proc_macro::Delimiter::Brace,
98− ::proc_macro::TokenStream::from_iter(tokens)
99− )));
91+ tokens,
92+ ))]);
10093 quote_spanned!(@proc $v $span $($tt)*);
10194 };
10295 (@proc $v:ident $span:ident :: $($tt:tt)*) => {
103− $v.push(::proc_macro::TokenTree::Punct(
104− ::proc_macro::Punct::new(':', ::proc_macro::Spacing::Joint)
105− ));
106− $v.push(::proc_macro::TokenTree::Punct(
107− ::proc_macro::Punct::new(':', ::proc_macro::Spacing::Alone)
108− ));
96+ $v.extend([::proc_macro::Spacing::Joint, ::proc_macro::Spacing::Alone].map(|spacing| {
97+ ::proc_macro::TokenTree::Punct(::proc_macro::Punct::new(':', spacing))
98+ }));
10999 quote_spanned!(@proc $v $span $($tt)*);
110100 };
111101 (@proc $v:ident $span:ident : $($tt:tt)*) => {
112− $v.push(::proc_macro::TokenTree::Punct(
113− ::proc_macro::Punct::new(':', ::proc_macro::Spacing::Alone)
114− ));
102+ $v.extend([::proc_macro::TokenTree::Punct(
103+ ::proc_macro::Punct::new(':', ::proc_macro::Spacing::Alone),
104+ )]);
115105 quote_spanned!(@proc $v $span $($tt)*);
116106 };
117107 (@proc $v:ident $span:ident , $($tt:tt)*) => {
118− $v.push(::proc_macro::TokenTree::Punct(
119− ::proc_macro::Punct::new(',', ::proc_macro::Spacing::Alone)
120− ));
108+ $v.extend([::proc_macro::TokenTree::Punct(
109+ ::proc_macro::Punct::new(',', ::proc_macro::Spacing::Alone),
110+ )]);
121111 quote_spanned!(@proc $v $span $($tt)*);
122112 };
123113 (@proc $v:ident $span:ident @ $($tt:tt)*) => {
124− $v.push(::proc_macro::TokenTree::Punct(
125− ::proc_macro::Punct::new('@', ::proc_macro::Spacing::Alone)
126− ));
114+ $v.extend([::proc_macro::TokenTree::Punct(
115+ ::proc_macro::Punct::new('@', ::proc_macro::Spacing::Alone),
116+ )]);
127117 quote_spanned!(@proc $v $span $($tt)*);
128118 };
129119 (@proc $v:ident $span:ident ! $($tt:tt)*) => {
130− $v.push(::proc_macro::TokenTree::Punct(
131− ::proc_macro::Punct::new('!', ::proc_macro::Spacing::Alone)
132− ));
120+ $v.extend([::proc_macro::TokenTree::Punct(
121+ ::proc_macro::Punct::new('!', ::proc_macro::Spacing::Alone),
122+ )]);
133123 quote_spanned!(@proc $v $span $($tt)*);
134124 };
135125 (@proc $v:ident $span:ident ; $($tt:tt)*) => {
136− $v.push(::proc_macro::TokenTree::Punct(
137− ::proc_macro::Punct::new(';', ::proc_macro::Spacing::Alone)
138− ));
126+ $v.extend([::proc_macro::TokenTree::Punct(
127+ ::proc_macro::Punct::new(';', ::proc_macro::Spacing::Alone),
128+ )]);
139129 quote_spanned!(@proc $v $span $($tt)*);
140130 };
141131 (@proc $v:ident $span:ident + $($tt:tt)*) => {
142− $v.push(::proc_macro::TokenTree::Punct(
143− ::proc_macro::Punct::new('+', ::proc_macro::Spacing::Alone)
144− ));
132+ $v.extend([::proc_macro::TokenTree::Punct(
133+ ::proc_macro::Punct::new('+', ::proc_macro::Spacing::Alone),
134+ )]);
145135 quote_spanned!(@proc $v $span $($tt)*);
146136 };
147137 (@proc $v:ident $span:ident = $($tt:tt)*) => {
148− $v.push(::proc_macro::TokenTree::Punct(
149− ::proc_macro::Punct::new('=', ::proc_macro::Spacing::Alone)
150− ));
138+ $v.extend([::proc_macro::TokenTree::Punct(
139+ ::proc_macro::Punct::new('=', ::proc_macro::Spacing::Alone),
140+ )]);
151141 quote_spanned!(@proc $v $span $($tt)*);
152142 };
153143 (@proc $v:ident $span:ident # $($tt:tt)*) => {
154− $v.push(::proc_macro::TokenTree::Punct(
155− ::proc_macro::Punct::new('#', ::proc_macro::Spacing::Alone)
156− ));
144+ $v.extend([::proc_macro::TokenTree::Punct(
145+ ::proc_macro::Punct::new('#', ::proc_macro::Spacing::Alone),
146+ )]);
157147 quote_spanned!(@proc $v $span $($tt)*);
158148 };
159149 (@proc $v:ident $span:ident _ $($tt:tt)*) => {
160− $v.push(::proc_macro::TokenTree::Ident(::proc_macro::Ident::new("_", $span)));
150+ $v.extend([::proc_macro::TokenTree::Ident(
151+ ::proc_macro::Ident::new("_", $span),
152+ )]);
161153 quote_spanned!(@proc $v $span $($tt)*);
162154 };
163155 (@proc $v:ident $span:ident $id:ident $($tt:tt)*) => {
164− $v.push(::proc_macro::TokenTree::Ident(::proc_macro::Ident::new(stringify!($id), $span)));
156+ $v.extend([::proc_macro::TokenTree::Ident(
157+ ::proc_macro::Ident::new(stringify!($id), $span),
158+ )]);
165159 quote_spanned!(@proc $v $span $($tt)*);
166160 };
167161 }
rust/uapi/lib.rs+2−0
@@ -34,4 +34,6 @@ type __kernel_size_t = usize; · 33 unmodified lines
3434 type __kernel_ssize_t = isize;
3535 type __kernel_ptrdiff_t = isize;
3636
37+use pin_init::MaybeZeroable;
38+
3739 include!(concat!(env!("OBJTREE"), "/rust/uapi/uapi_generated.rs"));
samples/rust/rust_configfs.rs+1−1
@@ -94,7 +94,7 @@ impl configfs::AttributeOperations<0> for Configuration { · 93 unmodified lines
9494
9595 fn show(container: &Configuration, page: &mut [u8; PAGE_SIZE]) -> Result<usize> {
9696 pr_info!("Show message\n");
97− let data = container.message;
97+ let data = container.message.to_bytes();
9898 page[0..data.len()].copy_from_slice(data);
9999 Ok(data.len())
100100 }
samples/rust/rust_dma.rs+1−1
@@ -10,7 +10,7 @@ use kernel::{ · 9 unmodified lines
1010 dma::{CoherentAllocation, Device, DmaMask},
1111 pci,
1212 prelude::*,
13− types::ARef,
13+ sync::aref::ARef,
1414 };
1515
1616 struct DmaSampleDriver {
scripts/generate_rust_analyzer.py+2−2
@@ -139,8 +139,8 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit · 138 unmodified lines
139139 "exclude_dirs": [],
140140 }
141141
142− append_crate_with_generated("bindings", ["core", "ffi"])
143− append_crate_with_generated("uapi", ["core", "ffi"])
142+ append_crate_with_generated("bindings", ["core", "ffi", "pin_init"])
143+ append_crate_with_generated("uapi", ["core", "ffi", "pin_init"])
144144 append_crate_with_generated("kernel", ["core", "macros", "build_error", "pin_init", "ffi", "bindings", "uapi"])
145145
146146 def is_root_crate(build_file, target):
scripts/rustdoc_test_gen.rs+1−1
@@ -202,7 +202,7 @@ pub extern "C" fn {kunit_name}(__kunit_test: *mut ::kernel::bindings::kunit) {{ · 201 unmodified lines
202202 // This follows the syntax for declaring test metadata in the proposed KTAP v2 spec, which may
203203 // be used for the proposed KUnit test attributes API. Thus hopefully this will make migration
204204 // easier later on.
205− ::kernel::kunit::info(format_args!(" # {kunit_name}.location: {real_path}:{line}\n"));
205+ ::kernel::kunit::info(fmt!(" # {kunit_name}.location: {real_path}:{line}\n"));
206206
207207 /// The anchor where the test code body starts.
208208 #[allow(unused)]