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

Pull Rust updates from Miguel Ojeda:
"Toolchain and infrastructure:

- KUnit '#[test]'s:

- Support KUnit-mapped 'assert!' macros.

The support that landed last cycle was very basic, and the
'assert!' macros panicked since they were the standard library
ones. Now, they are mapped to the KUnit ones in a similar way to
how is done for doctests, reusing the infrastructure there.

With this, a failing test like:

#[test]
fn my_first_test() {
assert_eq!(42, 43);
}

will report:

# my_first_test: ASSERTION FAILED at rust/kernel/lib.rs:251
Expected 42 == 43 to be true, but is false
# my_first_test.speed: normal
not ok 1 my_first_test

- Support tests with checked 'Result' return types.

The return value of test functions that return a 'Result' will
be checked, thus one can now easily catch errors when e.g. using
the '?' operator in tests.

With this, a failing test like:

#[test]
fn my_test() -> Result {
f()?;
Ok(())
}

will report:

# my_test: ASSERTION FAILED at rust/kernel/lib.rs:321
Expected is_test_result_ok(my_test()) to be true, but is false
# my_test.speed: normal
not ok 1 my_test

- Add 'kunit_tests' to the prelude.

- Clarify the remaining language unstable features in use.

- Compile 'core' with edition 2024 for Rust >= 1.87.

- Workaround 'bindgen' issue with forward references to 'enum' types.

- objtool: relax slice condition to cover more 'noreturn' functions.

- Use absolute paths in macros referencing 'core' and 'kernel'
crates.

- Skip '-mno-fdpic' flag for bindgen in GCC 32-bit arm builds.

- Clean some 'doc_markdown' lint hits -- we may enable it later on.

'kernel' crate:

- 'alloc' module:

- 'Box': support for type coercion, e.g. 'Box<T>' to 'Box<dyn U>'
if 'T' implements 'U'.

- 'Vec': implement new methods (prerequisites for nova-core and
binder): 'truncate', 'resize', 'clear', 'pop',
'push_within_capacity' (with new error type 'PushError'),
'drain_all', 'retain', 'remove' (with new error type
'RemoveError'), insert_within_capacity' (with new error type
'InsertError').

In addition, simplify 'push' using 'spare_capacity_mut', split
'set_len' into 'inc_len' and 'dec_len', add type invariant 'len
<= capacity' and simplify 'truncate' using 'dec_len'.

- 'time' module:

- Morph the Rust hrtimer subsystem into the Rust timekeeping
subsystem, covering delay, sleep, timekeeping, timers. This new
subsystem has all the relevant timekeeping C maintainers listed
in the entry.

- Replace 'Ktime' with 'Delta' and 'Instant' types to represent a
duration of time and a point in time.

- Temporarily add 'Ktime' to 'hrtimer' module to allow 'hrtimer'
to delay converting to 'Instant' and 'Delta'.

- 'xarray' module:

- Add a Rust abstraction for the 'xarray' data structure. This
abstraction allows Rust code to leverage the 'xarray' to store
types that implement 'ForeignOwnable'. This support is a
dependency for memory backing feature of the Rust null block
driver, which is waiting to be merged.

- Set up an entry in 'MAINTAINERS' for the XArray Rust support.
Patches will go to the new Rust XArray tree and then via the
Rust subsystem tree for now.

- Allow 'ForeignOwnable' to carry information about the pointed-to
type. This helps asserting alignment requirements for the
pointer passed to the foreign language.

- 'container_of!': retain pointer mut-ness and add a compile-time
check of the type of the first parameter ('$field_ptr').

- Support optional message in 'static_assert!'.

- Add C FFI types (e.g. 'c_int') to the prelude.

- 'str' module: simplify KUnit tests 'format!' macro, convert
'rusttest' tests into KUnit, take advantage of the '-> Result'
support in KUnit '#[test]'s.

- 'list' module: add examples for 'List', fix path of
'assert_pinned!' (so far unused macro rule).

- 'workqueue' module: remove 'HasWork::OFFSET'.

- 'page' module: add 'inline' attribute.

'macros' crate:

- 'module' macro: place 'cleanup_module()' in '.exit.text' section.

'pin-init' crate:

- Add 'Wrapper<T>' trait for creating pin-initializers for wrapper
structs with a structurally pinned value such as 'UnsafeCell<T>' or
'MaybeUninit<T>'.

- Add 'MaybeZeroable' derive macro to try to derive 'Zeroable', but
not error if not all fields implement it. This is needed to derive
'Zeroable' for all bindgen-generated structs.

- Add 'unsafe fn cast_[pin_]init()' functions to unsafely change the
initialized type of an initializer. These are utilized by the
'Wrapper<T>' implementations.

- Add support for visibility in 'Zeroable' derive macro.

- Add support for 'union's in 'Zeroable' derive macro.

- Upstream dev news: streamline CI, fix some bugs. Add new workflows
to check if the user-space version and the one in the kernel tree
have diverged. Use the issues tab [1] to track them, which should
help folks report and diagnose issues w.r.t. 'pin-init' better.

[1] https://github.com/rust-for-linux/pin-init/issues

Documentation:

- Testing: add docs on the new KUnit '#[test]' tests.

- Coding guidelines: explain that '///' vs. '//' applies to private
items too. Add section on C FFI types.

- Quick Start guide: update Ubuntu instructions and split them into
"25.04" and "24.04 LTS and older".

And a few other cleanups and improvements"

* tag 'rust-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (78 commits)
rust: list: Fix typo `much` in arc.rs
rust: check type of `$ptr` in `container_of!`
rust: workqueue: remove HasWork::OFFSET
rust: retain pointer mut-ness in `container_of!`
Documentation: rust: testing: add docs on the new KUnit `#[test]` tests
Documentation: rust: rename `#[test]`s to "`rusttest` host tests"
rust: str: take advantage of the `-> Result` support in KUnit `#[test]`'s
rust: str: simplify KUnit tests `format!` macro
rust: str: convert `rusttest` tests into KUnit
rust: add `kunit_tests` to the prelude
rust: kunit: support checked `-> Result`s in KUnit `#[test]`s
rust: kunit: support KUnit-mapped `assert!` macros in `#[test]`s
rust: make section names plural
rust: list: fix path of `assert_pinned!`
rust: compile libcore with edition 2024 for 1.87+
rust: dma: add missing Markdown code span
rust: task: add missing Markdown code spans and intra-doc links
rust: pci: fix docs related to missing Markdown code spans
rust: alloc: add missing Markdown code span
rust: alloc: add missing Markdown code spans
...

