Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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!}`
...

+1054 -315
-1
Documentation/gpu/nova/core/todo.rst
··· 147 147 Nova uses integer operations that are not part of the standard library (or not 148 148 implemented in an optimized way for the kernel). These include: 149 149 150 - - Aligning up and down to a power of two, 151 150 - The "Find Last Set Bit" (`fls` function of the C part of the kernel) 152 151 operation. 153 152
+1 -1
drivers/block/rnull.rs
··· 51 51 .logical_block_size(4096)? 52 52 .physical_block_size(4096)? 53 53 .rotational(false) 54 - .build(format_args!("rnullb{}", 0), tagset) 54 + .build(fmt!("rnullb{}", 0), tagset) 55 55 })(); 56 56 57 57 try_pin_init!(Self {
+1 -1
drivers/gpu/drm/drm_panic_qr.rs
··· 968 968 // nul-terminated string. 969 969 let url_cstr: &CStr = unsafe { CStr::from_char_ptr(url) }; 970 970 let segments = &[ 971 - &Segment::Binary(url_cstr.as_bytes()), 971 + &Segment::Binary(url_cstr.to_bytes()), 972 972 &Segment::Numeric(&data_slice[0..data_len]), 973 973 ]; 974 974 match EncodedMsg::new(segments, tmp_slice) {
+3 -3
drivers/gpu/nova-core/fb.rs
··· 3 3 use core::ops::Range; 4 4 5 5 use kernel::prelude::*; 6 + use kernel::ptr::{Alignable, Alignment}; 6 7 use kernel::sizes::*; 7 8 use kernel::types::ARef; 8 9 use kernel::{dev_warn, device}; ··· 131 130 }; 132 131 133 132 let frts = { 134 - const FRTS_DOWN_ALIGN: u64 = SZ_128K as u64; 133 + const FRTS_DOWN_ALIGN: Alignment = Alignment::new::<SZ_128K>(); 135 134 const FRTS_SIZE: u64 = SZ_1M as u64; 136 - // TODO[NUMM]: replace with `align_down` once it lands. 137 - let frts_base = (vga_workspace.start & !(FRTS_DOWN_ALIGN - 1)) - FRTS_SIZE; 135 + let frts_base = vga_workspace.start.align_down(FRTS_DOWN_ALIGN) - FRTS_SIZE; 138 136 139 137 frts_base..frts_base + FRTS_SIZE 140 138 };
+1 -2
drivers/gpu/nova-core/gpu.rs
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 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}; 4 4 5 5 use crate::driver::Bar0; 6 6 use crate::falcon::{gsp::Gsp, sec2::Sec2, Falcon}; ··· 12 12 use crate::regs; 13 13 use crate::util; 14 14 use crate::vbios::Vbios; 15 - use core::fmt; 16 15 17 16 macro_rules! define_chipset { 18 17 ({ $($variant:ident = $value:expr),* $(,)* }) =>
+3 -3
drivers/gpu/nova-core/regs/macros.rs
··· 149 149 150 150 // TODO[REGA]: display the raw hex value, then the value of all the fields. This requires 151 151 // 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 { 154 154 f.debug_tuple(stringify!($name)) 155 - .field(&format_args!("0x{0:x}", &self.0)) 155 + .field(&::kernel::prelude::fmt!("0x{0:x}", &self.0)) 156 156 .finish() 157 157 } 158 158 }
+2 -2
drivers/gpu/nova-core/vbios.rs
··· 10 10 use kernel::error::Result; 11 11 use kernel::pci; 12 12 use kernel::prelude::*; 13 + use kernel::ptr::{Alignable, Alignment}; 13 14 14 15 /// The offset of the VBIOS ROM in the BAR0 space. 15 16 const ROM_OFFSET: usize = 0x300000; ··· 178 177 179 178 // Advance to next image (aligned to 512 bytes). 180 179 self.current_offset += image_size; 181 - // TODO[NUMM]: replace with `align_up` once it lands. 182 - self.current_offset = self.current_offset.next_multiple_of(512); 180 + self.current_offset = self.current_offset.align_up(Alignment::new::<512>())?; 183 181 184 182 Some(Ok(full_image)) 185 183 }
+15 -14
rust/Makefile
··· 98 98 # and then retouch the generated files. 99 99 rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ 100 100 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 101 107 $(Q)cp $(srctree)/Documentation/images/logo.svg $(rustdoc_output)/static.files/ 102 108 $(Q)cp $(srctree)/Documentation/images/COPYING-logo $(rustdoc_output)/static.files/ 103 109 $(Q)find $(rustdoc_output) -name '*.html' -type f -print0 | xargs -0 sed -Ei \ ··· 199 193 $(obj)/bindings.o FORCE 200 194 +$(call if_changed,rustc_test_library) 201 195 202 - rusttestlib-bindings: private rustc_target_flags = --extern ffi 203 - rusttestlib-bindings: $(src)/bindings/lib.rs rusttestlib-ffi FORCE 196 + rusttestlib-bindings: private rustc_target_flags = --extern ffi --extern pin_init 197 + rusttestlib-bindings: $(src)/bindings/lib.rs rusttestlib-ffi rusttestlib-pin_init FORCE 204 198 +$(call if_changed,rustc_test_library) 205 199 206 - rusttestlib-uapi: private rustc_target_flags = --extern ffi 207 - rusttestlib-uapi: $(src)/uapi/lib.rs rusttestlib-ffi FORCE 200 + rusttestlib-uapi: private rustc_target_flags = --extern ffi --extern pin_init 201 + rusttestlib-uapi: $(src)/uapi/lib.rs rusttestlib-ffi rusttestlib-pin_init FORCE 208 202 +$(call if_changed,rustc_test_library) 209 203 210 204 quiet_cmd_rustdoc_test = RUSTDOC T $< ··· 254 248 $(objtree)/$(obj)/test/$(subst rusttest-,,$@) $(rust_test_quiet) \ 255 249 $(rustc_test_run_flags) 256 250 257 - rusttest: rusttest-macros rusttest-kernel 251 + rusttest: rusttest-macros 258 252 259 253 rusttest-macros: private rustc_target_flags = --extern proc_macro \ 260 254 --extern macros --extern kernel --extern pin_init ··· 263 257 rusttestlib-macros rusttestlib-kernel rusttestlib-pin_init FORCE 264 258 +$(call if_changed,rustc_test) 265 259 +$(call if_changed,rustdoc_test) 266 - 267 - rusttest-kernel: private rustc_target_flags = --extern ffi --extern pin_init \ 268 - --extern build_error --extern macros --extern bindings --extern uapi 269 - rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-ffi rusttestlib-kernel \ 270 - rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \ 271 - rusttestlib-uapi rusttestlib-pin_init FORCE 272 - +$(call if_changed,rustc_test) 273 260 274 261 ifdef CONFIG_CC_IS_CLANG 275 262 bindgen_c_flags = $(c_flags) ··· 530 531 $(obj)/ffi.o: $(src)/ffi.rs $(obj)/compiler_builtins.o FORCE 531 532 +$(call if_changed_rule,rustc_library) 532 533 533 - $(obj)/bindings.o: private rustc_target_flags = --extern ffi 534 + $(obj)/bindings.o: private rustc_target_flags = --extern ffi --extern pin_init 534 535 $(obj)/bindings.o: $(src)/bindings/lib.rs \ 535 536 $(obj)/ffi.o \ 537 + $(obj)/pin_init.o \ 536 538 $(obj)/bindings/bindings_generated.rs \ 537 539 $(obj)/bindings/bindings_helpers_generated.rs FORCE 538 540 +$(call if_changed_rule,rustc_library) 539 541 540 - $(obj)/uapi.o: private rustc_target_flags = --extern ffi 542 + $(obj)/uapi.o: private rustc_target_flags = --extern ffi --extern pin_init 541 543 $(obj)/uapi.o: private skip_gendwarfksyms = 1 542 544 $(obj)/uapi.o: $(src)/uapi/lib.rs \ 543 545 $(obj)/ffi.o \ 546 + $(obj)/pin_init.o \ 544 547 $(obj)/uapi/uapi_generated.rs FORCE 545 548 +$(call if_changed_rule,rustc_library) 546 549
+5
rust/bindgen_parameters
··· 34 34 # We use const helpers to aid bindgen, to avoid conflicts when constants are 35 35 # recognized, block generation of the non-helper constants. 36 36 --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
+1
rust/bindings/bindings_helper.h
··· 84 84 85 85 /* `bindgen` gets confused at certain things. */ 86 86 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; 87 88 const size_t RUST_CONST_HELPER_PAGE_SIZE = PAGE_SIZE; 88 89 const gfp_t RUST_CONST_HELPER_GFP_ATOMIC = GFP_ATOMIC; 89 90 const gfp_t RUST_CONST_HELPER_GFP_KERNEL = GFP_KERNEL;
+8
rust/bindings/lib.rs
··· 31 31 #[allow(clippy::undocumented_unsafe_blocks)] 32 32 #[cfg_attr(CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES, allow(unnecessary_transmutes))] 33 33 mod bindings_raw { 34 + use pin_init::{MaybeZeroable, Zeroable}; 35 + 34 36 // Manual definition for blocklisted types. 35 37 type __kernel_size_t = usize; 36 38 type __kernel_ssize_t = isize; 37 39 type __kernel_ptrdiff_t = isize; 40 + 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 {} 38 46 39 47 // Use glob import here to expose all helpers. 40 48 // Symbols defined within the module will take precedence to the glob import.
+2 -5
rust/kernel/acpi.rs
··· 37 37 /// Create a new device id from an ACPI 'id' string. 38 38 #[inline(always)] 39 39 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"); 45 42 // Replace with `bindings::acpi_device_id::default()` once stabilized for `const`. 46 43 // SAFETY: FFI type is valid to be zero-initialized. 47 44 let mut acpi: bindings::acpi_device_id = unsafe { core::mem::zeroed() };
+8 -7
rust/kernel/alloc.rs
··· 2 2 3 3 //! Implementation of the kernel's memory allocation infrastructure. 4 4 5 - #[cfg(not(any(test, testlib)))] 6 5 pub mod allocator; 7 6 pub mod kbox; 8 7 pub mod kvec; 9 8 pub mod layout; 10 - 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 9 17 10 pub use self::kbox::Box; 18 11 pub use self::kbox::KBox; ··· 130 137 /// - Implementers must ensure that all trait functions abide by the guarantees documented in the 131 138 /// `# Guarantees` sections. 132 139 pub unsafe trait Allocator { 140 + /// The minimum alignment satisfied by all allocations from this allocator. 141 + /// 142 + /// # Guarantees 143 + /// 144 + /// Any pointer allocated by this allocator is guaranteed to be aligned to `MIN_ALIGN` even if 145 + /// the requested layout has a smaller alignment. 146 + const MIN_ALIGN: usize; 147 + 133 148 /// Allocate memory based on `layout` and `flags`. 134 149 /// 135 150 /// On success, returns a buffer represented as `NonNull<[u8]>` that satisfies the layout
+8
rust/kernel/alloc/allocator.rs
··· 17 17 use crate::bindings; 18 18 use crate::pr_warn; 19 19 20 + const ARCH_KMALLOC_MINALIGN: usize = bindings::ARCH_KMALLOC_MINALIGN; 21 + 20 22 /// The contiguous kernel allocator. 21 23 /// 22 24 /// `Kmalloc` is typically used for physically contiguous allocations up to page size, but also ··· 130 128 // - passing a pointer to a valid memory allocation is OK, 131 129 // - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same. 132 130 unsafe impl Allocator for Kmalloc { 131 + const MIN_ALIGN: usize = ARCH_KMALLOC_MINALIGN; 132 + 133 133 #[inline] 134 134 unsafe fn realloc( 135 135 ptr: Option<NonNull<u8>>, ··· 151 147 // - passing a pointer to a valid memory allocation is OK, 152 148 // - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same. 153 149 unsafe impl Allocator for Vmalloc { 150 + const MIN_ALIGN: usize = kernel::page::PAGE_SIZE; 151 + 154 152 #[inline] 155 153 unsafe fn realloc( 156 154 ptr: Option<NonNull<u8>>, ··· 177 171 // - passing a pointer to a valid memory allocation is OK, 178 172 // - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same. 179 173 unsafe impl Allocator for KVmalloc { 174 + const MIN_ALIGN: usize = ARCH_KMALLOC_MINALIGN; 175 + 180 176 #[inline] 181 177 unsafe fn realloc( 182 178 ptr: Option<NonNull<u8>>,
-124
rust/kernel/alloc/allocator_test.rs
··· 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 - }
+87 -5
rust/kernel/alloc/kbox.rs
··· 7 7 use super::{AllocError, Allocator, Flags}; 8 8 use core::alloc::Layout; 9 9 use core::borrow::{Borrow, BorrowMut}; 10 - use core::fmt; 11 10 use core::marker::PhantomData; 12 11 use core::mem::ManuallyDrop; 13 12 use core::mem::MaybeUninit; ··· 16 17 use core::result::Result; 17 18 18 19 use crate::ffi::c_void; 20 + use crate::fmt; 19 21 use crate::init::InPlaceInit; 20 22 use crate::types::ForeignOwnable; 21 23 use pin_init::{InPlaceWrite, Init, PinInit, ZeroableOption}; ··· 290 290 Ok(Self::new(x, flags)?.into()) 291 291 } 292 292 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 + 293 370 /// Convert a [`Box<T,A>`] to a [`Pin<Box<T,A>>`]. If `T` does not implement 294 371 /// [`Unpin`], then `x` will be pinned in memory and can't be moved. 295 372 pub fn into_pin(this: Self) -> Pin<Self> { ··· 478 401 } 479 402 480 403 // SAFETY: The pointer returned by `into_foreign` comes from a well aligned 481 - // pointer to `T`. 404 + // pointer to `T` allocated by `A`. 482 405 unsafe impl<T: 'static, A> ForeignOwnable for Box<T, A> 483 406 where 484 407 A: Allocator, 485 408 { 486 - const FOREIGN_ALIGN: usize = core::mem::align_of::<T>(); 409 + const FOREIGN_ALIGN: usize = if core::mem::align_of::<T>() < A::MIN_ALIGN { 410 + A::MIN_ALIGN 411 + } else { 412 + core::mem::align_of::<T>() 413 + }; 414 + 487 415 type Borrowed<'a> = &'a T; 488 416 type BorrowedMut<'a> = &'a mut T; 489 417 ··· 517 435 } 518 436 519 437 // SAFETY: The pointer returned by `into_foreign` comes from a well aligned 520 - // pointer to `T`. 438 + // pointer to `T` allocated by `A`. 521 439 unsafe impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>> 522 440 where 523 441 A: Allocator, 524 442 { 525 - const FOREIGN_ALIGN: usize = core::mem::align_of::<T>(); 443 + const FOREIGN_ALIGN: usize = <Box<T, A> as ForeignOwnable>::FOREIGN_ALIGN; 526 444 type Borrowed<'a> = Pin<&'a T>; 527 445 type BorrowedMut<'a> = Pin<&'a mut T>; 528 446
+17 -7
rust/kernel/alloc/kvec.rs
··· 7 7 layout::ArrayLayout, 8 8 AllocError, Allocator, Box, Flags, 9 9 }; 10 + use crate::fmt; 10 11 use core::{ 11 12 borrow::{Borrow, BorrowMut}, 12 - fmt, 13 13 marker::PhantomData, 14 14 mem::{ManuallyDrop, MaybeUninit}, 15 15 ops::Deref, ··· 175 175 176 176 /// Returns the number of elements that can be stored within the vector without allocating 177 177 /// additional memory. 178 - pub fn capacity(&self) -> usize { 178 + pub const fn capacity(&self) -> usize { 179 179 if const { Self::is_zst() } { 180 180 usize::MAX 181 181 } else { ··· 185 185 186 186 /// Returns the number of elements stored within the vector. 187 187 #[inline] 188 - pub fn len(&self) -> usize { 188 + pub const fn len(&self) -> usize { 189 189 self.len 190 190 } 191 191 ··· 196 196 /// - `additional` must be less than or equal to `self.capacity - self.len`. 197 197 /// - All elements within the interval [`self.len`,`self.len + additional`) must be initialized. 198 198 #[inline] 199 - pub unsafe fn inc_len(&mut self, additional: usize) { 199 + pub const unsafe fn inc_len(&mut self, additional: usize) { 200 200 // Guaranteed by the type invariant to never underflow. 201 201 debug_assert!(additional <= self.capacity() - self.len()); 202 202 // INVARIANT: By the safety requirements of this method this represents the exact number of ··· 224 224 } 225 225 226 226 /// 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 + /// ``` 227 237 #[inline] 228 238 pub fn as_slice(&self) -> &[T] { 229 239 self ··· 255 245 /// Returns a raw pointer to the vector's backing buffer, or, if `T` is a ZST, a dangling raw 256 246 /// pointer. 257 247 #[inline] 258 - pub fn as_ptr(&self) -> *const T { 248 + pub const fn as_ptr(&self) -> *const T { 259 249 self.ptr.as_ptr() 260 250 } 261 251 ··· 271 261 /// assert!(!v.is_empty()); 272 262 /// ``` 273 263 #[inline] 274 - pub fn is_empty(&self) -> bool { 264 + pub const fn is_empty(&self) -> bool { 275 265 self.len() == 0 276 266 } 277 267 ··· 1304 1294 } 1305 1295 } 1306 1296 1307 - #[macros::kunit_tests(rust_kvec_kunit)] 1297 + #[macros::kunit_tests(rust_kvec)] 1308 1298 mod tests { 1309 1299 use super::*; 1310 1300 use crate::prelude::*;
+1 -1
rust/kernel/alloc/kvec/errors.rs
··· 2 2 3 3 //! Errors for the [`Vec`] type. 4 4 5 - use core::fmt::{self, Debug, Formatter}; 5 + use kernel::fmt::{self, Debug, Formatter}; 6 6 use kernel::prelude::*; 7 7 8 8 /// Error type for [`Vec::push_within_capacity`].
+1 -1
rust/kernel/alloc/layout.rs
··· 80 80 /// # Safety 81 81 /// 82 82 /// `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 { 84 84 // INVARIANT: By the safety requirements of this function 85 85 // `len * size_of::<T>() <= isize::MAX`. 86 86 Self {
+2 -2
rust/kernel/auxiliary.rs
··· 105 105 impl DeviceId { 106 106 /// Create a new [`DeviceId`] from name. 107 107 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(); 110 110 111 111 // TODO: Replace with `bindings::auxiliary_device_id::default()` once stabilized for 112 112 // `const`.
+1 -1
rust/kernel/block/mq.rs
··· 82 82 //! Arc::pin_init(TagSet::new(1, 256, 1), flags::GFP_KERNEL)?; 83 83 //! let mut disk = gen_disk::GenDiskBuilder::new() 84 84 //! .capacity_sectors(4096) 85 - //! .build(format_args!("myblk"), tagset)?; 85 + //! .build(fmt!("myblk"), tagset)?; 86 86 //! 87 87 //! # Ok::<(), kernel::error::Error>(()) 88 88 //! ```
+2 -2
rust/kernel/block/mq/gen_disk.rs
··· 3 3 //! Generic disk abstraction. 4 4 //! 5 5 //! 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) 7 7 8 8 use crate::block::mq::{raw_writer::RawWriter, Operations, TagSet}; 9 + use crate::fmt::{self, Write}; 9 10 use crate::{bindings, error::from_err_ptr, error::Result, sync::Arc}; 10 11 use crate::{error, static_lock_class}; 11 - use core::fmt::{self, Write}; 12 12 13 13 /// A builder for [`GenDisk`]. 14 14 ///
+1 -2
rust/kernel/block/mq/raw_writer.rs
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 - use core::fmt::{self, Write}; 4 - 5 3 use crate::error::Result; 4 + use crate::fmt::{self, Write}; 6 5 use crate::prelude::EINVAL; 7 6 8 7 /// A mutable reference to a byte buffer where a string can be written into.
+2 -2
rust/kernel/configfs.rs
··· 263 263 try_pin_init!(Self { 264 264 group <- pin_init::init_zeroed().chain(|v: &mut Opaque<bindings::config_group>| { 265 265 let place = v.get(); 266 - let name = name.as_bytes_with_nul().as_ptr(); 266 + let name = name.to_bytes_with_nul().as_ptr(); 267 267 // SAFETY: It is safe to initialize a group once it has been zeroed. 268 268 unsafe { 269 269 bindings::config_group_init_type_name(place, name.cast(), item_type.as_ptr()) ··· 613 613 pub const fn new(name: &'static CStr) -> Self { 614 614 Self { 615 615 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), 617 617 ca_owner: core::ptr::null_mut(), 618 618 ca_mode: 0o660, 619 619 show: Some(Self::show),
+1
rust/kernel/cpu.rs
··· 109 109 /// unexpectedly due to preemption or CPU migration. It should only be 110 110 /// used when the context ensures that the task remains on the same CPU 111 111 /// or the users could use a stale (yet valid) CPU ID. 112 + #[inline] 112 113 pub fn current() -> Self { 113 114 // SAFETY: raw_smp_processor_id() always returns a valid CPU ID. 114 115 unsafe { Self::from_u32_unchecked(bindings::raw_smp_processor_id()) }
+2 -4
rust/kernel/cpufreq.rs
··· 27 27 use core::{ 28 28 cell::UnsafeCell, 29 29 marker::PhantomData, 30 - mem::MaybeUninit, 31 30 ops::{Deref, DerefMut}, 32 31 pin::Pin, 33 32 ptr, ··· 1012 1013 } else { 1013 1014 None 1014 1015 }, 1015 - // SAFETY: All zeros is a valid value for `bindings::cpufreq_driver`. 1016 - ..unsafe { MaybeUninit::zeroed().assume_init() } 1016 + ..pin_init::zeroed() 1017 1017 }; 1018 1018 1019 1019 const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] { 1020 - let src = name.as_bytes_with_nul(); 1020 + let src = name.to_bytes_with_nul(); 1021 1021 let mut dst = [0; CPUFREQ_NAME_LEN]; 1022 1022 1023 1023 build_assert!(src.len() <= CPUFREQ_NAME_LEN);
+3 -3
rust/kernel/device.rs
··· 5 5 //! C header: [`include/linux/device.h`](srctree/include/linux/device.h) 6 6 7 7 use crate::{ 8 - bindings, 8 + bindings, fmt, 9 9 types::{ARef, ForeignOwnable, Opaque}, 10 10 }; 11 - use core::{fmt, marker::PhantomData, ptr}; 11 + use core::{marker::PhantomData, ptr}; 12 12 13 13 #[cfg(CONFIG_PRINTK)] 14 14 use crate::c_str; ··· 596 596 macro_rules! dev_printk { 597 597 ($method:ident, $dev:expr, $($f:tt)*) => { 598 598 { 599 - ($dev).$method(::core::format_args!($($f)*)); 599 + ($dev).$method($crate::prelude::fmt!($($f)*)); 600 600 } 601 601 } 602 602 }
+12 -11
rust/kernel/device/property.rs
··· 11 11 alloc::KVec, 12 12 bindings, 13 13 error::{to_result, Result}, 14 + fmt, 14 15 prelude::*, 15 16 str::{CStr, CString}, 16 17 types::{ARef, Opaque}, ··· 69 68 unsafe { bindings::is_of_node(self.as_raw()) } 70 69 } 71 70 72 - /// Returns an object that implements [`Display`](core::fmt::Display) for 71 + /// Returns an object that implements [`Display`](fmt::Display) for 73 72 /// printing the name of a node. 74 73 /// 75 74 /// This is an alternative to the default `Display` implementation, which 76 75 /// prints the full path. 77 - pub fn display_name(&self) -> impl core::fmt::Display + '_ { 76 + pub fn display_name(&self) -> impl fmt::Display + '_ { 78 77 struct FwNodeDisplayName<'a>(&'a FwNode); 79 78 80 - impl core::fmt::Display for FwNodeDisplayName<'_> { 81 - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 79 + impl fmt::Display for FwNodeDisplayName<'_> { 80 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 82 81 // SAFETY: `self` is valid by its type invariant. 83 82 let name = unsafe { bindings::fwnode_get_name(self.0.as_raw()) }; 84 83 if name.is_null() { ··· 88 87 // - `fwnode_get_name` returns null or a valid C string. 89 88 // - `name` was checked to be non-null. 90 89 let name = unsafe { CStr::from_char_ptr(name) }; 91 - write!(f, "{name}") 90 + fmt::Display::fmt(name, f) 92 91 } 93 92 } 94 93 ··· 352 351 } 353 352 } 354 353 355 - impl core::fmt::Debug for FwNodeReferenceArgs { 356 - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 354 + impl fmt::Debug for FwNodeReferenceArgs { 355 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 357 356 write!(f, "{:?}", self.as_slice()) 358 357 } 359 358 } ··· 378 377 Owned(ARef<FwNode>), 379 378 } 380 379 381 - impl core::fmt::Display for FwNode { 382 - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 380 + impl fmt::Display for FwNode { 381 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 383 382 // The logic here is the same as the one in lib/vsprintf.c 384 383 // (fwnode_full_name_string). 385 384 ··· 414 413 // SAFETY: `fwnode_get_name_prefix` returns null or a 415 414 // valid C string. 416 415 let prefix = unsafe { CStr::from_char_ptr(prefix) }; 417 - write!(f, "{prefix}")?; 416 + fmt::Display::fmt(prefix, f)?; 418 417 } 419 - write!(f, "{}", fwnode.display_name())?; 418 + fmt::Display::fmt(&fwnode.display_name(), f)?; 420 419 } 421 420 422 421 Ok(())
+1 -1
rust/kernel/dma.rs
··· 9 9 device::{Bound, Core}, 10 10 error::{to_result, Result}, 11 11 prelude::*, 12 + sync::aref::ARef, 12 13 transmute::{AsBytes, FromBytes}, 13 - types::ARef, 14 14 }; 15 15 16 16 /// Trait to be implemented by DMA capable bus devices.
+3 -3
rust/kernel/drm/device.rs
··· 2 2 3 3 //! DRM device. 4 4 //! 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) 6 6 7 7 use crate::{ 8 8 alloc::allocator::Kmalloc, ··· 82 82 major: T::INFO.major, 83 83 minor: T::INFO.minor, 84 84 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(), 87 87 88 88 driver_features: drm::driver::FEAT_GEM, 89 89 ioctls: T::IOCTLS.as_ptr(),
+1 -1
rust/kernel/drm/driver.rs
··· 2 2 3 3 //! DRM driver core. 4 4 //! 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) 6 6 7 7 use crate::{ 8 8 bindings, device, devres, drm,
+1 -1
rust/kernel/drm/file.rs
··· 2 2 3 3 //! DRM File objects. 4 4 //! 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) 6 6 7 7 use crate::{bindings, drm, error::Result, prelude::*, types::Opaque}; 8 8 use core::marker::PhantomData;
+1 -1
rust/kernel/drm/gem/mod.rs
··· 2 2 3 3 //! DRM GEM API 4 4 //! 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) 6 6 7 7 use crate::{ 8 8 alloc::flags::*,
+1 -1
rust/kernel/drm/ioctl.rs
··· 2 2 3 3 //! DRM IOCTL definitions. 4 4 //! 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) 6 6 7 7 use crate::ioctl; 8 8
+59 -7
rust/kernel/error.rs
··· 2 2 3 3 //! Kernel errors. 4 4 //! 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) 6 8 7 9 use crate::{ 8 10 alloc::{layout::LayoutError, AllocError}, ··· 103 101 impl Error { 104 102 /// Creates an [`Error`] from a kernel error code. 105 103 /// 106 - /// It is a bug to pass an out-of-range `errno`. `EINVAL` would 107 - /// be returned in such a case. 104 + /// `errno` must be within error code range (i.e. `>= -MAX_ERRNO && < 0`). 105 + /// 106 + /// It is a bug to pass an out-of-range `errno`. [`code::EINVAL`] is returned in such a case. 107 + /// 108 + /// # Examples 109 + /// 110 + /// ``` 111 + /// assert_eq!(Error::from_errno(-1), EPERM); 112 + /// assert_eq!(Error::from_errno(-2), ENOENT); 113 + /// ``` 114 + /// 115 + /// The following calls are considered a bug: 116 + /// 117 + /// ``` 118 + /// assert_eq!(Error::from_errno(0), EINVAL); 119 + /// assert_eq!(Error::from_errno(-1000000), EINVAL); 120 + /// ``` 108 121 pub fn from_errno(errno: crate::ffi::c_int) -> Error { 109 122 if let Some(error) = Self::try_from_errno(errno) { 110 123 error ··· 175 158 } 176 159 177 160 /// Returns a string representing the error, if one exists. 178 - #[cfg(not(any(test, testlib)))] 161 + #[cfg(not(testlib))] 179 162 pub fn name(&self) -> Option<&'static CStr> { 180 163 // SAFETY: Just an FFI call, there are no extra safety requirements. 181 164 let ptr = unsafe { bindings::errname(-self.0.get()) }; ··· 192 175 /// When `testlib` is configured, this always returns `None` to avoid the dependency on a 193 176 /// kernel function so that tests that use this (e.g., by calling [`Result::unwrap`]) can still 194 177 /// run in userspace. 195 - #[cfg(any(test, testlib))] 178 + #[cfg(testlib)] 196 179 pub fn name(&self) -> Option<&'static CStr> { 197 180 None 198 181 } ··· 392 375 /// [Rust documentation]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html 393 376 pub type Result<T = (), E = Error> = core::result::Result<T, E>; 394 377 395 - /// Converts an integer as returned by a C kernel function to an error if it's negative, and 396 - /// `Ok(())` otherwise. 378 + /// Converts an integer as returned by a C kernel function to a [`Result`]. 379 + /// 380 + /// If the integer is negative, an [`Err`] with an [`Error`] as given by [`Error::from_errno`] is 381 + /// returned. This means the integer must be `>= -MAX_ERRNO`. 382 + /// 383 + /// Otherwise, it returns [`Ok`]. 384 + /// 385 + /// It is a bug to pass an out-of-range negative integer. `Err(EINVAL)` is returned in such a case. 386 + /// 387 + /// # Examples 388 + /// 389 + /// This function may be used to easily perform early returns with the [`?`] operator when working 390 + /// with C APIs within Rust abstractions: 391 + /// 392 + /// ``` 393 + /// # use kernel::error::to_result; 394 + /// # mod bindings { 395 + /// # #![expect(clippy::missing_safety_doc)] 396 + /// # use kernel::prelude::*; 397 + /// # pub(super) unsafe fn f1() -> c_int { 0 } 398 + /// # pub(super) unsafe fn f2() -> c_int { EINVAL.to_errno() } 399 + /// # } 400 + /// fn f() -> Result { 401 + /// // SAFETY: ... 402 + /// to_result(unsafe { bindings::f1() })?; 403 + /// 404 + /// // SAFETY: ... 405 + /// to_result(unsafe { bindings::f2() })?; 406 + /// 407 + /// // ... 408 + /// 409 + /// Ok(()) 410 + /// } 411 + /// # assert_eq!(f(), Err(EINVAL)); 412 + /// ``` 413 + /// 414 + /// [`?`]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator 397 415 pub fn to_result(err: crate::ffi::c_int) -> Result { 398 416 if err < 0 { 399 417 Err(Error::from_errno(err))
+1 -1
rust/kernel/firmware.rs
··· 291 291 let module_name = this.module_name; 292 292 293 293 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()); 295 295 296 296 if N != 0 { 297 297 // Re-use the space taken by the NULL terminator and swap it with the '.' separator.
+3 -2
rust/kernel/fs/file.rs
··· 11 11 bindings, 12 12 cred::Credential, 13 13 error::{code::*, to_result, Error, Result}, 14 + fmt, 14 15 sync::aref::{ARef, AlwaysRefCounted}, 15 16 types::{NotThreadSafe, Opaque}, 16 17 }; ··· 461 460 } 462 461 } 463 462 464 - impl core::fmt::Debug for BadFdError { 465 - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 463 + impl fmt::Debug for BadFdError { 464 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 466 465 f.pad("EBADF") 467 466 } 468 467 }
+7 -7
rust/kernel/kunit.rs
··· 6 6 //! 7 7 //! Reference: <https://docs.kernel.org/dev-tools/kunit/index.html> 8 8 9 + use crate::fmt; 9 10 use crate::prelude::*; 10 - use core::fmt; 11 11 12 12 #[cfg(CONFIG_PRINTK)] 13 13 use crate::c_str; ··· 74 74 // mistake (it is hidden to prevent that). 75 75 // 76 76 // This mimics KUnit's failed assertion format. 77 - $crate::kunit::err(format_args!( 77 + $crate::kunit::err($crate::prelude::fmt!( 78 78 " # {}: ASSERTION FAILED at {FILE}:{LINE}\n", 79 79 $name 80 80 )); 81 - $crate::kunit::err(format_args!( 81 + $crate::kunit::err($crate::prelude::fmt!( 82 82 " Expected {CONDITION} to be true, but is false\n" 83 83 )); 84 - $crate::kunit::err(format_args!( 84 + $crate::kunit::err($crate::prelude::fmt!( 85 85 " Failure not reported to KUnit since this is a non-KUnit task\n" 86 86 )); 87 87 break 'out; ··· 102 102 unsafe impl Sync for UnaryAssert {} 103 103 104 104 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), 106 106 line: LINE, 107 107 }); 108 108 static ASSERTION: UnaryAssert = UnaryAssert($crate::bindings::kunit_unary_assert { 109 109 assert: $crate::bindings::kunit_assert {}, 110 - condition: CONDITION.as_char_ptr(), 110 + condition: $crate::str::as_char_ptr_in_const_context(CONDITION), 111 111 expected_true: true, 112 112 }); 113 113 ··· 202 202 ) -> kernel::bindings::kunit_case { 203 203 kernel::bindings::kunit_case { 204 204 run_case: Some(run_case), 205 - name: name.as_char_ptr(), 205 + name: kernel::str::as_char_ptr_in_const_context(name), 206 206 attr: kernel::bindings::kunit_attributes { 207 207 speed: kernel::bindings::kunit_speed_KUNIT_SPEED_NORMAL, 208 208 },
+4 -1
rust/kernel/lib.rs
··· 17 17 // the unstable features in use. 18 18 // 19 19 // Stable since Rust 1.79.0. 20 + #![feature(generic_nonzero)] 20 21 #![feature(inline_const)] 21 22 // 22 23 // Stable since Rust 1.81.0. ··· 29 28 // Stable since Rust 1.83.0. 30 29 #![feature(const_maybe_uninit_as_mut_ptr)] 31 30 #![feature(const_mut_refs)] 31 + #![feature(const_option)] 32 32 #![feature(const_ptr_write)] 33 33 #![feature(const_refs_to_cell)] 34 34 // ··· 112 110 pub mod platform; 113 111 pub mod prelude; 114 112 pub mod print; 113 + pub mod ptr; 115 114 pub mod rbtree; 116 115 pub mod regulator; 117 116 pub mod revocable; ··· 209 206 } 210 207 } 211 208 212 - #[cfg(not(any(testlib, test)))] 209 + #[cfg(not(testlib))] 213 210 #[panic_handler] 214 211 fn panic(info: &core::panic::PanicInfo<'_>) -> ! { 215 212 pr_emerg!("{}\n", info);
+120
rust/kernel/list.rs
··· 38 38 /// 39 39 /// # Examples 40 40 /// 41 + /// Use [`ListLinks`] as the type of the intrusive field. 42 + /// 41 43 /// ``` 42 44 /// use kernel::list::*; 43 45 /// ··· 137 135 /// assert_eq!(iter.next().ok_or(EINVAL)?.value, 15); 138 136 /// assert_eq!(iter.next().ok_or(EINVAL)?.value, 25); 139 137 /// assert_eq!(iter.next().ok_or(EINVAL)?.value, 35); 138 + /// assert!(iter.next().is_none()); 139 + /// assert!(list2.is_empty()); 140 + /// } 141 + /// # Result::<(), Error>::Ok(()) 142 + /// ``` 143 + /// 144 + /// Use [`ListLinksSelfPtr`] as the type of the intrusive field. This allows a list of trait object 145 + /// type. 146 + /// 147 + /// ``` 148 + /// use kernel::list::*; 149 + /// 150 + /// trait Foo { 151 + /// fn foo(&self) -> (&'static str, i32); 152 + /// } 153 + /// 154 + /// #[pin_data] 155 + /// struct DTWrap<T: ?Sized> { 156 + /// #[pin] 157 + /// links: ListLinksSelfPtr<DTWrap<dyn Foo>>, 158 + /// value: T, 159 + /// } 160 + /// 161 + /// impl<T> DTWrap<T> { 162 + /// fn new(value: T) -> Result<ListArc<Self>> { 163 + /// ListArc::pin_init(try_pin_init!(Self { 164 + /// value, 165 + /// links <- ListLinksSelfPtr::new(), 166 + /// }), GFP_KERNEL) 167 + /// } 168 + /// } 169 + /// 170 + /// impl_list_arc_safe! { 171 + /// impl{T: ?Sized} ListArcSafe<0> for DTWrap<T> { untracked; } 172 + /// } 173 + /// impl_list_item! { 174 + /// impl ListItem<0> for DTWrap<dyn Foo> { using ListLinksSelfPtr { self.links }; } 175 + /// } 176 + /// 177 + /// // Create a new empty list. 178 + /// let mut list = List::<DTWrap<dyn Foo>>::new(); 179 + /// { 180 + /// assert!(list.is_empty()); 181 + /// } 182 + /// 183 + /// struct A(i32); 184 + /// // `A` returns the inner value for `foo`. 185 + /// impl Foo for A { fn foo(&self) -> (&'static str, i32) { ("a", self.0) } } 186 + /// 187 + /// struct B; 188 + /// // `B` always returns 42. 189 + /// impl Foo for B { fn foo(&self) -> (&'static str, i32) { ("b", 42) } } 190 + /// 191 + /// // Insert 3 element using `push_back()`. 192 + /// list.push_back(DTWrap::new(A(15))?); 193 + /// list.push_back(DTWrap::new(A(32))?); 194 + /// list.push_back(DTWrap::new(B)?); 195 + /// 196 + /// // Iterate over the list to verify the nodes were inserted correctly. 197 + /// // [A(15), A(32), B] 198 + /// { 199 + /// let mut iter = list.iter(); 200 + /// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 15)); 201 + /// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 32)); 202 + /// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42)); 203 + /// assert!(iter.next().is_none()); 204 + /// 205 + /// // Verify the length of the list. 206 + /// assert_eq!(list.iter().count(), 3); 207 + /// } 208 + /// 209 + /// // Pop the items from the list using `pop_back()` and verify the content. 210 + /// { 211 + /// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("b", 42)); 212 + /// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 32)); 213 + /// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 15)); 214 + /// } 215 + /// 216 + /// // Insert 3 elements using `push_front()`. 217 + /// list.push_front(DTWrap::new(A(15))?); 218 + /// list.push_front(DTWrap::new(A(32))?); 219 + /// list.push_front(DTWrap::new(B)?); 220 + /// 221 + /// // Iterate over the list to verify the nodes were inserted correctly. 222 + /// // [B, A(32), A(15)] 223 + /// { 224 + /// let mut iter = list.iter(); 225 + /// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42)); 226 + /// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 32)); 227 + /// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 15)); 228 + /// assert!(iter.next().is_none()); 229 + /// 230 + /// // Verify the length of the list. 231 + /// assert_eq!(list.iter().count(), 3); 232 + /// } 233 + /// 234 + /// // Pop the items from the list using `pop_front()` and verify the content. 235 + /// { 236 + /// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 15)); 237 + /// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 32)); 238 + /// } 239 + /// 240 + /// // Push `list2` to `list` through `push_all_back()`. 241 + /// // list: [B] 242 + /// // list2: [B, A(25)] 243 + /// { 244 + /// let mut list2 = List::<DTWrap<dyn Foo>>::new(); 245 + /// list2.push_back(DTWrap::new(B)?); 246 + /// list2.push_back(DTWrap::new(A(25))?); 247 + /// 248 + /// list.push_all_back(&mut list2); 249 + /// 250 + /// // list: [B, B, A(25)] 251 + /// // list2: [] 252 + /// let mut iter = list.iter(); 253 + /// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42)); 254 + /// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42)); 255 + /// assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 25)); 140 256 /// assert!(iter.next().is_none()); 141 257 /// assert!(list2.is_empty()); 142 258 /// }
+1 -1
rust/kernel/miscdevice.rs
··· 34 34 // SAFETY: All zeros is valid for this C type. 35 35 let mut result: bindings::miscdevice = unsafe { MaybeUninit::zeroed().assume_init() }; 36 36 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); 38 38 result.fops = MiscdeviceVTable::<T>::build(); 39 39 result 40 40 }
+1 -1
rust/kernel/net/phy.rs
··· 497 497 pub const fn create_phy_driver<T: Driver>() -> DriverVTable { 498 498 // INVARIANT: All the fields of `struct phy_driver` are initialized properly. 499 499 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(), 501 501 flags: T::FLAGS, 502 502 phy_id: T::PHY_DEVICE_ID.id(), 503 503 phy_id_mask: T::PHY_DEVICE_ID.mask_as_int(),
+1 -1
rust/kernel/of.rs
··· 34 34 impl DeviceId { 35 35 /// Create a new device id from an OF 'compatible' string. 36 36 pub const fn new(compatible: &'static CStr) -> Self { 37 - let src = compatible.as_bytes_with_nul(); 37 + let src = compatible.to_bytes_with_nul(); 38 38 // Replace with `bindings::of_device_id::default()` once stabilized for `const`. 39 39 // SAFETY: FFI type is valid to be zero-initialized. 40 40 let mut of: bindings::of_device_id = unsafe { core::mem::zeroed() };
+4 -1
rust/kernel/prelude.rs
··· 12 12 //! ``` 13 13 14 14 #[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 + }; 16 19 17 20 pub use ::ffi::{ 18 21 c_char, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint, c_ulong, c_ulonglong,
+228
rust/kernel/ptr.rs
··· 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);
+3 -3
rust/kernel/seq_file.rs
··· 4 4 //! 5 5 //! C header: [`include/linux/seq_file.h`](srctree/include/linux/seq_file.h) 6 6 7 - use crate::{bindings, c_str, types::NotThreadSafe, types::Opaque}; 7 + use crate::{bindings, c_str, fmt, types::NotThreadSafe, types::Opaque}; 8 8 9 9 /// A utility for generating the contents of a seq file. 10 10 #[repr(transparent)] ··· 31 31 32 32 /// Used by the [`seq_print`] macro. 33 33 #[inline] 34 - pub fn call_printf(&self, args: core::fmt::Arguments<'_>) { 34 + pub fn call_printf(&self, args: fmt::Arguments<'_>) { 35 35 // SAFETY: Passing a void pointer to `Arguments` is valid for `%pA`. 36 36 unsafe { 37 37 bindings::seq_printf( ··· 47 47 #[macro_export] 48 48 macro_rules! seq_print { 49 49 ($m:expr, $($arg:tt)+) => ( 50 - $m.call_printf(format_args!($($arg)+)) 50 + $m.call_printf($crate::prelude::fmt!($($arg)+)) 51 51 ); 52 52 } 53 53 pub use seq_print;
+4 -4
rust/kernel/sync/arc.rs
··· 19 19 use crate::{ 20 20 alloc::{AllocError, Flags, KBox}, 21 21 ffi::c_void, 22 + fmt, 22 23 init::InPlaceInit, 23 24 sync::Refcount, 24 25 try_init, ··· 28 27 use core::{ 29 28 alloc::Layout, 30 29 borrow::{Borrow, BorrowMut}, 31 - fmt, 32 30 marker::PhantomData, 33 31 mem::{ManuallyDrop, MaybeUninit}, 34 32 ops::{Deref, DerefMut}, ··· 367 367 } 368 368 } 369 369 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. 372 372 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; 374 374 375 375 type Borrowed<'a> = ArcBorrow<'a, T>; 376 376 type BorrowedMut<'a> = Self::Borrowed<'a>;
+16 -1
rust/kernel/sync/aref.rs
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 3 //! 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 4 19 5 20 use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull}; 6 21 ··· 112 97 /// 113 98 /// ``` 114 99 /// use core::ptr::NonNull; 115 - /// use kernel::types::{ARef, AlwaysRefCounted}; 100 + /// use kernel::sync::aref::{ARef, AlwaysRefCounted}; 116 101 /// 117 102 /// struct Empty {} 118 103 ///
+4 -3
rust/kernel/task.rs
··· 9 9 ffi::{c_int, c_long, c_uint}, 10 10 mm::MmWithUser, 11 11 pid_namespace::PidNamespace, 12 - types::{ARef, NotThreadSafe, Opaque}, 12 + sync::aref::ARef, 13 + types::{NotThreadSafe, Opaque}, 13 14 }; 14 15 use core::{ 15 16 cmp::{Eq, PartialEq}, ··· 77 76 /// incremented when creating `State` and decremented when it is dropped: 78 77 /// 79 78 /// ``` 80 - /// use kernel::{task::Task, types::ARef}; 79 + /// use kernel::{task::Task, sync::aref::ARef}; 81 80 /// 82 81 /// struct State { 83 82 /// creator: ARef<Task>, ··· 348 347 } 349 348 350 349 // SAFETY: The type invariants guarantee that `Task` is always refcounted. 351 - unsafe impl crate::types::AlwaysRefCounted for Task { 350 + unsafe impl crate::sync::aref::AlwaysRefCounted for Task { 352 351 #[inline] 353 352 fn inc_ref(&self) { 354 353 // SAFETY: The existence of a shared reference means that the refcount is nonzero.
+162 -1
rust/kernel/time.rs
··· 25 25 //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h). 26 26 27 27 use core::marker::PhantomData; 28 + use core::ops; 28 29 29 30 pub mod delay; 30 31 pub mod hrtimer; ··· 201 200 pub(crate) fn as_nanos(&self) -> i64 { 202 201 self.inner 203 202 } 203 + 204 + /// Create an [`Instant`] from a `ktime_t` without checking if it is non-negative. 205 + /// 206 + /// # Panics 207 + /// 208 + /// On debug builds, this function will panic if `ktime` is not in the range from 0 to 209 + /// `KTIME_MAX`. 210 + /// 211 + /// # Safety 212 + /// 213 + /// The caller promises that `ktime` is in the range from 0 to `KTIME_MAX`. 214 + #[inline] 215 + pub(crate) unsafe fn from_ktime(ktime: bindings::ktime_t) -> Self { 216 + debug_assert!(ktime >= 0); 217 + 218 + // INVARIANT: Our safety contract ensures that `ktime` is in the range from 0 to 219 + // `KTIME_MAX`. 220 + Self { 221 + inner: ktime, 222 + _c: PhantomData, 223 + } 224 + } 204 225 } 205 226 206 - impl<C: ClockSource> core::ops::Sub for Instant<C> { 227 + impl<C: ClockSource> ops::Sub for Instant<C> { 207 228 type Output = Delta; 208 229 209 230 // By the type invariant, it never overflows. ··· 233 210 fn sub(self, other: Instant<C>) -> Delta { 234 211 Delta { 235 212 nanos: self.inner - other.inner, 213 + } 214 + } 215 + } 216 + 217 + impl<T: ClockSource> ops::Add<Delta> for Instant<T> { 218 + type Output = Self; 219 + 220 + #[inline] 221 + fn add(self, rhs: Delta) -> Self::Output { 222 + // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow 223 + // (e.g. go above `KTIME_MAX`) 224 + let res = self.inner + rhs.nanos; 225 + 226 + // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0 227 + #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)] 228 + assert!(res >= 0); 229 + 230 + Self { 231 + inner: res, 232 + _c: PhantomData, 233 + } 234 + } 235 + } 236 + 237 + impl<T: ClockSource> ops::Sub<Delta> for Instant<T> { 238 + type Output = Self; 239 + 240 + #[inline] 241 + fn sub(self, rhs: Delta) -> Self::Output { 242 + // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow 243 + // (e.g. go above `KTIME_MAX`) 244 + let res = self.inner - rhs.nanos; 245 + 246 + // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0 247 + #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)] 248 + assert!(res >= 0); 249 + 250 + Self { 251 + inner: res, 252 + _c: PhantomData, 236 253 } 237 254 } 238 255 } ··· 285 222 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 286 223 pub struct Delta { 287 224 nanos: i64, 225 + } 226 + 227 + impl ops::Add for Delta { 228 + type Output = Self; 229 + 230 + #[inline] 231 + fn add(self, rhs: Self) -> Self { 232 + Self { 233 + nanos: self.nanos + rhs.nanos, 234 + } 235 + } 236 + } 237 + 238 + impl ops::AddAssign for Delta { 239 + #[inline] 240 + fn add_assign(&mut self, rhs: Self) { 241 + self.nanos += rhs.nanos; 242 + } 243 + } 244 + 245 + impl ops::Sub for Delta { 246 + type Output = Self; 247 + 248 + #[inline] 249 + fn sub(self, rhs: Self) -> Self::Output { 250 + Self { 251 + nanos: self.nanos - rhs.nanos, 252 + } 253 + } 254 + } 255 + 256 + impl ops::SubAssign for Delta { 257 + #[inline] 258 + fn sub_assign(&mut self, rhs: Self) { 259 + self.nanos -= rhs.nanos; 260 + } 261 + } 262 + 263 + impl ops::Mul<i64> for Delta { 264 + type Output = Self; 265 + 266 + #[inline] 267 + fn mul(self, rhs: i64) -> Self::Output { 268 + Self { 269 + nanos: self.nanos * rhs, 270 + } 271 + } 272 + } 273 + 274 + impl ops::MulAssign<i64> for Delta { 275 + #[inline] 276 + fn mul_assign(&mut self, rhs: i64) { 277 + self.nanos *= rhs; 278 + } 279 + } 280 + 281 + impl ops::Div for Delta { 282 + type Output = i64; 283 + 284 + #[inline] 285 + fn div(self, rhs: Self) -> Self::Output { 286 + #[cfg(CONFIG_64BIT)] 287 + { 288 + self.nanos / rhs.nanos 289 + } 290 + 291 + #[cfg(not(CONFIG_64BIT))] 292 + { 293 + // SAFETY: This function is always safe to call regardless of the input values 294 + unsafe { bindings::div64_s64(self.nanos, rhs.nanos) } 295 + } 296 + } 288 297 } 289 298 290 299 impl Delta { ··· 445 310 // SAFETY: It is always safe to call `ktime_to_ms()` with any value. 446 311 unsafe { 447 312 bindings::ktime_to_ms(self.as_nanos()) 313 + } 314 + } 315 + 316 + /// Return `self % dividend` where `dividend` is in nanoseconds. 317 + /// 318 + /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is 319 + /// limited to 32 bit dividends. 320 + #[inline] 321 + pub fn rem_nanos(self, dividend: i32) -> Self { 322 + #[cfg(CONFIG_64BIT)] 323 + { 324 + Self { 325 + nanos: self.as_nanos() % i64::from(dividend), 326 + } 327 + } 328 + 329 + #[cfg(not(CONFIG_64BIT))] 330 + { 331 + let mut rem = 0; 332 + 333 + // SAFETY: `rem` is in the stack, so we can always provide a valid pointer to it. 334 + unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) }; 335 + 336 + Self { 337 + nanos: i64::from(rem), 338 + } 448 339 } 449 340 } 450 341 }
+149 -3
rust/kernel/time/hrtimer.rs
··· 69 69 70 70 use super::{ClockSource, Delta, Instant}; 71 71 use crate::{prelude::*, types::Opaque}; 72 - use core::marker::PhantomData; 72 + use core::{marker::PhantomData, ptr::NonNull}; 73 73 use pin_init::PinInit; 74 + 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>; 74 79 75 80 /// A timer backed by a C `struct hrtimer`. 76 81 /// ··· 167 162 // SAFETY: `c_timer_ptr` is initialized and valid. Synchronization is 168 163 // handled on the C side. 169 164 unsafe { bindings::hrtimer_cancel(c_timer_ptr) != 0 } 165 + } 166 + 167 + /// Forward the timer expiry for a given timer pointer. 168 + /// 169 + /// # Safety 170 + /// 171 + /// - `self_ptr` must point to a valid `Self`. 172 + /// - The caller must either have exclusive access to the data pointed at by `self_ptr`, or be 173 + /// within the context of the timer callback. 174 + #[inline] 175 + unsafe fn raw_forward(self_ptr: *mut Self, now: HrTimerInstant<T>, interval: Delta) -> u64 176 + where 177 + T: HasHrTimer<T>, 178 + { 179 + // SAFETY: 180 + // * The C API requirements for this function are fulfilled by our safety contract. 181 + // * `self_ptr` is guaranteed to point to a valid `Self` via our safety contract 182 + unsafe { 183 + bindings::hrtimer_forward(Self::raw_get(self_ptr), now.as_nanos(), interval.as_nanos()) 184 + } 185 + } 186 + 187 + /// Conditionally forward the timer. 188 + /// 189 + /// If the timer expires after `now`, this function does nothing and returns 0. If the timer 190 + /// expired at or before `now`, this function forwards the timer by `interval` until the timer 191 + /// expires after `now` and then returns the number of times the timer was forwarded by 192 + /// `interval`. 193 + /// 194 + /// This function is mainly useful for timer types which can provide exclusive access to the 195 + /// timer when the timer is not running. For forwarding the timer from within the timer callback 196 + /// context, see [`HrTimerCallbackContext::forward()`]. 197 + /// 198 + /// Returns the number of overruns that occurred as a result of the timer expiry change. 199 + pub fn forward(self: Pin<&mut Self>, now: HrTimerInstant<T>, interval: Delta) -> u64 200 + where 201 + T: HasHrTimer<T>, 202 + { 203 + // SAFETY: `raw_forward` does not move `Self` 204 + let this = unsafe { self.get_unchecked_mut() }; 205 + 206 + // SAFETY: By existence of `Pin<&mut Self>`, the pointer passed to `raw_forward` points to a 207 + // valid `Self` that we have exclusive access to. 208 + unsafe { Self::raw_forward(this, now, interval) } 209 + } 210 + 211 + /// Conditionally forward the timer. 212 + /// 213 + /// This is a variant of [`forward()`](Self::forward) that uses an interval after the current 214 + /// time of the base clock for the [`HrTimer`]. 215 + pub fn forward_now(self: Pin<&mut Self>, interval: Delta) -> u64 216 + where 217 + T: HasHrTimer<T>, 218 + { 219 + self.forward(HrTimerInstant::<T>::now(), interval) 220 + } 221 + 222 + /// Return the time expiry for this [`HrTimer`]. 223 + /// 224 + /// This value should only be used as a snapshot, as the actual expiry time could change after 225 + /// this function is called. 226 + pub fn expires(&self) -> HrTimerInstant<T> 227 + where 228 + T: HasHrTimer<T>, 229 + { 230 + // SAFETY: `self` is an immutable reference and thus always points to a valid `HrTimer`. 231 + let c_timer_ptr = unsafe { HrTimer::raw_get(self) }; 232 + 233 + // SAFETY: 234 + // - Timers cannot have negative ktime_t values as their expiration time. 235 + // - There's no actual locking here, a racy read is fine and expected 236 + unsafe { 237 + Instant::from_ktime( 238 + // This `read_volatile` is intended to correspond to a READ_ONCE call. 239 + // FIXME(read_once): Replace with `read_once` when available on the Rust side. 240 + core::ptr::read_volatile(&raw const ((*c_timer_ptr).node.expires)), 241 + ) 242 + } 170 243 } 171 244 } 172 245 ··· 383 300 type Pointer<'a>: RawHrTimerCallback; 384 301 385 302 /// Called by the timer logic when the timer fires. 386 - fn run(this: <Self::Pointer<'_> as RawHrTimerCallback>::CallbackTarget<'_>) -> HrTimerRestart 303 + fn run( 304 + this: <Self::Pointer<'_> as RawHrTimerCallback>::CallbackTarget<'_>, 305 + ctx: HrTimerCallbackContext<'_, Self>, 306 + ) -> HrTimerRestart 387 307 where 388 - Self: Sized; 308 + Self: Sized, 309 + Self: HasHrTimer<Self>; 389 310 } 390 311 391 312 /// A handle representing a potentially running timer. ··· 411 324 /// Note that the timer might be started by a concurrent start operation. If 412 325 /// so, the timer might not be in the **stopped** state when this function 413 326 /// returns. 327 + /// 328 + /// Returns `true` if the timer was running. 414 329 fn cancel(&mut self) -> bool; 415 330 } 416 331 ··· 672 583 673 584 type Clock = C; 674 585 type Expires = Delta; 586 + } 587 + 588 + /// Privileged smart-pointer for a [`HrTimer`] callback context. 589 + /// 590 + /// Many [`HrTimer`] methods can only be called in two situations: 591 + /// 592 + /// * When the caller has exclusive access to the `HrTimer` and the `HrTimer` is guaranteed not to 593 + /// be running. 594 + /// * From within the context of an `HrTimer`'s callback method. 595 + /// 596 + /// This type provides access to said methods from within a timer callback context. 597 + /// 598 + /// # Invariants 599 + /// 600 + /// * The existence of this type means the caller is currently within the callback for an 601 + /// [`HrTimer`]. 602 + /// * `self.0` always points to a live instance of [`HrTimer<T>`]. 603 + pub struct HrTimerCallbackContext<'a, T: HasHrTimer<T>>(NonNull<HrTimer<T>>, PhantomData<&'a ()>); 604 + 605 + impl<'a, T: HasHrTimer<T>> HrTimerCallbackContext<'a, T> { 606 + /// Create a new [`HrTimerCallbackContext`]. 607 + /// 608 + /// # Safety 609 + /// 610 + /// This function relies on the caller being within the context of a timer callback, so it must 611 + /// not be used anywhere except for within implementations of [`RawHrTimerCallback::run`]. The 612 + /// caller promises that `timer` points to a valid initialized instance of 613 + /// [`bindings::hrtimer`]. 614 + /// 615 + /// The returned `Self` must not outlive the function context of [`RawHrTimerCallback::run`] 616 + /// where this function is called. 617 + pub(crate) unsafe fn from_raw(timer: *mut HrTimer<T>) -> Self { 618 + // SAFETY: The caller guarantees `timer` is a valid pointer to an initialized 619 + // `bindings::hrtimer` 620 + // INVARIANT: Our safety contract ensures that we're within the context of a timer callback 621 + // and that `timer` points to a live instance of `HrTimer<T>`. 622 + Self(unsafe { NonNull::new_unchecked(timer) }, PhantomData) 623 + } 624 + 625 + /// Conditionally forward the timer. 626 + /// 627 + /// This function is identical to [`HrTimer::forward()`] except that it may only be used from 628 + /// within the context of a [`HrTimer`] callback. 629 + pub fn forward(&mut self, now: HrTimerInstant<T>, interval: Delta) -> u64 { 630 + // SAFETY: 631 + // - We are guaranteed to be within the context of a timer callback by our type invariants 632 + // - By our type invariants, `self.0` always points to a valid `HrTimer<T>` 633 + unsafe { HrTimer::<T>::raw_forward(self.0.as_ptr(), now, interval) } 634 + } 635 + 636 + /// Conditionally forward the timer. 637 + /// 638 + /// This is a variant of [`HrTimerCallbackContext::forward()`] that uses an interval after the 639 + /// current time of the base clock for the [`HrTimer`]. 640 + pub fn forward_now(&mut self, duration: Delta) -> u64 { 641 + self.forward(HrTimerInstant::<T>::now(), duration) 642 + } 675 643 } 676 644 677 645 /// Use to implement the [`HasHrTimer<T>`] trait.
+8 -1
rust/kernel/time/hrtimer/arc.rs
··· 3 3 use super::HasHrTimer; 4 4 use super::HrTimer; 5 5 use super::HrTimerCallback; 6 + use super::HrTimerCallbackContext; 6 7 use super::HrTimerHandle; 7 8 use super::HrTimerMode; 8 9 use super::HrTimerPointer; ··· 100 99 // allocation from other `Arc` clones. 101 100 let receiver = unsafe { ArcBorrow::from_raw(data_ptr) }; 102 101 103 - T::run(receiver).into_c() 102 + // SAFETY: 103 + // - By C API contract `timer_ptr` is the pointer that we passed when queuing the timer, so 104 + // it is a valid pointer to a `HrTimer<T>` embedded in a `T`. 105 + // - We are within `RawHrTimerCallback::run` 106 + let context = unsafe { HrTimerCallbackContext::from_raw(timer_ptr) }; 107 + 108 + T::run(receiver, context).into_c() 104 109 } 105 110 }
+8 -1
rust/kernel/time/hrtimer/pin.rs
··· 3 3 use super::HasHrTimer; 4 4 use super::HrTimer; 5 5 use super::HrTimerCallback; 6 + use super::HrTimerCallbackContext; 6 7 use super::HrTimerHandle; 7 8 use super::HrTimerMode; 8 9 use super::RawHrTimerCallback; ··· 104 103 // here. 105 104 let receiver_pin = unsafe { Pin::new_unchecked(receiver_ref) }; 106 105 107 - T::run(receiver_pin).into_c() 106 + // SAFETY: 107 + // - By C API contract `timer_ptr` is the pointer that we passed when queuing the timer, so 108 + // it is a valid pointer to a `HrTimer<T>` embedded in a `T`. 109 + // - We are within `RawHrTimerCallback::run` 110 + let context = unsafe { HrTimerCallbackContext::from_raw(timer_ptr) }; 111 + 112 + T::run(receiver_pin, context).into_c() 108 113 } 109 114 }
+9 -3
rust/kernel/time/hrtimer/pin_mut.rs
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 3 use super::{ 4 - HasHrTimer, HrTimer, HrTimerCallback, HrTimerHandle, HrTimerMode, RawHrTimerCallback, 5 - UnsafeHrTimerPointer, 4 + HasHrTimer, HrTimer, HrTimerCallback, HrTimerCallbackContext, HrTimerHandle, HrTimerMode, 5 + RawHrTimerCallback, UnsafeHrTimerPointer, 6 6 }; 7 7 use core::{marker::PhantomData, pin::Pin, ptr::NonNull}; 8 8 ··· 107 107 // here. 108 108 let receiver_pin = unsafe { Pin::new_unchecked(receiver_ref) }; 109 109 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() 111 117 } 112 118 }
+8 -1
rust/kernel/time/hrtimer/tbox.rs
··· 3 3 use super::HasHrTimer; 4 4 use super::HrTimer; 5 5 use super::HrTimerCallback; 6 + use super::HrTimerCallbackContext; 6 7 use super::HrTimerHandle; 7 8 use super::HrTimerMode; 8 9 use super::HrTimerPointer; ··· 120 119 // `data_ptr` exist. 121 120 let data_mut_ref = unsafe { Pin::new_unchecked(&mut *data_ptr) }; 122 121 123 - T::run(data_mut_ref).into_c() 122 + // SAFETY: 123 + // - By C API contract `timer_ptr` is the pointer that we passed when queuing the timer, so 124 + // it is a valid pointer to a `HrTimer<T>` embedded in a `T`. 125 + // - We are within `RawHrTimerCallback::run` 126 + let context = unsafe { HrTimerCallbackContext::from_raw(timer_ptr) }; 127 + 128 + T::run(data_mut_ref, context).into_c() 124 129 } 125 130 }
+49 -55
rust/macros/quote.rs
··· 2 2 3 3 use proc_macro::{TokenStream, TokenTree}; 4 4 5 - #[allow(dead_code)] 6 5 pub(crate) trait ToTokens { 7 6 fn to_tokens(&self, tokens: &mut TokenStream); 8 7 } ··· 46 47 /// `quote` crate but provides only just enough functionality needed by the current `macros` crate. 47 48 macro_rules! quote_spanned { 48 49 ($span:expr => $($tt:tt)*) => {{ 49 - let mut tokens: ::std::vec::Vec<::proc_macro::TokenTree>; 50 - #[allow(clippy::vec_init_then_push)] 50 + let mut tokens = ::proc_macro::TokenStream::new(); 51 51 { 52 - tokens = ::std::vec::Vec::new(); 53 52 let span = $span; 54 53 quote_spanned!(@proc tokens span $($tt)*); 55 54 } 56 - ::proc_macro::TokenStream::from_iter(tokens) 55 + tokens 57 56 }}; 58 57 (@proc $v:ident $span:ident) => {}; 59 58 (@proc $v:ident $span:ident #$id:ident $($tt:tt)*) => { 60 - let mut ts = ::proc_macro::TokenStream::new(); 61 - $crate::quote::ToTokens::to_tokens(&$id, &mut ts); 62 - $v.extend(ts); 59 + $crate::quote::ToTokens::to_tokens(&$id, &mut $v); 63 60 quote_spanned!(@proc $v $span $($tt)*); 64 61 }; 65 62 (@proc $v:ident $span:ident #(#$id:ident)* $($tt:tt)*) => { 66 63 for token in $id { 67 - let mut ts = ::proc_macro::TokenStream::new(); 68 - $crate::quote::ToTokens::to_tokens(&token, &mut ts); 69 - $v.extend(ts); 64 + $crate::quote::ToTokens::to_tokens(&token, &mut $v); 70 65 } 71 66 quote_spanned!(@proc $v $span $($tt)*); 72 67 }; 73 68 (@proc $v:ident $span:ident ( $($inner:tt)* ) $($tt:tt)*) => { 74 69 #[allow(unused_mut)] 75 - let mut tokens = ::std::vec::Vec::<::proc_macro::TokenTree>::new(); 70 + let mut tokens = ::proc_macro::TokenStream::new(); 76 71 quote_spanned!(@proc tokens $span $($inner)*); 77 - $v.push(::proc_macro::TokenTree::Group(::proc_macro::Group::new( 72 + $v.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new( 78 73 ::proc_macro::Delimiter::Parenthesis, 79 - ::proc_macro::TokenStream::from_iter(tokens) 80 - ))); 74 + tokens, 75 + ))]); 81 76 quote_spanned!(@proc $v $span $($tt)*); 82 77 }; 83 78 (@proc $v:ident $span:ident [ $($inner:tt)* ] $($tt:tt)*) => { 84 - let mut tokens = ::std::vec::Vec::new(); 79 + let mut tokens = ::proc_macro::TokenStream::new(); 85 80 quote_spanned!(@proc tokens $span $($inner)*); 86 - $v.push(::proc_macro::TokenTree::Group(::proc_macro::Group::new( 81 + $v.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new( 87 82 ::proc_macro::Delimiter::Bracket, 88 - ::proc_macro::TokenStream::from_iter(tokens) 89 - ))); 83 + tokens, 84 + ))]); 90 85 quote_spanned!(@proc $v $span $($tt)*); 91 86 }; 92 87 (@proc $v:ident $span:ident { $($inner:tt)* } $($tt:tt)*) => { 93 - let mut tokens = ::std::vec::Vec::new(); 88 + let mut tokens = ::proc_macro::TokenStream::new(); 94 89 quote_spanned!(@proc tokens $span $($inner)*); 95 - $v.push(::proc_macro::TokenTree::Group(::proc_macro::Group::new( 90 + $v.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new( 96 91 ::proc_macro::Delimiter::Brace, 97 - ::proc_macro::TokenStream::from_iter(tokens) 98 - ))); 92 + tokens, 93 + ))]); 99 94 quote_spanned!(@proc $v $span $($tt)*); 100 95 }; 101 96 (@proc $v:ident $span:ident :: $($tt:tt)*) => { 102 - $v.push(::proc_macro::TokenTree::Punct( 103 - ::proc_macro::Punct::new(':', ::proc_macro::Spacing::Joint) 104 - )); 105 - $v.push(::proc_macro::TokenTree::Punct( 106 - ::proc_macro::Punct::new(':', ::proc_macro::Spacing::Alone) 107 - )); 97 + $v.extend([::proc_macro::Spacing::Joint, ::proc_macro::Spacing::Alone].map(|spacing| { 98 + ::proc_macro::TokenTree::Punct(::proc_macro::Punct::new(':', spacing)) 99 + })); 108 100 quote_spanned!(@proc $v $span $($tt)*); 109 101 }; 110 102 (@proc $v:ident $span:ident : $($tt:tt)*) => { 111 - $v.push(::proc_macro::TokenTree::Punct( 112 - ::proc_macro::Punct::new(':', ::proc_macro::Spacing::Alone) 113 - )); 103 + $v.extend([::proc_macro::TokenTree::Punct( 104 + ::proc_macro::Punct::new(':', ::proc_macro::Spacing::Alone), 105 + )]); 114 106 quote_spanned!(@proc $v $span $($tt)*); 115 107 }; 116 108 (@proc $v:ident $span:ident , $($tt:tt)*) => { 117 - $v.push(::proc_macro::TokenTree::Punct( 118 - ::proc_macro::Punct::new(',', ::proc_macro::Spacing::Alone) 119 - )); 109 + $v.extend([::proc_macro::TokenTree::Punct( 110 + ::proc_macro::Punct::new(',', ::proc_macro::Spacing::Alone), 111 + )]); 120 112 quote_spanned!(@proc $v $span $($tt)*); 121 113 }; 122 114 (@proc $v:ident $span:ident @ $($tt:tt)*) => { 123 - $v.push(::proc_macro::TokenTree::Punct( 124 - ::proc_macro::Punct::new('@', ::proc_macro::Spacing::Alone) 125 - )); 115 + $v.extend([::proc_macro::TokenTree::Punct( 116 + ::proc_macro::Punct::new('@', ::proc_macro::Spacing::Alone), 117 + )]); 126 118 quote_spanned!(@proc $v $span $($tt)*); 127 119 }; 128 120 (@proc $v:ident $span:ident ! $($tt:tt)*) => { 129 - $v.push(::proc_macro::TokenTree::Punct( 130 - ::proc_macro::Punct::new('!', ::proc_macro::Spacing::Alone) 131 - )); 121 + $v.extend([::proc_macro::TokenTree::Punct( 122 + ::proc_macro::Punct::new('!', ::proc_macro::Spacing::Alone), 123 + )]); 132 124 quote_spanned!(@proc $v $span $($tt)*); 133 125 }; 134 126 (@proc $v:ident $span:ident ; $($tt:tt)*) => { 135 - $v.push(::proc_macro::TokenTree::Punct( 136 - ::proc_macro::Punct::new(';', ::proc_macro::Spacing::Alone) 137 - )); 127 + $v.extend([::proc_macro::TokenTree::Punct( 128 + ::proc_macro::Punct::new(';', ::proc_macro::Spacing::Alone), 129 + )]); 138 130 quote_spanned!(@proc $v $span $($tt)*); 139 131 }; 140 132 (@proc $v:ident $span:ident + $($tt:tt)*) => { 141 - $v.push(::proc_macro::TokenTree::Punct( 142 - ::proc_macro::Punct::new('+', ::proc_macro::Spacing::Alone) 143 - )); 133 + $v.extend([::proc_macro::TokenTree::Punct( 134 + ::proc_macro::Punct::new('+', ::proc_macro::Spacing::Alone), 135 + )]); 144 136 quote_spanned!(@proc $v $span $($tt)*); 145 137 }; 146 138 (@proc $v:ident $span:ident = $($tt:tt)*) => { 147 - $v.push(::proc_macro::TokenTree::Punct( 148 - ::proc_macro::Punct::new('=', ::proc_macro::Spacing::Alone) 149 - )); 139 + $v.extend([::proc_macro::TokenTree::Punct( 140 + ::proc_macro::Punct::new('=', ::proc_macro::Spacing::Alone), 141 + )]); 150 142 quote_spanned!(@proc $v $span $($tt)*); 151 143 }; 152 144 (@proc $v:ident $span:ident # $($tt:tt)*) => { 153 - $v.push(::proc_macro::TokenTree::Punct( 154 - ::proc_macro::Punct::new('#', ::proc_macro::Spacing::Alone) 155 - )); 145 + $v.extend([::proc_macro::TokenTree::Punct( 146 + ::proc_macro::Punct::new('#', ::proc_macro::Spacing::Alone), 147 + )]); 156 148 quote_spanned!(@proc $v $span $($tt)*); 157 149 }; 158 150 (@proc $v:ident $span:ident _ $($tt:tt)*) => { 159 - $v.push(::proc_macro::TokenTree::Ident(::proc_macro::Ident::new("_", $span))); 151 + $v.extend([::proc_macro::TokenTree::Ident( 152 + ::proc_macro::Ident::new("_", $span), 153 + )]); 160 154 quote_spanned!(@proc $v $span $($tt)*); 161 155 }; 162 156 (@proc $v:ident $span:ident $id:ident $($tt:tt)*) => { 163 - $v.push(::proc_macro::TokenTree::Ident(::proc_macro::Ident::new(stringify!($id), $span))); 157 + $v.extend([::proc_macro::TokenTree::Ident( 158 + ::proc_macro::Ident::new(stringify!($id), $span), 159 + )]); 164 160 quote_spanned!(@proc $v $span $($tt)*); 165 161 }; 166 162 }
+2
rust/uapi/lib.rs
··· 34 34 type __kernel_ssize_t = isize; 35 35 type __kernel_ptrdiff_t = isize; 36 36 37 + use pin_init::MaybeZeroable; 38 + 37 39 include!(concat!(env!("OBJTREE"), "/rust/uapi/uapi_generated.rs"));
+1 -1
samples/rust/rust_configfs.rs
··· 94 94 95 95 fn show(container: &Configuration, page: &mut [u8; PAGE_SIZE]) -> Result<usize> { 96 96 pr_info!("Show message\n"); 97 - let data = container.message; 97 + let data = container.message.to_bytes(); 98 98 page[0..data.len()].copy_from_slice(data); 99 99 Ok(data.len()) 100 100 }
+1 -1
samples/rust/rust_dma.rs
··· 10 10 dma::{CoherentAllocation, Device, DmaMask}, 11 11 pci, 12 12 prelude::*, 13 - types::ARef, 13 + sync::aref::ARef, 14 14 }; 15 15 16 16 struct DmaSampleDriver {
+2 -2
scripts/generate_rust_analyzer.py
··· 139 139 "exclude_dirs": [], 140 140 } 141 141 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"]) 144 144 append_crate_with_generated("kernel", ["core", "macros", "build_error", "pin_init", "ffi", "bindings", "uapi"]) 145 145 146 146 def is_root_crate(build_file, target):
+1 -1
scripts/rustdoc_test_gen.rs
··· 202 202 // This follows the syntax for declaring test metadata in the proposed KTAP v2 spec, which may 203 203 // be used for the proposed KUnit test attributes API. Thus hopefully this will make migration 204 204 // 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")); 206 206 207 207 /// The anchor where the test code body starts. 208 208 #[allow(unused)]