+1980 -394
+1
.mailmap
··· 135 135 Benjamin Poirier <benjamin.poirier@gmail.com> <bpoirier@suse.de> 136 136 Benjamin Tissoires <bentiss@kernel.org> <benjamin.tissoires@gmail.com> 137 137 Benjamin Tissoires <bentiss@kernel.org> <benjamin.tissoires@redhat.com> 138 + Benno Lossin <lossin@kernel.org> <benno.lossin@proton.me> 138 139 Bingwu Zhang <xtex@aosc.io> <xtexchooser@duck.com> 139 140 Bingwu Zhang <xtex@aosc.io> <xtex@xtexx.eu.org> 140 141 Bjorn Andersson <andersson@kernel.org> <bjorn@kryo.se>
+29
Documentation/rust/coding-guidelines.rst
··· 85 85 // ... 86 86 } 87 87 88 + This applies to both public and private items. This increases consistency with 89 + public items, allows changes to visibility with less changes involved and will 90 + allow us to potentially generate the documentation for private items as well. 91 + In other words, if documentation is written for a private item, then ``///`` 92 + should still be used. For instance: 93 + 94 + .. code-block:: rust 95 + 96 + /// My private function. 97 + // TODO: ... 98 + fn f() {} 99 + 88 100 One special kind of comments are the ``// SAFETY:`` comments. These must appear 89 101 before every ``unsafe`` block, and they explain why the code inside the block is 90 102 correct/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.: ··· 201 189 .. code-block:: rust 202 190 203 191 /// [`struct mutex`]: srctree/include/linux/mutex.h 192 + 193 + 194 + C FFI types 195 + ----------- 196 + 197 + Rust kernel code refers to C types, such as ``int``, using type aliases such as 198 + ``c_int``, which are readily available from the ``kernel`` prelude. Please do 199 + not use the aliases from ``core::ffi`` -- they may not map to the correct types. 200 + 201 + These aliases should generally be referred directly by their identifier, i.e. 202 + as a single segment path. For instance: 203 + 204 + .. code-block:: rust 205 + 206 + fn f(p: *const c_char) -> c_int { 207 + // ... 208 + } 204 209 205 210 206 211 Naming
+41 -3
Documentation/rust/quick-start.rst
··· 90 90 Ubuntu 91 91 ****** 92 92 93 - Ubuntu LTS and non-LTS (interim) releases provide recent Rust releases and thus 94 - they should generally work out of the box, e.g.:: 93 + 25.04 94 + ~~~~~ 95 95 96 - apt install rustc-1.80 rust-1.80-src bindgen-0.65 rustfmt-1.80 rust-1.80-clippy 96 + The latest Ubuntu releases provide recent Rust releases and thus they should 97 + generally work out of the box, e.g.:: 98 + 99 + apt install rustc rust-src bindgen rustfmt rust-clippy 100 + 101 + In addition, ``RUST_LIB_SRC`` needs to be set, e.g.:: 102 + 103 + RUST_LIB_SRC=/usr/src/rustc-$(rustc --version | cut -d' ' -f2)/library 104 + 105 + For convenience, ``RUST_LIB_SRC`` can be exported to the global environment. 106 + 107 + 108 + 24.04 LTS and older 109 + ~~~~~~~~~~~~~~~~~~~ 110 + 111 + Though Ubuntu 24.04 LTS and older versions still provide recent Rust 112 + releases, they require some additional configuration to be set, using 113 + the versioned packages, e.g.:: 114 + 115 + apt install rustc-1.80 rust-1.80-src bindgen-0.65 rustfmt-1.80 \ 116 + rust-1.80-clippy 117 + ln -s /usr/lib/rust-1.80/bin/rustfmt /usr/bin/rustfmt-1.80 118 + ln -s /usr/lib/rust-1.80/bin/clippy-driver /usr/bin/clippy-driver-1.80 119 + 120 + None of these packages set their tools as defaults; therefore they should be 121 + specified explicitly, e.g.:: 122 + 123 + make LLVM=1 RUSTC=rustc-1.80 RUSTDOC=rustdoc-1.80 RUSTFMT=rustfmt-1.80 \ 124 + CLIPPY_DRIVER=clippy-driver-1.80 BINDGEN=bindgen-0.65 125 + 126 + Alternatively, modify the ``PATH`` variable to place the Rust 1.80 binaries 127 + first and set ``bindgen`` as the default, e.g.:: 128 + 129 + PATH=/usr/lib/rust-1.80/bin:$PATH 130 + update-alternatives --install /usr/bin/bindgen bindgen \ 131 + /usr/bin/bindgen-0.65 100 132 + update-alternatives --set bindgen /usr/bin/bindgen-0.65 97 133 98 134 ``RUST_LIB_SRC`` needs to be set when using the versioned packages, e.g.:: 99 135 100 136 RUST_LIB_SRC=/usr/src/rustc-$(rustc-1.80 --version | cut -d' ' -f2)/library 137 + 138 + For convenience, ``RUST_LIB_SRC`` can be exported to the global environment. 101 139 102 140 In addition, ``bindgen-0.65`` is available in newer releases (24.04 LTS and 103 141 24.10), but it may not be available in older ones (20.04 LTS and 22.04 LTS),
+76 -4
Documentation/rust/testing.rst
··· 133 133 The ``#[test]`` tests 134 134 --------------------- 135 135 136 - Additionally, there are the ``#[test]`` tests. These can be run using the 137 - ``rusttest`` Make target:: 136 + Additionally, there are the ``#[test]`` tests. Like for documentation tests, 137 + these are also fairly similar to what you would expect from userspace, and they 138 + are also mapped to KUnit. 139 + 140 + These tests are introduced by the ``kunit_tests`` procedural macro, which takes 141 + the name of the test suite as an argument. 142 + 143 + For instance, assume we want to test the function ``f`` from the documentation 144 + tests section. We could write, in the same file where we have our function: 145 + 146 + .. code-block:: rust 147 + 148 + #[kunit_tests(rust_kernel_mymod)] 149 + mod tests { 150 + use super::*; 151 + 152 + #[test] 153 + fn test_f() { 154 + assert_eq!(f(10, 20), 30); 155 + } 156 + } 157 + 158 + And if we run it, the kernel log would look like:: 159 + 160 + KTAP version 1 161 + # Subtest: rust_kernel_mymod 162 + # speed: normal 163 + 1..1 164 + # test_f.speed: normal 165 + ok 1 test_f 166 + ok 1 rust_kernel_mymod 167 + 168 + Like documentation tests, the ``assert!`` and ``assert_eq!`` macros are mapped 169 + back to KUnit and do not panic. Similarly, the 170 + `? <https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator>`_ 171 + operator is supported, i.e. the test functions may return either nothing (i.e. 172 + the unit type ``()``) or ``Result`` (i.e. any ``Result<T, E>``). For instance: 173 + 174 + .. code-block:: rust 175 + 176 + #[kunit_tests(rust_kernel_mymod)] 177 + mod tests { 178 + use super::*; 179 + 180 + #[test] 181 + fn test_g() -> Result { 182 + let x = g()?; 183 + assert_eq!(x, 30); 184 + Ok(()) 185 + } 186 + } 187 + 188 + If we run the test and the call to ``g`` fails, then the kernel log would show:: 189 + 190 + KTAP version 1 191 + # Subtest: rust_kernel_mymod 192 + # speed: normal 193 + 1..1 194 + # test_g: ASSERTION FAILED at rust/kernel/lib.rs:335 195 + Expected is_test_result_ok(test_g()) to be true, but is false 196 + # test_g.speed: normal 197 + not ok 1 test_g 198 + not ok 1 rust_kernel_mymod 199 + 200 + If a ``#[test]`` test could be useful as an example for the user, then please 201 + use a documentation test instead. Even edge cases of an API, e.g. error or 202 + boundary cases, can be interesting to show in examples. 203 + 204 + The ``rusttest`` host tests 205 + --------------------------- 206 + 207 + These are userspace tests that can be built and run in the host (i.e. the one 208 + that performs the kernel build) using the ``rusttest`` Make target:: 138 209 139 210 make LLVM=1 rusttest 140 211 141 - This requires the kernel ``.config``. It runs the ``#[test]`` tests on the host 142 - (currently) and thus is fairly limited in what these tests can test. 212 + This requires the kernel ``.config``. 213 + 214 + Currently, they are mostly used for testing the ``macros`` crate's examples. 143 215 144 216 The Kselftests 145 217 --------------
+20 -6
MAINTAINERS
··· 10719 10719 F: kernel/time/timer_migration.* 10720 10720 F: tools/testing/selftests/timers/ 10721 10721 10722 - HIGH-RESOLUTION TIMERS [RUST] 10722 + DELAY, SLEEP, TIMEKEEPING, TIMERS [RUST] 10723 10723 M: Andreas Hindborg <a.hindborg@kernel.org> 10724 10724 R: Boqun Feng <boqun.feng@gmail.com> 10725 + R: FUJITA Tomonori <fujita.tomonori@gmail.com> 10725 10726 R: Frederic Weisbecker <frederic@kernel.org> 10726 10727 R: Lyude Paul <lyude@redhat.com> 10727 10728 R: Thomas Gleixner <tglx@linutronix.de> 10728 10729 R: Anna-Maria Behnsen <anna-maria@linutronix.de> 10730 + R: John Stultz <jstultz@google.com> 10731 + R: Stephen Boyd <sboyd@kernel.org> 10729 10732 L: rust-for-linux@vger.kernel.org 10730 10733 S: Supported 10731 10734 W: https://rust-for-linux.com 10732 10735 B: https://github.com/Rust-for-Linux/linux/issues 10733 - T: git https://github.com/Rust-for-Linux/linux.git hrtimer-next 10734 - F: rust/kernel/time/hrtimer.rs 10735 - F: rust/kernel/time/hrtimer/ 10736 + T: git https://github.com/Rust-for-Linux/linux.git timekeeping-next 10737 + F: rust/kernel/time.rs 10738 + F: rust/kernel/time/ 10736 10739 10737 10740 HIGH-SPEED SCC DRIVER FOR AX.25 10738 10741 L: linux-hams@vger.kernel.org ··· 21591 21588 R: Boqun Feng <boqun.feng@gmail.com> 21592 21589 R: Gary Guo <gary@garyguo.net> 21593 21590 R: Björn Roy Baron <bjorn3_gh@protonmail.com> 21594 - R: Benno Lossin <benno.lossin@proton.me> 21591 + R: Benno Lossin <lossin@kernel.org> 21595 21592 R: Andreas Hindborg <a.hindborg@kernel.org> 21596 21593 R: Alice Ryhl <aliceryhl@google.com> 21597 21594 R: Trevor Gross <tmgross@umich.edu> ··· 21621 21618 F: rust/kernel/alloc/ 21622 21619 21623 21620 RUST [PIN-INIT] 21624 - M: Benno Lossin <benno.lossin@proton.me> 21621 + M: Benno Lossin <lossin@kernel.org> 21625 21622 L: rust-for-linux@vger.kernel.org 21626 21623 S: Maintained 21627 21624 W: https://rust-for-linux.com/pin-init ··· 26831 26828 F: lib/test_xarray.c 26832 26829 F: lib/xarray.c 26833 26830 F: tools/testing/radix-tree 26831 + 26832 + XARRAY API [RUST] 26833 + M: Tamir Duberstein <tamird@gmail.com> 26834 + M: Andreas Hindborg <a.hindborg@kernel.org> 26835 + L: rust-for-linux@vger.kernel.org 26836 + S: Supported 26837 + W: https://rust-for-linux.com 26838 + B: https://github.com/Rust-for-Linux/linux/issues 26839 + C: https://rust-for-linux.zulipchat.com 26840 + T: git https://github.com/Rust-for-Linux/linux.git xarray-next 26841 + F: rust/kernel/xarray.rs 26834 26842 26835 26843 XBOX DVD IR REMOTE 26836 26844 M: Benjamin Valentin <benpicco@googlemail.com>
+3
init/Kconfig
··· 136 136 config RUSTC_HAS_COERCE_POINTEE 137 137 def_bool RUSTC_VERSION >= 108400 138 138 139 + config RUSTC_HAS_SPAN_FILE 140 + def_bool RUSTC_VERSION >= 108800 141 + 139 142 config RUSTC_HAS_UNNECESSARY_TRANSMUTES 140 143 def_bool RUSTC_VERSION >= 108800 141 144
+11 -8
rust/Makefile
··· 60 60 core-cfgs = \ 61 61 --cfg no_fp_fmt_parse 62 62 63 + core-edition := $(if $(call rustc-min-version,108700),2024,2021) 64 + 63 65 # `rustc` recognizes `--remap-path-prefix` since 1.26.0, but `rustdoc` only 64 66 # since Rust 1.81.0. Moreover, `rustdoc` ICEs on out-of-tree builds since Rust 65 67 # 1.82.0 (https://github.com/rust-lang/rust/issues/138520). Thus workaround both ··· 108 106 109 107 # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should 110 108 # not be needed -- see https://github.com/rust-lang/rust/pull/128307. 111 - rustdoc-core: private skip_flags = -Wrustdoc::unescaped_backticks 112 - rustdoc-core: private rustc_target_flags = $(core-cfgs) 109 + rustdoc-core: private skip_flags = --edition=2021 -Wrustdoc::unescaped_backticks 110 + rustdoc-core: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) 113 111 rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE 114 112 +$(call if_changed,rustdoc) 115 113 ··· 275 273 -fzero-call-used-regs=% -fno-stack-clash-protection \ 276 274 -fno-inline-functions-called-once -fsanitize=bounds-strict \ 277 275 -fstrict-flex-arrays=% -fmin-function-alignment=% \ 278 - -fzero-init-padding-bits=% \ 276 + -fzero-init-padding-bits=% -mno-fdpic \ 279 277 --param=% --param asan-% 280 278 281 279 # Derived from `scripts/Makefile.clang`. ··· 404 402 -Clink-args='$(call escsq,$(KBUILD_PROCMACROLDFLAGS))' \ 405 403 --emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \ 406 404 --crate-type proc-macro \ 407 - --crate-name $(patsubst lib%.$(libmacros_extension),%,$(notdir $@)) $< 405 + --crate-name $(patsubst lib%.$(libmacros_extension),%,$(notdir $@)) \ 406 + @$(objtree)/include/generated/rustc_cfg $< 408 407 409 408 # Procedural macros can only be used with the `rustc` that compiled it. 410 409 $(obj)/$(libmacros_name): $(src)/macros/lib.rs FORCE ··· 419 416 cmd_rustc_library = \ 420 417 OBJTREE=$(abspath $(objtree)) \ 421 418 $(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \ 422 - $(filter-out $(skip_flags),$(rust_flags) $(rustc_target_flags)) \ 419 + $(filter-out $(skip_flags),$(rust_flags)) $(rustc_target_flags) \ 423 420 --emit=dep-info=$(depfile) --emit=obj=$@ \ 424 421 --emit=metadata=$(dir $@)$(patsubst %.o,lib%.rmeta,$(notdir $@)) \ 425 422 --crate-type rlib -L$(objtree)/$(obj) \ ··· 430 427 431 428 rust-analyzer: 432 429 $(Q)MAKEFLAGS= $(srctree)/scripts/generate_rust_analyzer.py \ 433 - --cfgs='core=$(core-cfgs)' \ 430 + --cfgs='core=$(core-cfgs)' $(core-edition) \ 434 431 $(realpath $(srctree)) $(realpath $(objtree)) \ 435 432 $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ 436 433 > rust-project.json ··· 486 483 $(obj)/exports.o: private skip_gendwarfksyms = 1 487 484 488 485 $(obj)/core.o: private skip_clippy = 1 489 - $(obj)/core.o: private skip_flags = -Wunreachable_pub 486 + $(obj)/core.o: private skip_flags = --edition=2021 -Wunreachable_pub 490 487 $(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym)) 491 - $(obj)/core.o: private rustc_target_flags = $(core-cfgs) 488 + $(obj)/core.o: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) 492 489 $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs \ 493 490 $(wildcard $(objtree)/include/config/RUSTC_VERSION_TEXT) FORCE 494 491 +$(call if_changed_rule,rustc_library)
+28
rust/bindings/bindings_helper.h
··· 6 6 * Sorted alphabetically. 7 7 */ 8 8 9 + /* 10 + * First, avoid forward references to `enum` types. 11 + * 12 + * This workarounds a `bindgen` issue with them: 13 + * <https://github.com/rust-lang/rust-bindgen/issues/3179>. 14 + * 15 + * Without this, the generated Rust type may be the wrong one (`i32`) or 16 + * the proper one (typically `c_uint`) depending on how the headers are 17 + * included, which in turn may depend on the particular kernel configuration 18 + * or the architecture. 19 + * 20 + * The alternative would be to use casts and likely an 21 + * `#[allow(clippy::unnecessary_cast)]` in the Rust source files. Instead, 22 + * this approach allows us to keep the correct code in the source files and 23 + * simply remove this section when the issue is fixed upstream and we bump 24 + * the minimum `bindgen` version. 25 + * 26 + * This workaround may not be possible in some cases, depending on how the C 27 + * headers are set up. 28 + */ 29 + #include <linux/hrtimer_types.h> 30 + 9 31 #include <drm/drm_device.h> 10 32 #include <drm/drm_drv.h> 11 33 #include <drm/drm_file.h> ··· 70 48 #include <linux/tracepoint.h> 71 49 #include <linux/wait.h> 72 50 #include <linux/workqueue.h> 51 + #include <linux/xarray.h> 73 52 #include <trace/events/rust_sample.h> 74 53 75 54 #if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE) ··· 90 67 const gfp_t RUST_CONST_HELPER___GFP_NOWARN = ___GFP_NOWARN; 91 68 const blk_features_t RUST_CONST_HELPER_BLK_FEAT_ROTATIONAL = BLK_FEAT_ROTATIONAL; 92 69 const fop_flags_t RUST_CONST_HELPER_FOP_UNSIGNED_OFFSET = FOP_UNSIGNED_OFFSET; 70 + 71 + const xa_mark_t RUST_CONST_HELPER_XA_PRESENT = XA_PRESENT; 72 + 73 + const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC = XA_FLAGS_ALLOC; 74 + const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC1 = XA_FLAGS_ALLOC1;
+1 -1
rust/ffi.rs
··· 17 17 18 18 // Check size compatibility with `core`. 19 19 const _: () = assert!( 20 - core::mem::size_of::<$name>() == core::mem::size_of::<core::ffi::$name>() 20 + ::core::mem::size_of::<$name>() == ::core::mem::size_of::<::core::ffi::$name>() 21 21 ); 22 22 )*} 23 23 }
+1
rust/helpers/helpers.c
··· 43 43 #include "vmalloc.c" 44 44 #include "wait.c" 45 45 #include "workqueue.c" 46 + #include "xarray.c"
+28
rust/helpers/xarray.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/xarray.h> 4 + 5 + int rust_helper_xa_err(void *entry) 6 + { 7 + return xa_err(entry); 8 + } 9 + 10 + void rust_helper_xa_init_flags(struct xarray *xa, gfp_t flags) 11 + { 12 + return xa_init_flags(xa, flags); 13 + } 14 + 15 + int rust_helper_xa_trylock(struct xarray *xa) 16 + { 17 + return xa_trylock(xa); 18 + } 19 + 20 + void rust_helper_xa_lock(struct xarray *xa) 21 + { 22 + return xa_lock(xa); 23 + } 24 + 25 + void rust_helper_xa_unlock(struct xarray *xa) 26 + { 27 + return xa_unlock(xa); 28 + }
+2 -2
rust/kernel/alloc.rs
··· 94 94 /// 95 95 /// A lower watermark is applied to allow access to "atomic reserves". The current 96 96 /// implementation doesn't support NMI and few other strict non-preemptive contexts (e.g. 97 - /// raw_spin_lock). The same applies to [`GFP_NOWAIT`]. 97 + /// `raw_spin_lock`). The same applies to [`GFP_NOWAIT`]. 98 98 pub const GFP_ATOMIC: Flags = Flags(bindings::GFP_ATOMIC); 99 99 100 - /// Typical for kernel-internal allocations. The caller requires ZONE_NORMAL or a lower zone 100 + /// Typical for kernel-internal allocations. The caller requires `ZONE_NORMAL` or a lower zone 101 101 /// for direct access but can direct reclaim. 102 102 pub const GFP_KERNEL: Flags = Flags(bindings::GFP_KERNEL); 103 103
+1 -1
rust/kernel/alloc/allocator_test.rs
··· 4 4 //! of those types (e.g. `CString`) use kernel allocators for instantiation. 5 5 //! 6 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 7 + //! `Cmalloc` allocator within the `allocator_test` module and type alias all kernel allocators to 8 8 //! `Cmalloc`. The `Cmalloc` allocator uses libc's `realloc()` function as allocator backend. 9 9 10 10 #![allow(missing_docs)]
+60 -20
rust/kernel/alloc/kbox.rs
··· 57 57 /// assert!(KVBox::<Huge>::new_uninit(GFP_KERNEL).is_ok()); 58 58 /// ``` 59 59 /// 60 + /// [`Box`]es can also be used to store trait objects by coercing their type: 61 + /// 62 + /// ``` 63 + /// trait FooTrait {} 64 + /// 65 + /// struct FooStruct; 66 + /// impl FooTrait for FooStruct {} 67 + /// 68 + /// let _ = KBox::new(FooStruct, GFP_KERNEL)? as KBox<dyn FooTrait>; 69 + /// # Ok::<(), Error>(()) 70 + /// ``` 71 + /// 60 72 /// # Invariants 61 73 /// 62 74 /// `self.0` is always properly aligned and either points to memory allocated with `A` or, for 63 75 /// zero-sized types, is a dangling, well aligned pointer. 64 76 #[repr(transparent)] 65 - pub struct Box<T: ?Sized, A: Allocator>(NonNull<T>, PhantomData<A>); 77 + #[cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, derive(core::marker::CoercePointee))] 78 + pub struct Box<#[cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, pointee)] T: ?Sized, A: Allocator>( 79 + NonNull<T>, 80 + PhantomData<A>, 81 + ); 82 + 83 + // This is to allow coercion from `Box<T, A>` to `Box<U, A>` if `T` can be converted to the 84 + // dynamically-sized type (DST) `U`. 85 + #[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))] 86 + impl<T, U, A> core::ops::CoerceUnsized<Box<U, A>> for Box<T, A> 87 + where 88 + T: ?Sized + core::marker::Unsize<U>, 89 + U: ?Sized, 90 + A: Allocator, 91 + { 92 + } 93 + 94 + // This is to allow `Box<U, A>` to be dispatched on when `Box<T, A>` can be coerced into `Box<U, 95 + // A>`. 96 + #[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))] 97 + impl<T, U, A> core::ops::DispatchFromDyn<Box<U, A>> for Box<T, A> 98 + where 99 + T: ?Sized + core::marker::Unsize<U>, 100 + U: ?Sized, 101 + A: Allocator, 102 + { 103 + } 66 104 67 105 /// Type alias for [`Box`] with a [`Kmalloc`] allocator. 68 106 /// ··· 139 101 pub type KVBox<T> = Box<T, super::allocator::KVmalloc>; 140 102 141 103 // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee: 142 - // https://doc.rust-lang.org/stable/std/option/index.html#representation). 104 + // <https://doc.rust-lang.org/stable/std/option/index.html#representation>). 143 105 unsafe impl<T, A: Allocator> ZeroableOption for Box<T, A> {} 144 106 145 107 // SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`. ··· 398 360 } 399 361 } 400 362 401 - impl<T: 'static, A> ForeignOwnable for Box<T, A> 363 + // SAFETY: The `into_foreign` function returns a pointer that is well-aligned. 364 + unsafe impl<T: 'static, A> ForeignOwnable for Box<T, A> 402 365 where 403 366 A: Allocator, 404 367 { 368 + type PointedTo = T; 405 369 type Borrowed<'a> = &'a T; 406 370 type BorrowedMut<'a> = &'a mut T; 407 371 408 - fn into_foreign(self) -> *mut crate::ffi::c_void { 409 - Box::into_raw(self).cast() 372 + fn into_foreign(self) -> *mut Self::PointedTo { 373 + Box::into_raw(self) 410 374 } 411 375 412 - unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self { 376 + unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self { 413 377 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 414 378 // call to `Self::into_foreign`. 415 - unsafe { Box::from_raw(ptr.cast()) } 379 + unsafe { Box::from_raw(ptr) } 416 380 } 417 381 418 - unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> &'a T { 382 + unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> &'a T { 419 383 // SAFETY: The safety requirements of this method ensure that the object remains alive and 420 384 // immutable for the duration of 'a. 421 - unsafe { &*ptr.cast() } 385 + unsafe { &*ptr } 422 386 } 423 387 424 - unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> &'a mut T { 425 - let ptr = ptr.cast(); 388 + unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> &'a mut T { 426 389 // SAFETY: The safety requirements of this method ensure that the pointer is valid and that 427 390 // nothing else will access the value for the duration of 'a. 428 391 unsafe { &mut *ptr } 429 392 } 430 393 } 431 394 432 - impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>> 395 + // SAFETY: The `into_foreign` function returns a pointer that is well-aligned. 396 + unsafe impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>> 433 397 where 434 398 A: Allocator, 435 399 { 400 + type PointedTo = T; 436 401 type Borrowed<'a> = Pin<&'a T>; 437 402 type BorrowedMut<'a> = Pin<&'a mut T>; 438 403 439 - fn into_foreign(self) -> *mut crate::ffi::c_void { 404 + fn into_foreign(self) -> *mut Self::PointedTo { 440 405 // SAFETY: We are still treating the box as pinned. 441 - Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast() 406 + Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) 442 407 } 443 408 444 - unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self { 409 + unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self { 445 410 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 446 411 // call to `Self::into_foreign`. 447 - unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) } 412 + unsafe { Pin::new_unchecked(Box::from_raw(ptr)) } 448 413 } 449 414 450 - unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a T> { 415 + unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> Pin<&'a T> { 451 416 // SAFETY: The safety requirements for this function ensure that the object is still alive, 452 417 // so it is safe to dereference the raw pointer. 453 418 // The safety requirements of `from_foreign` also ensure that the object remains alive for 454 419 // the lifetime of the returned value. 455 - let r = unsafe { &*ptr.cast() }; 420 + let r = unsafe { &*ptr }; 456 421 457 422 // SAFETY: This pointer originates from a `Pin<Box<T>>`. 458 423 unsafe { Pin::new_unchecked(r) } 459 424 } 460 425 461 - unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a mut T> { 462 - let ptr = ptr.cast(); 426 + unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> Pin<&'a mut T> { 463 427 // SAFETY: The safety requirements for this function ensure that the object is still alive, 464 428 // so it is safe to dereference the raw pointer. 465 429 // The safety requirements of `from_foreign` also ensure that the object remains alive for
+404 -29
rust/kernel/alloc/kvec.rs
··· 2 2 3 3 //! Implementation of [`Vec`]. 4 4 5 - // May not be needed in Rust 1.87.0 (pending beta backport). 6 - #![allow(clippy::ptr_eq)] 7 - 8 5 use super::{ 9 6 allocator::{KVmalloc, Kmalloc, Vmalloc}, 10 7 layout::ArrayLayout, ··· 20 23 slice, 21 24 slice::SliceIndex, 22 25 }; 26 + 27 + mod errors; 28 + pub use self::errors::{InsertError, PushError, RemoveError}; 23 29 24 30 /// Create a [`KVec`] containing the arguments. 25 31 /// ··· 92 92 /// - `self.layout` represents the absolute number of elements that can be stored within the vector 93 93 /// without re-allocation. For ZSTs `self.layout`'s capacity is zero. However, it is legal for the 94 94 /// backing buffer to be larger than `layout`. 95 + /// 96 + /// - `self.len()` is always less than or equal to `self.capacity()`. 95 97 /// 96 98 /// - The `Allocator` type `A` of the vector is the exact same `Allocator` type the backing buffer 97 99 /// was allocated with (and must be freed with). ··· 188 186 self.len 189 187 } 190 188 191 - /// Forcefully sets `self.len` to `new_len`. 189 + /// Increments `self.len` by `additional`. 192 190 /// 193 191 /// # Safety 194 192 /// 195 - /// - `new_len` must be less than or equal to [`Self::capacity`]. 196 - /// - If `new_len` is greater than `self.len`, all elements within the interval 197 - /// [`self.len`,`new_len`) must be initialized. 193 + /// - `additional` must be less than or equal to `self.capacity - self.len`. 194 + /// - All elements within the interval [`self.len`,`self.len + additional`) must be initialized. 198 195 #[inline] 199 - pub unsafe fn set_len(&mut self, new_len: usize) { 200 - debug_assert!(new_len <= self.capacity()); 201 - self.len = new_len; 196 + pub unsafe fn inc_len(&mut self, additional: usize) { 197 + // Guaranteed by the type invariant to never underflow. 198 + debug_assert!(additional <= self.capacity() - self.len()); 199 + // INVARIANT: By the safety requirements of this method this represents the exact number of 200 + // elements stored within `self`. 201 + self.len += additional; 202 + } 203 + 204 + /// Decreases `self.len` by `count`. 205 + /// 206 + /// Returns a mutable slice to the elements forgotten by the vector. It is the caller's 207 + /// responsibility to drop these elements if necessary. 208 + /// 209 + /// # Safety 210 + /// 211 + /// - `count` must be less than or equal to `self.len`. 212 + unsafe fn dec_len(&mut self, count: usize) -> &mut [T] { 213 + debug_assert!(count <= self.len()); 214 + // INVARIANT: We relinquish ownership of the elements within the range `[self.len - count, 215 + // self.len)`, hence the updated value of `set.len` represents the exact number of elements 216 + // stored within `self`. 217 + self.len -= count; 218 + // SAFETY: The memory after `self.len()` is guaranteed to contain `count` initialized 219 + // elements of type `T`. 220 + unsafe { slice::from_raw_parts_mut(self.as_mut_ptr().add(self.len), count) } 202 221 } 203 222 204 223 /// Returns a slice of the entire vector. ··· 285 262 /// Returns a slice of `MaybeUninit<T>` for the remaining spare capacity of the vector. 286 263 pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] { 287 264 // SAFETY: 288 - // - `self.len` is smaller than `self.capacity` and hence, the resulting pointer is 289 - // guaranteed to be part of the same allocated object. 265 + // - `self.len` is smaller than `self.capacity` by the type invariant and hence, the 266 + // resulting pointer is guaranteed to be part of the same allocated object. 290 267 // - `self.len` can not overflow `isize`. 291 268 let ptr = unsafe { self.as_mut_ptr().add(self.len) } as *mut MaybeUninit<T>; 292 269 ··· 310 287 /// ``` 311 288 pub fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> { 312 289 self.reserve(1, flags)?; 290 + // SAFETY: The call to `reserve` was successful, so the capacity is at least one greater 291 + // than the length. 292 + unsafe { self.push_within_capacity_unchecked(v) }; 293 + Ok(()) 294 + } 313 295 314 - // SAFETY: 315 - // - `self.len` is smaller than `self.capacity` and hence, the resulting pointer is 316 - // guaranteed to be part of the same allocated object. 317 - // - `self.len` can not overflow `isize`. 318 - let ptr = unsafe { self.as_mut_ptr().add(self.len) }; 296 + /// Appends an element to the back of the [`Vec`] instance without reallocating. 297 + /// 298 + /// Fails if the vector does not have capacity for the new element. 299 + /// 300 + /// # Examples 301 + /// 302 + /// ``` 303 + /// let mut v = KVec::with_capacity(10, GFP_KERNEL)?; 304 + /// for i in 0..10 { 305 + /// v.push_within_capacity(i)?; 306 + /// } 307 + /// 308 + /// assert!(v.push_within_capacity(10).is_err()); 309 + /// # Ok::<(), Error>(()) 310 + /// ``` 311 + pub fn push_within_capacity(&mut self, v: T) -> Result<(), PushError<T>> { 312 + if self.len() < self.capacity() { 313 + // SAFETY: The length is less than the capacity. 314 + unsafe { self.push_within_capacity_unchecked(v) }; 315 + Ok(()) 316 + } else { 317 + Err(PushError(v)) 318 + } 319 + } 319 320 320 - // SAFETY: 321 - // - `ptr` is properly aligned and valid for writes. 322 - unsafe { core::ptr::write(ptr, v) }; 321 + /// Appends an element to the back of the [`Vec`] instance without reallocating. 322 + /// 323 + /// # Safety 324 + /// 325 + /// The length must be less than the capacity. 326 + unsafe fn push_within_capacity_unchecked(&mut self, v: T) { 327 + let spare = self.spare_capacity_mut(); 328 + 329 + // SAFETY: By the safety requirements, `spare` is non-empty. 330 + unsafe { spare.get_unchecked_mut(0) }.write(v); 323 331 324 332 // SAFETY: We just initialised the first spare entry, so it is safe to increase the length 325 - // by 1. We also know that the new length is <= capacity because of the previous call to 326 - // `reserve` above. 327 - unsafe { self.set_len(self.len() + 1) }; 333 + // by 1. We also know that the new length is <= capacity because the caller guarantees that 334 + // the length is less than the capacity at the beginning of this function. 335 + unsafe { self.inc_len(1) }; 336 + } 337 + 338 + /// Inserts an element at the given index in the [`Vec`] instance. 339 + /// 340 + /// Fails if the vector does not have capacity for the new element. Panics if the index is out 341 + /// of bounds. 342 + /// 343 + /// # Examples 344 + /// 345 + /// ``` 346 + /// use kernel::alloc::kvec::InsertError; 347 + /// 348 + /// let mut v = KVec::with_capacity(5, GFP_KERNEL)?; 349 + /// for i in 0..5 { 350 + /// v.insert_within_capacity(0, i)?; 351 + /// } 352 + /// 353 + /// assert!(matches!(v.insert_within_capacity(0, 5), Err(InsertError::OutOfCapacity(_)))); 354 + /// assert!(matches!(v.insert_within_capacity(1000, 5), Err(InsertError::IndexOutOfBounds(_)))); 355 + /// assert_eq!(v, [4, 3, 2, 1, 0]); 356 + /// # Ok::<(), Error>(()) 357 + /// ``` 358 + pub fn insert_within_capacity( 359 + &mut self, 360 + index: usize, 361 + element: T, 362 + ) -> Result<(), InsertError<T>> { 363 + let len = self.len(); 364 + if index > len { 365 + return Err(InsertError::IndexOutOfBounds(element)); 366 + } 367 + 368 + if len >= self.capacity() { 369 + return Err(InsertError::OutOfCapacity(element)); 370 + } 371 + 372 + // SAFETY: This is in bounds since `index <= len < capacity`. 373 + let p = unsafe { self.as_mut_ptr().add(index) }; 374 + // INVARIANT: This breaks the Vec invariants by making `index` contain an invalid element, 375 + // but we restore the invariants below. 376 + // SAFETY: Both the src and dst ranges end no later than one element after the length. 377 + // Since the length is less than the capacity, both ranges are in bounds of the allocation. 378 + unsafe { ptr::copy(p, p.add(1), len - index) }; 379 + // INVARIANT: This restores the Vec invariants. 380 + // SAFETY: The pointer is in-bounds of the allocation. 381 + unsafe { ptr::write(p, element) }; 382 + // SAFETY: Index `len` contains a valid element due to the above copy and write. 383 + unsafe { self.inc_len(1) }; 328 384 Ok(()) 385 + } 386 + 387 + /// Removes the last element from a vector and returns it, or `None` if it is empty. 388 + /// 389 + /// # Examples 390 + /// 391 + /// ``` 392 + /// let mut v = KVec::new(); 393 + /// v.push(1, GFP_KERNEL)?; 394 + /// v.push(2, GFP_KERNEL)?; 395 + /// assert_eq!(&v, &[1, 2]); 396 + /// 397 + /// assert_eq!(v.pop(), Some(2)); 398 + /// assert_eq!(v.pop(), Some(1)); 399 + /// assert_eq!(v.pop(), None); 400 + /// # Ok::<(), Error>(()) 401 + /// ``` 402 + pub fn pop(&mut self) -> Option<T> { 403 + if self.is_empty() { 404 + return None; 405 + } 406 + 407 + let removed: *mut T = { 408 + // SAFETY: We just checked that the length is at least one. 409 + let slice = unsafe { self.dec_len(1) }; 410 + // SAFETY: The argument to `dec_len` was 1 so this returns a slice of length 1. 411 + unsafe { slice.get_unchecked_mut(0) } 412 + }; 413 + 414 + // SAFETY: The guarantees of `dec_len` allow us to take ownership of this value. 415 + Some(unsafe { removed.read() }) 416 + } 417 + 418 + /// Removes the element at the given index. 419 + /// 420 + /// # Examples 421 + /// 422 + /// ``` 423 + /// let mut v = kernel::kvec![1, 2, 3]?; 424 + /// assert_eq!(v.remove(1)?, 2); 425 + /// assert_eq!(v, [1, 3]); 426 + /// # Ok::<(), Error>(()) 427 + /// ``` 428 + pub fn remove(&mut self, i: usize) -> Result<T, RemoveError> { 429 + let value = { 430 + let value_ref = self.get(i).ok_or(RemoveError)?; 431 + // INVARIANT: This breaks the invariants by invalidating the value at index `i`, but we 432 + // restore the invariants below. 433 + // SAFETY: The value at index `i` is valid, because otherwise we would have already 434 + // failed with `RemoveError`. 435 + unsafe { ptr::read(value_ref) } 436 + }; 437 + 438 + // SAFETY: We checked that `i` is in-bounds. 439 + let p = unsafe { self.as_mut_ptr().add(i) }; 440 + 441 + // INVARIANT: After this call, the invalid value is at the last slot, so the Vec invariants 442 + // are restored after the below call to `dec_len(1)`. 443 + // SAFETY: `p.add(1).add(self.len - i - 1)` is `i+1+len-i-1 == len` elements after the 444 + // beginning of the vector, so this is in-bounds of the vector's allocation. 445 + unsafe { ptr::copy(p.add(1), p, self.len - i - 1) }; 446 + 447 + // SAFETY: Since the check at the beginning of this call did not fail with `RemoveError`, 448 + // the length is at least one. 449 + unsafe { self.dec_len(1) }; 450 + 451 + Ok(value) 329 452 } 330 453 331 454 /// Creates a new [`Vec`] instance with at least the given capacity. ··· 567 398 (ptr, len, capacity) 568 399 } 569 400 401 + /// Clears the vector, removing all values. 402 + /// 403 + /// Note that this method has no effect on the allocated capacity 404 + /// of the vector. 405 + /// 406 + /// # Examples 407 + /// 408 + /// ``` 409 + /// let mut v = kernel::kvec![1, 2, 3]?; 410 + /// 411 + /// v.clear(); 412 + /// 413 + /// assert!(v.is_empty()); 414 + /// # Ok::<(), Error>(()) 415 + /// ``` 416 + #[inline] 417 + pub fn clear(&mut self) { 418 + self.truncate(0); 419 + } 420 + 570 421 /// Ensures that the capacity exceeds the length by at least `additional` elements. 571 422 /// 572 423 /// # Examples ··· 644 455 645 456 Ok(()) 646 457 } 458 + 459 + /// Shortens the vector, setting the length to `len` and drops the removed values. 460 + /// If `len` is greater than or equal to the current length, this does nothing. 461 + /// 462 + /// This has no effect on the capacity and will not allocate. 463 + /// 464 + /// # Examples 465 + /// 466 + /// ``` 467 + /// let mut v = kernel::kvec![1, 2, 3]?; 468 + /// v.truncate(1); 469 + /// assert_eq!(v.len(), 1); 470 + /// assert_eq!(&v, &[1]); 471 + /// 472 + /// # Ok::<(), Error>(()) 473 + /// ``` 474 + pub fn truncate(&mut self, len: usize) { 475 + if let Some(count) = self.len().checked_sub(len) { 476 + // SAFETY: `count` is `self.len() - len` so it is guaranteed to be less than or 477 + // equal to `self.len()`. 478 + let ptr: *mut [T] = unsafe { self.dec_len(count) }; 479 + 480 + // SAFETY: the contract of `dec_len` guarantees that the elements in `ptr` are 481 + // valid elements whose ownership has been transferred to the caller. 482 + unsafe { ptr::drop_in_place(ptr) }; 483 + } 484 + } 485 + 486 + /// Takes ownership of all items in this vector without consuming the allocation. 487 + /// 488 + /// # Examples 489 + /// 490 + /// ``` 491 + /// let mut v = kernel::kvec![0, 1, 2, 3]?; 492 + /// 493 + /// for (i, j) in v.drain_all().enumerate() { 494 + /// assert_eq!(i, j); 495 + /// } 496 + /// 497 + /// assert!(v.capacity() >= 4); 498 + /// # Ok::<(), Error>(()) 499 + /// ``` 500 + pub fn drain_all(&mut self) -> DrainAll<'_, T> { 501 + // SAFETY: This does not underflow the length. 502 + let elems = unsafe { self.dec_len(self.len()) }; 503 + // INVARIANT: The first `len` elements of the spare capacity are valid values, and as we 504 + // just set the length to zero, we may transfer ownership to the `DrainAll` object. 505 + DrainAll { 506 + elements: elems.iter_mut(), 507 + } 508 + } 509 + 510 + /// Removes all elements that don't match the provided closure. 511 + /// 512 + /// # Examples 513 + /// 514 + /// ``` 515 + /// let mut v = kernel::kvec![1, 2, 3, 4]?; 516 + /// v.retain(|i| *i % 2 == 0); 517 + /// assert_eq!(v, [2, 4]); 518 + /// # Ok::<(), Error>(()) 519 + /// ``` 520 + pub fn retain(&mut self, mut f: impl FnMut(&mut T) -> bool) { 521 + let mut num_kept = 0; 522 + let mut next_to_check = 0; 523 + while let Some(to_check) = self.get_mut(next_to_check) { 524 + if f(to_check) { 525 + self.swap(num_kept, next_to_check); 526 + num_kept += 1; 527 + } 528 + next_to_check += 1; 529 + } 530 + self.truncate(num_kept); 531 + } 647 532 } 648 533 649 534 impl<T: Clone, A: Allocator> Vec<T, A> { ··· 741 478 // SAFETY: 742 479 // - `self.len() + n < self.capacity()` due to the call to reserve above, 743 480 // - the loop and the line above initialized the next `n` elements. 744 - unsafe { self.set_len(self.len() + n) }; 481 + unsafe { self.inc_len(n) }; 745 482 746 483 Ok(()) 747 484 } ··· 772 509 // the length by the same number. 773 510 // - `self.len() + other.len() <= self.capacity()` is guaranteed by the preceding `reserve` 774 511 // call. 775 - unsafe { self.set_len(self.len() + other.len()) }; 512 + unsafe { self.inc_len(other.len()) }; 776 513 Ok(()) 777 514 } 778 515 ··· 783 520 v.extend_with(n, value, flags)?; 784 521 785 522 Ok(v) 523 + } 524 + 525 + /// Resizes the [`Vec`] so that `len` is equal to `new_len`. 526 + /// 527 + /// If `new_len` is smaller than `len`, the `Vec` is [`Vec::truncate`]d. 528 + /// If `new_len` is larger, each new slot is filled with clones of `value`. 529 + /// 530 + /// # Examples 531 + /// 532 + /// ``` 533 + /// let mut v = kernel::kvec![1, 2, 3]?; 534 + /// v.resize(1, 42, GFP_KERNEL)?; 535 + /// assert_eq!(&v, &[1]); 536 + /// 537 + /// v.resize(3, 42, GFP_KERNEL)?; 538 + /// assert_eq!(&v, &[1, 42, 42]); 539 + /// 540 + /// # Ok::<(), Error>(()) 541 + /// ``` 542 + pub fn resize(&mut self, new_len: usize, value: T, flags: Flags) -> Result<(), AllocError> { 543 + match new_len.checked_sub(self.len()) { 544 + Some(n) => self.extend_with(n, value, flags), 545 + None => { 546 + self.truncate(new_len); 547 + Ok(()) 548 + } 549 + } 786 550 } 787 551 } 788 552 ··· 1050 760 unsafe { ptr::copy(ptr, buf.as_ptr(), len) }; 1051 761 ptr = buf.as_ptr(); 1052 762 1053 - // SAFETY: `len` is guaranteed to be smaller than `self.layout.len()`. 763 + // SAFETY: `len` is guaranteed to be smaller than `self.layout.len()` by the type 764 + // invariant. 1054 765 let layout = unsafe { ArrayLayout::<T>::new_unchecked(len) }; 1055 766 1056 - // SAFETY: `buf` points to the start of the backing buffer and `len` is guaranteed to be 1057 - // smaller than `cap`. Depending on `alloc` this operation may shrink the buffer or leaves 1058 - // it as it is. 767 + // SAFETY: `buf` points to the start of the backing buffer and `len` is guaranteed by 768 + // the type invariant to be smaller than `cap`. Depending on `realloc` this operation 769 + // may shrink the buffer or leave it as it is. 1059 770 ptr = match unsafe { 1060 771 A::realloc(Some(buf.cast()), layout.into(), old_layout.into(), flags) 1061 772 } { ··· 1202 911 len, 1203 912 layout, 1204 913 _p: PhantomData::<A>, 914 + } 915 + } 916 + } 917 + 918 + /// An iterator that owns all items in a vector, but does not own its allocation. 919 + /// 920 + /// # Invariants 921 + /// 922 + /// Every `&mut T` returned by the iterator references a `T` that the iterator may take ownership 923 + /// of. 924 + pub struct DrainAll<'vec, T> { 925 + elements: slice::IterMut<'vec, T>, 926 + } 927 + 928 + impl<'vec, T> Iterator for DrainAll<'vec, T> { 929 + type Item = T; 930 + 931 + fn next(&mut self) -> Option<T> { 932 + let elem: *mut T = self.elements.next()?; 933 + // SAFETY: By the type invariants, we may take ownership of this value. 934 + Some(unsafe { elem.read() }) 935 + } 936 + 937 + fn size_hint(&self) -> (usize, Option<usize>) { 938 + self.elements.size_hint() 939 + } 940 + } 941 + 942 + impl<'vec, T> Drop for DrainAll<'vec, T> { 943 + fn drop(&mut self) { 944 + if core::mem::needs_drop::<T>() { 945 + let iter = core::mem::take(&mut self.elements); 946 + let ptr: *mut [T] = iter.into_slice(); 947 + // SAFETY: By the type invariants, we own these values so we may destroy them. 948 + unsafe { ptr::drop_in_place(ptr) }; 949 + } 950 + } 951 + } 952 + 953 + #[macros::kunit_tests(rust_kvec_kunit)] 954 + mod tests { 955 + use super::*; 956 + use crate::prelude::*; 957 + 958 + #[test] 959 + fn test_kvec_retain() { 960 + /// Verify correctness for one specific function. 961 + #[expect(clippy::needless_range_loop)] 962 + fn verify(c: &[bool]) { 963 + let mut vec1: KVec<usize> = KVec::with_capacity(c.len(), GFP_KERNEL).unwrap(); 964 + let mut vec2: KVec<usize> = KVec::with_capacity(c.len(), GFP_KERNEL).unwrap(); 965 + 966 + for i in 0..c.len() { 967 + vec1.push_within_capacity(i).unwrap(); 968 + if c[i] { 969 + vec2.push_within_capacity(i).unwrap(); 970 + } 971 + } 972 + 973 + vec1.retain(|i| c[*i]); 974 + 975 + assert_eq!(vec1, vec2); 976 + } 977 + 978 + /// Add one to a binary integer represented as a boolean array. 979 + fn add(value: &mut [bool]) { 980 + let mut carry = true; 981 + for v in value { 982 + let new_v = carry != *v; 983 + carry = carry && *v; 984 + *v = new_v; 985 + } 986 + } 987 + 988 + // This boolean array represents a function from index to boolean. We check that `retain` 989 + // behaves correctly for all possible boolean arrays of every possible length less than 990 + // ten. 991 + let mut func = KVec::with_capacity(10, GFP_KERNEL).unwrap(); 992 + for len in 0..10 { 993 + for _ in 0u32..1u32 << len { 994 + verify(&func); 995 + add(&mut func); 996 + } 997 + func.push_within_capacity(false).unwrap(); 1205 998 } 1206 999 } 1207 1000 }
+61
rust/kernel/alloc/kvec/errors.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! Errors for the [`Vec`] type. 4 + 5 + use core::fmt::{self, Debug, Formatter}; 6 + use kernel::prelude::*; 7 + 8 + /// Error type for [`Vec::push_within_capacity`]. 9 + pub struct PushError<T>(pub T); 10 + 11 + impl<T> Debug for PushError<T> { 12 + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 13 + write!(f, "Not enough capacity") 14 + } 15 + } 16 + 17 + impl<T> From<PushError<T>> for Error { 18 + fn from(_: PushError<T>) -> Error { 19 + // Returning ENOMEM isn't appropriate because the system is not out of memory. The vector 20 + // is just full and we are refusing to resize it. 21 + EINVAL 22 + } 23 + } 24 + 25 + /// Error type for [`Vec::remove`]. 26 + pub struct RemoveError; 27 + 28 + impl Debug for RemoveError { 29 + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 30 + write!(f, "Index out of bounds") 31 + } 32 + } 33 + 34 + impl From<RemoveError> for Error { 35 + fn from(_: RemoveError) -> Error { 36 + EINVAL 37 + } 38 + } 39 + 40 + /// Error type for [`Vec::insert_within_capacity`]. 41 + pub enum InsertError<T> { 42 + /// The value could not be inserted because the index is out of bounds. 43 + IndexOutOfBounds(T), 44 + /// The value could not be inserted because the vector is out of capacity. 45 + OutOfCapacity(T), 46 + } 47 + 48 + impl<T> Debug for InsertError<T> { 49 + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 50 + match self { 51 + InsertError::IndexOutOfBounds(_) => write!(f, "Index out of bounds"), 52 + InsertError::OutOfCapacity(_) => write!(f, "Not enough capacity"), 53 + } 54 + } 55 + } 56 + 57 + impl<T> From<InsertError<T>> for Error { 58 + fn from(_: InsertError<T>) -> Error { 59 + EINVAL 60 + } 61 + }
+5 -3
rust/kernel/auxiliary.rs
··· 73 73 // Let the `struct auxiliary_device` own a reference of the driver's private data. 74 74 // SAFETY: By the type invariant `adev.as_raw` returns a valid pointer to a 75 75 // `struct auxiliary_device`. 76 - unsafe { bindings::auxiliary_set_drvdata(adev.as_raw(), data.into_foreign()) }; 76 + unsafe { 77 + bindings::auxiliary_set_drvdata(adev.as_raw(), data.into_foreign().cast()) 78 + }; 77 79 } 78 80 Err(err) => return Error::to_errno(err), 79 81 } ··· 91 89 // SAFETY: `remove_callback` is only ever called after a successful call to 92 90 // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized 93 91 // `KBox<T>` pointer created through `KBox::into_foreign`. 94 - drop(unsafe { KBox::<T>::from_foreign(ptr) }); 92 + drop(unsafe { KBox::<T>::from_foreign(ptr.cast()) }); 95 93 } 96 94 } 97 95 ··· 236 234 extern "C" fn release(dev: *mut bindings::device) { 237 235 // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device` 238 236 // embedded in `struct auxiliary_device`. 239 - let adev = unsafe { container_of!(dev, bindings::auxiliary_device, dev) }.cast_mut(); 237 + let adev = unsafe { container_of!(dev, bindings::auxiliary_device, dev) }; 240 238 241 239 // SAFETY: `adev` points to the memory that has been allocated in `Registration::new`, via 242 240 // `KBox::new(Opaque::<bindings::auxiliary_device>::zeroed(), GFP_KERNEL)`.
+1 -1
rust/kernel/block/mq/gen_disk.rs
··· 129 129 get_unique_id: None, 130 130 // TODO: Set to THIS_MODULE. Waiting for const_refs_to_static feature to 131 131 // be merged (unstable in rustc 1.78 which is staged for linux 6.10) 132 - // https://github.com/rust-lang/rust/issues/119618 132 + // <https://github.com/rust-lang/rust/issues/119618> 133 133 owner: core::ptr::null_mut(), 134 134 pr_ops: core::ptr::null_mut(), 135 135 free_disk: None,
+2 -2
rust/kernel/configfs.rs
··· 554 554 let c_group: *mut bindings::config_group = 555 555 // SAFETY: By function safety requirements, `item` is embedded in a 556 556 // `config_group`. 557 - unsafe { container_of!(item, bindings::config_group, cg_item) }.cast_mut(); 557 + unsafe { container_of!(item, bindings::config_group, cg_item) }; 558 558 559 559 // SAFETY: The function safety requirements for this function satisfy 560 560 // the conditions for this call. ··· 588 588 let c_group: *mut bindings::config_group = 589 589 // SAFETY: By function safety requirements, `item` is embedded in a 590 590 // `config_group`. 591 - unsafe { container_of!(item, bindings::config_group, cg_item) }.cast_mut(); 591 + unsafe { container_of!(item, bindings::config_group, cg_item) }; 592 592 593 593 // SAFETY: The function safety requirements for this function satisfy 594 594 // the conditions for this call.
+2 -2
rust/kernel/cpufreq.rs
··· 635 635 None 636 636 } else { 637 637 // SAFETY: The data is earlier set from [`set_data`]. 638 - Some(unsafe { T::borrow(self.as_ref().driver_data) }) 638 + Some(unsafe { T::borrow(self.as_ref().driver_data.cast()) }) 639 639 } 640 640 } 641 641 ··· 662 662 let data = Some( 663 663 // SAFETY: The data is earlier set by us from [`set_data`]. It is safe to take 664 664 // back the ownership of the data from the foreign interface. 665 - unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data) }, 665 + unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data.cast()) }, 666 666 ); 667 667 self.as_mut_ref().driver_data = ptr::null_mut(); 668 668 data
+17 -9
rust/kernel/device.rs
··· 345 345 macro_rules! dev_printk { 346 346 ($method:ident, $dev:expr, $($f:tt)*) => { 347 347 { 348 - ($dev).$method(core::format_args!($($f)*)); 348 + ($dev).$method(::core::format_args!($($f)*)); 349 349 } 350 350 } 351 351 } ··· 357 357 /// Equivalent to the kernel's `dev_emerg` macro. 358 358 /// 359 359 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 360 - /// [`core::fmt`] and `alloc::format!`. 360 + /// [`core::fmt`] and [`std::format!`]. 361 361 /// 362 362 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 363 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 363 364 /// 364 365 /// # Examples 365 366 /// ··· 383 382 /// Equivalent to the kernel's `dev_alert` macro. 384 383 /// 385 384 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 386 - /// [`core::fmt`] and `alloc::format!`. 385 + /// [`core::fmt`] and [`std::format!`]. 387 386 /// 388 387 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 388 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 389 389 /// 390 390 /// # Examples 391 391 /// ··· 409 407 /// Equivalent to the kernel's `dev_crit` macro. 410 408 /// 411 409 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 412 - /// [`core::fmt`] and `alloc::format!`. 410 + /// [`core::fmt`] and [`std::format!`]. 413 411 /// 414 412 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 413 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 415 414 /// 416 415 /// # Examples 417 416 /// ··· 435 432 /// Equivalent to the kernel's `dev_err` macro. 436 433 /// 437 434 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 438 - /// [`core::fmt`] and `alloc::format!`. 435 + /// [`core::fmt`] and [`std::format!`]. 439 436 /// 440 437 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 438 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 441 439 /// 442 440 /// # Examples 443 441 /// ··· 461 457 /// Equivalent to the kernel's `dev_warn` macro. 462 458 /// 463 459 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 464 - /// [`core::fmt`] and `alloc::format!`. 460 + /// [`core::fmt`] and [`std::format!`]. 465 461 /// 466 462 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 463 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 467 464 /// 468 465 /// # Examples 469 466 /// ··· 487 482 /// Equivalent to the kernel's `dev_notice` macro. 488 483 /// 489 484 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 490 - /// [`core::fmt`] and `alloc::format!`. 485 + /// [`core::fmt`] and [`std::format!`]. 491 486 /// 492 487 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 488 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 493 489 /// 494 490 /// # Examples 495 491 /// ··· 513 507 /// Equivalent to the kernel's `dev_info` macro. 514 508 /// 515 509 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 516 - /// [`core::fmt`] and `alloc::format!`. 510 + /// [`core::fmt`] and [`std::format!`]. 517 511 /// 518 512 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 513 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 519 514 /// 520 515 /// # Examples 521 516 /// ··· 539 532 /// Equivalent to the kernel's `dev_dbg` macro, except that it doesn't support dynamic debug yet. 540 533 /// 541 534 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 542 - /// [`core::fmt`] and `alloc::format!`. 535 + /// [`core::fmt`] and [`std::format!`]. 543 536 /// 544 537 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 538 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 545 539 /// 546 540 /// # Examples 547 541 ///
+2 -2
rust/kernel/device_id.rs
··· 159 159 "_", line!(), 160 160 "_", stringify!($table_name)) 161 161 ] 162 - static $module_table_name: [core::mem::MaybeUninit<u8>; $table_name.raw_ids().size()] = 163 - unsafe { core::mem::transmute_copy($table_name.raw_ids()) }; 162 + static $module_table_name: [::core::mem::MaybeUninit<u8>; $table_name.raw_ids().size()] = 163 + unsafe { ::core::mem::transmute_copy($table_name.raw_ids()) }; 164 164 }; 165 165 }
+1 -1
rust/kernel/dma.rs
··· 94 94 pub const DMA_ATTR_ALLOC_SINGLE_PAGES: Attrs = Attrs(bindings::DMA_ATTR_ALLOC_SINGLE_PAGES); 95 95 96 96 /// This tells the DMA-mapping subsystem to suppress allocation failure reports (similarly to 97 - /// __GFP_NOWARN). 97 + /// `__GFP_NOWARN`). 98 98 pub const DMA_ATTR_NO_WARN: Attrs = Attrs(bindings::DMA_ATTR_NO_WARN); 99 99 100 100 /// Used to indicate that the buffer is fully accessible at an elevated privilege level (and
+2
rust/kernel/drm/device.rs
··· 135 135 /// 136 136 /// `ptr` must be a valid pointer to a `struct device` embedded in `Self`. 137 137 unsafe fn from_drm_device(ptr: *const bindings::drm_device) -> *mut Self { 138 + let ptr: *const Opaque<bindings::drm_device> = ptr.cast(); 139 + 138 140 // SAFETY: By the safety requirements of this function `ptr` is a valid pointer to a 139 141 // `struct drm_device` embedded in `Self`. 140 142 unsafe { crate::container_of!(ptr, Self, dev) }.cast_mut()
+5 -1
rust/kernel/drm/gem/mod.rs
··· 125 125 } 126 126 127 127 unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a Self { 128 + let self_ptr: *mut Opaque<bindings::drm_gem_object> = self_ptr.cast(); 129 + 128 130 // SAFETY: `obj` is guaranteed to be in an `Object<T>` via the safety contract of this 129 131 // function 130 132 unsafe { &*crate::container_of!(self_ptr, Object<T>, obj) } ··· 271 269 } 272 270 273 271 extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) { 272 + let ptr: *mut Opaque<bindings::drm_gem_object> = obj.cast(); 273 + 274 274 // SAFETY: All of our objects are of type `Object<T>`. 275 - let this = unsafe { crate::container_of!(obj, Self, obj) }.cast_mut(); 275 + let this = unsafe { crate::container_of!(ptr, Self, obj) }; 276 276 277 277 // SAFETY: The C code only ever calls this callback with a valid pointer to a `struct 278 278 // drm_gem_object`.
+30 -7
rust/kernel/kunit.rs
··· 6 6 //! 7 7 //! Reference: <https://docs.kernel.org/dev-tools/kunit/index.html> 8 8 9 + use crate::prelude::*; 9 10 use core::{ffi::c_void, fmt}; 10 11 11 12 /// Prints a KUnit error-level message. ··· 41 40 } 42 41 } 43 42 44 - use macros::kunit_tests; 45 - 46 43 /// Asserts that a boolean expression is `true` at runtime. 47 44 /// 48 45 /// Public but hidden since it should only be used from generated tests. ··· 58 59 } 59 60 60 61 static FILE: &'static $crate::str::CStr = $crate::c_str!($file); 61 - static LINE: i32 = core::line!() as i32 - $diff; 62 + static LINE: i32 = ::core::line!() as i32 - $diff; 62 63 static CONDITION: &'static $crate::str::CStr = $crate::c_str!(stringify!($condition)); 63 64 64 65 // SAFETY: FFI call without safety requirements. ··· 129 130 unsafe { 130 131 $crate::bindings::__kunit_do_failed_assertion( 131 132 kunit_test, 132 - core::ptr::addr_of!(LOCATION.0), 133 + ::core::ptr::addr_of!(LOCATION.0), 133 134 $crate::bindings::kunit_assert_type_KUNIT_ASSERTION, 134 - core::ptr::addr_of!(ASSERTION.0.assert), 135 + ::core::ptr::addr_of!(ASSERTION.0.assert), 135 136 Some($crate::bindings::kunit_unary_assert_format), 136 - core::ptr::null(), 137 + ::core::ptr::null(), 137 138 ); 138 139 } 139 140 ··· 161 162 // KUnit supports only a few types (e.g. integers). 162 163 $crate::kunit_assert!($name, $file, $diff, $left == $right); 163 164 }}; 165 + } 166 + 167 + trait TestResult { 168 + fn is_test_result_ok(&self) -> bool; 169 + } 170 + 171 + impl TestResult for () { 172 + fn is_test_result_ok(&self) -> bool { 173 + true 174 + } 175 + } 176 + 177 + impl<T, E> TestResult for Result<T, E> { 178 + fn is_test_result_ok(&self) -> bool { 179 + self.is_ok() 180 + } 181 + } 182 + 183 + /// Returns whether a test result is to be considered OK. 184 + /// 185 + /// This will be `assert!`ed from the generated tests. 186 + #[doc(hidden)] 187 + #[expect(private_bounds)] 188 + pub fn is_test_result_ok(t: impl TestResult) -> bool { 189 + t.is_test_result_ok() 164 190 } 165 191 166 192 /// Represents an individual test case. ··· 347 323 348 324 #[test] 349 325 fn rust_test_kunit_example_test() { 350 - #![expect(clippy::eq_op)] 351 326 assert_eq!(1 + 1, 2); 352 327 } 353 328
+33 -12
rust/kernel/lib.rs
··· 12 12 //! do so first instead of bypassing this crate. 13 13 14 14 #![no_std] 15 - #![feature(arbitrary_self_types)] 16 - #![cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, feature(derive_coerce_pointee))] 17 - #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(coerce_unsized))] 18 - #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(dispatch_from_dyn))] 19 - #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(unsize))] 15 + // 16 + // Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on 17 + // the unstable features in use. 18 + // 19 + // Stable since Rust 1.79.0. 20 20 #![feature(inline_const)] 21 + // 22 + // Stable since Rust 1.81.0. 21 23 #![feature(lint_reasons)] 22 - // Stable in Rust 1.82 24 + // 25 + // Stable since Rust 1.82.0. 23 26 #![feature(raw_ref_op)] 24 - // Stable in Rust 1.83 27 + // 28 + // Stable since Rust 1.83.0. 25 29 #![feature(const_maybe_uninit_as_mut_ptr)] 26 30 #![feature(const_mut_refs)] 27 31 #![feature(const_ptr_write)] 28 32 #![feature(const_refs_to_cell)] 33 + // 34 + // Expected to become stable. 35 + #![feature(arbitrary_self_types)] 36 + // 37 + // `feature(derive_coerce_pointee)` is expected to become stable. Before Rust 38 + // 1.84.0, it did not exist, so enable the predecessor features. 39 + #![cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, feature(derive_coerce_pointee))] 40 + #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(coerce_unsized))] 41 + #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(dispatch_from_dyn))] 42 + #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(unsize))] 29 43 30 44 // Ensure conditional compilation based on the kernel configuration works; 31 45 // otherwise we may silently break things like initcall handling. ··· 116 102 pub mod types; 117 103 pub mod uaccess; 118 104 pub mod workqueue; 105 + pub mod xarray; 119 106 120 107 #[doc(hidden)] 121 108 pub use bindings; ··· 219 204 /// } 220 205 /// 221 206 /// let test = Test { a: 10, b: 20 }; 222 - /// let b_ptr = &test.b; 207 + /// let b_ptr: *const _ = &test.b; 223 208 /// // SAFETY: The pointer points at the `b` field of a `Test`, so the resulting pointer will be 224 209 /// // in-bounds of the same allocation as `b_ptr`. 225 210 /// let test_alias = unsafe { container_of!(b_ptr, Test, b) }; ··· 227 212 /// ``` 228 213 #[macro_export] 229 214 macro_rules! container_of { 230 - ($ptr:expr, $type:ty, $($f:tt)*) => {{ 231 - let ptr = $ptr as *const _ as *const u8; 232 - let offset: usize = ::core::mem::offset_of!($type, $($f)*); 233 - ptr.sub(offset) as *const $type 215 + ($field_ptr:expr, $Container:ty, $($fields:tt)*) => {{ 216 + let offset: usize = ::core::mem::offset_of!($Container, $($fields)*); 217 + let field_ptr = $field_ptr; 218 + let container_ptr = field_ptr.byte_sub(offset).cast::<$Container>(); 219 + $crate::assert_same_type(field_ptr, (&raw const (*container_ptr).$($fields)*).cast_mut()); 220 + container_ptr 234 221 }} 235 222 } 223 + 224 + /// Helper for [`container_of!`]. 225 + #[doc(hidden)] 226 + pub fn assert_same_type<T>(_: T, _: T) {} 236 227 237 228 /// Helper for `.rs.S` files. 238 229 #[doc(hidden)]
+110 -5
rust/kernel/list.rs
··· 4 4 5 5 //! A linked list implementation. 6 6 7 - // May not be needed in Rust 1.87.0 (pending beta backport). 8 - #![allow(clippy::ptr_eq)] 9 - 10 7 use crate::sync::ArcBorrow; 11 8 use crate::types::Opaque; 12 9 use core::iter::{DoubleEndedIterator, FusedIterator}; ··· 35 38 /// * All prev/next pointers in `ListLinks` fields of items in the list are valid and form a cycle. 36 39 /// * For every item in the list, the list owns the associated [`ListArc`] reference and has 37 40 /// exclusive access to the `ListLinks` field. 41 + /// 42 + /// # Examples 43 + /// 44 + /// ``` 45 + /// use kernel::list::*; 46 + /// 47 + /// #[pin_data] 48 + /// struct BasicItem { 49 + /// value: i32, 50 + /// #[pin] 51 + /// links: ListLinks, 52 + /// } 53 + /// 54 + /// impl BasicItem { 55 + /// fn new(value: i32) -> Result<ListArc<Self>> { 56 + /// ListArc::pin_init(try_pin_init!(Self { 57 + /// value, 58 + /// links <- ListLinks::new(), 59 + /// }), GFP_KERNEL) 60 + /// } 61 + /// } 62 + /// 63 + /// impl_has_list_links! { 64 + /// impl HasListLinks<0> for BasicItem { self.links } 65 + /// } 66 + /// impl_list_arc_safe! { 67 + /// impl ListArcSafe<0> for BasicItem { untracked; } 68 + /// } 69 + /// impl_list_item! { 70 + /// impl ListItem<0> for BasicItem { using ListLinks; } 71 + /// } 72 + /// 73 + /// // Create a new empty list. 74 + /// let mut list = List::new(); 75 + /// { 76 + /// assert!(list.is_empty()); 77 + /// } 78 + /// 79 + /// // Insert 3 elements using `push_back()`. 80 + /// list.push_back(BasicItem::new(15)?); 81 + /// list.push_back(BasicItem::new(10)?); 82 + /// list.push_back(BasicItem::new(30)?); 83 + /// 84 + /// // Iterate over the list to verify the nodes were inserted correctly. 85 + /// // [15, 10, 30] 86 + /// { 87 + /// let mut iter = list.iter(); 88 + /// assert_eq!(iter.next().unwrap().value, 15); 89 + /// assert_eq!(iter.next().unwrap().value, 10); 90 + /// assert_eq!(iter.next().unwrap().value, 30); 91 + /// assert!(iter.next().is_none()); 92 + /// 93 + /// // Verify the length of the list. 94 + /// assert_eq!(list.iter().count(), 3); 95 + /// } 96 + /// 97 + /// // Pop the items from the list using `pop_back()` and verify the content. 98 + /// { 99 + /// assert_eq!(list.pop_back().unwrap().value, 30); 100 + /// assert_eq!(list.pop_back().unwrap().value, 10); 101 + /// assert_eq!(list.pop_back().unwrap().value, 15); 102 + /// } 103 + /// 104 + /// // Insert 3 elements using `push_front()`. 105 + /// list.push_front(BasicItem::new(15)?); 106 + /// list.push_front(BasicItem::new(10)?); 107 + /// list.push_front(BasicItem::new(30)?); 108 + /// 109 + /// // Iterate over the list to verify the nodes were inserted correctly. 110 + /// // [30, 10, 15] 111 + /// { 112 + /// let mut iter = list.iter(); 113 + /// assert_eq!(iter.next().unwrap().value, 30); 114 + /// assert_eq!(iter.next().unwrap().value, 10); 115 + /// assert_eq!(iter.next().unwrap().value, 15); 116 + /// assert!(iter.next().is_none()); 117 + /// 118 + /// // Verify the length of the list. 119 + /// assert_eq!(list.iter().count(), 3); 120 + /// } 121 + /// 122 + /// // Pop the items from the list using `pop_front()` and verify the content. 123 + /// { 124 + /// assert_eq!(list.pop_front().unwrap().value, 30); 125 + /// assert_eq!(list.pop_front().unwrap().value, 10); 126 + /// } 127 + /// 128 + /// // Push `list2` to `list` through `push_all_back()`. 129 + /// // list: [15] 130 + /// // list2: [25, 35] 131 + /// { 132 + /// let mut list2 = List::new(); 133 + /// list2.push_back(BasicItem::new(25)?); 134 + /// list2.push_back(BasicItem::new(35)?); 135 + /// 136 + /// list.push_all_back(&mut list2); 137 + /// 138 + /// // list: [15, 25, 35] 139 + /// // list2: [] 140 + /// let mut iter = list.iter(); 141 + /// assert_eq!(iter.next().unwrap().value, 15); 142 + /// assert_eq!(iter.next().unwrap().value, 25); 143 + /// assert_eq!(iter.next().unwrap().value, 35); 144 + /// assert!(iter.next().is_none()); 145 + /// assert!(list2.is_empty()); 146 + /// } 147 + /// # Result::<(), Error>::Ok(()) 148 + /// ``` 38 149 pub struct List<T: ?Sized + ListItem<ID>, const ID: u64 = 0> { 39 150 first: *mut ListLinksFields, 40 151 _ty: PhantomData<ListArc<T, ID>>, ··· 427 322 428 323 /// Removes the last item from this list. 429 324 pub fn pop_back(&mut self) -> Option<ListArc<T, ID>> { 430 - if self.first.is_null() { 325 + if self.is_empty() { 431 326 return None; 432 327 } 433 328 ··· 439 334 440 335 /// Removes the first item from this list. 441 336 pub fn pop_front(&mut self) -> Option<ListArc<T, ID>> { 442 - if self.first.is_null() { 337 + if self.is_empty() { 443 338 return None; 444 339 } 445 340
+3 -3
rust/kernel/list/arc.rs
··· 74 74 /// 75 75 /// * The `untracked` strategy does not actually keep track of whether a [`ListArc`] exists. When 76 76 /// using this strategy, the only way to create a [`ListArc`] is using a [`UniqueArc`]. 77 - /// * The `tracked_by` strategy defers the tracking to a field of the struct. The user much specify 77 + /// * The `tracked_by` strategy defers the tracking to a field of the struct. The user must specify 78 78 /// which field to defer the tracking to. The field must implement [`ListArcSafe`]. If the field 79 79 /// implements [`TryNewListArc`], then the type will also implement [`TryNewListArc`]. 80 80 /// ··· 96 96 } $($rest:tt)*) => { 97 97 impl$(<$($generics)*>)? $crate::list::ListArcSafe<$num> for $t { 98 98 unsafe fn on_create_list_arc_from_unique(self: ::core::pin::Pin<&mut Self>) { 99 - $crate::assert_pinned!($t, $field, $fty, inline); 99 + ::pin_init::assert_pinned!($t, $field, $fty, inline); 100 100 101 101 // SAFETY: This field is structurally pinned as per the above assertion. 102 102 let field = unsafe { ··· 464 464 465 465 /// A utility for tracking whether a [`ListArc`] exists using an atomic. 466 466 /// 467 - /// # Invariant 467 + /// # Invariants 468 468 /// 469 469 /// If the boolean is `false`, then there is no [`ListArc`] for this value. 470 470 #[repr(transparent)]
+6 -6
rust/kernel/miscdevice.rs
··· 217 217 // type. 218 218 // 219 219 // SAFETY: The open call of a file can access the private data. 220 - unsafe { (*raw_file).private_data = ptr.into_foreign() }; 220 + unsafe { (*raw_file).private_data = ptr.into_foreign().cast() }; 221 221 222 222 0 223 223 } ··· 228 228 /// must be associated with a `MiscDeviceRegistration<T>`. 229 229 unsafe extern "C" fn release(_inode: *mut bindings::inode, file: *mut bindings::file) -> c_int { 230 230 // SAFETY: The release call of a file owns the private data. 231 - let private = unsafe { (*file).private_data }; 231 + let private = unsafe { (*file).private_data }.cast(); 232 232 // SAFETY: The release call of a file owns the private data. 233 233 let ptr = unsafe { <T::Ptr as ForeignOwnable>::from_foreign(private) }; 234 234 ··· 253 253 // SAFETY: This is a Rust Miscdevice, so we call `into_foreign` in `open` and 254 254 // `from_foreign` in `release`, and `fops_mmap` is guaranteed to be called between those 255 255 // two operations. 256 - let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 256 + let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private.cast()) }; 257 257 // SAFETY: The caller provides a vma that is undergoing initial VMA setup. 258 258 let area = unsafe { VmaNew::from_raw(vma) }; 259 259 // SAFETY: ··· 272 272 /// `file` must be a valid file that is associated with a `MiscDeviceRegistration<T>`. 273 273 unsafe extern "C" fn ioctl(file: *mut bindings::file, cmd: c_uint, arg: c_ulong) -> c_long { 274 274 // SAFETY: The ioctl call of a file can access the private data. 275 - let private = unsafe { (*file).private_data }; 275 + let private = unsafe { (*file).private_data }.cast(); 276 276 // SAFETY: Ioctl calls can borrow the private data of the file. 277 277 let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 278 278 ··· 297 297 arg: c_ulong, 298 298 ) -> c_long { 299 299 // SAFETY: The compat ioctl call of a file can access the private data. 300 - let private = unsafe { (*file).private_data }; 300 + let private = unsafe { (*file).private_data }.cast(); 301 301 // SAFETY: Ioctl calls can borrow the private data of the file. 302 302 let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 303 303 ··· 318 318 /// - `seq_file` must be a valid `struct seq_file` that we can write to. 319 319 unsafe extern "C" fn show_fdinfo(seq_file: *mut bindings::seq_file, file: *mut bindings::file) { 320 320 // SAFETY: The release call of a file owns the private data. 321 - let private = unsafe { (*file).private_data }; 321 + let private = unsafe { (*file).private_data }.cast(); 322 322 // SAFETY: Ioctl calls can borrow the private data of the file. 323 323 let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 324 324 // SAFETY:
+2
rust/kernel/page.rs
··· 69 69 /// let page = Page::alloc_page(GFP_KERNEL | __GFP_ZERO)?; 70 70 /// # Ok::<(), kernel::alloc::AllocError>(()) 71 71 /// ``` 72 + #[inline] 72 73 pub fn alloc_page(flags: Flags) -> Result<Self, AllocError> { 73 74 // SAFETY: Depending on the value of `gfp_flags`, this call may sleep. Other than that, it 74 75 // is always safe to call this method. ··· 252 251 } 253 252 254 253 impl Drop for Page { 254 + #[inline] 255 255 fn drop(&mut self) { 256 256 // SAFETY: By the type invariants, we have ownership of the page and can free it. 257 257 unsafe { bindings::__free_pages(self.page.as_ptr(), 0) };
+10 -7
rust/kernel/pci.rs
··· 89 89 extern "C" fn remove_callback(pdev: *mut bindings::pci_dev) { 90 90 // SAFETY: The PCI bus only ever calls the remove callback with a valid pointer to a 91 91 // `struct pci_dev`. 92 - let ptr = unsafe { bindings::pci_get_drvdata(pdev) }; 92 + let ptr = unsafe { bindings::pci_get_drvdata(pdev) }.cast(); 93 93 94 94 // SAFETY: `remove_callback` is only ever called after a successful call to 95 95 // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized ··· 118 118 }; 119 119 } 120 120 121 - /// Abstraction for bindings::pci_device_id. 121 + /// Abstraction for the PCI device ID structure ([`struct pci_device_id`]). 122 + /// 123 + /// [`struct pci_device_id`]: https://docs.kernel.org/PCI/pci.html#c.pci_device_id 122 124 #[repr(transparent)] 123 125 #[derive(Clone, Copy)] 124 126 pub struct DeviceId(bindings::pci_device_id); ··· 175 173 } 176 174 } 177 175 178 - /// IdTable type for PCI 176 + /// `IdTable` type for PCI. 179 177 pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>; 180 178 181 179 /// Create a PCI `IdTable` with its alias for modpost. ··· 226 224 /// `Adapter` documentation for an example. 227 225 pub trait Driver: Send { 228 226 /// The type holding information about each device id supported by the driver. 229 - /// 230 - /// TODO: Use associated_type_defaults once stabilized: 231 - /// 232 - /// type IdInfo: 'static = (); 227 + // TODO: Use `associated_type_defaults` once stabilized: 228 + // 229 + // ``` 230 + // type IdInfo: 'static = (); 231 + // ``` 233 232 type IdInfo: 'static; 234 233 235 234 /// The table of device ids supported by the driver.
+6 -5
rust/kernel/platform.rs
··· 79 79 80 80 extern "C" fn remove_callback(pdev: *mut bindings::platform_device) { 81 81 // SAFETY: `pdev` is a valid pointer to a `struct platform_device`. 82 - let ptr = unsafe { bindings::platform_get_drvdata(pdev) }; 82 + let ptr = unsafe { bindings::platform_get_drvdata(pdev) }.cast(); 83 83 84 84 // SAFETY: `remove_callback` is only ever called after a successful call to 85 85 // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized ··· 150 150 ///``` 151 151 pub trait Driver: Send { 152 152 /// The type holding driver private data about each device id supported by the driver. 153 - /// 154 - /// TODO: Use associated_type_defaults once stabilized: 155 - /// 156 - /// type IdInfo: 'static = (); 153 + // TODO: Use associated_type_defaults once stabilized: 154 + // 155 + // ``` 156 + // type IdInfo: 'static = (); 157 + // ``` 157 158 type IdInfo: 'static; 158 159 159 160 /// The table of OF device ids supported by the driver.
+6 -1
rust/kernel/prelude.rs
··· 14 14 #[doc(no_inline)] 15 15 pub use core::pin::Pin; 16 16 17 + pub use ::ffi::{ 18 + c_char, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint, c_ulong, c_ulonglong, 19 + c_ushort, c_void, 20 + }; 21 + 17 22 pub use crate::alloc::{flags::*, Box, KBox, KVBox, KVVec, KVec, VBox, VVec, Vec}; 18 23 19 24 #[doc(no_inline)] 20 - pub use macros::{export, module, vtable}; 25 + pub use macros::{export, kunit_tests, module, vtable}; 21 26 22 27 pub use pin_init::{init, pin_data, pin_init, pinned_drop, InPlaceWrite, Init, PinInit, Zeroable}; 23 28
+18 -9
rust/kernel/print.rs
··· 198 198 /// Equivalent to the kernel's [`pr_emerg`] macro. 199 199 /// 200 200 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 201 - /// `alloc::format!` for information about the formatting syntax. 201 + /// [`std::format!`] for information about the formatting syntax. 202 202 /// 203 203 /// [`pr_emerg`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_emerg 204 204 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 205 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 205 206 /// 206 207 /// # Examples 207 208 /// ··· 223 222 /// Equivalent to the kernel's [`pr_alert`] macro. 224 223 /// 225 224 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 226 - /// `alloc::format!` for information about the formatting syntax. 225 + /// [`std::format!`] for information about the formatting syntax. 227 226 /// 228 227 /// [`pr_alert`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_alert 229 228 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 229 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 230 230 /// 231 231 /// # Examples 232 232 /// ··· 248 246 /// Equivalent to the kernel's [`pr_crit`] macro. 249 247 /// 250 248 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 251 - /// `alloc::format!` for information about the formatting syntax. 249 + /// [`std::format!`] for information about the formatting syntax. 252 250 /// 253 251 /// [`pr_crit`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_crit 254 252 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 253 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 255 254 /// 256 255 /// # Examples 257 256 /// ··· 273 270 /// Equivalent to the kernel's [`pr_err`] macro. 274 271 /// 275 272 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 276 - /// `alloc::format!` for information about the formatting syntax. 273 + /// [`std::format!`] for information about the formatting syntax. 277 274 /// 278 275 /// [`pr_err`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_err 279 276 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 277 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 280 278 /// 281 279 /// # Examples 282 280 /// ··· 298 294 /// Equivalent to the kernel's [`pr_warn`] macro. 299 295 /// 300 296 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 301 - /// `alloc::format!` for information about the formatting syntax. 297 + /// [`std::format!`] for information about the formatting syntax. 302 298 /// 303 299 /// [`pr_warn`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_warn 304 300 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 301 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 305 302 /// 306 303 /// # Examples 307 304 /// ··· 323 318 /// Equivalent to the kernel's [`pr_notice`] macro. 324 319 /// 325 320 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 326 - /// `alloc::format!` for information about the formatting syntax. 321 + /// [`std::format!`] for information about the formatting syntax. 327 322 /// 328 323 /// [`pr_notice`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_notice 329 324 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 325 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 330 326 /// 331 327 /// # Examples 332 328 /// ··· 348 342 /// Equivalent to the kernel's [`pr_info`] macro. 349 343 /// 350 344 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 351 - /// `alloc::format!` for information about the formatting syntax. 345 + /// [`std::format!`] for information about the formatting syntax. 352 346 /// 353 347 /// [`pr_info`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_info 354 348 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 349 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 355 350 /// 356 351 /// # Examples 357 352 /// ··· 375 368 /// yet. 376 369 /// 377 370 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 378 - /// `alloc::format!` for information about the formatting syntax. 371 + /// [`std::format!`] for information about the formatting syntax. 379 372 /// 380 373 /// [`pr_debug`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_debug 381 374 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 375 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 382 376 /// 383 377 /// # Examples 384 378 /// ··· 403 395 /// Equivalent to the kernel's [`pr_cont`] macro. 404 396 /// 405 397 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 406 - /// `alloc::format!` for information about the formatting syntax. 398 + /// [`std::format!`] for information about the formatting syntax. 407 399 /// 408 400 /// [`pr_info!`]: crate::pr_info! 409 401 /// [`pr_cont`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_cont 410 402 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 403 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 411 404 /// 412 405 /// # Examples 413 406 ///
+10 -13
rust/kernel/rbtree.rs
··· 424 424 while !node.is_null() { 425 425 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 426 426 // point to the links field of `Node<K, V>` objects. 427 - let this = unsafe { container_of!(node, Node<K, V>, links) }.cast_mut(); 427 + let this = unsafe { container_of!(node, Node<K, V>, links) }; 428 428 // SAFETY: `this` is a non-null node so it is valid by the type invariants. 429 429 let this_key = unsafe { &(*this).key }; 430 430 // SAFETY: `node` is a non-null node so it is valid by the type invariants. ··· 496 496 // but it is not observable. The loop invariant is still maintained. 497 497 498 498 // SAFETY: `this` is valid per the loop invariant. 499 - unsafe { drop(KBox::from_raw(this.cast_mut())) }; 499 + unsafe { drop(KBox::from_raw(this)) }; 500 500 } 501 501 } 502 502 } ··· 761 761 let next = self.get_neighbor_raw(Direction::Next); 762 762 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 763 763 // point to the links field of `Node<K, V>` objects. 764 - let this = unsafe { container_of!(self.current.as_ptr(), Node<K, V>, links) }.cast_mut(); 764 + let this = unsafe { container_of!(self.current.as_ptr(), Node<K, V>, links) }; 765 765 // SAFETY: `this` is valid by the type invariants as described above. 766 766 let node = unsafe { KBox::from_raw(this) }; 767 767 let node = RBTreeNode { node }; ··· 806 806 unsafe { bindings::rb_erase(neighbor, addr_of_mut!(self.tree.root)) }; 807 807 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 808 808 // point to the links field of `Node<K, V>` objects. 809 - let this = unsafe { container_of!(neighbor, Node<K, V>, links) }.cast_mut(); 809 + let this = unsafe { container_of!(neighbor, Node<K, V>, links) }; 810 810 // SAFETY: `this` is valid by the type invariants as described above. 811 811 let node = unsafe { KBox::from_raw(this) }; 812 812 return Some(RBTreeNode { node }); ··· 912 912 unsafe fn to_key_value_raw<'b>(node: NonNull<bindings::rb_node>) -> (&'b K, *mut V) { 913 913 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 914 914 // point to the links field of `Node<K, V>` objects. 915 - let this = unsafe { container_of!(node.as_ptr(), Node<K, V>, links) }.cast_mut(); 915 + let this = unsafe { container_of!(node.as_ptr(), Node<K, V>, links) }; 916 916 // SAFETY: The passed `node` is the current node or a non-null neighbor, 917 917 // thus `this` is valid by the type invariants. 918 918 let k = unsafe { &(*this).key }; ··· 1021 1021 1022 1022 // SAFETY: By the type invariant of `IterRaw`, `self.next` is a valid node in an `RBTree`, 1023 1023 // and by the type invariant of `RBTree`, all nodes point to the links field of `Node<K, V>` objects. 1024 - let cur = unsafe { container_of!(self.next, Node<K, V>, links) }.cast_mut(); 1024 + let cur = unsafe { container_of!(self.next, Node<K, V>, links) }; 1025 1025 1026 1026 // SAFETY: `self.next` is a valid tree node by the type invariants. 1027 1027 self.next = unsafe { bindings::rb_next(self.next) }; ··· 1216 1216 // SAFETY: 1217 1217 // - `self.node_links` is a valid pointer to a node in the tree. 1218 1218 // - We have exclusive access to the underlying tree, and can thus give out a mutable reference. 1219 - unsafe { &mut (*(container_of!(self.node_links, Node<K, V>, links).cast_mut())).value } 1219 + unsafe { &mut (*(container_of!(self.node_links, Node<K, V>, links))).value } 1220 1220 } 1221 1221 1222 1222 /// Converts the entry into a mutable reference to its value. ··· 1226 1226 // SAFETY: 1227 1227 // - `self.node_links` is a valid pointer to a node in the tree. 1228 1228 // - This consumes the `&'a mut RBTree<K, V>`, therefore it can give out a mutable reference that lives for `'a`. 1229 - unsafe { &mut (*(container_of!(self.node_links, Node<K, V>, links).cast_mut())).value } 1229 + unsafe { &mut (*(container_of!(self.node_links, Node<K, V>, links))).value } 1230 1230 } 1231 1231 1232 1232 /// Remove this entry from the [`RBTree`]. ··· 1239 1239 RBTreeNode { 1240 1240 // SAFETY: The node was a node in the tree, but we removed it, so we can convert it 1241 1241 // back into a box. 1242 - node: unsafe { 1243 - KBox::from_raw(container_of!(self.node_links, Node<K, V>, links).cast_mut()) 1244 - }, 1242 + node: unsafe { KBox::from_raw(container_of!(self.node_links, Node<K, V>, links)) }, 1245 1243 } 1246 1244 } 1247 1245 ··· 1270 1272 // SAFETY: 1271 1273 // - `self.node_ptr` produces a valid pointer to a node in the tree. 1272 1274 // - Now that we removed this entry from the tree, we can convert the node to a box. 1273 - let old_node = 1274 - unsafe { KBox::from_raw(container_of!(self.node_links, Node<K, V>, links).cast_mut()) }; 1275 + let old_node = unsafe { KBox::from_raw(container_of!(self.node_links, Node<K, V>, links)) }; 1275 1276 1276 1277 RBTreeNode { node: old_node } 1277 1278 }
+7 -2
rust/kernel/static_assert.rs
··· 6 6 /// 7 7 /// Similar to C11 [`_Static_assert`] and C++11 [`static_assert`]. 8 8 /// 9 + /// An optional panic message can be supplied after the expression. 10 + /// Currently only a string literal without formatting is supported 11 + /// due to constness limitations of the [`assert!`] macro. 12 + /// 9 13 /// The feature may be added to Rust in the future: see [RFC 2790]. 10 14 /// 11 15 /// [`_Static_assert`]: https://en.cppreference.com/w/c/language/_Static_assert ··· 29 25 /// x + 2 30 26 /// } 31 27 /// static_assert!(f(40) == 42); 28 + /// static_assert!(f(40) == 42, "f(x) must add 2 to the given input."); 32 29 /// ``` 33 30 #[macro_export] 34 31 macro_rules! static_assert { 35 - ($condition:expr) => { 36 - const _: () = core::assert!($condition); 32 + ($condition:expr $(,$arg:literal)?) => { 33 + const _: () = ::core::assert!($condition $(,$arg)?); 37 34 }; 38 35 }
+1 -1
rust/kernel/std_vendor.rs
··· 148 148 }; 149 149 ($val:expr $(,)?) => { 150 150 // Use of `match` here is intentional because it affects the lifetimes 151 - // of temporaries - https://stackoverflow.com/a/48732525/1063961 151 + // of temporaries - <https://stackoverflow.com/a/48732525/1063961> 152 152 match $val { 153 153 tmp => { 154 154 $crate::pr_info!("[{}:{}:{}] {} = {:#?}\n",
+36 -46
rust/kernel/str.rs
··· 6 6 use core::fmt::{self, Write}; 7 7 use core::ops::{self, Deref, DerefMut, Index}; 8 8 9 - use crate::error::{code::*, Error}; 9 + use crate::prelude::*; 10 10 11 11 /// Byte string without UTF-8 validity guarantee. 12 12 #[repr(transparent)] ··· 572 572 }}; 573 573 } 574 574 575 - #[cfg(test)] 576 - #[expect(clippy::items_after_test_module)] 575 + #[kunit_tests(rust_kernel_str)] 577 576 mod tests { 578 577 use super::*; 579 578 580 - struct String(CString); 581 - 582 - impl String { 583 - fn from_fmt(args: fmt::Arguments<'_>) -> Self { 584 - String(CString::try_from_fmt(args).unwrap()) 585 - } 586 - } 587 - 588 - impl Deref for String { 589 - type Target = str; 590 - 591 - fn deref(&self) -> &str { 592 - self.0.to_str().unwrap() 593 - } 594 - } 595 - 596 579 macro_rules! format { 597 580 ($($f:tt)*) => ({ 598 - &*String::from_fmt(kernel::fmt!($($f)*)) 581 + CString::try_from_fmt(::kernel::fmt!($($f)*))?.to_str()? 599 582 }) 600 583 } 601 584 ··· 597 614 \\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff"; 598 615 599 616 #[test] 600 - fn test_cstr_to_str() { 617 + fn test_cstr_to_str() -> Result { 601 618 let good_bytes = b"\xf0\x9f\xa6\x80\0"; 602 - let checked_cstr = CStr::from_bytes_with_nul(good_bytes).unwrap(); 603 - let checked_str = checked_cstr.to_str().unwrap(); 619 + let checked_cstr = CStr::from_bytes_with_nul(good_bytes)?; 620 + let checked_str = checked_cstr.to_str()?; 604 621 assert_eq!(checked_str, "🦀"); 622 + Ok(()) 605 623 } 606 624 607 625 #[test] 608 - #[should_panic] 609 - fn test_cstr_to_str_panic() { 626 + fn test_cstr_to_str_invalid_utf8() -> Result { 610 627 let bad_bytes = b"\xc3\x28\0"; 611 - let checked_cstr = CStr::from_bytes_with_nul(bad_bytes).unwrap(); 612 - checked_cstr.to_str().unwrap(); 628 + let checked_cstr = CStr::from_bytes_with_nul(bad_bytes)?; 629 + assert!(checked_cstr.to_str().is_err()); 630 + Ok(()) 613 631 } 614 632 615 633 #[test] 616 - fn test_cstr_as_str_unchecked() { 634 + fn test_cstr_as_str_unchecked() -> Result { 617 635 let good_bytes = b"\xf0\x9f\x90\xA7\0"; 618 - let checked_cstr = CStr::from_bytes_with_nul(good_bytes).unwrap(); 636 + let checked_cstr = CStr::from_bytes_with_nul(good_bytes)?; 619 637 // SAFETY: The contents come from a string literal which contains valid UTF-8. 620 638 let unchecked_str = unsafe { checked_cstr.as_str_unchecked() }; 621 639 assert_eq!(unchecked_str, "🐧"); 640 + Ok(()) 622 641 } 623 642 624 643 #[test] 625 - fn test_cstr_display() { 626 - let hello_world = CStr::from_bytes_with_nul(b"hello, world!\0").unwrap(); 644 + fn test_cstr_display() -> Result { 645 + let hello_world = CStr::from_bytes_with_nul(b"hello, world!\0")?; 627 646 assert_eq!(format!("{hello_world}"), "hello, world!"); 628 - let non_printables = CStr::from_bytes_with_nul(b"\x01\x09\x0a\0").unwrap(); 647 + let non_printables = CStr::from_bytes_with_nul(b"\x01\x09\x0a\0")?; 629 648 assert_eq!(format!("{non_printables}"), "\\x01\\x09\\x0a"); 630 - let non_ascii = CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0").unwrap(); 649 + let non_ascii = CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0")?; 631 650 assert_eq!(format!("{non_ascii}"), "d\\xe9j\\xe0 vu"); 632 - let good_bytes = CStr::from_bytes_with_nul(b"\xf0\x9f\xa6\x80\0").unwrap(); 651 + let good_bytes = CStr::from_bytes_with_nul(b"\xf0\x9f\xa6\x80\0")?; 633 652 assert_eq!(format!("{good_bytes}"), "\\xf0\\x9f\\xa6\\x80"); 653 + Ok(()) 634 654 } 635 655 636 656 #[test] 637 - fn test_cstr_display_all_bytes() { 657 + fn test_cstr_display_all_bytes() -> Result { 638 658 let mut bytes: [u8; 256] = [0; 256]; 639 659 // fill `bytes` with [1..=255] + [0] 640 660 for i in u8::MIN..=u8::MAX { 641 661 bytes[i as usize] = i.wrapping_add(1); 642 662 } 643 - let cstr = CStr::from_bytes_with_nul(&bytes).unwrap(); 663 + let cstr = CStr::from_bytes_with_nul(&bytes)?; 644 664 assert_eq!(format!("{cstr}"), ALL_ASCII_CHARS); 665 + Ok(()) 645 666 } 646 667 647 668 #[test] 648 - fn test_cstr_debug() { 649 - let hello_world = CStr::from_bytes_with_nul(b"hello, world!\0").unwrap(); 669 + fn test_cstr_debug() -> Result { 670 + let hello_world = CStr::from_bytes_with_nul(b"hello, world!\0")?; 650 671 assert_eq!(format!("{hello_world:?}"), "\"hello, world!\""); 651 - let non_printables = CStr::from_bytes_with_nul(b"\x01\x09\x0a\0").unwrap(); 672 + let non_printables = CStr::from_bytes_with_nul(b"\x01\x09\x0a\0")?; 652 673 assert_eq!(format!("{non_printables:?}"), "\"\\x01\\x09\\x0a\""); 653 - let non_ascii = CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0").unwrap(); 674 + let non_ascii = CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0")?; 654 675 assert_eq!(format!("{non_ascii:?}"), "\"d\\xe9j\\xe0 vu\""); 655 - let good_bytes = CStr::from_bytes_with_nul(b"\xf0\x9f\xa6\x80\0").unwrap(); 676 + let good_bytes = CStr::from_bytes_with_nul(b"\xf0\x9f\xa6\x80\0")?; 656 677 assert_eq!(format!("{good_bytes:?}"), "\"\\xf0\\x9f\\xa6\\x80\""); 678 + Ok(()) 657 679 } 658 680 659 681 #[test] 660 - fn test_bstr_display() { 682 + fn test_bstr_display() -> Result { 661 683 let hello_world = BStr::from_bytes(b"hello, world!"); 662 684 assert_eq!(format!("{hello_world}"), "hello, world!"); 663 685 let escapes = BStr::from_bytes(b"_\t_\n_\r_\\_\'_\"_"); ··· 673 685 assert_eq!(format!("{non_ascii}"), "d\\xe9j\\xe0 vu"); 674 686 let good_bytes = BStr::from_bytes(b"\xf0\x9f\xa6\x80"); 675 687 assert_eq!(format!("{good_bytes}"), "\\xf0\\x9f\\xa6\\x80"); 688 + Ok(()) 676 689 } 677 690 678 691 #[test] 679 - fn test_bstr_debug() { 692 + fn test_bstr_debug() -> Result { 680 693 let hello_world = BStr::from_bytes(b"hello, world!"); 681 694 assert_eq!(format!("{hello_world:?}"), "\"hello, world!\""); 682 695 let escapes = BStr::from_bytes(b"_\t_\n_\r_\\_\'_\"_"); ··· 688 699 assert_eq!(format!("{non_ascii:?}"), "\"d\\xe9j\\xe0 vu\""); 689 700 let good_bytes = BStr::from_bytes(b"\xf0\x9f\xa6\x80"); 690 701 assert_eq!(format!("{good_bytes:?}"), "\"\\xf0\\x9f\\xa6\\x80\""); 702 + Ok(()) 691 703 } 692 704 } 693 705 ··· 742 752 /// for the lifetime of the returned [`RawFormatter`]. 743 753 pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self { 744 754 let pos = buf as usize; 745 - // INVARIANT: We ensure that `end` is never less then `buf`, and the safety requirements 755 + // INVARIANT: We ensure that `end` is never less than `buf`, and the safety requirements 746 756 // guarantees that the memory region is valid for writes. 747 757 Self { 748 758 pos, ··· 876 886 877 887 // SAFETY: The number of bytes that can be written to `f` is bounded by `size`, which is 878 888 // `buf`'s capacity. The contents of the buffer have been initialised by writes to `f`. 879 - unsafe { buf.set_len(f.bytes_written()) }; 889 + unsafe { buf.inc_len(f.bytes_written()) }; 880 890 881 891 // Check that there are no `NUL` bytes before the end. 882 892 // SAFETY: The buffer is valid for read because `f.bytes_written()` is bounded by `size` ··· 934 944 /// A convenience alias for [`core::format_args`]. 935 945 #[macro_export] 936 946 macro_rules! fmt { 937 - ($($f:tt)*) => ( core::format_args!($($f)*) ) 947 + ($($f:tt)*) => ( ::core::format_args!($($f)*) ) 938 948 }
+14 -11
rust/kernel/sync/arc.rs
··· 135 135 // meaningful with respect to dropck - but this may change in the future so this is left here 136 136 // out of an abundance of caution. 137 137 // 138 - // See https://doc.rust-lang.org/nomicon/phantom-data.html#generic-parameters-and-drop-checking 138 + // See <https://doc.rust-lang.org/nomicon/phantom-data.html#generic-parameters-and-drop-checking> 139 139 // for more detail on the semantics of dropck in the presence of `PhantomData`. 140 140 _p: PhantomData<ArcInner<T>>, 141 141 } 142 142 143 + #[doc(hidden)] 143 144 #[pin_data] 144 145 #[repr(C)] 145 - struct ArcInner<T: ?Sized> { 146 + pub struct ArcInner<T: ?Sized> { 146 147 refcount: Opaque<bindings::refcount_t>, 147 148 data: T, 148 149 } ··· 372 371 } 373 372 } 374 373 375 - impl<T: 'static> ForeignOwnable for Arc<T> { 374 + // SAFETY: The `into_foreign` function returns a pointer that is well-aligned. 375 + unsafe impl<T: 'static> ForeignOwnable for Arc<T> { 376 + type PointedTo = ArcInner<T>; 376 377 type Borrowed<'a> = ArcBorrow<'a, T>; 377 378 type BorrowedMut<'a> = Self::Borrowed<'a>; 378 379 379 - fn into_foreign(self) -> *mut crate::ffi::c_void { 380 - ManuallyDrop::new(self).ptr.as_ptr().cast() 380 + fn into_foreign(self) -> *mut Self::PointedTo { 381 + ManuallyDrop::new(self).ptr.as_ptr() 381 382 } 382 383 383 - unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self { 384 + unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self { 384 385 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 385 386 // call to `Self::into_foreign`. 386 - let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) }; 387 + let inner = unsafe { NonNull::new_unchecked(ptr) }; 387 388 388 389 // SAFETY: By the safety requirement of this function, we know that `ptr` came from 389 390 // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and ··· 393 390 unsafe { Self::from_inner(inner) } 394 391 } 395 392 396 - unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> { 393 + unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> ArcBorrow<'a, T> { 397 394 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 398 395 // call to `Self::into_foreign`. 399 - let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) }; 396 + let inner = unsafe { NonNull::new_unchecked(ptr) }; 400 397 401 398 // SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive 402 399 // for the lifetime of the returned value. 403 400 unsafe { ArcBorrow::new(inner) } 404 401 } 405 402 406 - unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> { 403 + unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> ArcBorrow<'a, T> { 407 404 // SAFETY: The safety requirements for `borrow_mut` are a superset of the safety 408 405 // requirements for `borrow`. 409 406 unsafe { Self::borrow(ptr) } ··· 492 489 /// There are no mutable references to the underlying [`Arc`], and it remains valid for the 493 490 /// lifetime of the [`ArcBorrow`] instance. 494 491 /// 495 - /// # Example 492 + /// # Examples 496 493 /// 497 494 /// ``` 498 495 /// use kernel::sync::{Arc, ArcBorrow};
+135 -46
rust/kernel/time.rs
··· 5 5 //! This module contains the kernel APIs related to time and timers that 6 6 //! have been ported or wrapped for usage by Rust code in the kernel. 7 7 //! 8 + //! There are two types in this module: 9 + //! 10 + //! - The [`Instant`] type represents a specific point in time. 11 + //! - The [`Delta`] type represents a span of time. 12 + //! 13 + //! Note that the C side uses `ktime_t` type to represent both. However, timestamp 14 + //! and timedelta are different. To avoid confusion, we use two different types. 15 + //! 16 + //! A [`Instant`] object can be created by calling the [`Instant::now()`] function. 17 + //! It represents a point in time at which the object was created. 18 + //! By calling the [`Instant::elapsed()`] method, a [`Delta`] object representing 19 + //! the elapsed time can be created. The [`Delta`] object can also be created 20 + //! by subtracting two [`Instant`] objects. 21 + //! 22 + //! A [`Delta`] type supports methods to retrieve the duration in various units. 23 + //! 8 24 //! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h). 9 25 //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h). 10 26 11 27 pub mod hrtimer; 12 28 29 + /// The number of nanoseconds per microsecond. 30 + pub const NSEC_PER_USEC: i64 = bindings::NSEC_PER_USEC as i64; 31 + 13 32 /// The number of nanoseconds per millisecond. 14 33 pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64; 34 + 35 + /// The number of nanoseconds per second. 36 + pub const NSEC_PER_SEC: i64 = bindings::NSEC_PER_SEC as i64; 15 37 16 38 /// The time unit of Linux kernel. One jiffy equals (1/HZ) second. 17 39 pub type Jiffies = crate::ffi::c_ulong; ··· 49 27 unsafe { bindings::__msecs_to_jiffies(msecs) } 50 28 } 51 29 52 - /// A Rust wrapper around a `ktime_t`. 30 + /// A specific point in time. 31 + /// 32 + /// # Invariants 33 + /// 34 + /// The `inner` value is in the range from 0 to `KTIME_MAX`. 53 35 #[repr(transparent)] 54 - #[derive(Copy, Clone)] 55 - pub struct Ktime { 36 + #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] 37 + pub struct Instant { 56 38 inner: bindings::ktime_t, 57 39 } 58 40 59 - impl Ktime { 60 - /// Create a `Ktime` from a raw `ktime_t`. 61 - #[inline] 62 - pub fn from_raw(inner: bindings::ktime_t) -> Self { 63 - Self { inner } 64 - } 65 - 41 + impl Instant { 66 42 /// Get the current time using `CLOCK_MONOTONIC`. 67 43 #[inline] 68 - pub fn ktime_get() -> Self { 69 - // SAFETY: It is always safe to call `ktime_get` outside of NMI context. 70 - Self::from_raw(unsafe { bindings::ktime_get() }) 71 - } 72 - 73 - /// Divide the number of nanoseconds by a compile-time constant. 74 - #[inline] 75 - fn divns_constant<const DIV: i64>(self) -> i64 { 76 - self.to_ns() / DIV 77 - } 78 - 79 - /// Returns the number of nanoseconds. 80 - #[inline] 81 - pub fn to_ns(self) -> i64 { 82 - self.inner 83 - } 84 - 85 - /// Returns the number of milliseconds. 86 - #[inline] 87 - pub fn to_ms(self) -> i64 { 88 - self.divns_constant::<NSEC_PER_MSEC>() 89 - } 90 - } 91 - 92 - /// Returns the number of milliseconds between two ktimes. 93 - #[inline] 94 - pub fn ktime_ms_delta(later: Ktime, earlier: Ktime) -> i64 { 95 - (later - earlier).to_ms() 96 - } 97 - 98 - impl core::ops::Sub for Ktime { 99 - type Output = Ktime; 100 - 101 - #[inline] 102 - fn sub(self, other: Ktime) -> Ktime { 44 + pub fn now() -> Self { 45 + // INVARIANT: The `ktime_get()` function returns a value in the range 46 + // from 0 to `KTIME_MAX`. 103 47 Self { 104 - inner: self.inner - other.inner, 48 + // SAFETY: It is always safe to call `ktime_get()` outside of NMI context. 49 + inner: unsafe { bindings::ktime_get() }, 50 + } 51 + } 52 + 53 + /// Return the amount of time elapsed since the [`Instant`]. 54 + #[inline] 55 + pub fn elapsed(&self) -> Delta { 56 + Self::now() - *self 57 + } 58 + } 59 + 60 + impl core::ops::Sub for Instant { 61 + type Output = Delta; 62 + 63 + // By the type invariant, it never overflows. 64 + #[inline] 65 + fn sub(self, other: Instant) -> Delta { 66 + Delta { 67 + nanos: self.inner - other.inner, 105 68 } 106 69 } 107 70 } ··· 154 147 impl ClockId { 155 148 fn into_c(self) -> bindings::clockid_t { 156 149 self as bindings::clockid_t 150 + } 151 + } 152 + 153 + /// A span of time. 154 + /// 155 + /// This struct represents a span of time, with its value stored as nanoseconds. 156 + /// The value can represent any valid i64 value, including negative, zero, and 157 + /// positive numbers. 158 + #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 159 + pub struct Delta { 160 + nanos: i64, 161 + } 162 + 163 + impl Delta { 164 + /// A span of time equal to zero. 165 + pub const ZERO: Self = Self { nanos: 0 }; 166 + 167 + /// Create a new [`Delta`] from a number of microseconds. 168 + /// 169 + /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775. 170 + /// If `micros` is outside this range, `i64::MIN` is used for negative values, 171 + /// and `i64::MAX` is used for positive values due to saturation. 172 + #[inline] 173 + pub const fn from_micros(micros: i64) -> Self { 174 + Self { 175 + nanos: micros.saturating_mul(NSEC_PER_USEC), 176 + } 177 + } 178 + 179 + /// Create a new [`Delta`] from a number of milliseconds. 180 + /// 181 + /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854. 182 + /// If `millis` is outside this range, `i64::MIN` is used for negative values, 183 + /// and `i64::MAX` is used for positive values due to saturation. 184 + #[inline] 185 + pub const fn from_millis(millis: i64) -> Self { 186 + Self { 187 + nanos: millis.saturating_mul(NSEC_PER_MSEC), 188 + } 189 + } 190 + 191 + /// Create a new [`Delta`] from a number of seconds. 192 + /// 193 + /// The `secs` can range from -9_223_372_036 to 9_223_372_036. 194 + /// If `secs` is outside this range, `i64::MIN` is used for negative values, 195 + /// and `i64::MAX` is used for positive values due to saturation. 196 + #[inline] 197 + pub const fn from_secs(secs: i64) -> Self { 198 + Self { 199 + nanos: secs.saturating_mul(NSEC_PER_SEC), 200 + } 201 + } 202 + 203 + /// Return `true` if the [`Delta`] spans no time. 204 + #[inline] 205 + pub fn is_zero(self) -> bool { 206 + self.as_nanos() == 0 207 + } 208 + 209 + /// Return `true` if the [`Delta`] spans a negative amount of time. 210 + #[inline] 211 + pub fn is_negative(self) -> bool { 212 + self.as_nanos() < 0 213 + } 214 + 215 + /// Return the number of nanoseconds in the [`Delta`]. 216 + #[inline] 217 + pub const fn as_nanos(self) -> i64 { 218 + self.nanos 219 + } 220 + 221 + /// Return the smallest number of microseconds greater than or equal 222 + /// to the value in the [`Delta`]. 223 + #[inline] 224 + pub const fn as_micros_ceil(self) -> i64 { 225 + self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC 226 + } 227 + 228 + /// Return the number of milliseconds in the [`Delta`]. 229 + #[inline] 230 + pub const fn as_millis(self) -> i64 { 231 + self.as_nanos() / NSEC_PER_MSEC 157 232 } 158 233 }
+19 -5
rust/kernel/time/hrtimer.rs
··· 68 68 //! `start` operation. 69 69 70 70 use super::ClockId; 71 - use crate::{prelude::*, time::Ktime, types::Opaque}; 71 + use crate::{prelude::*, types::Opaque}; 72 72 use core::marker::PhantomData; 73 73 use pin_init::PinInit; 74 + 75 + /// A Rust wrapper around a `ktime_t`. 76 + // NOTE: Ktime is going to be removed when hrtimer is converted to Instant/Delta. 77 + #[repr(transparent)] 78 + #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] 79 + pub struct Ktime { 80 + inner: bindings::ktime_t, 81 + } 82 + 83 + impl Ktime { 84 + /// Returns the number of nanoseconds. 85 + #[inline] 86 + pub fn to_ns(self) -> i64 { 87 + self.inner 88 + } 89 + } 74 90 75 91 /// A timer backed by a C `struct hrtimer`. 76 92 /// ··· 400 384 #[repr(u32)] 401 385 pub enum HrTimerRestart { 402 386 /// Timer should not be restarted. 403 - #[allow(clippy::unnecessary_cast)] 404 - NoRestart = bindings::hrtimer_restart_HRTIMER_NORESTART as u32, 387 + NoRestart = bindings::hrtimer_restart_HRTIMER_NORESTART, 405 388 /// Timer should be restarted. 406 - #[allow(clippy::unnecessary_cast)] 407 - Restart = bindings::hrtimer_restart_HRTIMER_RESTART as u32, 389 + Restart = bindings::hrtimer_restart_HRTIMER_RESTART, 408 390 } 409 391 410 392 impl HrTimerRestart {
+1 -1
rust/kernel/time/hrtimer/arc.rs
··· 5 5 use super::HrTimerCallback; 6 6 use super::HrTimerHandle; 7 7 use super::HrTimerPointer; 8 + use super::Ktime; 8 9 use super::RawHrTimerCallback; 9 10 use crate::sync::Arc; 10 11 use crate::sync::ArcBorrow; 11 - use crate::time::Ktime; 12 12 13 13 /// A handle for an `Arc<HasHrTimer<T>>` returned by a call to 14 14 /// [`HrTimerPointer::start`].
+1 -1
rust/kernel/time/hrtimer/pin.rs
··· 4 4 use super::HrTimer; 5 5 use super::HrTimerCallback; 6 6 use super::HrTimerHandle; 7 + use super::Ktime; 7 8 use super::RawHrTimerCallback; 8 9 use super::UnsafeHrTimerPointer; 9 - use crate::time::Ktime; 10 10 use core::pin::Pin; 11 11 12 12 /// A handle for a `Pin<&HasHrTimer>`. When the handle exists, the timer might be
+2 -2
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, RawHrTimerCallback, UnsafeHrTimerPointer, 4 + HasHrTimer, HrTimer, HrTimerCallback, HrTimerHandle, Ktime, RawHrTimerCallback, 5 + UnsafeHrTimerPointer, 5 6 }; 6 - use crate::time::Ktime; 7 7 use core::{marker::PhantomData, pin::Pin, ptr::NonNull}; 8 8 9 9 /// A handle for a `Pin<&mut HasHrTimer>`. When the handle exists, the timer might
+1 -1
rust/kernel/time/hrtimer/tbox.rs
··· 5 5 use super::HrTimerCallback; 6 6 use super::HrTimerHandle; 7 7 use super::HrTimerPointer; 8 + use super::Ktime; 8 9 use super::RawHrTimerCallback; 9 10 use crate::prelude::*; 10 - use crate::time::Ktime; 11 11 use core::ptr::NonNull; 12 12 13 13 /// A handle for a [`Box<HasHrTimer<T>>`] returned by a call to
+31 -15
rust/kernel/types.rs
··· 18 18 /// 19 19 /// This trait is meant to be used in cases when Rust objects are stored in C objects and 20 20 /// eventually "freed" back to Rust. 21 - pub trait ForeignOwnable: Sized { 21 + /// 22 + /// # Safety 23 + /// 24 + /// Implementers must ensure that [`into_foreign`] returns a pointer which meets the alignment 25 + /// requirements of [`PointedTo`]. 26 + /// 27 + /// [`into_foreign`]: Self::into_foreign 28 + /// [`PointedTo`]: Self::PointedTo 29 + pub unsafe trait ForeignOwnable: Sized { 30 + /// Type used when the value is foreign-owned. In practical terms only defines the alignment of 31 + /// the pointer. 32 + type PointedTo; 33 + 22 34 /// Type used to immutably borrow a value that is currently foreign-owned. 23 35 type Borrowed<'a>; 24 36 ··· 39 27 40 28 /// Converts a Rust-owned object to a foreign-owned one. 41 29 /// 42 - /// The foreign representation is a pointer to void. There are no guarantees for this pointer. 43 - /// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in 44 - /// any way except for [`from_foreign`], [`try_from_foreign`], [`borrow`], or [`borrow_mut`] can 45 - /// result in undefined behavior. 30 + /// # Guarantees 31 + /// 32 + /// The return value is guaranteed to be well-aligned, but there are no other guarantees for 33 + /// this pointer. For example, it might be null, dangling, or point to uninitialized memory. 34 + /// Using it in any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`], 35 + /// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior. 46 36 /// 47 37 /// [`from_foreign`]: Self::from_foreign 48 38 /// [`try_from_foreign`]: Self::try_from_foreign 49 39 /// [`borrow`]: Self::borrow 50 40 /// [`borrow_mut`]: Self::borrow_mut 51 - fn into_foreign(self) -> *mut crate::ffi::c_void; 41 + fn into_foreign(self) -> *mut Self::PointedTo; 52 42 53 43 /// Converts a foreign-owned object back to a Rust-owned one. 54 44 /// ··· 60 46 /// must not be passed to `from_foreign` more than once. 61 47 /// 62 48 /// [`into_foreign`]: Self::into_foreign 63 - unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self; 49 + unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self; 64 50 65 51 /// Tries to convert a foreign-owned object back to a Rust-owned one. 66 52 /// ··· 72 58 /// `ptr` must either be null or satisfy the safety requirements for [`from_foreign`]. 73 59 /// 74 60 /// [`from_foreign`]: Self::from_foreign 75 - unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> { 61 + unsafe fn try_from_foreign(ptr: *mut Self::PointedTo) -> Option<Self> { 76 62 if ptr.is_null() { 77 63 None 78 64 } else { ··· 95 81 /// 96 82 /// [`into_foreign`]: Self::into_foreign 97 83 /// [`from_foreign`]: Self::from_foreign 98 - unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>; 84 + unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> Self::Borrowed<'a>; 99 85 100 86 /// Borrows a foreign-owned object mutably. 101 87 /// ··· 123 109 /// [`from_foreign`]: Self::from_foreign 124 110 /// [`borrow`]: Self::borrow 125 111 /// [`Arc`]: crate::sync::Arc 126 - unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a>; 112 + unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> Self::BorrowedMut<'a>; 127 113 } 128 114 129 - impl ForeignOwnable for () { 115 + // SAFETY: The `into_foreign` function returns a pointer that is dangling, but well-aligned. 116 + unsafe impl ForeignOwnable for () { 117 + type PointedTo = (); 130 118 type Borrowed<'a> = (); 131 119 type BorrowedMut<'a> = (); 132 120 133 - fn into_foreign(self) -> *mut crate::ffi::c_void { 121 + fn into_foreign(self) -> *mut Self::PointedTo { 134 122 core::ptr::NonNull::dangling().as_ptr() 135 123 } 136 124 137 - unsafe fn from_foreign(_: *mut crate::ffi::c_void) -> Self {} 125 + unsafe fn from_foreign(_: *mut Self::PointedTo) -> Self {} 138 126 139 - unsafe fn borrow<'a>(_: *mut crate::ffi::c_void) -> Self::Borrowed<'a> {} 140 - unsafe fn borrow_mut<'a>(_: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a> {} 127 + unsafe fn borrow<'a>(_: *mut Self::PointedTo) -> Self::Borrowed<'a> {} 128 + unsafe fn borrow_mut<'a>(_: *mut Self::PointedTo) -> Self::BorrowedMut<'a> {} 141 129 } 142 130 143 131 /// Runs a cleanup function/closure when dropped.
+2 -4
rust/kernel/uaccess.rs
··· 46 46 /// 47 47 /// ```no_run 48 48 /// use kernel::ffi::c_void; 49 - /// use kernel::error::Result; 50 49 /// use kernel::uaccess::{UserPtr, UserSlice}; 51 50 /// 52 - /// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result<()> { 51 + /// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result { 53 52 /// let (read, mut write) = UserSlice::new(uptr, len).reader_writer(); 54 53 /// 55 54 /// let mut buf = KVec::new(); ··· 67 68 /// 68 69 /// ```no_run 69 70 /// use kernel::ffi::c_void; 70 - /// use kernel::error::{code::EINVAL, Result}; 71 71 /// use kernel::uaccess::{UserPtr, UserSlice}; 72 72 /// 73 73 /// /// Returns whether the data in this region is valid. ··· 288 290 289 291 // SAFETY: Since the call to `read_raw` was successful, so the next `len` bytes of the 290 292 // vector have been initialized. 291 - unsafe { buf.set_len(buf.len() + len) }; 293 + unsafe { buf.inc_len(len) }; 292 294 Ok(()) 293 295 } 294 296 }
+17 -33
rust/kernel/workqueue.rs
··· 429 429 /// 430 430 /// # Safety 431 431 /// 432 - /// The [`OFFSET`] constant must be the offset of a field in `Self` of type [`Work<T, ID>`]. The 433 - /// methods on this trait must have exactly the behavior that the definitions given below have. 432 + /// The methods [`raw_get_work`] and [`work_container_of`] must return valid pointers and must be 433 + /// true inverses of each other; that is, they must satisfy the following invariants: 434 + /// - `work_container_of(raw_get_work(ptr)) == ptr` for any `ptr: *mut Self`. 435 + /// - `raw_get_work(work_container_of(ptr)) == ptr` for any `ptr: *mut Work<T, ID>`. 434 436 /// 435 437 /// [`impl_has_work!`]: crate::impl_has_work 436 - /// [`OFFSET`]: HasWork::OFFSET 438 + /// [`raw_get_work`]: HasWork::raw_get_work 439 + /// [`work_container_of`]: HasWork::work_container_of 437 440 pub unsafe trait HasWork<T, const ID: u64 = 0> { 438 - /// The offset of the [`Work<T, ID>`] field. 439 - const OFFSET: usize; 440 - 441 - /// Returns the offset of the [`Work<T, ID>`] field. 442 - /// 443 - /// This method exists because the [`OFFSET`] constant cannot be accessed if the type is not 444 - /// [`Sized`]. 445 - /// 446 - /// [`OFFSET`]: HasWork::OFFSET 447 - #[inline] 448 - fn get_work_offset(&self) -> usize { 449 - Self::OFFSET 450 - } 451 - 452 441 /// Returns a pointer to the [`Work<T, ID>`] field. 453 442 /// 454 443 /// # Safety 455 444 /// 456 445 /// The provided pointer must point at a valid struct of type `Self`. 457 - #[inline] 458 - unsafe fn raw_get_work(ptr: *mut Self) -> *mut Work<T, ID> { 459 - // SAFETY: The caller promises that the pointer is valid. 460 - unsafe { (ptr as *mut u8).add(Self::OFFSET) as *mut Work<T, ID> } 461 - } 446 + unsafe fn raw_get_work(ptr: *mut Self) -> *mut Work<T, ID>; 462 447 463 448 /// Returns a pointer to the struct containing the [`Work<T, ID>`] field. 464 449 /// 465 450 /// # Safety 466 451 /// 467 452 /// The pointer must point at a [`Work<T, ID>`] field in a struct of type `Self`. 468 - #[inline] 469 - unsafe fn work_container_of(ptr: *mut Work<T, ID>) -> *mut Self 470 - where 471 - Self: Sized, 472 - { 473 - // SAFETY: The caller promises that the pointer points at a field of the right type in the 474 - // right kind of struct. 475 - unsafe { (ptr as *mut u8).sub(Self::OFFSET) as *mut Self } 476 - } 453 + unsafe fn work_container_of(ptr: *mut Work<T, ID>) -> *mut Self; 477 454 } 478 455 479 456 /// Used to safely implement the [`HasWork<T, ID>`] trait. ··· 481 504 // SAFETY: The implementation of `raw_get_work` only compiles if the field has the right 482 505 // type. 483 506 unsafe impl$(<$($generics)+>)? $crate::workqueue::HasWork<$work_type $(, $id)?> for $self { 484 - const OFFSET: usize = ::core::mem::offset_of!(Self, $field) as usize; 485 - 486 507 #[inline] 487 508 unsafe fn raw_get_work(ptr: *mut Self) -> *mut $crate::workqueue::Work<$work_type $(, $id)?> { 488 509 // SAFETY: The caller promises that the pointer is not dangling. 489 510 unsafe { 490 511 ::core::ptr::addr_of_mut!((*ptr).$field) 491 512 } 513 + } 514 + 515 + #[inline] 516 + unsafe fn work_container_of( 517 + ptr: *mut $crate::workqueue::Work<$work_type $(, $id)?>, 518 + ) -> *mut Self { 519 + // SAFETY: The caller promises that the pointer points at a field of the right type 520 + // in the right kind of struct. 521 + unsafe { $crate::container_of!(ptr, Self, $field) } 492 522 } 493 523 } 494 524 )*};
+275
rust/kernel/xarray.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! XArray abstraction. 4 + //! 5 + //! C header: [`include/linux/xarray.h`](srctree/include/linux/xarray.h) 6 + 7 + use crate::{ 8 + alloc, bindings, build_assert, 9 + error::{Error, Result}, 10 + types::{ForeignOwnable, NotThreadSafe, Opaque}, 11 + }; 12 + use core::{iter, marker::PhantomData, mem, pin::Pin, ptr::NonNull}; 13 + use pin_init::{pin_data, pin_init, pinned_drop, PinInit}; 14 + 15 + /// An array which efficiently maps sparse integer indices to owned objects. 16 + /// 17 + /// This is similar to a [`crate::alloc::kvec::Vec<Option<T>>`], but more efficient when there are 18 + /// holes in the index space, and can be efficiently grown. 19 + /// 20 + /// # Invariants 21 + /// 22 + /// `self.xa` is always an initialized and valid [`bindings::xarray`] whose entries are either 23 + /// `XA_ZERO_ENTRY` or came from `T::into_foreign`. 24 + /// 25 + /// # Examples 26 + /// 27 + /// ```rust 28 + /// use kernel::alloc::KBox; 29 + /// use kernel::xarray::{AllocKind, XArray}; 30 + /// 31 + /// let xa = KBox::pin_init(XArray::new(AllocKind::Alloc1), GFP_KERNEL)?; 32 + /// 33 + /// let dead = KBox::new(0xdead, GFP_KERNEL)?; 34 + /// let beef = KBox::new(0xbeef, GFP_KERNEL)?; 35 + /// 36 + /// let mut guard = xa.lock(); 37 + /// 38 + /// assert_eq!(guard.get(0), None); 39 + /// 40 + /// assert_eq!(guard.store(0, dead, GFP_KERNEL)?.as_deref(), None); 41 + /// assert_eq!(guard.get(0).copied(), Some(0xdead)); 42 + /// 43 + /// *guard.get_mut(0).unwrap() = 0xffff; 44 + /// assert_eq!(guard.get(0).copied(), Some(0xffff)); 45 + /// 46 + /// assert_eq!(guard.store(0, beef, GFP_KERNEL)?.as_deref().copied(), Some(0xffff)); 47 + /// assert_eq!(guard.get(0).copied(), Some(0xbeef)); 48 + /// 49 + /// guard.remove(0); 50 + /// assert_eq!(guard.get(0), None); 51 + /// 52 + /// # Ok::<(), Error>(()) 53 + /// ``` 54 + #[pin_data(PinnedDrop)] 55 + pub struct XArray<T: ForeignOwnable> { 56 + #[pin] 57 + xa: Opaque<bindings::xarray>, 58 + _p: PhantomData<T>, 59 + } 60 + 61 + #[pinned_drop] 62 + impl<T: ForeignOwnable> PinnedDrop for XArray<T> { 63 + fn drop(self: Pin<&mut Self>) { 64 + self.iter().for_each(|ptr| { 65 + let ptr = ptr.as_ptr(); 66 + // SAFETY: `ptr` came from `T::into_foreign`. 67 + // 68 + // INVARIANT: we own the only reference to the array which is being dropped so the 69 + // broken invariant is not observable on function exit. 70 + drop(unsafe { T::from_foreign(ptr) }) 71 + }); 72 + 73 + // SAFETY: `self.xa` is always valid by the type invariant. 74 + unsafe { bindings::xa_destroy(self.xa.get()) }; 75 + } 76 + } 77 + 78 + /// Flags passed to [`XArray::new`] to configure the array's allocation tracking behavior. 79 + pub enum AllocKind { 80 + /// Consider the first element to be at index 0. 81 + Alloc, 82 + /// Consider the first element to be at index 1. 83 + Alloc1, 84 + } 85 + 86 + impl<T: ForeignOwnable> XArray<T> { 87 + /// Creates a new initializer for this type. 88 + pub fn new(kind: AllocKind) -> impl PinInit<Self> { 89 + let flags = match kind { 90 + AllocKind::Alloc => bindings::XA_FLAGS_ALLOC, 91 + AllocKind::Alloc1 => bindings::XA_FLAGS_ALLOC1, 92 + }; 93 + pin_init!(Self { 94 + // SAFETY: `xa` is valid while the closure is called. 95 + // 96 + // INVARIANT: `xa` is initialized here to an empty, valid [`bindings::xarray`]. 97 + xa <- Opaque::ffi_init(|xa| unsafe { 98 + bindings::xa_init_flags(xa, flags) 99 + }), 100 + _p: PhantomData, 101 + }) 102 + } 103 + 104 + fn iter(&self) -> impl Iterator<Item = NonNull<T::PointedTo>> + '_ { 105 + let mut index = 0; 106 + 107 + // SAFETY: `self.xa` is always valid by the type invariant. 108 + iter::once(unsafe { 109 + bindings::xa_find(self.xa.get(), &mut index, usize::MAX, bindings::XA_PRESENT) 110 + }) 111 + .chain(iter::from_fn(move || { 112 + // SAFETY: `self.xa` is always valid by the type invariant. 113 + Some(unsafe { 114 + bindings::xa_find_after(self.xa.get(), &mut index, usize::MAX, bindings::XA_PRESENT) 115 + }) 116 + })) 117 + .map_while(|ptr| NonNull::new(ptr.cast())) 118 + } 119 + 120 + /// Attempts to lock the [`XArray`] for exclusive access. 121 + pub fn try_lock(&self) -> Option<Guard<'_, T>> { 122 + // SAFETY: `self.xa` is always valid by the type invariant. 123 + if (unsafe { bindings::xa_trylock(self.xa.get()) } != 0) { 124 + Some(Guard { 125 + xa: self, 126 + _not_send: NotThreadSafe, 127 + }) 128 + } else { 129 + None 130 + } 131 + } 132 + 133 + /// Locks the [`XArray`] for exclusive access. 134 + pub fn lock(&self) -> Guard<'_, T> { 135 + // SAFETY: `self.xa` is always valid by the type invariant. 136 + unsafe { bindings::xa_lock(self.xa.get()) }; 137 + 138 + Guard { 139 + xa: self, 140 + _not_send: NotThreadSafe, 141 + } 142 + } 143 + } 144 + 145 + /// A lock guard. 146 + /// 147 + /// The lock is unlocked when the guard goes out of scope. 148 + #[must_use = "the lock unlocks immediately when the guard is unused"] 149 + pub struct Guard<'a, T: ForeignOwnable> { 150 + xa: &'a XArray<T>, 151 + _not_send: NotThreadSafe, 152 + } 153 + 154 + impl<T: ForeignOwnable> Drop for Guard<'_, T> { 155 + fn drop(&mut self) { 156 + // SAFETY: 157 + // - `self.xa.xa` is always valid by the type invariant. 158 + // - The caller holds the lock, so it is safe to unlock it. 159 + unsafe { bindings::xa_unlock(self.xa.xa.get()) }; 160 + } 161 + } 162 + 163 + /// The error returned by [`store`](Guard::store). 164 + /// 165 + /// Contains the underlying error and the value that was not stored. 166 + pub struct StoreError<T> { 167 + /// The error that occurred. 168 + pub error: Error, 169 + /// The value that was not stored. 170 + pub value: T, 171 + } 172 + 173 + impl<T> From<StoreError<T>> for Error { 174 + fn from(value: StoreError<T>) -> Self { 175 + value.error 176 + } 177 + } 178 + 179 + impl<'a, T: ForeignOwnable> Guard<'a, T> { 180 + fn load<F, U>(&self, index: usize, f: F) -> Option<U> 181 + where 182 + F: FnOnce(NonNull<T::PointedTo>) -> U, 183 + { 184 + // SAFETY: `self.xa.xa` is always valid by the type invariant. 185 + let ptr = unsafe { bindings::xa_load(self.xa.xa.get(), index) }; 186 + let ptr = NonNull::new(ptr.cast())?; 187 + Some(f(ptr)) 188 + } 189 + 190 + /// Provides a reference to the element at the given index. 191 + pub fn get(&self, index: usize) -> Option<T::Borrowed<'_>> { 192 + self.load(index, |ptr| { 193 + // SAFETY: `ptr` came from `T::into_foreign`. 194 + unsafe { T::borrow(ptr.as_ptr()) } 195 + }) 196 + } 197 + 198 + /// Provides a mutable reference to the element at the given index. 199 + pub fn get_mut(&mut self, index: usize) -> Option<T::BorrowedMut<'_>> { 200 + self.load(index, |ptr| { 201 + // SAFETY: `ptr` came from `T::into_foreign`. 202 + unsafe { T::borrow_mut(ptr.as_ptr()) } 203 + }) 204 + } 205 + 206 + /// Removes and returns the element at the given index. 207 + pub fn remove(&mut self, index: usize) -> Option<T> { 208 + // SAFETY: 209 + // - `self.xa.xa` is always valid by the type invariant. 210 + // - The caller holds the lock. 211 + let ptr = unsafe { bindings::__xa_erase(self.xa.xa.get(), index) }.cast(); 212 + // SAFETY: 213 + // - `ptr` is either NULL or came from `T::into_foreign`. 214 + // - `&mut self` guarantees that the lifetimes of [`T::Borrowed`] and [`T::BorrowedMut`] 215 + // borrowed from `self` have ended. 216 + unsafe { T::try_from_foreign(ptr) } 217 + } 218 + 219 + /// Stores an element at the given index. 220 + /// 221 + /// May drop the lock if needed to allocate memory, and then reacquire it afterwards. 222 + /// 223 + /// On success, returns the element which was previously at the given index. 224 + /// 225 + /// On failure, returns the element which was attempted to be stored. 226 + pub fn store( 227 + &mut self, 228 + index: usize, 229 + value: T, 230 + gfp: alloc::Flags, 231 + ) -> Result<Option<T>, StoreError<T>> { 232 + build_assert!( 233 + mem::align_of::<T::PointedTo>() >= 4, 234 + "pointers stored in XArray must be 4-byte aligned" 235 + ); 236 + let new = value.into_foreign(); 237 + 238 + let old = { 239 + let new = new.cast(); 240 + // SAFETY: 241 + // - `self.xa.xa` is always valid by the type invariant. 242 + // - The caller holds the lock. 243 + // 244 + // INVARIANT: `new` came from `T::into_foreign`. 245 + unsafe { bindings::__xa_store(self.xa.xa.get(), index, new, gfp.as_raw()) } 246 + }; 247 + 248 + // SAFETY: `__xa_store` returns the old entry at this index on success or `xa_err` if an 249 + // error happened. 250 + let errno = unsafe { bindings::xa_err(old) }; 251 + if errno != 0 { 252 + // SAFETY: `new` came from `T::into_foreign` and `__xa_store` does not take 253 + // ownership of the value on error. 254 + let value = unsafe { T::from_foreign(new) }; 255 + Err(StoreError { 256 + value, 257 + error: Error::from_errno(errno), 258 + }) 259 + } else { 260 + let old = old.cast(); 261 + // SAFETY: `ptr` is either NULL or came from `T::into_foreign`. 262 + // 263 + // NB: `XA_ZERO_ENTRY` is never returned by functions belonging to the Normal XArray 264 + // API; such entries present as `NULL`. 265 + Ok(unsafe { T::try_from_foreign(old) }) 266 + } 267 + } 268 + } 269 + 270 + // SAFETY: `XArray<T>` has no shared mutable state so it is `Send` iff `T` is `Send`. 271 + unsafe impl<T: ForeignOwnable + Send> Send for XArray<T> {} 272 + 273 + // SAFETY: `XArray<T>` serialises the interior mutability it provides so it is `Sync` iff `T` is 274 + // `Send`. 275 + unsafe impl<T: ForeignOwnable + Send> Sync for XArray<T> {}
+17
rust/macros/helpers.rs
··· 86 86 } 87 87 None 88 88 } 89 + 90 + pub(crate) fn file() -> String { 91 + #[cfg(not(CONFIG_RUSTC_HAS_SPAN_FILE))] 92 + { 93 + proc_macro::Span::call_site() 94 + .source_file() 95 + .path() 96 + .to_string_lossy() 97 + .into_owned() 98 + } 99 + 100 + #[cfg(CONFIG_RUSTC_HAS_SPAN_FILE)] 101 + #[allow(clippy::incompatible_msrv)] 102 + { 103 + proc_macro::Span::call_site().file() 104 + } 105 + }
+42 -16
rust/macros/kunit.rs
··· 57 57 } 58 58 } 59 59 60 - // Add `#[cfg(CONFIG_KUNIT)]` before the module declaration. 61 - let config_kunit = "#[cfg(CONFIG_KUNIT)]".to_owned().parse().unwrap(); 60 + // Add `#[cfg(CONFIG_KUNIT="y")]` before the module declaration. 61 + let config_kunit = "#[cfg(CONFIG_KUNIT=\"y\")]".to_owned().parse().unwrap(); 62 62 tokens.insert( 63 63 0, 64 64 TokenTree::Group(Group::new(Delimiter::None, config_kunit)), ··· 85 85 // Looks like: 86 86 // 87 87 // ``` 88 - // unsafe extern "C" fn kunit_rust_wrapper_foo(_test: *mut kernel::bindings::kunit) { foo(); } 89 - // unsafe extern "C" fn kunit_rust_wrapper_bar(_test: *mut kernel::bindings::kunit) { bar(); } 88 + // unsafe extern "C" fn kunit_rust_wrapper_foo(_test: *mut ::kernel::bindings::kunit) { foo(); } 89 + // unsafe extern "C" fn kunit_rust_wrapper_bar(_test: *mut ::kernel::bindings::kunit) { bar(); } 90 90 // 91 - // static mut TEST_CASES: [kernel::bindings::kunit_case; 3] = [ 92 - // kernel::kunit::kunit_case(kernel::c_str!("foo"), kunit_rust_wrapper_foo), 93 - // kernel::kunit::kunit_case(kernel::c_str!("bar"), kunit_rust_wrapper_bar), 94 - // kernel::kunit::kunit_case_null(), 91 + // static mut TEST_CASES: [::kernel::bindings::kunit_case; 3] = [ 92 + // ::kernel::kunit::kunit_case(::kernel::c_str!("foo"), kunit_rust_wrapper_foo), 93 + // ::kernel::kunit::kunit_case(::kernel::c_str!("bar"), kunit_rust_wrapper_bar), 94 + // ::kernel::kunit::kunit_case_null(), 95 95 // ]; 96 96 // 97 - // kernel::kunit_unsafe_test_suite!(kunit_test_suit_name, TEST_CASES); 97 + // ::kernel::kunit_unsafe_test_suite!(kunit_test_suit_name, TEST_CASES); 98 98 // ``` 99 99 let mut kunit_macros = "".to_owned(); 100 100 let mut test_cases = "".to_owned(); 101 + let mut assert_macros = "".to_owned(); 102 + let path = crate::helpers::file(); 101 103 for test in &tests { 102 104 let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{test}"); 105 + // An extra `use` is used here to reduce the length of the message. 103 106 let kunit_wrapper = format!( 104 - "unsafe extern \"C\" fn {kunit_wrapper_fn_name}(_test: *mut kernel::bindings::kunit) {{ {test}(); }}" 107 + "unsafe extern \"C\" fn {kunit_wrapper_fn_name}(_test: *mut ::kernel::bindings::kunit) {{ use ::kernel::kunit::is_test_result_ok; assert!(is_test_result_ok({test}())); }}", 105 108 ); 106 109 writeln!(kunit_macros, "{kunit_wrapper}").unwrap(); 107 110 writeln!( 108 111 test_cases, 109 - " kernel::kunit::kunit_case(kernel::c_str!(\"{test}\"), {kunit_wrapper_fn_name})," 112 + " ::kernel::kunit::kunit_case(::kernel::c_str!(\"{test}\"), {kunit_wrapper_fn_name})," 113 + ) 114 + .unwrap(); 115 + writeln!( 116 + assert_macros, 117 + r#" 118 + /// Overrides the usual [`assert!`] macro with one that calls KUnit instead. 119 + #[allow(unused)] 120 + macro_rules! assert {{ 121 + ($cond:expr $(,)?) => {{{{ 122 + kernel::kunit_assert!("{test}", "{path}", 0, $cond); 123 + }}}} 124 + }} 125 + 126 + /// Overrides the usual [`assert_eq!`] macro with one that calls KUnit instead. 127 + #[allow(unused)] 128 + macro_rules! assert_eq {{ 129 + ($left:expr, $right:expr $(,)?) => {{{{ 130 + kernel::kunit_assert_eq!("{test}", "{path}", 0, $left, $right); 131 + }}}} 132 + }} 133 + "# 110 134 ) 111 135 .unwrap(); 112 136 } ··· 138 114 writeln!(kunit_macros).unwrap(); 139 115 writeln!( 140 116 kunit_macros, 141 - "static mut TEST_CASES: [kernel::bindings::kunit_case; {}] = [\n{test_cases} kernel::kunit::kunit_case_null(),\n];", 117 + "static mut TEST_CASES: [::kernel::bindings::kunit_case; {}] = [\n{test_cases} ::kernel::kunit::kunit_case_null(),\n];", 142 118 tests.len() + 1 143 119 ) 144 120 .unwrap(); 145 121 146 122 writeln!( 147 123 kunit_macros, 148 - "kernel::kunit_unsafe_test_suite!({attr}, TEST_CASES);" 124 + "::kernel::kunit_unsafe_test_suite!({attr}, TEST_CASES);" 149 125 ) 150 126 .unwrap(); 151 127 ··· 171 147 } 172 148 } 173 149 174 - let mut new_body = TokenStream::from_iter(new_body); 175 - new_body.extend::<TokenStream>(kunit_macros.parse().unwrap()); 150 + let mut final_body = TokenStream::new(); 151 + final_body.extend::<TokenStream>(assert_macros.parse().unwrap()); 152 + final_body.extend(new_body); 153 + final_body.extend::<TokenStream>(kunit_macros.parse().unwrap()); 176 154 177 - tokens.push(TokenTree::Group(Group::new(Delimiter::Brace, new_body))); 155 + tokens.push(TokenTree::Group(Group::new(Delimiter::Brace, final_body))); 178 156 179 157 tokens.into_iter().collect() 180 158 }
+10 -5
rust/macros/lib.rs
··· 6 6 // and thus add a dependency on `include/config/RUSTC_VERSION_TEXT`, which is 7 7 // touched by Kconfig when the version string from the compiler changes. 8 8 9 + // Stable since Rust 1.88.0 under a different name, `proc_macro_span_file`, 10 + // which was added in Rust 1.88.0. This is why `cfg_attr` is used here, i.e. 11 + // to avoid depending on the full `proc_macro_span` on Rust >= 1.88.0. 12 + #![cfg_attr(not(CONFIG_RUSTC_HAS_SPAN_FILE), feature(proc_macro_span))] 13 + 9 14 #[macro_use] 10 15 mod quote; 11 16 mod concat_idents; ··· 268 263 /// literals (lifetimes and documentation strings are not supported). There is a difference in 269 264 /// supported modifiers as well. 270 265 /// 271 - /// # Example 266 + /// # Examples 272 267 /// 273 268 /// ``` 274 269 /// # const binder_driver_return_protocol_BR_OK: u32 = 0; ··· 288 283 /// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14; 289 284 /// macro_rules! pub_no_prefix { 290 285 /// ($prefix:ident, $($newname:ident),+) => { 291 - /// kernel::macros::paste! { 286 + /// ::kernel::macros::paste! { 292 287 /// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+ 293 288 /// } 294 289 /// }; ··· 345 340 /// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14; 346 341 /// macro_rules! pub_no_prefix { 347 342 /// ($prefix:ident, $($newname:ident),+) => { 348 - /// kernel::macros::paste! { 343 + /// ::kernel::macros::paste! { 349 344 /// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+ 350 345 /// } 351 346 /// }; ··· 380 375 /// ``` 381 376 /// macro_rules! create_numbered_fn { 382 377 /// ($name:literal, $val:literal) => { 383 - /// kernel::macros::paste! { 378 + /// ::kernel::macros::paste! { 384 379 /// fn [<some_ $name _fn $val>]() -> u32 { $val } 385 380 /// } 386 381 /// }; ··· 407 402 /// # Examples 408 403 /// 409 404 /// ```ignore 410 - /// # use macros::kunit_tests; 405 + /// # use kernel::prelude::*; 411 406 /// #[kunit_tests(kunit_test_suit_name)] 412 407 /// mod tests { 413 408 /// #[test]
+16 -15
rust/macros/module.rs
··· 217 217 // SAFETY: `__this_module` is constructed by the kernel at load time and will not be 218 218 // freed until the module is unloaded. 219 219 #[cfg(MODULE)] 220 - static THIS_MODULE: kernel::ThisModule = unsafe {{ 220 + static THIS_MODULE: ::kernel::ThisModule = unsafe {{ 221 221 extern \"C\" {{ 222 - static __this_module: kernel::types::Opaque<kernel::bindings::module>; 222 + static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>; 223 223 }} 224 224 225 - kernel::ThisModule::from_ptr(__this_module.get()) 225 + ::kernel::ThisModule::from_ptr(__this_module.get()) 226 226 }}; 227 227 #[cfg(not(MODULE))] 228 - static THIS_MODULE: kernel::ThisModule = unsafe {{ 229 - kernel::ThisModule::from_ptr(core::ptr::null_mut()) 228 + static THIS_MODULE: ::kernel::ThisModule = unsafe {{ 229 + ::kernel::ThisModule::from_ptr(::core::ptr::null_mut()) 230 230 }}; 231 231 232 232 /// The `LocalModule` type is the type of the module created by `module!`, 233 233 /// `module_pci_driver!`, `module_platform_driver!`, etc. 234 234 type LocalModule = {type_}; 235 235 236 - impl kernel::ModuleMetadata for {type_} {{ 237 - const NAME: &'static kernel::str::CStr = kernel::c_str!(\"{name}\"); 236 + impl ::kernel::ModuleMetadata for {type_} {{ 237 + const NAME: &'static ::kernel::str::CStr = ::kernel::c_str!(\"{name}\"); 238 238 }} 239 239 240 240 // Double nested modules, since then nobody can access the public items inside. ··· 252 252 #[used] 253 253 static __IS_RUST_MODULE: () = (); 254 254 255 - static mut __MOD: core::mem::MaybeUninit<{type_}> = 256 - core::mem::MaybeUninit::uninit(); 255 + static mut __MOD: ::core::mem::MaybeUninit<{type_}> = 256 + ::core::mem::MaybeUninit::uninit(); 257 257 258 258 // Loadable modules need to export the `{{init,cleanup}}_module` identifiers. 259 259 /// # Safety ··· 264 264 #[doc(hidden)] 265 265 #[no_mangle] 266 266 #[link_section = \".init.text\"] 267 - pub unsafe extern \"C\" fn init_module() -> kernel::ffi::c_int {{ 267 + pub unsafe extern \"C\" fn init_module() -> ::kernel::ffi::c_int {{ 268 268 // SAFETY: This function is inaccessible to the outside due to the double 269 269 // module wrapping it. It is called exactly once by the C side via its 270 270 // unique name. ··· 280 280 #[cfg(MODULE)] 281 281 #[doc(hidden)] 282 282 #[no_mangle] 283 + #[link_section = \".exit.text\"] 283 284 pub extern \"C\" fn cleanup_module() {{ 284 285 // SAFETY: 285 286 // - This function is inaccessible to the outside due to the double ··· 305 304 #[link_section = \"{initcall_section}\"] 306 305 #[used] 307 306 pub static __{ident}_initcall: extern \"C\" fn() -> 308 - kernel::ffi::c_int = __{ident}_init; 307 + ::kernel::ffi::c_int = __{ident}_init; 309 308 310 309 #[cfg(not(MODULE))] 311 310 #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] 312 - core::arch::global_asm!( 311 + ::core::arch::global_asm!( 313 312 r#\".section \"{initcall_section}\", \"a\" 314 313 __{ident}_initcall: 315 314 .long __{ident}_init - . ··· 320 319 #[cfg(not(MODULE))] 321 320 #[doc(hidden)] 322 321 #[no_mangle] 323 - pub extern \"C\" fn __{ident}_init() -> kernel::ffi::c_int {{ 322 + pub extern \"C\" fn __{ident}_init() -> ::kernel::ffi::c_int {{ 324 323 // SAFETY: This function is inaccessible to the outside due to the double 325 324 // module wrapping it. It is called exactly once by the C side via its 326 325 // placement above in the initcall section. ··· 343 342 /// # Safety 344 343 /// 345 344 /// This function must only be called once. 346 - unsafe fn __init() -> kernel::ffi::c_int {{ 345 + unsafe fn __init() -> ::kernel::ffi::c_int {{ 347 346 let initer = 348 - <{type_} as kernel::InPlaceModule>::init(&super::super::THIS_MODULE); 347 + <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE); 349 348 // SAFETY: No data race, since `__MOD` can only be accessed by this module 350 349 // and there only `__init` and `__exit` access it. These functions are only 351 350 // called once and `__exit` cannot be called before or during `__init`.
+11 -3
rust/pin-init/README.md
··· 40 40 will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std 41 41 mode. 42 42 43 + ### Nightly needed for `unsafe-pinned` feature 44 + 45 + This feature enables the `Wrapper` implementation on the unstable `core::pin::UnsafePinned` type. 46 + This requires the [`unsafe_pinned` unstable feature](https://github.com/rust-lang/rust/issues/125735) 47 + and therefore a nightly compiler. Note that this feature is not enabled by default. 48 + 43 49 ## Overview 44 50 45 51 To initialize a `struct` with an in-place constructor you will need two things: ··· 222 216 223 217 [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html 224 218 [pinning]: https://doc.rust-lang.org/std/pin/index.html 225 - [structurally pinned fields]: https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field 219 + [structurally pinned fields]: https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning 226 220 [stack]: https://docs.rs/pin-init/latest/pin_init/macro.stack_pin_init.html 227 - [`Arc<T>`]: https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html 228 - [`Box<T>`]: https://doc.rust-lang.org/stable/alloc/boxed/struct.Box.html 229 221 [`impl PinInit<Foo>`]: https://docs.rs/pin-init/latest/pin_init/trait.PinInit.html 230 222 [`impl PinInit<T, E>`]: https://docs.rs/pin-init/latest/pin_init/trait.PinInit.html 231 223 [`impl Init<T, E>`]: https://docs.rs/pin-init/latest/pin_init/trait.Init.html 232 224 [Rust-for-Linux]: https://rust-for-linux.com/ 233 225 234 226 <!-- cargo-rdme end --> 227 + 228 + <!-- These links are not picked up by cargo-rdme, since they are behind cfgs... --> 229 + [`Arc<T>`]: https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html 230 + [`Box<T>`]: https://doc.rust-lang.org/stable/alloc/boxed/struct.Box.html
+1
rust/pin-init/examples/linked_list.rs
··· 2 2 3 3 #![allow(clippy::undocumented_unsafe_blocks)] 4 4 #![cfg_attr(feature = "alloc", feature(allocator_api))] 5 + #![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] 5 6 6 7 use core::{ 7 8 cell::Cell,
+1
rust/pin-init/examples/mutex.rs
··· 2 2 3 3 #![allow(clippy::undocumented_unsafe_blocks)] 4 4 #![cfg_attr(feature = "alloc", feature(allocator_api))] 5 + #![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] 5 6 #![allow(clippy::missing_safety_doc)] 6 7 7 8 use core::{
+3 -1
rust/pin-init/examples/pthread_mutex.rs
··· 3 3 // inspired by <https://github.com/nbdd0121/pin-init/blob/trunk/examples/pthread_mutex.rs> 4 4 #![allow(clippy::undocumented_unsafe_blocks)] 5 5 #![cfg_attr(feature = "alloc", feature(allocator_api))] 6 + #![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] 7 + 6 8 #[cfg(not(windows))] 7 9 mod pthread_mtx { 8 10 #[cfg(feature = "alloc")] ··· 42 40 43 41 #[derive(Debug)] 44 42 pub enum Error { 45 - #[expect(dead_code)] 43 + #[allow(dead_code)] 46 44 IO(std::io::Error), 47 45 Alloc, 48 46 }
+1
rust/pin-init/examples/static_init.rs
··· 2 2 3 3 #![allow(clippy::undocumented_unsafe_blocks)] 4 4 #![cfg_attr(feature = "alloc", feature(allocator_api))] 5 + #![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] 5 6 6 7 use core::{ 7 8 cell::{Cell, UnsafeCell},
+6
rust/pin-init/internal/src/lib.rs
··· 22 22 #[cfg(kernel)] 23 23 #[path = "../../../macros/quote.rs"] 24 24 #[macro_use] 25 + #[cfg_attr(not(kernel), rustfmt::skip)] 25 26 mod quote; 26 27 #[cfg(not(kernel))] 27 28 #[macro_use] ··· 46 45 #[proc_macro_derive(Zeroable)] 47 46 pub fn derive_zeroable(input: TokenStream) -> TokenStream { 48 47 zeroable::derive(input.into()).into() 48 + } 49 + 50 + #[proc_macro_derive(MaybeZeroable)] 51 + pub fn maybe_derive_zeroable(input: TokenStream) -> TokenStream { 52 + zeroable::maybe_derive(input.into()).into() 49 53 }
+26 -1
rust/pin-init/internal/src/zeroable.rs
··· 6 6 use crate::helpers::{parse_generics, Generics}; 7 7 use proc_macro::{TokenStream, TokenTree}; 8 8 9 - pub(crate) fn derive(input: TokenStream) -> TokenStream { 9 + pub(crate) fn parse_zeroable_derive_input( 10 + input: TokenStream, 11 + ) -> ( 12 + Vec<TokenTree>, 13 + Vec<TokenTree>, 14 + Vec<TokenTree>, 15 + Option<TokenTree>, 16 + ) { 10 17 let ( 11 18 Generics { 12 19 impl_generics, ··· 71 64 if in_generic && !inserted { 72 65 new_impl_generics.extend(quote! { : ::pin_init::Zeroable }); 73 66 } 67 + (rest, new_impl_generics, ty_generics, last) 68 + } 69 + 70 + pub(crate) fn derive(input: TokenStream) -> TokenStream { 71 + let (rest, new_impl_generics, ty_generics, last) = parse_zeroable_derive_input(input); 74 72 quote! { 75 73 ::pin_init::__derive_zeroable!( 74 + parse_input: 75 + @sig(#(#rest)*), 76 + @impl_generics(#(#new_impl_generics)*), 77 + @ty_generics(#(#ty_generics)*), 78 + @body(#last), 79 + ); 80 + } 81 + } 82 + 83 + pub(crate) fn maybe_derive(input: TokenStream) -> TokenStream { 84 + let (rest, new_impl_generics, ty_generics, last) = parse_zeroable_derive_input(input); 85 + quote! { 86 + ::pin_init::__maybe_derive_zeroable!( 76 87 parse_input: 77 88 @sig(#(#rest)*), 78 89 @impl_generics(#(#new_impl_generics)*),
+140 -4
rust/pin-init/src/lib.rs
··· 32 32 //! will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std 33 33 //! mode. 34 34 //! 35 + //! ## Nightly needed for `unsafe-pinned` feature 36 + //! 37 + //! This feature enables the `Wrapper` implementation on the unstable `core::pin::UnsafePinned` type. 38 + //! This requires the [`unsafe_pinned` unstable feature](https://github.com/rust-lang/rust/issues/125735) 39 + //! and therefore a nightly compiler. Note that this feature is not enabled by default. 40 + //! 35 41 //! # Overview 36 42 //! 37 43 //! To initialize a `struct` with an in-place constructor you will need two things: ··· 247 241 //! [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html 248 242 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html 249 243 //! [structurally pinned fields]: 250 - //! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field 244 + //! https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning 251 245 //! [stack]: crate::stack_pin_init 252 246 #![cfg_attr( 253 247 kernel, ··· 275 269 #![forbid(missing_docs, unsafe_op_in_unsafe_fn)] 276 270 #![cfg_attr(not(feature = "std"), no_std)] 277 271 #![cfg_attr(feature = "alloc", feature(allocator_api))] 272 + #![cfg_attr( 273 + all(feature = "unsafe-pinned", CONFIG_RUSTC_HAS_UNSAFE_PINNED), 274 + feature(unsafe_pinned) 275 + )] 278 276 279 277 use core::{ 280 278 cell::UnsafeCell, ··· 395 385 /// ``` 396 386 pub use ::pin_init_internal::pinned_drop; 397 387 398 - /// Derives the [`Zeroable`] trait for the given struct. 388 + /// Derives the [`Zeroable`] trait for the given `struct` or `union`. 399 389 /// 400 - /// This can only be used for structs where every field implements the [`Zeroable`] trait. 390 + /// This can only be used for `struct`s/`union`s where every field implements the [`Zeroable`] 391 + /// trait. 401 392 /// 402 393 /// # Examples 403 394 /// ··· 407 396 /// 408 397 /// #[derive(Zeroable)] 409 398 /// pub struct DriverData { 410 - /// id: i64, 399 + /// pub(crate) id: i64, 411 400 /// buf_ptr: *mut u8, 412 401 /// len: usize, 413 402 /// } 414 403 /// ``` 404 + /// 405 + /// ``` 406 + /// use pin_init::Zeroable; 407 + /// 408 + /// #[derive(Zeroable)] 409 + /// pub union SignCast { 410 + /// signed: i64, 411 + /// unsigned: u64, 412 + /// } 413 + /// ``` 415 414 pub use ::pin_init_internal::Zeroable; 415 + 416 + /// Derives the [`Zeroable`] trait for the given `struct` or `union` if all fields implement 417 + /// [`Zeroable`]. 418 + /// 419 + /// Contrary to the derive macro named [`macro@Zeroable`], this one silently fails when a field 420 + /// doesn't implement [`Zeroable`]. 421 + /// 422 + /// # Examples 423 + /// 424 + /// ``` 425 + /// use pin_init::MaybeZeroable; 426 + /// 427 + /// // implmements `Zeroable` 428 + /// #[derive(MaybeZeroable)] 429 + /// pub struct DriverData { 430 + /// pub(crate) id: i64, 431 + /// buf_ptr: *mut u8, 432 + /// len: usize, 433 + /// } 434 + /// 435 + /// // does not implmement `Zeroable` 436 + /// #[derive(MaybeZeroable)] 437 + /// pub struct DriverData2 { 438 + /// pub(crate) id: i64, 439 + /// buf_ptr: *mut u8, 440 + /// len: usize, 441 + /// // this field doesn't implement `Zeroable` 442 + /// other_data: &'static i32, 443 + /// } 444 + /// ``` 445 + pub use ::pin_init_internal::MaybeZeroable; 416 446 417 447 /// Initialize and pin a type directly on the stack. 418 448 /// ··· 1268 1216 __internal::InitClosure(f, PhantomData) 1269 1217 } 1270 1218 1219 + /// Changes the to be initialized type. 1220 + /// 1221 + /// # Safety 1222 + /// 1223 + /// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a 1224 + /// pointer must result in a valid `U`. 1225 + #[expect(clippy::let_and_return)] 1226 + pub const unsafe fn cast_pin_init<T, U, E>(init: impl PinInit<T, E>) -> impl PinInit<U, E> { 1227 + // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety 1228 + // requirements. 1229 + let res = unsafe { pin_init_from_closure(|ptr: *mut U| init.__pinned_init(ptr.cast::<T>())) }; 1230 + // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a 1231 + // cycle when computing the type returned by this function) 1232 + res 1233 + } 1234 + 1235 + /// Changes the to be initialized type. 1236 + /// 1237 + /// # Safety 1238 + /// 1239 + /// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a 1240 + /// pointer must result in a valid `U`. 1241 + #[expect(clippy::let_and_return)] 1242 + pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> { 1243 + // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety 1244 + // requirements. 1245 + let res = unsafe { init_from_closure(|ptr: *mut U| init.__init(ptr.cast::<T>())) }; 1246 + // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a 1247 + // cycle when computing the type returned by this function) 1248 + res 1249 + } 1250 + 1271 1251 /// An initializer that leaves the memory uninitialized. 1272 1252 /// 1273 1253 /// The initializer is a no-op. The `slot` memory is not changed. ··· 1565 1481 } 1566 1482 1567 1483 impl_tuple_zeroable!(A, B, C, D, E, F, G, H, I, J); 1484 + 1485 + /// This trait allows creating an instance of `Self` which contains exactly one 1486 + /// [structurally pinned value](https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning). 1487 + /// 1488 + /// This is useful when using wrapper `struct`s like [`UnsafeCell`] or with new-type `struct`s. 1489 + /// 1490 + /// # Examples 1491 + /// 1492 + /// ``` 1493 + /// # use core::cell::UnsafeCell; 1494 + /// # use pin_init::{pin_data, pin_init, Wrapper}; 1495 + /// 1496 + /// #[pin_data] 1497 + /// struct Foo {} 1498 + /// 1499 + /// #[pin_data] 1500 + /// struct Bar { 1501 + /// #[pin] 1502 + /// content: UnsafeCell<Foo> 1503 + /// }; 1504 + /// 1505 + /// let foo_initializer = pin_init!(Foo{}); 1506 + /// let initializer = pin_init!(Bar { 1507 + /// content <- UnsafeCell::pin_init(foo_initializer) 1508 + /// }); 1509 + /// ``` 1510 + pub trait Wrapper<T> { 1511 + /// Creates an pin-initializer for a [`Self`] containing `T` from the `value_init` initializer. 1512 + fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E>; 1513 + } 1514 + 1515 + impl<T> Wrapper<T> for UnsafeCell<T> { 1516 + fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> { 1517 + // SAFETY: `UnsafeCell<T>` has a compatible layout to `T`. 1518 + unsafe { cast_pin_init(value_init) } 1519 + } 1520 + } 1521 + 1522 + impl<T> Wrapper<T> for MaybeUninit<T> { 1523 + fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> { 1524 + // SAFETY: `MaybeUninit<T>` has a compatible layout to `T`. 1525 + unsafe { cast_pin_init(value_init) } 1526 + } 1527 + } 1528 + 1529 + #[cfg(all(feature = "unsafe-pinned", CONFIG_RUSTC_HAS_UNSAFE_PINNED))] 1530 + impl<T> Wrapper<T> for core::pin::UnsafePinned<T> { 1531 + fn pin_init<E>(init: impl PinInit<T, E>) -> impl PinInit<Self, E> { 1532 + // SAFETY: `UnsafePinned<T>` has a compatible layout to `T`. 1533 + unsafe { cast_pin_init(init) } 1534 + } 1535 + }
+90 -1
rust/pin-init/src/macros.rs
··· 1393 1393 @body({ 1394 1394 $( 1395 1395 $(#[$($field_attr:tt)*])* 1396 - $field:ident : $field_ty:ty 1396 + $field_vis:vis $field:ident : $field_ty:ty 1397 1397 ),* $(,)? 1398 1398 }), 1399 1399 ) => { ··· 1411 1411 $(assert_zeroable::<$field_ty>();)* 1412 1412 } 1413 1413 }; 1414 + }; 1415 + (parse_input: 1416 + @sig( 1417 + $(#[$($struct_attr:tt)*])* 1418 + $vis:vis union $name:ident 1419 + $(where $($whr:tt)*)? 1420 + ), 1421 + @impl_generics($($impl_generics:tt)*), 1422 + @ty_generics($($ty_generics:tt)*), 1423 + @body({ 1424 + $( 1425 + $(#[$($field_attr:tt)*])* 1426 + $field_vis:vis $field:ident : $field_ty:ty 1427 + ),* $(,)? 1428 + }), 1429 + ) => { 1430 + // SAFETY: Every field type implements `Zeroable` and padding bytes may be zero. 1431 + #[automatically_derived] 1432 + unsafe impl<$($impl_generics)*> $crate::Zeroable for $name<$($ty_generics)*> 1433 + where 1434 + $($($whr)*)? 1435 + {} 1436 + const _: () = { 1437 + fn assert_zeroable<T: ?::core::marker::Sized + $crate::Zeroable>() {} 1438 + fn ensure_zeroable<$($impl_generics)*>() 1439 + where $($($whr)*)? 1440 + { 1441 + $(assert_zeroable::<$field_ty>();)* 1442 + } 1443 + }; 1444 + }; 1445 + } 1446 + 1447 + #[doc(hidden)] 1448 + #[macro_export] 1449 + macro_rules! __maybe_derive_zeroable { 1450 + (parse_input: 1451 + @sig( 1452 + $(#[$($struct_attr:tt)*])* 1453 + $vis:vis struct $name:ident 1454 + $(where $($whr:tt)*)? 1455 + ), 1456 + @impl_generics($($impl_generics:tt)*), 1457 + @ty_generics($($ty_generics:tt)*), 1458 + @body({ 1459 + $( 1460 + $(#[$($field_attr:tt)*])* 1461 + $field_vis:vis $field:ident : $field_ty:ty 1462 + ),* $(,)? 1463 + }), 1464 + ) => { 1465 + // SAFETY: Every field type implements `Zeroable` and padding bytes may be zero. 1466 + #[automatically_derived] 1467 + unsafe impl<$($impl_generics)*> $crate::Zeroable for $name<$($ty_generics)*> 1468 + where 1469 + $( 1470 + // the `for<'__dummy>` HRTB makes this not error without the `trivial_bounds` 1471 + // feature <https://github.com/rust-lang/rust/issues/48214#issuecomment-2557829956>. 1472 + $field_ty: for<'__dummy> $crate::Zeroable, 1473 + )* 1474 + $($($whr)*)? 1475 + {} 1476 + }; 1477 + (parse_input: 1478 + @sig( 1479 + $(#[$($struct_attr:tt)*])* 1480 + $vis:vis union $name:ident 1481 + $(where $($whr:tt)*)? 1482 + ), 1483 + @impl_generics($($impl_generics:tt)*), 1484 + @ty_generics($($ty_generics:tt)*), 1485 + @body({ 1486 + $( 1487 + $(#[$($field_attr:tt)*])* 1488 + $field_vis:vis $field:ident : $field_ty:ty 1489 + ),* $(,)? 1490 + }), 1491 + ) => { 1492 + // SAFETY: Every field type implements `Zeroable` and padding bytes may be zero. 1493 + #[automatically_derived] 1494 + unsafe impl<$($impl_generics)*> $crate::Zeroable for $name<$($ty_generics)*> 1495 + where 1496 + $( 1497 + // the `for<'__dummy>` HRTB makes this not error without the `trivial_bounds` 1498 + // feature <https://github.com/rust-lang/rust/issues/48214#issuecomment-2557829956>. 1499 + $field_ty: for<'__dummy> $crate::Zeroable, 1500 + )* 1501 + $($($whr)*)? 1502 + {} 1414 1503 }; 1415 1504 }
+9
scripts/Makefile.build
··· 222 222 # Compile Rust sources (.rs) 223 223 # --------------------------------------------------------------------------- 224 224 225 + # The features in this list are the ones allowed for non-`rust/` code. 226 + # 227 + # - Stable since Rust 1.81.0: `feature(lint_reasons)`. 228 + # - Stable since Rust 1.82.0: `feature(asm_const)`, `feature(raw_ref_op)`. 229 + # - Stable since Rust 1.87.0: `feature(asm_goto)`. 230 + # - Expected to become stable: `feature(arbitrary_self_types)`. 231 + # 232 + # Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on 233 + # the unstable features in use. 225 234 rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,raw_ref_op 226 235 227 236 # `--out-dir` is required to avoid temporaries being created by `rustc` in the
+8 -5
scripts/generate_rust_analyzer.py
··· 19 19 20 20 return crates_cfgs 21 21 22 - def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): 22 + def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edition): 23 23 # Generate the configuration list. 24 24 cfg = [] 25 25 with open(objtree / "include" / "generated" / "rustc_cfg") as fd: ··· 35 35 crates_indexes = {} 36 36 crates_cfgs = args_crates_cfgs(cfgs) 37 37 38 - def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False): 38 + def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False, edition="2021"): 39 39 crate = { 40 40 "display_name": display_name, 41 41 "root_module": str(root_module), ··· 43 43 "is_proc_macro": is_proc_macro, 44 44 "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps], 45 45 "cfg": cfg, 46 - "edition": "2021", 46 + "edition": edition, 47 47 "env": { 48 48 "RUST_MODFILE": "This is only for rust-analyzer" 49 49 } ··· 61 61 display_name, 62 62 deps, 63 63 cfg=[], 64 + edition="2021", 64 65 ): 65 66 append_crate( 66 67 display_name, ··· 69 68 deps, 70 69 cfg, 71 70 is_workspace_member=False, 71 + edition=edition, 72 72 ) 73 73 74 74 # NB: sysroot crates reexport items from one another so setting up our transitive dependencies 75 75 # here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth 76 76 # for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`. 77 - append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", [])) 77 + append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []), edition=core_edition) 78 78 append_sysroot_crate("alloc", ["core"]) 79 79 append_sysroot_crate("std", ["alloc", "core"]) 80 80 append_sysroot_crate("proc_macro", ["core", "std"]) ··· 179 177 parser = argparse.ArgumentParser() 180 178 parser.add_argument('--verbose', '-v', action='store_true') 181 179 parser.add_argument('--cfgs', action='append', default=[]) 180 + parser.add_argument("core_edition") 182 181 parser.add_argument("srctree", type=pathlib.Path) 183 182 parser.add_argument("objtree", type=pathlib.Path) 184 183 parser.add_argument("sysroot", type=pathlib.Path) ··· 196 193 assert args.sysroot in args.sysroot_src.parents 197 194 198 195 rust_project = { 199 - "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs), 196 + "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs, args.core_edition), 200 197 "sysroot": str(args.sysroot), 201 198 } 202 199
+2 -2
scripts/generate_rust_target.rs
··· 209 209 // target feature of the same name plus the other two target features in 210 210 // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via 211 211 // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated 212 - // flag); see https://github.com/rust-lang/rust/issues/116852. 212 + // flag); see <https://github.com/rust-lang/rust/issues/116852>. 213 213 features += ",+retpoline-external-thunk"; 214 214 features += ",+retpoline-indirect-branches"; 215 215 features += ",+retpoline-indirect-calls"; ··· 218 218 // The kernel uses `-mharden-sls=all`, which Clang maps to both these target features in 219 219 // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via 220 220 // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated 221 - // flag); see https://github.com/rust-lang/rust/issues/116851. 221 + // flag); see <https://github.com/rust-lang/rust/issues/116851>. 222 222 features += ",+harden-sls-ijmp"; 223 223 features += ",+harden-sls-ret"; 224 224 }
+5 -3
scripts/rustdoc_test_builder.rs
··· 28 28 // 29 29 // ``` 30 30 // fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_28_0() { 31 - // fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_37_0() -> Result<(), impl core::fmt::Debug> { 31 + // fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_37_0() -> Result<(), impl ::core::fmt::Debug> { 32 32 // ``` 33 33 // 34 34 // It should be unlikely that doctest code matches such lines (when code is formatted properly). ··· 49 49 50 50 // Qualify `Result` to avoid the collision with our own `Result` coming from the prelude. 51 51 let body = body.replace( 52 - &format!("{rustdoc_function_name}() -> Result<(), impl core::fmt::Debug> {{"), 53 - &format!("{rustdoc_function_name}() -> core::result::Result<(), impl core::fmt::Debug> {{"), 52 + &format!("{rustdoc_function_name}() -> Result<(), impl ::core::fmt::Debug> {{"), 53 + &format!( 54 + "{rustdoc_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{" 55 + ), 54 56 ); 55 57 56 58 // For tests that get generated with `Result`, like above, `rustdoc` generates an `unwrap()` on
+10 -6
scripts/rustdoc_test_gen.rs
··· 167 167 rust_tests, 168 168 r#"/// Generated `{name}` KUnit test case from a Rust documentation test. 169 169 #[no_mangle] 170 - pub extern "C" fn {kunit_name}(__kunit_test: *mut kernel::bindings::kunit) {{ 170 + pub extern "C" fn {kunit_name}(__kunit_test: *mut ::kernel::bindings::kunit) {{ 171 171 /// Overrides the usual [`assert!`] macro with one that calls KUnit instead. 172 172 #[allow(unused)] 173 173 macro_rules! assert {{ 174 174 ($cond:expr $(,)?) => {{{{ 175 - kernel::kunit_assert!("{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $cond); 175 + ::kernel::kunit_assert!( 176 + "{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $cond 177 + ); 176 178 }}}} 177 179 }} 178 180 ··· 182 180 #[allow(unused)] 183 181 macro_rules! assert_eq {{ 184 182 ($left:expr, $right:expr $(,)?) => {{{{ 185 - kernel::kunit_assert_eq!("{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $left, $right); 183 + ::kernel::kunit_assert_eq!( 184 + "{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $left, $right 185 + ); 186 186 }}}} 187 187 }} 188 188 189 189 // Many tests need the prelude, so provide it by default. 190 190 #[allow(unused)] 191 - use kernel::prelude::*; 191 + use ::kernel::prelude::*; 192 192 193 193 // Unconditionally print the location of the original doctest (i.e. rather than the location in 194 194 // the generated file) so that developers can easily map the test back to the source code. ··· 201 197 // This follows the syntax for declaring test metadata in the proposed KTAP v2 spec, which may 202 198 // be used for the proposed KUnit test attributes API. Thus hopefully this will make migration 203 199 // easier later on. 204 - kernel::kunit::info(format_args!(" # {kunit_name}.location: {real_path}:{line}\n")); 200 + ::kernel::kunit::info(format_args!(" # {kunit_name}.location: {real_path}:{line}\n")); 205 201 206 202 /// The anchor where the test code body starts. 207 203 #[allow(unused)] 208 - static __DOCTEST_ANCHOR: i32 = core::line!() as i32 + {body_offset} + 1; 204 + static __DOCTEST_ANCHOR: i32 = ::core::line!() as i32 + {body_offset} + 1; 209 205 {{ 210 206 {body} 211 207 main();
+2 -1
tools/objtool/check.c
··· 230 230 str_ends_with(func->name, "_7___rustc17rust_begin_unwind") || 231 231 strstr(func->name, "_4core9panicking13assert_failed") || 232 232 strstr(func->name, "_4core9panicking11panic_const24panic_const_") || 233 - (strstr(func->name, "_4core5slice5index24slice_") && 233 + (strstr(func->name, "_4core5slice5index") && 234 + strstr(func->name, "slice_") && 234 235 str_ends_with(func->name, "_fail")); 235 236 } 236 237