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 Benjamin Poirier <benjamin.poirier@gmail.com> <bpoirier@suse.de> 136 Benjamin Tissoires <bentiss@kernel.org> <benjamin.tissoires@gmail.com> 137 Benjamin Tissoires <bentiss@kernel.org> <benjamin.tissoires@redhat.com> 138 Bingwu Zhang <xtex@aosc.io> <xtexchooser@duck.com> 139 Bingwu Zhang <xtex@aosc.io> <xtex@xtexx.eu.org> 140 Bjorn Andersson <andersson@kernel.org> <bjorn@kryo.se>
··· 135 Benjamin Poirier <benjamin.poirier@gmail.com> <bpoirier@suse.de> 136 Benjamin Tissoires <bentiss@kernel.org> <benjamin.tissoires@gmail.com> 137 Benjamin Tissoires <bentiss@kernel.org> <benjamin.tissoires@redhat.com> 138 + Benno Lossin <lossin@kernel.org> <benno.lossin@proton.me> 139 Bingwu Zhang <xtex@aosc.io> <xtexchooser@duck.com> 140 Bingwu Zhang <xtex@aosc.io> <xtex@xtexx.eu.org> 141 Bjorn Andersson <andersson@kernel.org> <bjorn@kryo.se>
+29
Documentation/rust/coding-guidelines.rst
··· 85 // ... 86 } 87 88 One special kind of comments are the ``// SAFETY:`` comments. These must appear 89 before every ``unsafe`` block, and they explain why the code inside the block is 90 correct/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.: ··· 201 .. code-block:: rust 202 203 /// [`struct mutex`]: srctree/include/linux/mutex.h 204 205 206 Naming
··· 85 // ... 86 } 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 + 100 One special kind of comments are the ``// SAFETY:`` comments. These must appear 101 before every ``unsafe`` block, and they explain why the code inside the block is 102 correct/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.: ··· 189 .. code-block:: rust 190 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 + } 209 210 211 Naming
+41 -3
Documentation/rust/quick-start.rst
··· 90 Ubuntu 91 ****** 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.:: 95 96 - apt install rustc-1.80 rust-1.80-src bindgen-0.65 rustfmt-1.80 rust-1.80-clippy 97 98 ``RUST_LIB_SRC`` needs to be set when using the versioned packages, e.g.:: 99 100 RUST_LIB_SRC=/usr/src/rustc-$(rustc-1.80 --version | cut -d' ' -f2)/library 101 102 In addition, ``bindgen-0.65`` is available in newer releases (24.04 LTS and 103 24.10), but it may not be available in older ones (20.04 LTS and 22.04 LTS),
··· 90 Ubuntu 91 ****** 92 93 + 25.04 94 + ~~~~~ 95 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 133 134 ``RUST_LIB_SRC`` needs to be set when using the versioned packages, e.g.:: 135 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. 139 140 In addition, ``bindgen-0.65`` is available in newer releases (24.04 LTS and 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 The ``#[test]`` tests 134 --------------------- 135 136 - Additionally, there are the ``#[test]`` tests. These can be run using the 137 - ``rusttest`` Make target:: 138 139 make LLVM=1 rusttest 140 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. 143 144 The Kselftests 145 --------------
··· 133 The ``#[test]`` tests 134 --------------------- 135 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:: 209 210 make LLVM=1 rusttest 211 212 + This requires the kernel ``.config``. 213 + 214 + Currently, they are mostly used for testing the ``macros`` crate's examples. 215 216 The Kselftests 217 --------------
+20 -6
MAINTAINERS
··· 10719 F: kernel/time/timer_migration.* 10720 F: tools/testing/selftests/timers/ 10721 10722 - HIGH-RESOLUTION TIMERS [RUST] 10723 M: Andreas Hindborg <a.hindborg@kernel.org> 10724 R: Boqun Feng <boqun.feng@gmail.com> 10725 R: Frederic Weisbecker <frederic@kernel.org> 10726 R: Lyude Paul <lyude@redhat.com> 10727 R: Thomas Gleixner <tglx@linutronix.de> 10728 R: Anna-Maria Behnsen <anna-maria@linutronix.de> 10729 L: rust-for-linux@vger.kernel.org 10730 S: Supported 10731 W: https://rust-for-linux.com 10732 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 10737 HIGH-SPEED SCC DRIVER FOR AX.25 10738 L: linux-hams@vger.kernel.org ··· 21591 R: Boqun Feng <boqun.feng@gmail.com> 21592 R: Gary Guo <gary@garyguo.net> 21593 R: Björn Roy Baron <bjorn3_gh@protonmail.com> 21594 - R: Benno Lossin <benno.lossin@proton.me> 21595 R: Andreas Hindborg <a.hindborg@kernel.org> 21596 R: Alice Ryhl <aliceryhl@google.com> 21597 R: Trevor Gross <tmgross@umich.edu> ··· 21621 F: rust/kernel/alloc/ 21622 21623 RUST [PIN-INIT] 21624 - M: Benno Lossin <benno.lossin@proton.me> 21625 L: rust-for-linux@vger.kernel.org 21626 S: Maintained 21627 W: https://rust-for-linux.com/pin-init ··· 26831 F: lib/test_xarray.c 26832 F: lib/xarray.c 26833 F: tools/testing/radix-tree 26834 26835 XBOX DVD IR REMOTE 26836 M: Benjamin Valentin <benpicco@googlemail.com>
··· 10719 F: kernel/time/timer_migration.* 10720 F: tools/testing/selftests/timers/ 10721 10722 + DELAY, SLEEP, TIMEKEEPING, TIMERS [RUST] 10723 M: Andreas Hindborg <a.hindborg@kernel.org> 10724 R: Boqun Feng <boqun.feng@gmail.com> 10725 + R: FUJITA Tomonori <fujita.tomonori@gmail.com> 10726 R: Frederic Weisbecker <frederic@kernel.org> 10727 R: Lyude Paul <lyude@redhat.com> 10728 R: Thomas Gleixner <tglx@linutronix.de> 10729 R: Anna-Maria Behnsen <anna-maria@linutronix.de> 10730 + R: John Stultz <jstultz@google.com> 10731 + R: Stephen Boyd <sboyd@kernel.org> 10732 L: rust-for-linux@vger.kernel.org 10733 S: Supported 10734 W: https://rust-for-linux.com 10735 B: https://github.com/Rust-for-Linux/linux/issues 10736 + T: git https://github.com/Rust-for-Linux/linux.git timekeeping-next 10737 + F: rust/kernel/time.rs 10738 + F: rust/kernel/time/ 10739 10740 HIGH-SPEED SCC DRIVER FOR AX.25 10741 L: linux-hams@vger.kernel.org ··· 21588 R: Boqun Feng <boqun.feng@gmail.com> 21589 R: Gary Guo <gary@garyguo.net> 21590 R: Björn Roy Baron <bjorn3_gh@protonmail.com> 21591 + R: Benno Lossin <lossin@kernel.org> 21592 R: Andreas Hindborg <a.hindborg@kernel.org> 21593 R: Alice Ryhl <aliceryhl@google.com> 21594 R: Trevor Gross <tmgross@umich.edu> ··· 21618 F: rust/kernel/alloc/ 21619 21620 RUST [PIN-INIT] 21621 + M: Benno Lossin <lossin@kernel.org> 21622 L: rust-for-linux@vger.kernel.org 21623 S: Maintained 21624 W: https://rust-for-linux.com/pin-init ··· 26828 F: lib/test_xarray.c 26829 F: lib/xarray.c 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 26842 26843 XBOX DVD IR REMOTE 26844 M: Benjamin Valentin <benpicco@googlemail.com>
+3
init/Kconfig
··· 136 config RUSTC_HAS_COERCE_POINTEE 137 def_bool RUSTC_VERSION >= 108400 138 139 config RUSTC_HAS_UNNECESSARY_TRANSMUTES 140 def_bool RUSTC_VERSION >= 108800 141
··· 136 config RUSTC_HAS_COERCE_POINTEE 137 def_bool RUSTC_VERSION >= 108400 138 139 + config RUSTC_HAS_SPAN_FILE 140 + def_bool RUSTC_VERSION >= 108800 141 + 142 config RUSTC_HAS_UNNECESSARY_TRANSMUTES 143 def_bool RUSTC_VERSION >= 108800 144
+11 -8
rust/Makefile
··· 60 core-cfgs = \ 61 --cfg no_fp_fmt_parse 62 63 # `rustc` recognizes `--remap-path-prefix` since 1.26.0, but `rustdoc` only 64 # since Rust 1.81.0. Moreover, `rustdoc` ICEs on out-of-tree builds since Rust 65 # 1.82.0 (https://github.com/rust-lang/rust/issues/138520). Thus workaround both ··· 108 109 # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should 110 # 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) 113 rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE 114 +$(call if_changed,rustdoc) 115 ··· 275 -fzero-call-used-regs=% -fno-stack-clash-protection \ 276 -fno-inline-functions-called-once -fsanitize=bounds-strict \ 277 -fstrict-flex-arrays=% -fmin-function-alignment=% \ 278 - -fzero-init-padding-bits=% \ 279 --param=% --param asan-% 280 281 # Derived from `scripts/Makefile.clang`. ··· 404 -Clink-args='$(call escsq,$(KBUILD_PROCMACROLDFLAGS))' \ 405 --emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \ 406 --crate-type proc-macro \ 407 - --crate-name $(patsubst lib%.$(libmacros_extension),%,$(notdir $@)) $< 408 409 # Procedural macros can only be used with the `rustc` that compiled it. 410 $(obj)/$(libmacros_name): $(src)/macros/lib.rs FORCE ··· 419 cmd_rustc_library = \ 420 OBJTREE=$(abspath $(objtree)) \ 421 $(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \ 422 - $(filter-out $(skip_flags),$(rust_flags) $(rustc_target_flags)) \ 423 --emit=dep-info=$(depfile) --emit=obj=$@ \ 424 --emit=metadata=$(dir $@)$(patsubst %.o,lib%.rmeta,$(notdir $@)) \ 425 --crate-type rlib -L$(objtree)/$(obj) \ ··· 430 431 rust-analyzer: 432 $(Q)MAKEFLAGS= $(srctree)/scripts/generate_rust_analyzer.py \ 433 - --cfgs='core=$(core-cfgs)' \ 434 $(realpath $(srctree)) $(realpath $(objtree)) \ 435 $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ 436 > rust-project.json ··· 486 $(obj)/exports.o: private skip_gendwarfksyms = 1 487 488 $(obj)/core.o: private skip_clippy = 1 489 - $(obj)/core.o: private skip_flags = -Wunreachable_pub 490 $(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) 492 $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs \ 493 $(wildcard $(objtree)/include/config/RUSTC_VERSION_TEXT) FORCE 494 +$(call if_changed_rule,rustc_library)
··· 60 core-cfgs = \ 61 --cfg no_fp_fmt_parse 62 63 + core-edition := $(if $(call rustc-min-version,108700),2024,2021) 64 + 65 # `rustc` recognizes `--remap-path-prefix` since 1.26.0, but `rustdoc` only 66 # since Rust 1.81.0. Moreover, `rustdoc` ICEs on out-of-tree builds since Rust 67 # 1.82.0 (https://github.com/rust-lang/rust/issues/138520). Thus workaround both ··· 106 107 # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should 108 # not be needed -- see https://github.com/rust-lang/rust/pull/128307. 109 + rustdoc-core: private skip_flags = --edition=2021 -Wrustdoc::unescaped_backticks 110 + rustdoc-core: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) 111 rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE 112 +$(call if_changed,rustdoc) 113 ··· 273 -fzero-call-used-regs=% -fno-stack-clash-protection \ 274 -fno-inline-functions-called-once -fsanitize=bounds-strict \ 275 -fstrict-flex-arrays=% -fmin-function-alignment=% \ 276 + -fzero-init-padding-bits=% -mno-fdpic \ 277 --param=% --param asan-% 278 279 # Derived from `scripts/Makefile.clang`. ··· 402 -Clink-args='$(call escsq,$(KBUILD_PROCMACROLDFLAGS))' \ 403 --emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \ 404 --crate-type proc-macro \ 405 + --crate-name $(patsubst lib%.$(libmacros_extension),%,$(notdir $@)) \ 406 + @$(objtree)/include/generated/rustc_cfg $< 407 408 # Procedural macros can only be used with the `rustc` that compiled it. 409 $(obj)/$(libmacros_name): $(src)/macros/lib.rs FORCE ··· 416 cmd_rustc_library = \ 417 OBJTREE=$(abspath $(objtree)) \ 418 $(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \ 419 + $(filter-out $(skip_flags),$(rust_flags)) $(rustc_target_flags) \ 420 --emit=dep-info=$(depfile) --emit=obj=$@ \ 421 --emit=metadata=$(dir $@)$(patsubst %.o,lib%.rmeta,$(notdir $@)) \ 422 --crate-type rlib -L$(objtree)/$(obj) \ ··· 427 428 rust-analyzer: 429 $(Q)MAKEFLAGS= $(srctree)/scripts/generate_rust_analyzer.py \ 430 + --cfgs='core=$(core-cfgs)' $(core-edition) \ 431 $(realpath $(srctree)) $(realpath $(objtree)) \ 432 $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ 433 > rust-project.json ··· 483 $(obj)/exports.o: private skip_gendwarfksyms = 1 484 485 $(obj)/core.o: private skip_clippy = 1 486 + $(obj)/core.o: private skip_flags = --edition=2021 -Wunreachable_pub 487 $(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym)) 488 + $(obj)/core.o: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) 489 $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs \ 490 $(wildcard $(objtree)/include/config/RUSTC_VERSION_TEXT) FORCE 491 +$(call if_changed_rule,rustc_library)
+28
rust/bindings/bindings_helper.h
··· 6 * Sorted alphabetically. 7 */ 8 9 #include <drm/drm_device.h> 10 #include <drm/drm_drv.h> 11 #include <drm/drm_file.h> ··· 70 #include <linux/tracepoint.h> 71 #include <linux/wait.h> 72 #include <linux/workqueue.h> 73 #include <trace/events/rust_sample.h> 74 75 #if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE) ··· 90 const gfp_t RUST_CONST_HELPER___GFP_NOWARN = ___GFP_NOWARN; 91 const blk_features_t RUST_CONST_HELPER_BLK_FEAT_ROTATIONAL = BLK_FEAT_ROTATIONAL; 92 const fop_flags_t RUST_CONST_HELPER_FOP_UNSIGNED_OFFSET = FOP_UNSIGNED_OFFSET;
··· 6 * Sorted alphabetically. 7 */ 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 + 31 #include <drm/drm_device.h> 32 #include <drm/drm_drv.h> 33 #include <drm/drm_file.h> ··· 48 #include <linux/tracepoint.h> 49 #include <linux/wait.h> 50 #include <linux/workqueue.h> 51 + #include <linux/xarray.h> 52 #include <trace/events/rust_sample.h> 53 54 #if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE) ··· 67 const gfp_t RUST_CONST_HELPER___GFP_NOWARN = ___GFP_NOWARN; 68 const blk_features_t RUST_CONST_HELPER_BLK_FEAT_ROTATIONAL = BLK_FEAT_ROTATIONAL; 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 18 // Check size compatibility with `core`. 19 const _: () = assert!( 20 - core::mem::size_of::<$name>() == core::mem::size_of::<core::ffi::$name>() 21 ); 22 )*} 23 }
··· 17 18 // Check size compatibility with `core`. 19 const _: () = assert!( 20 + ::core::mem::size_of::<$name>() == ::core::mem::size_of::<::core::ffi::$name>() 21 ); 22 )*} 23 }
+1
rust/helpers/helpers.c
··· 43 #include "vmalloc.c" 44 #include "wait.c" 45 #include "workqueue.c"
··· 43 #include "vmalloc.c" 44 #include "wait.c" 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 /// 95 /// A lower watermark is applied to allow access to "atomic reserves". The current 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`]. 98 pub const GFP_ATOMIC: Flags = Flags(bindings::GFP_ATOMIC); 99 100 - /// Typical for kernel-internal allocations. The caller requires ZONE_NORMAL or a lower zone 101 /// for direct access but can direct reclaim. 102 pub const GFP_KERNEL: Flags = Flags(bindings::GFP_KERNEL); 103
··· 94 /// 95 /// A lower watermark is applied to allow access to "atomic reserves". The current 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`]. 98 pub const GFP_ATOMIC: Flags = Flags(bindings::GFP_ATOMIC); 99 100 + /// Typical for kernel-internal allocations. The caller requires `ZONE_NORMAL` or a lower zone 101 /// for direct access but can direct reclaim. 102 pub const GFP_KERNEL: Flags = Flags(bindings::GFP_KERNEL); 103
+1 -1
rust/kernel/alloc/allocator_test.rs
··· 4 //! of those types (e.g. `CString`) use kernel allocators for instantiation. 5 //! 6 //! In order to allow userspace test cases to make use of such types as well, implement the 7 - //! `Cmalloc` allocator within the allocator_test module and type alias all kernel allocators to 8 //! `Cmalloc`. The `Cmalloc` allocator uses libc's `realloc()` function as allocator backend. 9 10 #![allow(missing_docs)]
··· 4 //! of those types (e.g. `CString`) use kernel allocators for instantiation. 5 //! 6 //! In order to allow userspace test cases to make use of such types as well, implement the 7 + //! `Cmalloc` allocator within the `allocator_test` module and type alias all kernel allocators to 8 //! `Cmalloc`. The `Cmalloc` allocator uses libc's `realloc()` function as allocator backend. 9 10 #![allow(missing_docs)]
+60 -20
rust/kernel/alloc/kbox.rs
··· 57 /// assert!(KVBox::<Huge>::new_uninit(GFP_KERNEL).is_ok()); 58 /// ``` 59 /// 60 /// # Invariants 61 /// 62 /// `self.0` is always properly aligned and either points to memory allocated with `A` or, for 63 /// zero-sized types, is a dangling, well aligned pointer. 64 #[repr(transparent)] 65 - pub struct Box<T: ?Sized, A: Allocator>(NonNull<T>, PhantomData<A>); 66 67 /// Type alias for [`Box`] with a [`Kmalloc`] allocator. 68 /// ··· 139 pub type KVBox<T> = Box<T, super::allocator::KVmalloc>; 140 141 // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee: 142 - // https://doc.rust-lang.org/stable/std/option/index.html#representation). 143 unsafe impl<T, A: Allocator> ZeroableOption for Box<T, A> {} 144 145 // SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`. ··· 398 } 399 } 400 401 - impl<T: 'static, A> ForeignOwnable for Box<T, A> 402 where 403 A: Allocator, 404 { 405 type Borrowed<'a> = &'a T; 406 type BorrowedMut<'a> = &'a mut T; 407 408 - fn into_foreign(self) -> *mut crate::ffi::c_void { 409 - Box::into_raw(self).cast() 410 } 411 412 - unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self { 413 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 414 // call to `Self::into_foreign`. 415 - unsafe { Box::from_raw(ptr.cast()) } 416 } 417 418 - unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> &'a T { 419 // SAFETY: The safety requirements of this method ensure that the object remains alive and 420 // immutable for the duration of 'a. 421 - unsafe { &*ptr.cast() } 422 } 423 424 - unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> &'a mut T { 425 - let ptr = ptr.cast(); 426 // SAFETY: The safety requirements of this method ensure that the pointer is valid and that 427 // nothing else will access the value for the duration of 'a. 428 unsafe { &mut *ptr } 429 } 430 } 431 432 - impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>> 433 where 434 A: Allocator, 435 { 436 type Borrowed<'a> = Pin<&'a T>; 437 type BorrowedMut<'a> = Pin<&'a mut T>; 438 439 - fn into_foreign(self) -> *mut crate::ffi::c_void { 440 // SAFETY: We are still treating the box as pinned. 441 - Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast() 442 } 443 444 - unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self { 445 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 446 // call to `Self::into_foreign`. 447 - unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) } 448 } 449 450 - unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a T> { 451 // SAFETY: The safety requirements for this function ensure that the object is still alive, 452 // so it is safe to dereference the raw pointer. 453 // The safety requirements of `from_foreign` also ensure that the object remains alive for 454 // the lifetime of the returned value. 455 - let r = unsafe { &*ptr.cast() }; 456 457 // SAFETY: This pointer originates from a `Pin<Box<T>>`. 458 unsafe { Pin::new_unchecked(r) } 459 } 460 461 - unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a mut T> { 462 - let ptr = ptr.cast(); 463 // SAFETY: The safety requirements for this function ensure that the object is still alive, 464 // so it is safe to dereference the raw pointer. 465 // The safety requirements of `from_foreign` also ensure that the object remains alive for
··· 57 /// assert!(KVBox::<Huge>::new_uninit(GFP_KERNEL).is_ok()); 58 /// ``` 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 + /// 72 /// # Invariants 73 /// 74 /// `self.0` is always properly aligned and either points to memory allocated with `A` or, for 75 /// zero-sized types, is a dangling, well aligned pointer. 76 #[repr(transparent)] 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 + } 104 105 /// Type alias for [`Box`] with a [`Kmalloc`] allocator. 106 /// ··· 101 pub type KVBox<T> = Box<T, super::allocator::KVmalloc>; 102 103 // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee: 104 + // <https://doc.rust-lang.org/stable/std/option/index.html#representation>). 105 unsafe impl<T, A: Allocator> ZeroableOption for Box<T, A> {} 106 107 // SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`. ··· 360 } 361 } 362 363 + // SAFETY: The `into_foreign` function returns a pointer that is well-aligned. 364 + unsafe impl<T: 'static, A> ForeignOwnable for Box<T, A> 365 where 366 A: Allocator, 367 { 368 + type PointedTo = T; 369 type Borrowed<'a> = &'a T; 370 type BorrowedMut<'a> = &'a mut T; 371 372 + fn into_foreign(self) -> *mut Self::PointedTo { 373 + Box::into_raw(self) 374 } 375 376 + unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self { 377 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 378 // call to `Self::into_foreign`. 379 + unsafe { Box::from_raw(ptr) } 380 } 381 382 + unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> &'a T { 383 // SAFETY: The safety requirements of this method ensure that the object remains alive and 384 // immutable for the duration of 'a. 385 + unsafe { &*ptr } 386 } 387 388 + unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> &'a mut T { 389 // SAFETY: The safety requirements of this method ensure that the pointer is valid and that 390 // nothing else will access the value for the duration of 'a. 391 unsafe { &mut *ptr } 392 } 393 } 394 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>> 397 where 398 A: Allocator, 399 { 400 + type PointedTo = T; 401 type Borrowed<'a> = Pin<&'a T>; 402 type BorrowedMut<'a> = Pin<&'a mut T>; 403 404 + fn into_foreign(self) -> *mut Self::PointedTo { 405 // SAFETY: We are still treating the box as pinned. 406 + Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) 407 } 408 409 + unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self { 410 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 411 // call to `Self::into_foreign`. 412 + unsafe { Pin::new_unchecked(Box::from_raw(ptr)) } 413 } 414 415 + unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> Pin<&'a T> { 416 // SAFETY: The safety requirements for this function ensure that the object is still alive, 417 // so it is safe to dereference the raw pointer. 418 // The safety requirements of `from_foreign` also ensure that the object remains alive for 419 // the lifetime of the returned value. 420 + let r = unsafe { &*ptr }; 421 422 // SAFETY: This pointer originates from a `Pin<Box<T>>`. 423 unsafe { Pin::new_unchecked(r) } 424 } 425 426 + unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> Pin<&'a mut T> { 427 // SAFETY: The safety requirements for this function ensure that the object is still alive, 428 // so it is safe to dereference the raw pointer. 429 // The safety requirements of `from_foreign` also ensure that the object remains alive for
+404 -29
rust/kernel/alloc/kvec.rs
··· 2 3 //! Implementation of [`Vec`]. 4 5 - // May not be needed in Rust 1.87.0 (pending beta backport). 6 - #![allow(clippy::ptr_eq)] 7 - 8 use super::{ 9 allocator::{KVmalloc, Kmalloc, Vmalloc}, 10 layout::ArrayLayout, ··· 20 slice, 21 slice::SliceIndex, 22 }; 23 24 /// Create a [`KVec`] containing the arguments. 25 /// ··· 92 /// - `self.layout` represents the absolute number of elements that can be stored within the vector 93 /// without re-allocation. For ZSTs `self.layout`'s capacity is zero. However, it is legal for the 94 /// backing buffer to be larger than `layout`. 95 /// 96 /// - The `Allocator` type `A` of the vector is the exact same `Allocator` type the backing buffer 97 /// was allocated with (and must be freed with). ··· 188 self.len 189 } 190 191 - /// Forcefully sets `self.len` to `new_len`. 192 /// 193 /// # Safety 194 /// 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. 198 #[inline] 199 - pub unsafe fn set_len(&mut self, new_len: usize) { 200 - debug_assert!(new_len <= self.capacity()); 201 - self.len = new_len; 202 } 203 204 /// Returns a slice of the entire vector. ··· 285 /// Returns a slice of `MaybeUninit<T>` for the remaining spare capacity of the vector. 286 pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] { 287 // 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. 290 // - `self.len` can not overflow `isize`. 291 let ptr = unsafe { self.as_mut_ptr().add(self.len) } as *mut MaybeUninit<T>; 292 ··· 310 /// ``` 311 pub fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> { 312 self.reserve(1, flags)?; 313 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) }; 319 320 - // SAFETY: 321 - // - `ptr` is properly aligned and valid for writes. 322 - unsafe { core::ptr::write(ptr, v) }; 323 324 // 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) }; 328 Ok(()) 329 } 330 331 /// Creates a new [`Vec`] instance with at least the given capacity. ··· 567 (ptr, len, capacity) 568 } 569 570 /// Ensures that the capacity exceeds the length by at least `additional` elements. 571 /// 572 /// # Examples ··· 644 645 Ok(()) 646 } 647 } 648 649 impl<T: Clone, A: Allocator> Vec<T, A> { ··· 741 // SAFETY: 742 // - `self.len() + n < self.capacity()` due to the call to reserve above, 743 // - the loop and the line above initialized the next `n` elements. 744 - unsafe { self.set_len(self.len() + n) }; 745 746 Ok(()) 747 } ··· 772 // the length by the same number. 773 // - `self.len() + other.len() <= self.capacity()` is guaranteed by the preceding `reserve` 774 // call. 775 - unsafe { self.set_len(self.len() + other.len()) }; 776 Ok(()) 777 } 778 ··· 783 v.extend_with(n, value, flags)?; 784 785 Ok(v) 786 } 787 } 788 ··· 1050 unsafe { ptr::copy(ptr, buf.as_ptr(), len) }; 1051 ptr = buf.as_ptr(); 1052 1053 - // SAFETY: `len` is guaranteed to be smaller than `self.layout.len()`. 1054 let layout = unsafe { ArrayLayout::<T>::new_unchecked(len) }; 1055 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. 1059 ptr = match unsafe { 1060 A::realloc(Some(buf.cast()), layout.into(), old_layout.into(), flags) 1061 } { ··· 1202 len, 1203 layout, 1204 _p: PhantomData::<A>, 1205 } 1206 } 1207 }
··· 2 3 //! Implementation of [`Vec`]. 4 5 use super::{ 6 allocator::{KVmalloc, Kmalloc, Vmalloc}, 7 layout::ArrayLayout, ··· 23 slice, 24 slice::SliceIndex, 25 }; 26 + 27 + mod errors; 28 + pub use self::errors::{InsertError, PushError, RemoveError}; 29 30 /// Create a [`KVec`] containing the arguments. 31 /// ··· 92 /// - `self.layout` represents the absolute number of elements that can be stored within the vector 93 /// without re-allocation. For ZSTs `self.layout`'s capacity is zero. However, it is legal for the 94 /// backing buffer to be larger than `layout`. 95 + /// 96 + /// - `self.len()` is always less than or equal to `self.capacity()`. 97 /// 98 /// - The `Allocator` type `A` of the vector is the exact same `Allocator` type the backing buffer 99 /// was allocated with (and must be freed with). ··· 186 self.len 187 } 188 189 + /// Increments `self.len` by `additional`. 190 /// 191 /// # Safety 192 /// 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. 195 #[inline] 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) } 221 } 222 223 /// Returns a slice of the entire vector. ··· 262 /// Returns a slice of `MaybeUninit<T>` for the remaining spare capacity of the vector. 263 pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] { 264 // SAFETY: 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. 267 // - `self.len` can not overflow `isize`. 268 let ptr = unsafe { self.as_mut_ptr().add(self.len) } as *mut MaybeUninit<T>; 269 ··· 287 /// ``` 288 pub fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> { 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 + } 295 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 + } 320 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); 331 332 // SAFETY: We just initialised the first spare entry, so it is safe to increase the length 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) }; 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) 452 } 453 454 /// Creates a new [`Vec`] instance with at least the given capacity. ··· 398 (ptr, len, capacity) 399 } 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 + 421 /// Ensures that the capacity exceeds the length by at least `additional` elements. 422 /// 423 /// # Examples ··· 455 456 Ok(()) 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 + } 532 } 533 534 impl<T: Clone, A: Allocator> Vec<T, A> { ··· 478 // SAFETY: 479 // - `self.len() + n < self.capacity()` due to the call to reserve above, 480 // - the loop and the line above initialized the next `n` elements. 481 + unsafe { self.inc_len(n) }; 482 483 Ok(()) 484 } ··· 509 // the length by the same number. 510 // - `self.len() + other.len() <= self.capacity()` is guaranteed by the preceding `reserve` 511 // call. 512 + unsafe { self.inc_len(other.len()) }; 513 Ok(()) 514 } 515 ··· 520 v.extend_with(n, value, flags)?; 521 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 + } 550 } 551 } 552 ··· 760 unsafe { ptr::copy(ptr, buf.as_ptr(), len) }; 761 ptr = buf.as_ptr(); 762 763 + // SAFETY: `len` is guaranteed to be smaller than `self.layout.len()` by the type 764 + // invariant. 765 let layout = unsafe { ArrayLayout::<T>::new_unchecked(len) }; 766 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. 770 ptr = match unsafe { 771 A::realloc(Some(buf.cast()), layout.into(), old_layout.into(), flags) 772 } { ··· 911 len, 912 layout, 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(); 998 } 999 } 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 // Let the `struct auxiliary_device` own a reference of the driver's private data. 74 // SAFETY: By the type invariant `adev.as_raw` returns a valid pointer to a 75 // `struct auxiliary_device`. 76 - unsafe { bindings::auxiliary_set_drvdata(adev.as_raw(), data.into_foreign()) }; 77 } 78 Err(err) => return Error::to_errno(err), 79 } ··· 91 // SAFETY: `remove_callback` is only ever called after a successful call to 92 // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized 93 // `KBox<T>` pointer created through `KBox::into_foreign`. 94 - drop(unsafe { KBox::<T>::from_foreign(ptr) }); 95 } 96 } 97 ··· 236 extern "C" fn release(dev: *mut bindings::device) { 237 // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device` 238 // embedded in `struct auxiliary_device`. 239 - let adev = unsafe { container_of!(dev, bindings::auxiliary_device, dev) }.cast_mut(); 240 241 // SAFETY: `adev` points to the memory that has been allocated in `Registration::new`, via 242 // `KBox::new(Opaque::<bindings::auxiliary_device>::zeroed(), GFP_KERNEL)`.
··· 73 // Let the `struct auxiliary_device` own a reference of the driver's private data. 74 // SAFETY: By the type invariant `adev.as_raw` returns a valid pointer to a 75 // `struct auxiliary_device`. 76 + unsafe { 77 + bindings::auxiliary_set_drvdata(adev.as_raw(), data.into_foreign().cast()) 78 + }; 79 } 80 Err(err) => return Error::to_errno(err), 81 } ··· 89 // SAFETY: `remove_callback` is only ever called after a successful call to 90 // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized 91 // `KBox<T>` pointer created through `KBox::into_foreign`. 92 + drop(unsafe { KBox::<T>::from_foreign(ptr.cast()) }); 93 } 94 } 95 ··· 234 extern "C" fn release(dev: *mut bindings::device) { 235 // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device` 236 // embedded in `struct auxiliary_device`. 237 + let adev = unsafe { container_of!(dev, bindings::auxiliary_device, dev) }; 238 239 // SAFETY: `adev` points to the memory that has been allocated in `Registration::new`, via 240 // `KBox::new(Opaque::<bindings::auxiliary_device>::zeroed(), GFP_KERNEL)`.
+1 -1
rust/kernel/block/mq/gen_disk.rs
··· 129 get_unique_id: None, 130 // TODO: Set to THIS_MODULE. Waiting for const_refs_to_static feature to 131 // be merged (unstable in rustc 1.78 which is staged for linux 6.10) 132 - // https://github.com/rust-lang/rust/issues/119618 133 owner: core::ptr::null_mut(), 134 pr_ops: core::ptr::null_mut(), 135 free_disk: None,
··· 129 get_unique_id: None, 130 // TODO: Set to THIS_MODULE. Waiting for const_refs_to_static feature to 131 // be merged (unstable in rustc 1.78 which is staged for linux 6.10) 132 + // <https://github.com/rust-lang/rust/issues/119618> 133 owner: core::ptr::null_mut(), 134 pr_ops: core::ptr::null_mut(), 135 free_disk: None,
+2 -2
rust/kernel/configfs.rs
··· 554 let c_group: *mut bindings::config_group = 555 // SAFETY: By function safety requirements, `item` is embedded in a 556 // `config_group`. 557 - unsafe { container_of!(item, bindings::config_group, cg_item) }.cast_mut(); 558 559 // SAFETY: The function safety requirements for this function satisfy 560 // the conditions for this call. ··· 588 let c_group: *mut bindings::config_group = 589 // SAFETY: By function safety requirements, `item` is embedded in a 590 // `config_group`. 591 - unsafe { container_of!(item, bindings::config_group, cg_item) }.cast_mut(); 592 593 // SAFETY: The function safety requirements for this function satisfy 594 // the conditions for this call.
··· 554 let c_group: *mut bindings::config_group = 555 // SAFETY: By function safety requirements, `item` is embedded in a 556 // `config_group`. 557 + unsafe { container_of!(item, bindings::config_group, cg_item) }; 558 559 // SAFETY: The function safety requirements for this function satisfy 560 // the conditions for this call. ··· 588 let c_group: *mut bindings::config_group = 589 // SAFETY: By function safety requirements, `item` is embedded in a 590 // `config_group`. 591 + unsafe { container_of!(item, bindings::config_group, cg_item) }; 592 593 // SAFETY: The function safety requirements for this function satisfy 594 // the conditions for this call.
+2 -2
rust/kernel/cpufreq.rs
··· 635 None 636 } else { 637 // SAFETY: The data is earlier set from [`set_data`]. 638 - Some(unsafe { T::borrow(self.as_ref().driver_data) }) 639 } 640 } 641 ··· 662 let data = Some( 663 // SAFETY: The data is earlier set by us from [`set_data`]. It is safe to take 664 // back the ownership of the data from the foreign interface. 665 - unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data) }, 666 ); 667 self.as_mut_ref().driver_data = ptr::null_mut(); 668 data
··· 635 None 636 } else { 637 // SAFETY: The data is earlier set from [`set_data`]. 638 + Some(unsafe { T::borrow(self.as_ref().driver_data.cast()) }) 639 } 640 } 641 ··· 662 let data = Some( 663 // SAFETY: The data is earlier set by us from [`set_data`]. It is safe to take 664 // back the ownership of the data from the foreign interface. 665 + unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data.cast()) }, 666 ); 667 self.as_mut_ref().driver_data = ptr::null_mut(); 668 data
+17 -9
rust/kernel/device.rs
··· 345 macro_rules! dev_printk { 346 ($method:ident, $dev:expr, $($f:tt)*) => { 347 { 348 - ($dev).$method(core::format_args!($($f)*)); 349 } 350 } 351 } ··· 357 /// Equivalent to the kernel's `dev_emerg` macro. 358 /// 359 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 360 - /// [`core::fmt`] and `alloc::format!`. 361 /// 362 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 363 /// 364 /// # Examples 365 /// ··· 383 /// Equivalent to the kernel's `dev_alert` macro. 384 /// 385 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 386 - /// [`core::fmt`] and `alloc::format!`. 387 /// 388 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 389 /// 390 /// # Examples 391 /// ··· 409 /// Equivalent to the kernel's `dev_crit` macro. 410 /// 411 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 412 - /// [`core::fmt`] and `alloc::format!`. 413 /// 414 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 415 /// 416 /// # Examples 417 /// ··· 435 /// Equivalent to the kernel's `dev_err` macro. 436 /// 437 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 438 - /// [`core::fmt`] and `alloc::format!`. 439 /// 440 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 441 /// 442 /// # Examples 443 /// ··· 461 /// Equivalent to the kernel's `dev_warn` macro. 462 /// 463 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 464 - /// [`core::fmt`] and `alloc::format!`. 465 /// 466 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 467 /// 468 /// # Examples 469 /// ··· 487 /// Equivalent to the kernel's `dev_notice` macro. 488 /// 489 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 490 - /// [`core::fmt`] and `alloc::format!`. 491 /// 492 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 493 /// 494 /// # Examples 495 /// ··· 513 /// Equivalent to the kernel's `dev_info` macro. 514 /// 515 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 516 - /// [`core::fmt`] and `alloc::format!`. 517 /// 518 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 519 /// 520 /// # Examples 521 /// ··· 539 /// Equivalent to the kernel's `dev_dbg` macro, except that it doesn't support dynamic debug yet. 540 /// 541 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 542 - /// [`core::fmt`] and `alloc::format!`. 543 /// 544 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 545 /// 546 /// # Examples 547 ///
··· 345 macro_rules! dev_printk { 346 ($method:ident, $dev:expr, $($f:tt)*) => { 347 { 348 + ($dev).$method(::core::format_args!($($f)*)); 349 } 350 } 351 } ··· 357 /// Equivalent to the kernel's `dev_emerg` macro. 358 /// 359 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 360 + /// [`core::fmt`] and [`std::format!`]. 361 /// 362 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 363 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 364 /// 365 /// # Examples 366 /// ··· 382 /// Equivalent to the kernel's `dev_alert` macro. 383 /// 384 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 385 + /// [`core::fmt`] and [`std::format!`]. 386 /// 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 /// 390 /// # Examples 391 /// ··· 407 /// Equivalent to the kernel's `dev_crit` macro. 408 /// 409 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 410 + /// [`core::fmt`] and [`std::format!`]. 411 /// 412 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 413 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 414 /// 415 /// # Examples 416 /// ··· 432 /// Equivalent to the kernel's `dev_err` macro. 433 /// 434 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 435 + /// [`core::fmt`] and [`std::format!`]. 436 /// 437 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 438 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 439 /// 440 /// # Examples 441 /// ··· 457 /// Equivalent to the kernel's `dev_warn` macro. 458 /// 459 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 460 + /// [`core::fmt`] and [`std::format!`]. 461 /// 462 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 463 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 464 /// 465 /// # Examples 466 /// ··· 482 /// Equivalent to the kernel's `dev_notice` macro. 483 /// 484 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 485 + /// [`core::fmt`] and [`std::format!`]. 486 /// 487 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 488 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 489 /// 490 /// # Examples 491 /// ··· 507 /// Equivalent to the kernel's `dev_info` macro. 508 /// 509 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 510 + /// [`core::fmt`] and [`std::format!`]. 511 /// 512 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 513 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 514 /// 515 /// # Examples 516 /// ··· 532 /// Equivalent to the kernel's `dev_dbg` macro, except that it doesn't support dynamic debug yet. 533 /// 534 /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 535 + /// [`core::fmt`] and [`std::format!`]. 536 /// 537 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 538 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 539 /// 540 /// # Examples 541 ///
+2 -2
rust/kernel/device_id.rs
··· 159 "_", line!(), 160 "_", stringify!($table_name)) 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()) }; 164 }; 165 }
··· 159 "_", line!(), 160 "_", stringify!($table_name)) 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()) }; 164 }; 165 }
+1 -1
rust/kernel/dma.rs
··· 94 pub const DMA_ATTR_ALLOC_SINGLE_PAGES: Attrs = Attrs(bindings::DMA_ATTR_ALLOC_SINGLE_PAGES); 95 96 /// This tells the DMA-mapping subsystem to suppress allocation failure reports (similarly to 97 - /// __GFP_NOWARN). 98 pub const DMA_ATTR_NO_WARN: Attrs = Attrs(bindings::DMA_ATTR_NO_WARN); 99 100 /// Used to indicate that the buffer is fully accessible at an elevated privilege level (and
··· 94 pub const DMA_ATTR_ALLOC_SINGLE_PAGES: Attrs = Attrs(bindings::DMA_ATTR_ALLOC_SINGLE_PAGES); 95 96 /// This tells the DMA-mapping subsystem to suppress allocation failure reports (similarly to 97 + /// `__GFP_NOWARN`). 98 pub const DMA_ATTR_NO_WARN: Attrs = Attrs(bindings::DMA_ATTR_NO_WARN); 99 100 /// Used to indicate that the buffer is fully accessible at an elevated privilege level (and
+2
rust/kernel/drm/device.rs
··· 135 /// 136 /// `ptr` must be a valid pointer to a `struct device` embedded in `Self`. 137 unsafe fn from_drm_device(ptr: *const bindings::drm_device) -> *mut Self { 138 // SAFETY: By the safety requirements of this function `ptr` is a valid pointer to a 139 // `struct drm_device` embedded in `Self`. 140 unsafe { crate::container_of!(ptr, Self, dev) }.cast_mut()
··· 135 /// 136 /// `ptr` must be a valid pointer to a `struct device` embedded in `Self`. 137 unsafe fn from_drm_device(ptr: *const bindings::drm_device) -> *mut Self { 138 + let ptr: *const Opaque<bindings::drm_device> = ptr.cast(); 139 + 140 // SAFETY: By the safety requirements of this function `ptr` is a valid pointer to a 141 // `struct drm_device` embedded in `Self`. 142 unsafe { crate::container_of!(ptr, Self, dev) }.cast_mut()
+5 -1
rust/kernel/drm/gem/mod.rs
··· 125 } 126 127 unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a Self { 128 // SAFETY: `obj` is guaranteed to be in an `Object<T>` via the safety contract of this 129 // function 130 unsafe { &*crate::container_of!(self_ptr, Object<T>, obj) } ··· 271 } 272 273 extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) { 274 // SAFETY: All of our objects are of type `Object<T>`. 275 - let this = unsafe { crate::container_of!(obj, Self, obj) }.cast_mut(); 276 277 // SAFETY: The C code only ever calls this callback with a valid pointer to a `struct 278 // drm_gem_object`.
··· 125 } 126 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 + 130 // SAFETY: `obj` is guaranteed to be in an `Object<T>` via the safety contract of this 131 // function 132 unsafe { &*crate::container_of!(self_ptr, Object<T>, obj) } ··· 269 } 270 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 // SAFETY: All of our objects are of type `Object<T>`. 275 + let this = unsafe { crate::container_of!(ptr, Self, obj) }; 276 277 // SAFETY: The C code only ever calls this callback with a valid pointer to a `struct 278 // drm_gem_object`.
+30 -7
rust/kernel/kunit.rs
··· 6 //! 7 //! Reference: <https://docs.kernel.org/dev-tools/kunit/index.html> 8 9 use core::{ffi::c_void, fmt}; 10 11 /// Prints a KUnit error-level message. ··· 41 } 42 } 43 44 - use macros::kunit_tests; 45 - 46 /// Asserts that a boolean expression is `true` at runtime. 47 /// 48 /// Public but hidden since it should only be used from generated tests. ··· 58 } 59 60 static FILE: &'static $crate::str::CStr = $crate::c_str!($file); 61 - static LINE: i32 = core::line!() as i32 - $diff; 62 static CONDITION: &'static $crate::str::CStr = $crate::c_str!(stringify!($condition)); 63 64 // SAFETY: FFI call without safety requirements. ··· 129 unsafe { 130 $crate::bindings::__kunit_do_failed_assertion( 131 kunit_test, 132 - core::ptr::addr_of!(LOCATION.0), 133 $crate::bindings::kunit_assert_type_KUNIT_ASSERTION, 134 - core::ptr::addr_of!(ASSERTION.0.assert), 135 Some($crate::bindings::kunit_unary_assert_format), 136 - core::ptr::null(), 137 ); 138 } 139 ··· 161 // KUnit supports only a few types (e.g. integers). 162 $crate::kunit_assert!($name, $file, $diff, $left == $right); 163 }}; 164 } 165 166 /// Represents an individual test case. ··· 347 348 #[test] 349 fn rust_test_kunit_example_test() { 350 - #![expect(clippy::eq_op)] 351 assert_eq!(1 + 1, 2); 352 } 353
··· 6 //! 7 //! Reference: <https://docs.kernel.org/dev-tools/kunit/index.html> 8 9 + use crate::prelude::*; 10 use core::{ffi::c_void, fmt}; 11 12 /// Prints a KUnit error-level message. ··· 40 } 41 } 42 43 /// Asserts that a boolean expression is `true` at runtime. 44 /// 45 /// Public but hidden since it should only be used from generated tests. ··· 59 } 60 61 static FILE: &'static $crate::str::CStr = $crate::c_str!($file); 62 + static LINE: i32 = ::core::line!() as i32 - $diff; 63 static CONDITION: &'static $crate::str::CStr = $crate::c_str!(stringify!($condition)); 64 65 // SAFETY: FFI call without safety requirements. ··· 130 unsafe { 131 $crate::bindings::__kunit_do_failed_assertion( 132 kunit_test, 133 + ::core::ptr::addr_of!(LOCATION.0), 134 $crate::bindings::kunit_assert_type_KUNIT_ASSERTION, 135 + ::core::ptr::addr_of!(ASSERTION.0.assert), 136 Some($crate::bindings::kunit_unary_assert_format), 137 + ::core::ptr::null(), 138 ); 139 } 140 ··· 162 // KUnit supports only a few types (e.g. integers). 163 $crate::kunit_assert!($name, $file, $diff, $left == $right); 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() 190 } 191 192 /// Represents an individual test case. ··· 323 324 #[test] 325 fn rust_test_kunit_example_test() { 326 assert_eq!(1 + 1, 2); 327 } 328
+33 -12
rust/kernel/lib.rs
··· 12 //! do so first instead of bypassing this crate. 13 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))] 20 #![feature(inline_const)] 21 #![feature(lint_reasons)] 22 - // Stable in Rust 1.82 23 #![feature(raw_ref_op)] 24 - // Stable in Rust 1.83 25 #![feature(const_maybe_uninit_as_mut_ptr)] 26 #![feature(const_mut_refs)] 27 #![feature(const_ptr_write)] 28 #![feature(const_refs_to_cell)] 29 30 // Ensure conditional compilation based on the kernel configuration works; 31 // otherwise we may silently break things like initcall handling. ··· 116 pub mod types; 117 pub mod uaccess; 118 pub mod workqueue; 119 120 #[doc(hidden)] 121 pub use bindings; ··· 219 /// } 220 /// 221 /// let test = Test { a: 10, b: 20 }; 222 - /// let b_ptr = &test.b; 223 /// // SAFETY: The pointer points at the `b` field of a `Test`, so the resulting pointer will be 224 /// // in-bounds of the same allocation as `b_ptr`. 225 /// let test_alias = unsafe { container_of!(b_ptr, Test, b) }; ··· 227 /// ``` 228 #[macro_export] 229 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 234 }} 235 } 236 237 /// Helper for `.rs.S` files. 238 #[doc(hidden)]
··· 12 //! do so first instead of bypassing this crate. 13 14 #![no_std] 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 #![feature(inline_const)] 21 + // 22 + // Stable since Rust 1.81.0. 23 #![feature(lint_reasons)] 24 + // 25 + // Stable since Rust 1.82.0. 26 #![feature(raw_ref_op)] 27 + // 28 + // Stable since Rust 1.83.0. 29 #![feature(const_maybe_uninit_as_mut_ptr)] 30 #![feature(const_mut_refs)] 31 #![feature(const_ptr_write)] 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))] 43 44 // Ensure conditional compilation based on the kernel configuration works; 45 // otherwise we may silently break things like initcall handling. ··· 102 pub mod types; 103 pub mod uaccess; 104 pub mod workqueue; 105 + pub mod xarray; 106 107 #[doc(hidden)] 108 pub use bindings; ··· 204 /// } 205 /// 206 /// let test = Test { a: 10, b: 20 }; 207 + /// let b_ptr: *const _ = &test.b; 208 /// // SAFETY: The pointer points at the `b` field of a `Test`, so the resulting pointer will be 209 /// // in-bounds of the same allocation as `b_ptr`. 210 /// let test_alias = unsafe { container_of!(b_ptr, Test, b) }; ··· 212 /// ``` 213 #[macro_export] 214 macro_rules! container_of { 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 221 }} 222 } 223 + 224 + /// Helper for [`container_of!`]. 225 + #[doc(hidden)] 226 + pub fn assert_same_type<T>(_: T, _: T) {} 227 228 /// Helper for `.rs.S` files. 229 #[doc(hidden)]
+110 -5
rust/kernel/list.rs
··· 4 5 //! A linked list implementation. 6 7 - // May not be needed in Rust 1.87.0 (pending beta backport). 8 - #![allow(clippy::ptr_eq)] 9 - 10 use crate::sync::ArcBorrow; 11 use crate::types::Opaque; 12 use core::iter::{DoubleEndedIterator, FusedIterator}; ··· 35 /// * All prev/next pointers in `ListLinks` fields of items in the list are valid and form a cycle. 36 /// * For every item in the list, the list owns the associated [`ListArc`] reference and has 37 /// exclusive access to the `ListLinks` field. 38 pub struct List<T: ?Sized + ListItem<ID>, const ID: u64 = 0> { 39 first: *mut ListLinksFields, 40 _ty: PhantomData<ListArc<T, ID>>, ··· 427 428 /// Removes the last item from this list. 429 pub fn pop_back(&mut self) -> Option<ListArc<T, ID>> { 430 - if self.first.is_null() { 431 return None; 432 } 433 ··· 439 440 /// Removes the first item from this list. 441 pub fn pop_front(&mut self) -> Option<ListArc<T, ID>> { 442 - if self.first.is_null() { 443 return None; 444 } 445
··· 4 5 //! A linked list implementation. 6 7 use crate::sync::ArcBorrow; 8 use crate::types::Opaque; 9 use core::iter::{DoubleEndedIterator, FusedIterator}; ··· 38 /// * All prev/next pointers in `ListLinks` fields of items in the list are valid and form a cycle. 39 /// * For every item in the list, the list owns the associated [`ListArc`] reference and has 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 + /// ``` 149 pub struct List<T: ?Sized + ListItem<ID>, const ID: u64 = 0> { 150 first: *mut ListLinksFields, 151 _ty: PhantomData<ListArc<T, ID>>, ··· 322 323 /// Removes the last item from this list. 324 pub fn pop_back(&mut self) -> Option<ListArc<T, ID>> { 325 + if self.is_empty() { 326 return None; 327 } 328 ··· 334 335 /// Removes the first item from this list. 336 pub fn pop_front(&mut self) -> Option<ListArc<T, ID>> { 337 + if self.is_empty() { 338 return None; 339 } 340
+3 -3
rust/kernel/list/arc.rs
··· 74 /// 75 /// * The `untracked` strategy does not actually keep track of whether a [`ListArc`] exists. When 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 78 /// which field to defer the tracking to. The field must implement [`ListArcSafe`]. If the field 79 /// implements [`TryNewListArc`], then the type will also implement [`TryNewListArc`]. 80 /// ··· 96 } $($rest:tt)*) => { 97 impl$(<$($generics)*>)? $crate::list::ListArcSafe<$num> for $t { 98 unsafe fn on_create_list_arc_from_unique(self: ::core::pin::Pin<&mut Self>) { 99 - $crate::assert_pinned!($t, $field, $fty, inline); 100 101 // SAFETY: This field is structurally pinned as per the above assertion. 102 let field = unsafe { ··· 464 465 /// A utility for tracking whether a [`ListArc`] exists using an atomic. 466 /// 467 - /// # Invariant 468 /// 469 /// If the boolean is `false`, then there is no [`ListArc`] for this value. 470 #[repr(transparent)]
··· 74 /// 75 /// * The `untracked` strategy does not actually keep track of whether a [`ListArc`] exists. When 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 must specify 78 /// which field to defer the tracking to. The field must implement [`ListArcSafe`]. If the field 79 /// implements [`TryNewListArc`], then the type will also implement [`TryNewListArc`]. 80 /// ··· 96 } $($rest:tt)*) => { 97 impl$(<$($generics)*>)? $crate::list::ListArcSafe<$num> for $t { 98 unsafe fn on_create_list_arc_from_unique(self: ::core::pin::Pin<&mut Self>) { 99 + ::pin_init::assert_pinned!($t, $field, $fty, inline); 100 101 // SAFETY: This field is structurally pinned as per the above assertion. 102 let field = unsafe { ··· 464 465 /// A utility for tracking whether a [`ListArc`] exists using an atomic. 466 /// 467 + /// # Invariants 468 /// 469 /// If the boolean is `false`, then there is no [`ListArc`] for this value. 470 #[repr(transparent)]
+6 -6
rust/kernel/miscdevice.rs
··· 217 // type. 218 // 219 // SAFETY: The open call of a file can access the private data. 220 - unsafe { (*raw_file).private_data = ptr.into_foreign() }; 221 222 0 223 } ··· 228 /// must be associated with a `MiscDeviceRegistration<T>`. 229 unsafe extern "C" fn release(_inode: *mut bindings::inode, file: *mut bindings::file) -> c_int { 230 // SAFETY: The release call of a file owns the private data. 231 - let private = unsafe { (*file).private_data }; 232 // SAFETY: The release call of a file owns the private data. 233 let ptr = unsafe { <T::Ptr as ForeignOwnable>::from_foreign(private) }; 234 ··· 253 // SAFETY: This is a Rust Miscdevice, so we call `into_foreign` in `open` and 254 // `from_foreign` in `release`, and `fops_mmap` is guaranteed to be called between those 255 // two operations. 256 - let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 257 // SAFETY: The caller provides a vma that is undergoing initial VMA setup. 258 let area = unsafe { VmaNew::from_raw(vma) }; 259 // SAFETY: ··· 272 /// `file` must be a valid file that is associated with a `MiscDeviceRegistration<T>`. 273 unsafe extern "C" fn ioctl(file: *mut bindings::file, cmd: c_uint, arg: c_ulong) -> c_long { 274 // SAFETY: The ioctl call of a file can access the private data. 275 - let private = unsafe { (*file).private_data }; 276 // SAFETY: Ioctl calls can borrow the private data of the file. 277 let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 278 ··· 297 arg: c_ulong, 298 ) -> c_long { 299 // SAFETY: The compat ioctl call of a file can access the private data. 300 - let private = unsafe { (*file).private_data }; 301 // SAFETY: Ioctl calls can borrow the private data of the file. 302 let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 303 ··· 318 /// - `seq_file` must be a valid `struct seq_file` that we can write to. 319 unsafe extern "C" fn show_fdinfo(seq_file: *mut bindings::seq_file, file: *mut bindings::file) { 320 // SAFETY: The release call of a file owns the private data. 321 - let private = unsafe { (*file).private_data }; 322 // SAFETY: Ioctl calls can borrow the private data of the file. 323 let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 324 // SAFETY:
··· 217 // type. 218 // 219 // SAFETY: The open call of a file can access the private data. 220 + unsafe { (*raw_file).private_data = ptr.into_foreign().cast() }; 221 222 0 223 } ··· 228 /// must be associated with a `MiscDeviceRegistration<T>`. 229 unsafe extern "C" fn release(_inode: *mut bindings::inode, file: *mut bindings::file) -> c_int { 230 // SAFETY: The release call of a file owns the private data. 231 + let private = unsafe { (*file).private_data }.cast(); 232 // SAFETY: The release call of a file owns the private data. 233 let ptr = unsafe { <T::Ptr as ForeignOwnable>::from_foreign(private) }; 234 ··· 253 // SAFETY: This is a Rust Miscdevice, so we call `into_foreign` in `open` and 254 // `from_foreign` in `release`, and `fops_mmap` is guaranteed to be called between those 255 // two operations. 256 + let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private.cast()) }; 257 // SAFETY: The caller provides a vma that is undergoing initial VMA setup. 258 let area = unsafe { VmaNew::from_raw(vma) }; 259 // SAFETY: ··· 272 /// `file` must be a valid file that is associated with a `MiscDeviceRegistration<T>`. 273 unsafe extern "C" fn ioctl(file: *mut bindings::file, cmd: c_uint, arg: c_ulong) -> c_long { 274 // SAFETY: The ioctl call of a file can access the private data. 275 + let private = unsafe { (*file).private_data }.cast(); 276 // SAFETY: Ioctl calls can borrow the private data of the file. 277 let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 278 ··· 297 arg: c_ulong, 298 ) -> c_long { 299 // SAFETY: The compat ioctl call of a file can access the private data. 300 + let private = unsafe { (*file).private_data }.cast(); 301 // SAFETY: Ioctl calls can borrow the private data of the file. 302 let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 303 ··· 318 /// - `seq_file` must be a valid `struct seq_file` that we can write to. 319 unsafe extern "C" fn show_fdinfo(seq_file: *mut bindings::seq_file, file: *mut bindings::file) { 320 // SAFETY: The release call of a file owns the private data. 321 + let private = unsafe { (*file).private_data }.cast(); 322 // SAFETY: Ioctl calls can borrow the private data of the file. 323 let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) }; 324 // SAFETY:
+2
rust/kernel/page.rs
··· 69 /// let page = Page::alloc_page(GFP_KERNEL | __GFP_ZERO)?; 70 /// # Ok::<(), kernel::alloc::AllocError>(()) 71 /// ``` 72 pub fn alloc_page(flags: Flags) -> Result<Self, AllocError> { 73 // SAFETY: Depending on the value of `gfp_flags`, this call may sleep. Other than that, it 74 // is always safe to call this method. ··· 252 } 253 254 impl Drop for Page { 255 fn drop(&mut self) { 256 // SAFETY: By the type invariants, we have ownership of the page and can free it. 257 unsafe { bindings::__free_pages(self.page.as_ptr(), 0) };
··· 69 /// let page = Page::alloc_page(GFP_KERNEL | __GFP_ZERO)?; 70 /// # Ok::<(), kernel::alloc::AllocError>(()) 71 /// ``` 72 + #[inline] 73 pub fn alloc_page(flags: Flags) -> Result<Self, AllocError> { 74 // SAFETY: Depending on the value of `gfp_flags`, this call may sleep. Other than that, it 75 // is always safe to call this method. ··· 251 } 252 253 impl Drop for Page { 254 + #[inline] 255 fn drop(&mut self) { 256 // SAFETY: By the type invariants, we have ownership of the page and can free it. 257 unsafe { bindings::__free_pages(self.page.as_ptr(), 0) };
+10 -7
rust/kernel/pci.rs
··· 89 extern "C" fn remove_callback(pdev: *mut bindings::pci_dev) { 90 // SAFETY: The PCI bus only ever calls the remove callback with a valid pointer to a 91 // `struct pci_dev`. 92 - let ptr = unsafe { bindings::pci_get_drvdata(pdev) }; 93 94 // SAFETY: `remove_callback` is only ever called after a successful call to 95 // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized ··· 118 }; 119 } 120 121 - /// Abstraction for bindings::pci_device_id. 122 #[repr(transparent)] 123 #[derive(Clone, Copy)] 124 pub struct DeviceId(bindings::pci_device_id); ··· 175 } 176 } 177 178 - /// IdTable type for PCI 179 pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>; 180 181 /// Create a PCI `IdTable` with its alias for modpost. ··· 226 /// `Adapter` documentation for an example. 227 pub trait Driver: Send { 228 /// 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 = (); 233 type IdInfo: 'static; 234 235 /// The table of device ids supported by the driver.
··· 89 extern "C" fn remove_callback(pdev: *mut bindings::pci_dev) { 90 // SAFETY: The PCI bus only ever calls the remove callback with a valid pointer to a 91 // `struct pci_dev`. 92 + let ptr = unsafe { bindings::pci_get_drvdata(pdev) }.cast(); 93 94 // SAFETY: `remove_callback` is only ever called after a successful call to 95 // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized ··· 118 }; 119 } 120 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 124 #[repr(transparent)] 125 #[derive(Clone, Copy)] 126 pub struct DeviceId(bindings::pci_device_id); ··· 173 } 174 } 175 176 + /// `IdTable` type for PCI. 177 pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>; 178 179 /// Create a PCI `IdTable` with its alias for modpost. ··· 224 /// `Adapter` documentation for an example. 225 pub trait Driver: Send { 226 /// The type holding information about each device id supported by the driver. 227 + // TODO: Use `associated_type_defaults` once stabilized: 228 + // 229 + // ``` 230 + // type IdInfo: 'static = (); 231 + // ``` 232 type IdInfo: 'static; 233 234 /// The table of device ids supported by the driver.
+6 -5
rust/kernel/platform.rs
··· 79 80 extern "C" fn remove_callback(pdev: *mut bindings::platform_device) { 81 // SAFETY: `pdev` is a valid pointer to a `struct platform_device`. 82 - let ptr = unsafe { bindings::platform_get_drvdata(pdev) }; 83 84 // SAFETY: `remove_callback` is only ever called after a successful call to 85 // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized ··· 150 ///``` 151 pub trait Driver: Send { 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 = (); 157 type IdInfo: 'static; 158 159 /// The table of OF device ids supported by the driver.
··· 79 80 extern "C" fn remove_callback(pdev: *mut bindings::platform_device) { 81 // SAFETY: `pdev` is a valid pointer to a `struct platform_device`. 82 + let ptr = unsafe { bindings::platform_get_drvdata(pdev) }.cast(); 83 84 // SAFETY: `remove_callback` is only ever called after a successful call to 85 // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized ··· 150 ///``` 151 pub trait Driver: Send { 152 /// The type holding driver private data about each device id supported by the driver. 153 + // TODO: Use associated_type_defaults once stabilized: 154 + // 155 + // ``` 156 + // type IdInfo: 'static = (); 157 + // ``` 158 type IdInfo: 'static; 159 160 /// The table of OF device ids supported by the driver.
+6 -1
rust/kernel/prelude.rs
··· 14 #[doc(no_inline)] 15 pub use core::pin::Pin; 16 17 pub use crate::alloc::{flags::*, Box, KBox, KVBox, KVVec, KVec, VBox, VVec, Vec}; 18 19 #[doc(no_inline)] 20 - pub use macros::{export, module, vtable}; 21 22 pub use pin_init::{init, pin_data, pin_init, pinned_drop, InPlaceWrite, Init, PinInit, Zeroable}; 23
··· 14 #[doc(no_inline)] 15 pub use core::pin::Pin; 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 + 22 pub use crate::alloc::{flags::*, Box, KBox, KVBox, KVVec, KVec, VBox, VVec, Vec}; 23 24 #[doc(no_inline)] 25 + pub use macros::{export, kunit_tests, module, vtable}; 26 27 pub use pin_init::{init, pin_data, pin_init, pinned_drop, InPlaceWrite, Init, PinInit, Zeroable}; 28
+18 -9
rust/kernel/print.rs
··· 198 /// Equivalent to the kernel's [`pr_emerg`] macro. 199 /// 200 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 201 - /// `alloc::format!` for information about the formatting syntax. 202 /// 203 /// [`pr_emerg`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_emerg 204 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 205 /// 206 /// # Examples 207 /// ··· 223 /// Equivalent to the kernel's [`pr_alert`] macro. 224 /// 225 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 226 - /// `alloc::format!` for information about the formatting syntax. 227 /// 228 /// [`pr_alert`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_alert 229 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 230 /// 231 /// # Examples 232 /// ··· 248 /// Equivalent to the kernel's [`pr_crit`] macro. 249 /// 250 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 251 - /// `alloc::format!` for information about the formatting syntax. 252 /// 253 /// [`pr_crit`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_crit 254 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 255 /// 256 /// # Examples 257 /// ··· 273 /// Equivalent to the kernel's [`pr_err`] macro. 274 /// 275 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 276 - /// `alloc::format!` for information about the formatting syntax. 277 /// 278 /// [`pr_err`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_err 279 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 280 /// 281 /// # Examples 282 /// ··· 298 /// Equivalent to the kernel's [`pr_warn`] macro. 299 /// 300 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 301 - /// `alloc::format!` for information about the formatting syntax. 302 /// 303 /// [`pr_warn`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_warn 304 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 305 /// 306 /// # Examples 307 /// ··· 323 /// Equivalent to the kernel's [`pr_notice`] macro. 324 /// 325 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 326 - /// `alloc::format!` for information about the formatting syntax. 327 /// 328 /// [`pr_notice`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_notice 329 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 330 /// 331 /// # Examples 332 /// ··· 348 /// Equivalent to the kernel's [`pr_info`] macro. 349 /// 350 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 351 - /// `alloc::format!` for information about the formatting syntax. 352 /// 353 /// [`pr_info`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_info 354 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 355 /// 356 /// # Examples 357 /// ··· 375 /// yet. 376 /// 377 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 378 - /// `alloc::format!` for information about the formatting syntax. 379 /// 380 /// [`pr_debug`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_debug 381 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 382 /// 383 /// # Examples 384 /// ··· 403 /// Equivalent to the kernel's [`pr_cont`] macro. 404 /// 405 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 406 - /// `alloc::format!` for information about the formatting syntax. 407 /// 408 /// [`pr_info!`]: crate::pr_info! 409 /// [`pr_cont`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_cont 410 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 411 /// 412 /// # Examples 413 ///
··· 198 /// Equivalent to the kernel's [`pr_emerg`] macro. 199 /// 200 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 201 + /// [`std::format!`] for information about the formatting syntax. 202 /// 203 /// [`pr_emerg`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_emerg 204 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 205 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 206 /// 207 /// # Examples 208 /// ··· 222 /// Equivalent to the kernel's [`pr_alert`] macro. 223 /// 224 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 225 + /// [`std::format!`] for information about the formatting syntax. 226 /// 227 /// [`pr_alert`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_alert 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 /// 231 /// # Examples 232 /// ··· 246 /// Equivalent to the kernel's [`pr_crit`] macro. 247 /// 248 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 249 + /// [`std::format!`] for information about the formatting syntax. 250 /// 251 /// [`pr_crit`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_crit 252 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 253 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 254 /// 255 /// # Examples 256 /// ··· 270 /// Equivalent to the kernel's [`pr_err`] macro. 271 /// 272 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 273 + /// [`std::format!`] for information about the formatting syntax. 274 /// 275 /// [`pr_err`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_err 276 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 277 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 278 /// 279 /// # Examples 280 /// ··· 294 /// Equivalent to the kernel's [`pr_warn`] macro. 295 /// 296 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 297 + /// [`std::format!`] for information about the formatting syntax. 298 /// 299 /// [`pr_warn`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_warn 300 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 301 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 302 /// 303 /// # Examples 304 /// ··· 318 /// Equivalent to the kernel's [`pr_notice`] macro. 319 /// 320 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 321 + /// [`std::format!`] for information about the formatting syntax. 322 /// 323 /// [`pr_notice`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_notice 324 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 325 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 326 /// 327 /// # Examples 328 /// ··· 342 /// Equivalent to the kernel's [`pr_info`] macro. 343 /// 344 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 345 + /// [`std::format!`] for information about the formatting syntax. 346 /// 347 /// [`pr_info`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_info 348 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 349 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 350 /// 351 /// # Examples 352 /// ··· 368 /// yet. 369 /// 370 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 371 + /// [`std::format!`] for information about the formatting syntax. 372 /// 373 /// [`pr_debug`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_debug 374 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 375 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 376 /// 377 /// # Examples 378 /// ··· 395 /// Equivalent to the kernel's [`pr_cont`] macro. 396 /// 397 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 398 + /// [`std::format!`] for information about the formatting syntax. 399 /// 400 /// [`pr_info!`]: crate::pr_info! 401 /// [`pr_cont`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_cont 402 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 403 + /// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html 404 /// 405 /// # Examples 406 ///
+10 -13
rust/kernel/rbtree.rs
··· 424 while !node.is_null() { 425 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 426 // point to the links field of `Node<K, V>` objects. 427 - let this = unsafe { container_of!(node, Node<K, V>, links) }.cast_mut(); 428 // SAFETY: `this` is a non-null node so it is valid by the type invariants. 429 let this_key = unsafe { &(*this).key }; 430 // SAFETY: `node` is a non-null node so it is valid by the type invariants. ··· 496 // but it is not observable. The loop invariant is still maintained. 497 498 // SAFETY: `this` is valid per the loop invariant. 499 - unsafe { drop(KBox::from_raw(this.cast_mut())) }; 500 } 501 } 502 } ··· 761 let next = self.get_neighbor_raw(Direction::Next); 762 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 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(); 765 // SAFETY: `this` is valid by the type invariants as described above. 766 let node = unsafe { KBox::from_raw(this) }; 767 let node = RBTreeNode { node }; ··· 806 unsafe { bindings::rb_erase(neighbor, addr_of_mut!(self.tree.root)) }; 807 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 808 // point to the links field of `Node<K, V>` objects. 809 - let this = unsafe { container_of!(neighbor, Node<K, V>, links) }.cast_mut(); 810 // SAFETY: `this` is valid by the type invariants as described above. 811 let node = unsafe { KBox::from_raw(this) }; 812 return Some(RBTreeNode { node }); ··· 912 unsafe fn to_key_value_raw<'b>(node: NonNull<bindings::rb_node>) -> (&'b K, *mut V) { 913 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 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(); 916 // SAFETY: The passed `node` is the current node or a non-null neighbor, 917 // thus `this` is valid by the type invariants. 918 let k = unsafe { &(*this).key }; ··· 1021 1022 // SAFETY: By the type invariant of `IterRaw`, `self.next` is a valid node in an `RBTree`, 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(); 1025 1026 // SAFETY: `self.next` is a valid tree node by the type invariants. 1027 self.next = unsafe { bindings::rb_next(self.next) }; ··· 1216 // SAFETY: 1217 // - `self.node_links` is a valid pointer to a node in the tree. 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 } 1220 } 1221 1222 /// Converts the entry into a mutable reference to its value. ··· 1226 // SAFETY: 1227 // - `self.node_links` is a valid pointer to a node in the tree. 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 } 1230 } 1231 1232 /// Remove this entry from the [`RBTree`]. ··· 1239 RBTreeNode { 1240 // SAFETY: The node was a node in the tree, but we removed it, so we can convert it 1241 // back into a box. 1242 - node: unsafe { 1243 - KBox::from_raw(container_of!(self.node_links, Node<K, V>, links).cast_mut()) 1244 - }, 1245 } 1246 } 1247 ··· 1270 // SAFETY: 1271 // - `self.node_ptr` produces a valid pointer to a node in the tree. 1272 // - 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 1276 RBTreeNode { node: old_node } 1277 }
··· 424 while !node.is_null() { 425 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 426 // point to the links field of `Node<K, V>` objects. 427 + let this = unsafe { container_of!(node, Node<K, V>, links) }; 428 // SAFETY: `this` is a non-null node so it is valid by the type invariants. 429 let this_key = unsafe { &(*this).key }; 430 // SAFETY: `node` is a non-null node so it is valid by the type invariants. ··· 496 // but it is not observable. The loop invariant is still maintained. 497 498 // SAFETY: `this` is valid per the loop invariant. 499 + unsafe { drop(KBox::from_raw(this)) }; 500 } 501 } 502 } ··· 761 let next = self.get_neighbor_raw(Direction::Next); 762 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 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) }; 765 // SAFETY: `this` is valid by the type invariants as described above. 766 let node = unsafe { KBox::from_raw(this) }; 767 let node = RBTreeNode { node }; ··· 806 unsafe { bindings::rb_erase(neighbor, addr_of_mut!(self.tree.root)) }; 807 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 808 // point to the links field of `Node<K, V>` objects. 809 + let this = unsafe { container_of!(neighbor, Node<K, V>, links) }; 810 // SAFETY: `this` is valid by the type invariants as described above. 811 let node = unsafe { KBox::from_raw(this) }; 812 return Some(RBTreeNode { node }); ··· 912 unsafe fn to_key_value_raw<'b>(node: NonNull<bindings::rb_node>) -> (&'b K, *mut V) { 913 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 914 // point to the links field of `Node<K, V>` objects. 915 + let this = unsafe { container_of!(node.as_ptr(), Node<K, V>, links) }; 916 // SAFETY: The passed `node` is the current node or a non-null neighbor, 917 // thus `this` is valid by the type invariants. 918 let k = unsafe { &(*this).key }; ··· 1021 1022 // SAFETY: By the type invariant of `IterRaw`, `self.next` is a valid node in an `RBTree`, 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) }; 1025 1026 // SAFETY: `self.next` is a valid tree node by the type invariants. 1027 self.next = unsafe { bindings::rb_next(self.next) }; ··· 1216 // SAFETY: 1217 // - `self.node_links` is a valid pointer to a node in the tree. 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))).value } 1220 } 1221 1222 /// Converts the entry into a mutable reference to its value. ··· 1226 // SAFETY: 1227 // - `self.node_links` is a valid pointer to a node in the tree. 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))).value } 1230 } 1231 1232 /// Remove this entry from the [`RBTree`]. ··· 1239 RBTreeNode { 1240 // SAFETY: The node was a node in the tree, but we removed it, so we can convert it 1241 // back into a box. 1242 + node: unsafe { KBox::from_raw(container_of!(self.node_links, Node<K, V>, links)) }, 1243 } 1244 } 1245 ··· 1272 // SAFETY: 1273 // - `self.node_ptr` produces a valid pointer to a node in the tree. 1274 // - Now that we removed this entry from the tree, we can convert the node to a box. 1275 + let old_node = unsafe { KBox::from_raw(container_of!(self.node_links, Node<K, V>, links)) }; 1276 1277 RBTreeNode { node: old_node } 1278 }
+7 -2
rust/kernel/static_assert.rs
··· 6 /// 7 /// Similar to C11 [`_Static_assert`] and C++11 [`static_assert`]. 8 /// 9 /// The feature may be added to Rust in the future: see [RFC 2790]. 10 /// 11 /// [`_Static_assert`]: https://en.cppreference.com/w/c/language/_Static_assert ··· 29 /// x + 2 30 /// } 31 /// static_assert!(f(40) == 42); 32 /// ``` 33 #[macro_export] 34 macro_rules! static_assert { 35 - ($condition:expr) => { 36 - const _: () = core::assert!($condition); 37 }; 38 }
··· 6 /// 7 /// Similar to C11 [`_Static_assert`] and C++11 [`static_assert`]. 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 + /// 13 /// The feature may be added to Rust in the future: see [RFC 2790]. 14 /// 15 /// [`_Static_assert`]: https://en.cppreference.com/w/c/language/_Static_assert ··· 25 /// x + 2 26 /// } 27 /// static_assert!(f(40) == 42); 28 + /// static_assert!(f(40) == 42, "f(x) must add 2 to the given input."); 29 /// ``` 30 #[macro_export] 31 macro_rules! static_assert { 32 + ($condition:expr $(,$arg:literal)?) => { 33 + const _: () = ::core::assert!($condition $(,$arg)?); 34 }; 35 }
+1 -1
rust/kernel/std_vendor.rs
··· 148 }; 149 ($val:expr $(,)?) => { 150 // Use of `match` here is intentional because it affects the lifetimes 151 - // of temporaries - https://stackoverflow.com/a/48732525/1063961 152 match $val { 153 tmp => { 154 $crate::pr_info!("[{}:{}:{}] {} = {:#?}\n",
··· 148 }; 149 ($val:expr $(,)?) => { 150 // Use of `match` here is intentional because it affects the lifetimes 151 + // of temporaries - <https://stackoverflow.com/a/48732525/1063961> 152 match $val { 153 tmp => { 154 $crate::pr_info!("[{}:{}:{}] {} = {:#?}\n",
+36 -46
rust/kernel/str.rs
··· 6 use core::fmt::{self, Write}; 7 use core::ops::{self, Deref, DerefMut, Index}; 8 9 - use crate::error::{code::*, Error}; 10 11 /// Byte string without UTF-8 validity guarantee. 12 #[repr(transparent)] ··· 572 }}; 573 } 574 575 - #[cfg(test)] 576 - #[expect(clippy::items_after_test_module)] 577 mod tests { 578 use super::*; 579 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 macro_rules! format { 597 ($($f:tt)*) => ({ 598 - &*String::from_fmt(kernel::fmt!($($f)*)) 599 }) 600 } 601 ··· 597 \\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff"; 598 599 #[test] 600 - fn test_cstr_to_str() { 601 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(); 604 assert_eq!(checked_str, "🦀"); 605 } 606 607 #[test] 608 - #[should_panic] 609 - fn test_cstr_to_str_panic() { 610 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(); 613 } 614 615 #[test] 616 - fn test_cstr_as_str_unchecked() { 617 let good_bytes = b"\xf0\x9f\x90\xA7\0"; 618 - let checked_cstr = CStr::from_bytes_with_nul(good_bytes).unwrap(); 619 // SAFETY: The contents come from a string literal which contains valid UTF-8. 620 let unchecked_str = unsafe { checked_cstr.as_str_unchecked() }; 621 assert_eq!(unchecked_str, "🐧"); 622 } 623 624 #[test] 625 - fn test_cstr_display() { 626 - let hello_world = CStr::from_bytes_with_nul(b"hello, world!\0").unwrap(); 627 assert_eq!(format!("{hello_world}"), "hello, world!"); 628 - let non_printables = CStr::from_bytes_with_nul(b"\x01\x09\x0a\0").unwrap(); 629 assert_eq!(format!("{non_printables}"), "\\x01\\x09\\x0a"); 630 - let non_ascii = CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0").unwrap(); 631 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(); 633 assert_eq!(format!("{good_bytes}"), "\\xf0\\x9f\\xa6\\x80"); 634 } 635 636 #[test] 637 - fn test_cstr_display_all_bytes() { 638 let mut bytes: [u8; 256] = [0; 256]; 639 // fill `bytes` with [1..=255] + [0] 640 for i in u8::MIN..=u8::MAX { 641 bytes[i as usize] = i.wrapping_add(1); 642 } 643 - let cstr = CStr::from_bytes_with_nul(&bytes).unwrap(); 644 assert_eq!(format!("{cstr}"), ALL_ASCII_CHARS); 645 } 646 647 #[test] 648 - fn test_cstr_debug() { 649 - let hello_world = CStr::from_bytes_with_nul(b"hello, world!\0").unwrap(); 650 assert_eq!(format!("{hello_world:?}"), "\"hello, world!\""); 651 - let non_printables = CStr::from_bytes_with_nul(b"\x01\x09\x0a\0").unwrap(); 652 assert_eq!(format!("{non_printables:?}"), "\"\\x01\\x09\\x0a\""); 653 - let non_ascii = CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0").unwrap(); 654 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(); 656 assert_eq!(format!("{good_bytes:?}"), "\"\\xf0\\x9f\\xa6\\x80\""); 657 } 658 659 #[test] 660 - fn test_bstr_display() { 661 let hello_world = BStr::from_bytes(b"hello, world!"); 662 assert_eq!(format!("{hello_world}"), "hello, world!"); 663 let escapes = BStr::from_bytes(b"_\t_\n_\r_\\_\'_\"_"); ··· 673 assert_eq!(format!("{non_ascii}"), "d\\xe9j\\xe0 vu"); 674 let good_bytes = BStr::from_bytes(b"\xf0\x9f\xa6\x80"); 675 assert_eq!(format!("{good_bytes}"), "\\xf0\\x9f\\xa6\\x80"); 676 } 677 678 #[test] 679 - fn test_bstr_debug() { 680 let hello_world = BStr::from_bytes(b"hello, world!"); 681 assert_eq!(format!("{hello_world:?}"), "\"hello, world!\""); 682 let escapes = BStr::from_bytes(b"_\t_\n_\r_\\_\'_\"_"); ··· 688 assert_eq!(format!("{non_ascii:?}"), "\"d\\xe9j\\xe0 vu\""); 689 let good_bytes = BStr::from_bytes(b"\xf0\x9f\xa6\x80"); 690 assert_eq!(format!("{good_bytes:?}"), "\"\\xf0\\x9f\\xa6\\x80\""); 691 } 692 } 693 ··· 742 /// for the lifetime of the returned [`RawFormatter`]. 743 pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self { 744 let pos = buf as usize; 745 - // INVARIANT: We ensure that `end` is never less then `buf`, and the safety requirements 746 // guarantees that the memory region is valid for writes. 747 Self { 748 pos, ··· 876 877 // SAFETY: The number of bytes that can be written to `f` is bounded by `size`, which is 878 // `buf`'s capacity. The contents of the buffer have been initialised by writes to `f`. 879 - unsafe { buf.set_len(f.bytes_written()) }; 880 881 // Check that there are no `NUL` bytes before the end. 882 // SAFETY: The buffer is valid for read because `f.bytes_written()` is bounded by `size` ··· 934 /// A convenience alias for [`core::format_args`]. 935 #[macro_export] 936 macro_rules! fmt { 937 - ($($f:tt)*) => ( core::format_args!($($f)*) ) 938 }
··· 6 use core::fmt::{self, Write}; 7 use core::ops::{self, Deref, DerefMut, Index}; 8 9 + use crate::prelude::*; 10 11 /// Byte string without UTF-8 validity guarantee. 12 #[repr(transparent)] ··· 572 }}; 573 } 574 575 + #[kunit_tests(rust_kernel_str)] 576 mod tests { 577 use super::*; 578 579 macro_rules! format { 580 ($($f:tt)*) => ({ 581 + CString::try_from_fmt(::kernel::fmt!($($f)*))?.to_str()? 582 }) 583 } 584 ··· 614 \\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff"; 615 616 #[test] 617 + fn test_cstr_to_str() -> Result { 618 let good_bytes = b"\xf0\x9f\xa6\x80\0"; 619 + let checked_cstr = CStr::from_bytes_with_nul(good_bytes)?; 620 + let checked_str = checked_cstr.to_str()?; 621 assert_eq!(checked_str, "🦀"); 622 + Ok(()) 623 } 624 625 #[test] 626 + fn test_cstr_to_str_invalid_utf8() -> Result { 627 let bad_bytes = b"\xc3\x28\0"; 628 + let checked_cstr = CStr::from_bytes_with_nul(bad_bytes)?; 629 + assert!(checked_cstr.to_str().is_err()); 630 + Ok(()) 631 } 632 633 #[test] 634 + fn test_cstr_as_str_unchecked() -> Result { 635 let good_bytes = b"\xf0\x9f\x90\xA7\0"; 636 + let checked_cstr = CStr::from_bytes_with_nul(good_bytes)?; 637 // SAFETY: The contents come from a string literal which contains valid UTF-8. 638 let unchecked_str = unsafe { checked_cstr.as_str_unchecked() }; 639 assert_eq!(unchecked_str, "🐧"); 640 + Ok(()) 641 } 642 643 #[test] 644 + fn test_cstr_display() -> Result { 645 + let hello_world = CStr::from_bytes_with_nul(b"hello, world!\0")?; 646 assert_eq!(format!("{hello_world}"), "hello, world!"); 647 + let non_printables = CStr::from_bytes_with_nul(b"\x01\x09\x0a\0")?; 648 assert_eq!(format!("{non_printables}"), "\\x01\\x09\\x0a"); 649 + let non_ascii = CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0")?; 650 assert_eq!(format!("{non_ascii}"), "d\\xe9j\\xe0 vu"); 651 + let good_bytes = CStr::from_bytes_with_nul(b"\xf0\x9f\xa6\x80\0")?; 652 assert_eq!(format!("{good_bytes}"), "\\xf0\\x9f\\xa6\\x80"); 653 + Ok(()) 654 } 655 656 #[test] 657 + fn test_cstr_display_all_bytes() -> Result { 658 let mut bytes: [u8; 256] = [0; 256]; 659 // fill `bytes` with [1..=255] + [0] 660 for i in u8::MIN..=u8::MAX { 661 bytes[i as usize] = i.wrapping_add(1); 662 } 663 + let cstr = CStr::from_bytes_with_nul(&bytes)?; 664 assert_eq!(format!("{cstr}"), ALL_ASCII_CHARS); 665 + Ok(()) 666 } 667 668 #[test] 669 + fn test_cstr_debug() -> Result { 670 + let hello_world = CStr::from_bytes_with_nul(b"hello, world!\0")?; 671 assert_eq!(format!("{hello_world:?}"), "\"hello, world!\""); 672 + let non_printables = CStr::from_bytes_with_nul(b"\x01\x09\x0a\0")?; 673 assert_eq!(format!("{non_printables:?}"), "\"\\x01\\x09\\x0a\""); 674 + let non_ascii = CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0")?; 675 assert_eq!(format!("{non_ascii:?}"), "\"d\\xe9j\\xe0 vu\""); 676 + let good_bytes = CStr::from_bytes_with_nul(b"\xf0\x9f\xa6\x80\0")?; 677 assert_eq!(format!("{good_bytes:?}"), "\"\\xf0\\x9f\\xa6\\x80\""); 678 + Ok(()) 679 } 680 681 #[test] 682 + fn test_bstr_display() -> Result { 683 let hello_world = BStr::from_bytes(b"hello, world!"); 684 assert_eq!(format!("{hello_world}"), "hello, world!"); 685 let escapes = BStr::from_bytes(b"_\t_\n_\r_\\_\'_\"_"); ··· 685 assert_eq!(format!("{non_ascii}"), "d\\xe9j\\xe0 vu"); 686 let good_bytes = BStr::from_bytes(b"\xf0\x9f\xa6\x80"); 687 assert_eq!(format!("{good_bytes}"), "\\xf0\\x9f\\xa6\\x80"); 688 + Ok(()) 689 } 690 691 #[test] 692 + fn test_bstr_debug() -> Result { 693 let hello_world = BStr::from_bytes(b"hello, world!"); 694 assert_eq!(format!("{hello_world:?}"), "\"hello, world!\""); 695 let escapes = BStr::from_bytes(b"_\t_\n_\r_\\_\'_\"_"); ··· 699 assert_eq!(format!("{non_ascii:?}"), "\"d\\xe9j\\xe0 vu\""); 700 let good_bytes = BStr::from_bytes(b"\xf0\x9f\xa6\x80"); 701 assert_eq!(format!("{good_bytes:?}"), "\"\\xf0\\x9f\\xa6\\x80\""); 702 + Ok(()) 703 } 704 } 705 ··· 752 /// for the lifetime of the returned [`RawFormatter`]. 753 pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self { 754 let pos = buf as usize; 755 + // INVARIANT: We ensure that `end` is never less than `buf`, and the safety requirements 756 // guarantees that the memory region is valid for writes. 757 Self { 758 pos, ··· 886 887 // SAFETY: The number of bytes that can be written to `f` is bounded by `size`, which is 888 // `buf`'s capacity. The contents of the buffer have been initialised by writes to `f`. 889 + unsafe { buf.inc_len(f.bytes_written()) }; 890 891 // Check that there are no `NUL` bytes before the end. 892 // SAFETY: The buffer is valid for read because `f.bytes_written()` is bounded by `size` ··· 944 /// A convenience alias for [`core::format_args`]. 945 #[macro_export] 946 macro_rules! fmt { 947 + ($($f:tt)*) => ( ::core::format_args!($($f)*) ) 948 }
+14 -11
rust/kernel/sync/arc.rs
··· 135 // meaningful with respect to dropck - but this may change in the future so this is left here 136 // out of an abundance of caution. 137 // 138 - // See https://doc.rust-lang.org/nomicon/phantom-data.html#generic-parameters-and-drop-checking 139 // for more detail on the semantics of dropck in the presence of `PhantomData`. 140 _p: PhantomData<ArcInner<T>>, 141 } 142 143 #[pin_data] 144 #[repr(C)] 145 - struct ArcInner<T: ?Sized> { 146 refcount: Opaque<bindings::refcount_t>, 147 data: T, 148 } ··· 372 } 373 } 374 375 - impl<T: 'static> ForeignOwnable for Arc<T> { 376 type Borrowed<'a> = ArcBorrow<'a, T>; 377 type BorrowedMut<'a> = Self::Borrowed<'a>; 378 379 - fn into_foreign(self) -> *mut crate::ffi::c_void { 380 - ManuallyDrop::new(self).ptr.as_ptr().cast() 381 } 382 383 - unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self { 384 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 385 // call to `Self::into_foreign`. 386 - let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) }; 387 388 // SAFETY: By the safety requirement of this function, we know that `ptr` came from 389 // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and ··· 393 unsafe { Self::from_inner(inner) } 394 } 395 396 - unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> { 397 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 398 // call to `Self::into_foreign`. 399 - let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) }; 400 401 // SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive 402 // for the lifetime of the returned value. 403 unsafe { ArcBorrow::new(inner) } 404 } 405 406 - unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> { 407 // SAFETY: The safety requirements for `borrow_mut` are a superset of the safety 408 // requirements for `borrow`. 409 unsafe { Self::borrow(ptr) } ··· 492 /// There are no mutable references to the underlying [`Arc`], and it remains valid for the 493 /// lifetime of the [`ArcBorrow`] instance. 494 /// 495 - /// # Example 496 /// 497 /// ``` 498 /// use kernel::sync::{Arc, ArcBorrow};
··· 135 // meaningful with respect to dropck - but this may change in the future so this is left here 136 // out of an abundance of caution. 137 // 138 + // See <https://doc.rust-lang.org/nomicon/phantom-data.html#generic-parameters-and-drop-checking> 139 // for more detail on the semantics of dropck in the presence of `PhantomData`. 140 _p: PhantomData<ArcInner<T>>, 141 } 142 143 + #[doc(hidden)] 144 #[pin_data] 145 #[repr(C)] 146 + pub struct ArcInner<T: ?Sized> { 147 refcount: Opaque<bindings::refcount_t>, 148 data: T, 149 } ··· 371 } 372 } 373 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>; 377 type Borrowed<'a> = ArcBorrow<'a, T>; 378 type BorrowedMut<'a> = Self::Borrowed<'a>; 379 380 + fn into_foreign(self) -> *mut Self::PointedTo { 381 + ManuallyDrop::new(self).ptr.as_ptr() 382 } 383 384 + unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self { 385 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 386 // call to `Self::into_foreign`. 387 + let inner = unsafe { NonNull::new_unchecked(ptr) }; 388 389 // SAFETY: By the safety requirement of this function, we know that `ptr` came from 390 // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and ··· 390 unsafe { Self::from_inner(inner) } 391 } 392 393 + unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> ArcBorrow<'a, T> { 394 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 395 // call to `Self::into_foreign`. 396 + let inner = unsafe { NonNull::new_unchecked(ptr) }; 397 398 // SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive 399 // for the lifetime of the returned value. 400 unsafe { ArcBorrow::new(inner) } 401 } 402 403 + unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> ArcBorrow<'a, T> { 404 // SAFETY: The safety requirements for `borrow_mut` are a superset of the safety 405 // requirements for `borrow`. 406 unsafe { Self::borrow(ptr) } ··· 489 /// There are no mutable references to the underlying [`Arc`], and it remains valid for the 490 /// lifetime of the [`ArcBorrow`] instance. 491 /// 492 + /// # Examples 493 /// 494 /// ``` 495 /// use kernel::sync::{Arc, ArcBorrow};
+135 -46
rust/kernel/time.rs
··· 5 //! This module contains the kernel APIs related to time and timers that 6 //! have been ported or wrapped for usage by Rust code in the kernel. 7 //! 8 //! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h). 9 //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h). 10 11 pub mod hrtimer; 12 13 /// The number of nanoseconds per millisecond. 14 pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64; 15 16 /// The time unit of Linux kernel. One jiffy equals (1/HZ) second. 17 pub type Jiffies = crate::ffi::c_ulong; ··· 49 unsafe { bindings::__msecs_to_jiffies(msecs) } 50 } 51 52 - /// A Rust wrapper around a `ktime_t`. 53 #[repr(transparent)] 54 - #[derive(Copy, Clone)] 55 - pub struct Ktime { 56 inner: bindings::ktime_t, 57 } 58 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 - 66 /// Get the current time using `CLOCK_MONOTONIC`. 67 #[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 { 103 Self { 104 - inner: self.inner - other.inner, 105 } 106 } 107 } ··· 154 impl ClockId { 155 fn into_c(self) -> bindings::clockid_t { 156 self as bindings::clockid_t 157 } 158 }
··· 5 //! This module contains the kernel APIs related to time and timers that 6 //! have been ported or wrapped for usage by Rust code in the kernel. 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 + //! 24 //! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h). 25 //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h). 26 27 pub mod hrtimer; 28 29 + /// The number of nanoseconds per microsecond. 30 + pub const NSEC_PER_USEC: i64 = bindings::NSEC_PER_USEC as i64; 31 + 32 /// The number of nanoseconds per millisecond. 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; 37 38 /// The time unit of Linux kernel. One jiffy equals (1/HZ) second. 39 pub type Jiffies = crate::ffi::c_ulong; ··· 27 unsafe { bindings::__msecs_to_jiffies(msecs) } 28 } 29 30 + /// A specific point in time. 31 + /// 32 + /// # Invariants 33 + /// 34 + /// The `inner` value is in the range from 0 to `KTIME_MAX`. 35 #[repr(transparent)] 36 + #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] 37 + pub struct Instant { 38 inner: bindings::ktime_t, 39 } 40 41 + impl Instant { 42 /// Get the current time using `CLOCK_MONOTONIC`. 43 #[inline] 44 + pub fn now() -> Self { 45 + // INVARIANT: The `ktime_get()` function returns a value in the range 46 + // from 0 to `KTIME_MAX`. 47 Self { 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, 68 } 69 } 70 } ··· 147 impl ClockId { 148 fn into_c(self) -> bindings::clockid_t { 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 232 } 233 }
+19 -5
rust/kernel/time/hrtimer.rs
··· 68 //! `start` operation. 69 70 use super::ClockId; 71 - use crate::{prelude::*, time::Ktime, types::Opaque}; 72 use core::marker::PhantomData; 73 use pin_init::PinInit; 74 75 /// A timer backed by a C `struct hrtimer`. 76 /// ··· 400 #[repr(u32)] 401 pub enum HrTimerRestart { 402 /// Timer should not be restarted. 403 - #[allow(clippy::unnecessary_cast)] 404 - NoRestart = bindings::hrtimer_restart_HRTIMER_NORESTART as u32, 405 /// Timer should be restarted. 406 - #[allow(clippy::unnecessary_cast)] 407 - Restart = bindings::hrtimer_restart_HRTIMER_RESTART as u32, 408 } 409 410 impl HrTimerRestart {
··· 68 //! `start` operation. 69 70 use super::ClockId; 71 + use crate::{prelude::*, types::Opaque}; 72 use core::marker::PhantomData; 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 + } 90 91 /// A timer backed by a C `struct hrtimer`. 92 /// ··· 384 #[repr(u32)] 385 pub enum HrTimerRestart { 386 /// Timer should not be restarted. 387 + NoRestart = bindings::hrtimer_restart_HRTIMER_NORESTART, 388 /// Timer should be restarted. 389 + Restart = bindings::hrtimer_restart_HRTIMER_RESTART, 390 } 391 392 impl HrTimerRestart {
+1 -1
rust/kernel/time/hrtimer/arc.rs
··· 5 use super::HrTimerCallback; 6 use super::HrTimerHandle; 7 use super::HrTimerPointer; 8 use super::RawHrTimerCallback; 9 use crate::sync::Arc; 10 use crate::sync::ArcBorrow; 11 - use crate::time::Ktime; 12 13 /// A handle for an `Arc<HasHrTimer<T>>` returned by a call to 14 /// [`HrTimerPointer::start`].
··· 5 use super::HrTimerCallback; 6 use super::HrTimerHandle; 7 use super::HrTimerPointer; 8 + use super::Ktime; 9 use super::RawHrTimerCallback; 10 use crate::sync::Arc; 11 use crate::sync::ArcBorrow; 12 13 /// A handle for an `Arc<HasHrTimer<T>>` returned by a call to 14 /// [`HrTimerPointer::start`].
+1 -1
rust/kernel/time/hrtimer/pin.rs
··· 4 use super::HrTimer; 5 use super::HrTimerCallback; 6 use super::HrTimerHandle; 7 use super::RawHrTimerCallback; 8 use super::UnsafeHrTimerPointer; 9 - use crate::time::Ktime; 10 use core::pin::Pin; 11 12 /// A handle for a `Pin<&HasHrTimer>`. When the handle exists, the timer might be
··· 4 use super::HrTimer; 5 use super::HrTimerCallback; 6 use super::HrTimerHandle; 7 + use super::Ktime; 8 use super::RawHrTimerCallback; 9 use super::UnsafeHrTimerPointer; 10 use core::pin::Pin; 11 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 // SPDX-License-Identifier: GPL-2.0 2 3 use super::{ 4 - HasHrTimer, HrTimer, HrTimerCallback, HrTimerHandle, RawHrTimerCallback, UnsafeHrTimerPointer, 5 }; 6 - use crate::time::Ktime; 7 use core::{marker::PhantomData, pin::Pin, ptr::NonNull}; 8 9 /// A handle for a `Pin<&mut HasHrTimer>`. When the handle exists, the timer might
··· 1 // SPDX-License-Identifier: GPL-2.0 2 3 use super::{ 4 + HasHrTimer, HrTimer, HrTimerCallback, HrTimerHandle, Ktime, RawHrTimerCallback, 5 + UnsafeHrTimerPointer, 6 }; 7 use core::{marker::PhantomData, pin::Pin, ptr::NonNull}; 8 9 /// A handle for a `Pin<&mut HasHrTimer>`. When the handle exists, the timer might
+1 -1
rust/kernel/time/hrtimer/tbox.rs
··· 5 use super::HrTimerCallback; 6 use super::HrTimerHandle; 7 use super::HrTimerPointer; 8 use super::RawHrTimerCallback; 9 use crate::prelude::*; 10 - use crate::time::Ktime; 11 use core::ptr::NonNull; 12 13 /// A handle for a [`Box<HasHrTimer<T>>`] returned by a call to
··· 5 use super::HrTimerCallback; 6 use super::HrTimerHandle; 7 use super::HrTimerPointer; 8 + use super::Ktime; 9 use super::RawHrTimerCallback; 10 use crate::prelude::*; 11 use core::ptr::NonNull; 12 13 /// A handle for a [`Box<HasHrTimer<T>>`] returned by a call to
+31 -15
rust/kernel/types.rs
··· 18 /// 19 /// This trait is meant to be used in cases when Rust objects are stored in C objects and 20 /// eventually "freed" back to Rust. 21 - pub trait ForeignOwnable: Sized { 22 /// Type used to immutably borrow a value that is currently foreign-owned. 23 type Borrowed<'a>; 24 ··· 39 40 /// Converts a Rust-owned object to a foreign-owned one. 41 /// 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. 46 /// 47 /// [`from_foreign`]: Self::from_foreign 48 /// [`try_from_foreign`]: Self::try_from_foreign 49 /// [`borrow`]: Self::borrow 50 /// [`borrow_mut`]: Self::borrow_mut 51 - fn into_foreign(self) -> *mut crate::ffi::c_void; 52 53 /// Converts a foreign-owned object back to a Rust-owned one. 54 /// ··· 60 /// must not be passed to `from_foreign` more than once. 61 /// 62 /// [`into_foreign`]: Self::into_foreign 63 - unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self; 64 65 /// Tries to convert a foreign-owned object back to a Rust-owned one. 66 /// ··· 72 /// `ptr` must either be null or satisfy the safety requirements for [`from_foreign`]. 73 /// 74 /// [`from_foreign`]: Self::from_foreign 75 - unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> { 76 if ptr.is_null() { 77 None 78 } else { ··· 95 /// 96 /// [`into_foreign`]: Self::into_foreign 97 /// [`from_foreign`]: Self::from_foreign 98 - unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>; 99 100 /// Borrows a foreign-owned object mutably. 101 /// ··· 123 /// [`from_foreign`]: Self::from_foreign 124 /// [`borrow`]: Self::borrow 125 /// [`Arc`]: crate::sync::Arc 126 - unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a>; 127 } 128 129 - impl ForeignOwnable for () { 130 type Borrowed<'a> = (); 131 type BorrowedMut<'a> = (); 132 133 - fn into_foreign(self) -> *mut crate::ffi::c_void { 134 core::ptr::NonNull::dangling().as_ptr() 135 } 136 137 - unsafe fn from_foreign(_: *mut crate::ffi::c_void) -> Self {} 138 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> {} 141 } 142 143 /// Runs a cleanup function/closure when dropped.
··· 18 /// 19 /// This trait is meant to be used in cases when Rust objects are stored in C objects and 20 /// eventually "freed" back to Rust. 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 + 34 /// Type used to immutably borrow a value that is currently foreign-owned. 35 type Borrowed<'a>; 36 ··· 27 28 /// Converts a Rust-owned object to a foreign-owned one. 29 /// 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. 36 /// 37 /// [`from_foreign`]: Self::from_foreign 38 /// [`try_from_foreign`]: Self::try_from_foreign 39 /// [`borrow`]: Self::borrow 40 /// [`borrow_mut`]: Self::borrow_mut 41 + fn into_foreign(self) -> *mut Self::PointedTo; 42 43 /// Converts a foreign-owned object back to a Rust-owned one. 44 /// ··· 46 /// must not be passed to `from_foreign` more than once. 47 /// 48 /// [`into_foreign`]: Self::into_foreign 49 + unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self; 50 51 /// Tries to convert a foreign-owned object back to a Rust-owned one. 52 /// ··· 58 /// `ptr` must either be null or satisfy the safety requirements for [`from_foreign`]. 59 /// 60 /// [`from_foreign`]: Self::from_foreign 61 + unsafe fn try_from_foreign(ptr: *mut Self::PointedTo) -> Option<Self> { 62 if ptr.is_null() { 63 None 64 } else { ··· 81 /// 82 /// [`into_foreign`]: Self::into_foreign 83 /// [`from_foreign`]: Self::from_foreign 84 + unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> Self::Borrowed<'a>; 85 86 /// Borrows a foreign-owned object mutably. 87 /// ··· 109 /// [`from_foreign`]: Self::from_foreign 110 /// [`borrow`]: Self::borrow 111 /// [`Arc`]: crate::sync::Arc 112 + unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> Self::BorrowedMut<'a>; 113 } 114 115 + // SAFETY: The `into_foreign` function returns a pointer that is dangling, but well-aligned. 116 + unsafe impl ForeignOwnable for () { 117 + type PointedTo = (); 118 type Borrowed<'a> = (); 119 type BorrowedMut<'a> = (); 120 121 + fn into_foreign(self) -> *mut Self::PointedTo { 122 core::ptr::NonNull::dangling().as_ptr() 123 } 124 125 + unsafe fn from_foreign(_: *mut Self::PointedTo) -> Self {} 126 127 + unsafe fn borrow<'a>(_: *mut Self::PointedTo) -> Self::Borrowed<'a> {} 128 + unsafe fn borrow_mut<'a>(_: *mut Self::PointedTo) -> Self::BorrowedMut<'a> {} 129 } 130 131 /// Runs a cleanup function/closure when dropped.
+2 -4
rust/kernel/uaccess.rs
··· 46 /// 47 /// ```no_run 48 /// use kernel::ffi::c_void; 49 - /// use kernel::error::Result; 50 /// use kernel::uaccess::{UserPtr, UserSlice}; 51 /// 52 - /// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result<()> { 53 /// let (read, mut write) = UserSlice::new(uptr, len).reader_writer(); 54 /// 55 /// let mut buf = KVec::new(); ··· 67 /// 68 /// ```no_run 69 /// use kernel::ffi::c_void; 70 - /// use kernel::error::{code::EINVAL, Result}; 71 /// use kernel::uaccess::{UserPtr, UserSlice}; 72 /// 73 /// /// Returns whether the data in this region is valid. ··· 288 289 // SAFETY: Since the call to `read_raw` was successful, so the next `len` bytes of the 290 // vector have been initialized. 291 - unsafe { buf.set_len(buf.len() + len) }; 292 Ok(()) 293 } 294 }
··· 46 /// 47 /// ```no_run 48 /// use kernel::ffi::c_void; 49 /// use kernel::uaccess::{UserPtr, UserSlice}; 50 /// 51 + /// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result { 52 /// let (read, mut write) = UserSlice::new(uptr, len).reader_writer(); 53 /// 54 /// let mut buf = KVec::new(); ··· 68 /// 69 /// ```no_run 70 /// use kernel::ffi::c_void; 71 /// use kernel::uaccess::{UserPtr, UserSlice}; 72 /// 73 /// /// Returns whether the data in this region is valid. ··· 290 291 // SAFETY: Since the call to `read_raw` was successful, so the next `len` bytes of the 292 // vector have been initialized. 293 + unsafe { buf.inc_len(len) }; 294 Ok(()) 295 } 296 }
+17 -33
rust/kernel/workqueue.rs
··· 429 /// 430 /// # Safety 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. 434 /// 435 /// [`impl_has_work!`]: crate::impl_has_work 436 - /// [`OFFSET`]: HasWork::OFFSET 437 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 /// Returns a pointer to the [`Work<T, ID>`] field. 453 /// 454 /// # Safety 455 /// 456 /// 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 - } 462 463 /// Returns a pointer to the struct containing the [`Work<T, ID>`] field. 464 /// 465 /// # Safety 466 /// 467 /// 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 - } 477 } 478 479 /// Used to safely implement the [`HasWork<T, ID>`] trait. ··· 481 // SAFETY: The implementation of `raw_get_work` only compiles if the field has the right 482 // type. 483 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 #[inline] 487 unsafe fn raw_get_work(ptr: *mut Self) -> *mut $crate::workqueue::Work<$work_type $(, $id)?> { 488 // SAFETY: The caller promises that the pointer is not dangling. 489 unsafe { 490 ::core::ptr::addr_of_mut!((*ptr).$field) 491 } 492 } 493 } 494 )*};
··· 429 /// 430 /// # Safety 431 /// 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>`. 436 /// 437 /// [`impl_has_work!`]: crate::impl_has_work 438 + /// [`raw_get_work`]: HasWork::raw_get_work 439 + /// [`work_container_of`]: HasWork::work_container_of 440 pub unsafe trait HasWork<T, const ID: u64 = 0> { 441 /// Returns a pointer to the [`Work<T, ID>`] field. 442 /// 443 /// # Safety 444 /// 445 /// The provided pointer must point at a valid struct of type `Self`. 446 + unsafe fn raw_get_work(ptr: *mut Self) -> *mut Work<T, ID>; 447 448 /// Returns a pointer to the struct containing the [`Work<T, ID>`] field. 449 /// 450 /// # Safety 451 /// 452 /// The pointer must point at a [`Work<T, ID>`] field in a struct of type `Self`. 453 + unsafe fn work_container_of(ptr: *mut Work<T, ID>) -> *mut Self; 454 } 455 456 /// Used to safely implement the [`HasWork<T, ID>`] trait. ··· 504 // SAFETY: The implementation of `raw_get_work` only compiles if the field has the right 505 // type. 506 unsafe impl$(<$($generics)+>)? $crate::workqueue::HasWork<$work_type $(, $id)?> for $self { 507 #[inline] 508 unsafe fn raw_get_work(ptr: *mut Self) -> *mut $crate::workqueue::Work<$work_type $(, $id)?> { 509 // SAFETY: The caller promises that the pointer is not dangling. 510 unsafe { 511 ::core::ptr::addr_of_mut!((*ptr).$field) 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) } 522 } 523 } 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 } 87 None 88 }
··· 86 } 87 None 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 } 58 } 59 60 - // Add `#[cfg(CONFIG_KUNIT)]` before the module declaration. 61 - let config_kunit = "#[cfg(CONFIG_KUNIT)]".to_owned().parse().unwrap(); 62 tokens.insert( 63 0, 64 TokenTree::Group(Group::new(Delimiter::None, config_kunit)), ··· 85 // Looks like: 86 // 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(); } 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(), 95 // ]; 96 // 97 - // kernel::kunit_unsafe_test_suite!(kunit_test_suit_name, TEST_CASES); 98 // ``` 99 let mut kunit_macros = "".to_owned(); 100 let mut test_cases = "".to_owned(); 101 for test in &tests { 102 let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{test}"); 103 let kunit_wrapper = format!( 104 - "unsafe extern \"C\" fn {kunit_wrapper_fn_name}(_test: *mut kernel::bindings::kunit) {{ {test}(); }}" 105 ); 106 writeln!(kunit_macros, "{kunit_wrapper}").unwrap(); 107 writeln!( 108 test_cases, 109 - " kernel::kunit::kunit_case(kernel::c_str!(\"{test}\"), {kunit_wrapper_fn_name})," 110 ) 111 .unwrap(); 112 } ··· 138 writeln!(kunit_macros).unwrap(); 139 writeln!( 140 kunit_macros, 141 - "static mut TEST_CASES: [kernel::bindings::kunit_case; {}] = [\n{test_cases} kernel::kunit::kunit_case_null(),\n];", 142 tests.len() + 1 143 ) 144 .unwrap(); 145 146 writeln!( 147 kunit_macros, 148 - "kernel::kunit_unsafe_test_suite!({attr}, TEST_CASES);" 149 ) 150 .unwrap(); 151 ··· 171 } 172 } 173 174 - let mut new_body = TokenStream::from_iter(new_body); 175 - new_body.extend::<TokenStream>(kunit_macros.parse().unwrap()); 176 177 - tokens.push(TokenTree::Group(Group::new(Delimiter::Brace, new_body))); 178 179 tokens.into_iter().collect() 180 }
··· 57 } 58 } 59 60 + // Add `#[cfg(CONFIG_KUNIT="y")]` before the module declaration. 61 + let config_kunit = "#[cfg(CONFIG_KUNIT=\"y\")]".to_owned().parse().unwrap(); 62 tokens.insert( 63 0, 64 TokenTree::Group(Group::new(Delimiter::None, config_kunit)), ··· 85 // Looks like: 86 // 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(); } 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(), 95 // ]; 96 // 97 + // ::kernel::kunit_unsafe_test_suite!(kunit_test_suit_name, TEST_CASES); 98 // ``` 99 let mut kunit_macros = "".to_owned(); 100 let mut test_cases = "".to_owned(); 101 + let mut assert_macros = "".to_owned(); 102 + let path = crate::helpers::file(); 103 for test in &tests { 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. 106 let kunit_wrapper = format!( 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}())); }}", 108 ); 109 writeln!(kunit_macros, "{kunit_wrapper}").unwrap(); 110 writeln!( 111 test_cases, 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 + "# 134 ) 135 .unwrap(); 136 } ··· 114 writeln!(kunit_macros).unwrap(); 115 writeln!( 116 kunit_macros, 117 + "static mut TEST_CASES: [::kernel::bindings::kunit_case; {}] = [\n{test_cases} ::kernel::kunit::kunit_case_null(),\n];", 118 tests.len() + 1 119 ) 120 .unwrap(); 121 122 writeln!( 123 kunit_macros, 124 + "::kernel::kunit_unsafe_test_suite!({attr}, TEST_CASES);" 125 ) 126 .unwrap(); 127 ··· 147 } 148 } 149 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()); 154 155 + tokens.push(TokenTree::Group(Group::new(Delimiter::Brace, final_body))); 156 157 tokens.into_iter().collect() 158 }
+10 -5
rust/macros/lib.rs
··· 6 // and thus add a dependency on `include/config/RUSTC_VERSION_TEXT`, which is 7 // touched by Kconfig when the version string from the compiler changes. 8 9 #[macro_use] 10 mod quote; 11 mod concat_idents; ··· 268 /// literals (lifetimes and documentation strings are not supported). There is a difference in 269 /// supported modifiers as well. 270 /// 271 - /// # Example 272 /// 273 /// ``` 274 /// # const binder_driver_return_protocol_BR_OK: u32 = 0; ··· 288 /// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14; 289 /// macro_rules! pub_no_prefix { 290 /// ($prefix:ident, $($newname:ident),+) => { 291 - /// kernel::macros::paste! { 292 /// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+ 293 /// } 294 /// }; ··· 345 /// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14; 346 /// macro_rules! pub_no_prefix { 347 /// ($prefix:ident, $($newname:ident),+) => { 348 - /// kernel::macros::paste! { 349 /// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+ 350 /// } 351 /// }; ··· 380 /// ``` 381 /// macro_rules! create_numbered_fn { 382 /// ($name:literal, $val:literal) => { 383 - /// kernel::macros::paste! { 384 /// fn [<some_ $name _fn $val>]() -> u32 { $val } 385 /// } 386 /// }; ··· 407 /// # Examples 408 /// 409 /// ```ignore 410 - /// # use macros::kunit_tests; 411 /// #[kunit_tests(kunit_test_suit_name)] 412 /// mod tests { 413 /// #[test]
··· 6 // and thus add a dependency on `include/config/RUSTC_VERSION_TEXT`, which is 7 // touched by Kconfig when the version string from the compiler changes. 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 + 14 #[macro_use] 15 mod quote; 16 mod concat_idents; ··· 263 /// literals (lifetimes and documentation strings are not supported). There is a difference in 264 /// supported modifiers as well. 265 /// 266 + /// # Examples 267 /// 268 /// ``` 269 /// # const binder_driver_return_protocol_BR_OK: u32 = 0; ··· 283 /// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14; 284 /// macro_rules! pub_no_prefix { 285 /// ($prefix:ident, $($newname:ident),+) => { 286 + /// ::kernel::macros::paste! { 287 /// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+ 288 /// } 289 /// }; ··· 340 /// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14; 341 /// macro_rules! pub_no_prefix { 342 /// ($prefix:ident, $($newname:ident),+) => { 343 + /// ::kernel::macros::paste! { 344 /// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+ 345 /// } 346 /// }; ··· 375 /// ``` 376 /// macro_rules! create_numbered_fn { 377 /// ($name:literal, $val:literal) => { 378 + /// ::kernel::macros::paste! { 379 /// fn [<some_ $name _fn $val>]() -> u32 { $val } 380 /// } 381 /// }; ··· 402 /// # Examples 403 /// 404 /// ```ignore 405 + /// # use kernel::prelude::*; 406 /// #[kunit_tests(kunit_test_suit_name)] 407 /// mod tests { 408 /// #[test]
+16 -15
rust/macros/module.rs
··· 217 // SAFETY: `__this_module` is constructed by the kernel at load time and will not be 218 // freed until the module is unloaded. 219 #[cfg(MODULE)] 220 - static THIS_MODULE: kernel::ThisModule = unsafe {{ 221 extern \"C\" {{ 222 - static __this_module: kernel::types::Opaque<kernel::bindings::module>; 223 }} 224 225 - kernel::ThisModule::from_ptr(__this_module.get()) 226 }}; 227 #[cfg(not(MODULE))] 228 - static THIS_MODULE: kernel::ThisModule = unsafe {{ 229 - kernel::ThisModule::from_ptr(core::ptr::null_mut()) 230 }}; 231 232 /// The `LocalModule` type is the type of the module created by `module!`, 233 /// `module_pci_driver!`, `module_platform_driver!`, etc. 234 type LocalModule = {type_}; 235 236 - impl kernel::ModuleMetadata for {type_} {{ 237 - const NAME: &'static kernel::str::CStr = kernel::c_str!(\"{name}\"); 238 }} 239 240 // Double nested modules, since then nobody can access the public items inside. ··· 252 #[used] 253 static __IS_RUST_MODULE: () = (); 254 255 - static mut __MOD: core::mem::MaybeUninit<{type_}> = 256 - core::mem::MaybeUninit::uninit(); 257 258 // Loadable modules need to export the `{{init,cleanup}}_module` identifiers. 259 /// # Safety ··· 264 #[doc(hidden)] 265 #[no_mangle] 266 #[link_section = \".init.text\"] 267 - pub unsafe extern \"C\" fn init_module() -> kernel::ffi::c_int {{ 268 // SAFETY: This function is inaccessible to the outside due to the double 269 // module wrapping it. It is called exactly once by the C side via its 270 // unique name. ··· 280 #[cfg(MODULE)] 281 #[doc(hidden)] 282 #[no_mangle] 283 pub extern \"C\" fn cleanup_module() {{ 284 // SAFETY: 285 // - This function is inaccessible to the outside due to the double ··· 305 #[link_section = \"{initcall_section}\"] 306 #[used] 307 pub static __{ident}_initcall: extern \"C\" fn() -> 308 - kernel::ffi::c_int = __{ident}_init; 309 310 #[cfg(not(MODULE))] 311 #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] 312 - core::arch::global_asm!( 313 r#\".section \"{initcall_section}\", \"a\" 314 __{ident}_initcall: 315 .long __{ident}_init - . ··· 320 #[cfg(not(MODULE))] 321 #[doc(hidden)] 322 #[no_mangle] 323 - pub extern \"C\" fn __{ident}_init() -> kernel::ffi::c_int {{ 324 // SAFETY: This function is inaccessible to the outside due to the double 325 // module wrapping it. It is called exactly once by the C side via its 326 // placement above in the initcall section. ··· 343 /// # Safety 344 /// 345 /// This function must only be called once. 346 - unsafe fn __init() -> kernel::ffi::c_int {{ 347 let initer = 348 - <{type_} as kernel::InPlaceModule>::init(&super::super::THIS_MODULE); 349 // SAFETY: No data race, since `__MOD` can only be accessed by this module 350 // and there only `__init` and `__exit` access it. These functions are only 351 // called once and `__exit` cannot be called before or during `__init`.
··· 217 // SAFETY: `__this_module` is constructed by the kernel at load time and will not be 218 // freed until the module is unloaded. 219 #[cfg(MODULE)] 220 + static THIS_MODULE: ::kernel::ThisModule = unsafe {{ 221 extern \"C\" {{ 222 + static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>; 223 }} 224 225 + ::kernel::ThisModule::from_ptr(__this_module.get()) 226 }}; 227 #[cfg(not(MODULE))] 228 + static THIS_MODULE: ::kernel::ThisModule = unsafe {{ 229 + ::kernel::ThisModule::from_ptr(::core::ptr::null_mut()) 230 }}; 231 232 /// The `LocalModule` type is the type of the module created by `module!`, 233 /// `module_pci_driver!`, `module_platform_driver!`, etc. 234 type LocalModule = {type_}; 235 236 + impl ::kernel::ModuleMetadata for {type_} {{ 237 + const NAME: &'static ::kernel::str::CStr = ::kernel::c_str!(\"{name}\"); 238 }} 239 240 // Double nested modules, since then nobody can access the public items inside. ··· 252 #[used] 253 static __IS_RUST_MODULE: () = (); 254 255 + static mut __MOD: ::core::mem::MaybeUninit<{type_}> = 256 + ::core::mem::MaybeUninit::uninit(); 257 258 // Loadable modules need to export the `{{init,cleanup}}_module` identifiers. 259 /// # Safety ··· 264 #[doc(hidden)] 265 #[no_mangle] 266 #[link_section = \".init.text\"] 267 + pub unsafe extern \"C\" fn init_module() -> ::kernel::ffi::c_int {{ 268 // SAFETY: This function is inaccessible to the outside due to the double 269 // module wrapping it. It is called exactly once by the C side via its 270 // unique name. ··· 280 #[cfg(MODULE)] 281 #[doc(hidden)] 282 #[no_mangle] 283 + #[link_section = \".exit.text\"] 284 pub extern \"C\" fn cleanup_module() {{ 285 // SAFETY: 286 // - This function is inaccessible to the outside due to the double ··· 304 #[link_section = \"{initcall_section}\"] 305 #[used] 306 pub static __{ident}_initcall: extern \"C\" fn() -> 307 + ::kernel::ffi::c_int = __{ident}_init; 308 309 #[cfg(not(MODULE))] 310 #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] 311 + ::core::arch::global_asm!( 312 r#\".section \"{initcall_section}\", \"a\" 313 __{ident}_initcall: 314 .long __{ident}_init - . ··· 319 #[cfg(not(MODULE))] 320 #[doc(hidden)] 321 #[no_mangle] 322 + pub extern \"C\" fn __{ident}_init() -> ::kernel::ffi::c_int {{ 323 // SAFETY: This function is inaccessible to the outside due to the double 324 // module wrapping it. It is called exactly once by the C side via its 325 // placement above in the initcall section. ··· 342 /// # Safety 343 /// 344 /// This function must only be called once. 345 + unsafe fn __init() -> ::kernel::ffi::c_int {{ 346 let initer = 347 + <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE); 348 // SAFETY: No data race, since `__MOD` can only be accessed by this module 349 // and there only `__init` and `__exit` access it. These functions are only 350 // called once and `__exit` cannot be called before or during `__init`.
+11 -3
rust/pin-init/README.md
··· 40 will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std 41 mode. 42 43 ## Overview 44 45 To initialize a `struct` with an in-place constructor you will need two things: ··· 222 223 [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html 224 [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 226 [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 [`impl PinInit<Foo>`]: https://docs.rs/pin-init/latest/pin_init/trait.PinInit.html 230 [`impl PinInit<T, E>`]: https://docs.rs/pin-init/latest/pin_init/trait.PinInit.html 231 [`impl Init<T, E>`]: https://docs.rs/pin-init/latest/pin_init/trait.Init.html 232 [Rust-for-Linux]: https://rust-for-linux.com/ 233 234 <!-- cargo-rdme end -->
··· 40 will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std 41 mode. 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 + 49 ## Overview 50 51 To initialize a `struct` with an in-place constructor you will need two things: ··· 216 217 [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html 218 [pinning]: https://doc.rust-lang.org/std/pin/index.html 219 + [structurally pinned fields]: https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning 220 [stack]: https://docs.rs/pin-init/latest/pin_init/macro.stack_pin_init.html 221 [`impl PinInit<Foo>`]: https://docs.rs/pin-init/latest/pin_init/trait.PinInit.html 222 [`impl PinInit<T, E>`]: https://docs.rs/pin-init/latest/pin_init/trait.PinInit.html 223 [`impl Init<T, E>`]: https://docs.rs/pin-init/latest/pin_init/trait.Init.html 224 [Rust-for-Linux]: https://rust-for-linux.com/ 225 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 3 #![allow(clippy::undocumented_unsafe_blocks)] 4 #![cfg_attr(feature = "alloc", feature(allocator_api))] 5 6 use core::{ 7 cell::Cell,
··· 2 3 #![allow(clippy::undocumented_unsafe_blocks)] 4 #![cfg_attr(feature = "alloc", feature(allocator_api))] 5 + #![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] 6 7 use core::{ 8 cell::Cell,
+1
rust/pin-init/examples/mutex.rs
··· 2 3 #![allow(clippy::undocumented_unsafe_blocks)] 4 #![cfg_attr(feature = "alloc", feature(allocator_api))] 5 #![allow(clippy::missing_safety_doc)] 6 7 use core::{
··· 2 3 #![allow(clippy::undocumented_unsafe_blocks)] 4 #![cfg_attr(feature = "alloc", feature(allocator_api))] 5 + #![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] 6 #![allow(clippy::missing_safety_doc)] 7 8 use core::{
+3 -1
rust/pin-init/examples/pthread_mutex.rs
··· 3 // inspired by <https://github.com/nbdd0121/pin-init/blob/trunk/examples/pthread_mutex.rs> 4 #![allow(clippy::undocumented_unsafe_blocks)] 5 #![cfg_attr(feature = "alloc", feature(allocator_api))] 6 #[cfg(not(windows))] 7 mod pthread_mtx { 8 #[cfg(feature = "alloc")] ··· 42 43 #[derive(Debug)] 44 pub enum Error { 45 - #[expect(dead_code)] 46 IO(std::io::Error), 47 Alloc, 48 }
··· 3 // inspired by <https://github.com/nbdd0121/pin-init/blob/trunk/examples/pthread_mutex.rs> 4 #![allow(clippy::undocumented_unsafe_blocks)] 5 #![cfg_attr(feature = "alloc", feature(allocator_api))] 6 + #![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] 7 + 8 #[cfg(not(windows))] 9 mod pthread_mtx { 10 #[cfg(feature = "alloc")] ··· 40 41 #[derive(Debug)] 42 pub enum Error { 43 + #[allow(dead_code)] 44 IO(std::io::Error), 45 Alloc, 46 }
+1
rust/pin-init/examples/static_init.rs
··· 2 3 #![allow(clippy::undocumented_unsafe_blocks)] 4 #![cfg_attr(feature = "alloc", feature(allocator_api))] 5 6 use core::{ 7 cell::{Cell, UnsafeCell},
··· 2 3 #![allow(clippy::undocumented_unsafe_blocks)] 4 #![cfg_attr(feature = "alloc", feature(allocator_api))] 5 + #![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] 6 7 use core::{ 8 cell::{Cell, UnsafeCell},
+6
rust/pin-init/internal/src/lib.rs
··· 22 #[cfg(kernel)] 23 #[path = "../../../macros/quote.rs"] 24 #[macro_use] 25 mod quote; 26 #[cfg(not(kernel))] 27 #[macro_use] ··· 46 #[proc_macro_derive(Zeroable)] 47 pub fn derive_zeroable(input: TokenStream) -> TokenStream { 48 zeroable::derive(input.into()).into() 49 }
··· 22 #[cfg(kernel)] 23 #[path = "../../../macros/quote.rs"] 24 #[macro_use] 25 + #[cfg_attr(not(kernel), rustfmt::skip)] 26 mod quote; 27 #[cfg(not(kernel))] 28 #[macro_use] ··· 45 #[proc_macro_derive(Zeroable)] 46 pub fn derive_zeroable(input: TokenStream) -> TokenStream { 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() 53 }
+26 -1
rust/pin-init/internal/src/zeroable.rs
··· 6 use crate::helpers::{parse_generics, Generics}; 7 use proc_macro::{TokenStream, TokenTree}; 8 9 - pub(crate) fn derive(input: TokenStream) -> TokenStream { 10 let ( 11 Generics { 12 impl_generics, ··· 71 if in_generic && !inserted { 72 new_impl_generics.extend(quote! { : ::pin_init::Zeroable }); 73 } 74 quote! { 75 ::pin_init::__derive_zeroable!( 76 parse_input: 77 @sig(#(#rest)*), 78 @impl_generics(#(#new_impl_generics)*),
··· 6 use crate::helpers::{parse_generics, Generics}; 7 use proc_macro::{TokenStream, TokenTree}; 8 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 + ) { 17 let ( 18 Generics { 19 impl_generics, ··· 64 if in_generic && !inserted { 65 new_impl_generics.extend(quote! { : ::pin_init::Zeroable }); 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); 72 quote! { 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!( 87 parse_input: 88 @sig(#(#rest)*), 89 @impl_generics(#(#new_impl_generics)*),
+140 -4
rust/pin-init/src/lib.rs
··· 32 //! will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std 33 //! mode. 34 //! 35 //! # Overview 36 //! 37 //! To initialize a `struct` with an in-place constructor you will need two things: ··· 247 //! [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html 248 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html 249 //! [structurally pinned fields]: 250 - //! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field 251 //! [stack]: crate::stack_pin_init 252 #![cfg_attr( 253 kernel, ··· 275 #![forbid(missing_docs, unsafe_op_in_unsafe_fn)] 276 #![cfg_attr(not(feature = "std"), no_std)] 277 #![cfg_attr(feature = "alloc", feature(allocator_api))] 278 279 use core::{ 280 cell::UnsafeCell, ··· 395 /// ``` 396 pub use ::pin_init_internal::pinned_drop; 397 398 - /// Derives the [`Zeroable`] trait for the given struct. 399 /// 400 - /// This can only be used for structs where every field implements the [`Zeroable`] trait. 401 /// 402 /// # Examples 403 /// ··· 407 /// 408 /// #[derive(Zeroable)] 409 /// pub struct DriverData { 410 - /// id: i64, 411 /// buf_ptr: *mut u8, 412 /// len: usize, 413 /// } 414 /// ``` 415 pub use ::pin_init_internal::Zeroable; 416 417 /// Initialize and pin a type directly on the stack. 418 /// ··· 1268 __internal::InitClosure(f, PhantomData) 1269 } 1270 1271 /// An initializer that leaves the memory uninitialized. 1272 /// 1273 /// The initializer is a no-op. The `slot` memory is not changed. ··· 1565 } 1566 1567 impl_tuple_zeroable!(A, B, C, D, E, F, G, H, I, J);
··· 32 //! will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std 33 //! mode. 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 + //! 41 //! # Overview 42 //! 43 //! To initialize a `struct` with an in-place constructor you will need two things: ··· 241 //! [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html 242 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html 243 //! [structurally pinned fields]: 244 + //! https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning 245 //! [stack]: crate::stack_pin_init 246 #![cfg_attr( 247 kernel, ··· 269 #![forbid(missing_docs, unsafe_op_in_unsafe_fn)] 270 #![cfg_attr(not(feature = "std"), no_std)] 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 + )] 276 277 use core::{ 278 cell::UnsafeCell, ··· 385 /// ``` 386 pub use ::pin_init_internal::pinned_drop; 387 388 + /// Derives the [`Zeroable`] trait for the given `struct` or `union`. 389 /// 390 + /// This can only be used for `struct`s/`union`s where every field implements the [`Zeroable`] 391 + /// trait. 392 /// 393 /// # Examples 394 /// ··· 396 /// 397 /// #[derive(Zeroable)] 398 /// pub struct DriverData { 399 + /// pub(crate) id: i64, 400 /// buf_ptr: *mut u8, 401 /// len: usize, 402 /// } 403 /// ``` 404 + /// 405 + /// ``` 406 + /// use pin_init::Zeroable; 407 + /// 408 + /// #[derive(Zeroable)] 409 + /// pub union SignCast { 410 + /// signed: i64, 411 + /// unsigned: u64, 412 + /// } 413 + /// ``` 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; 446 447 /// Initialize and pin a type directly on the stack. 448 /// ··· 1216 __internal::InitClosure(f, PhantomData) 1217 } 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 + 1251 /// An initializer that leaves the memory uninitialized. 1252 /// 1253 /// The initializer is a no-op. The `slot` memory is not changed. ··· 1481 } 1482 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 @body({ 1394 $( 1395 $(#[$($field_attr:tt)*])* 1396 - $field:ident : $field_ty:ty 1397 ),* $(,)? 1398 }), 1399 ) => { ··· 1411 $(assert_zeroable::<$field_ty>();)* 1412 } 1413 }; 1414 }; 1415 }
··· 1393 @body({ 1394 $( 1395 $(#[$($field_attr:tt)*])* 1396 + $field_vis:vis $field:ident : $field_ty:ty 1397 ),* $(,)? 1398 }), 1399 ) => { ··· 1411 $(assert_zeroable::<$field_ty>();)* 1412 } 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 + {} 1503 }; 1504 }
+9
scripts/Makefile.build
··· 222 # Compile Rust sources (.rs) 223 # --------------------------------------------------------------------------- 224 225 rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,raw_ref_op 226 227 # `--out-dir` is required to avoid temporaries being created by `rustc` in the
··· 222 # Compile Rust sources (.rs) 223 # --------------------------------------------------------------------------- 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. 234 rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,raw_ref_op 235 236 # `--out-dir` is required to avoid temporaries being created by `rustc` in the
+8 -5
scripts/generate_rust_analyzer.py
··· 19 20 return crates_cfgs 21 22 - def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): 23 # Generate the configuration list. 24 cfg = [] 25 with open(objtree / "include" / "generated" / "rustc_cfg") as fd: ··· 35 crates_indexes = {} 36 crates_cfgs = args_crates_cfgs(cfgs) 37 38 - def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False): 39 crate = { 40 "display_name": display_name, 41 "root_module": str(root_module), ··· 43 "is_proc_macro": is_proc_macro, 44 "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps], 45 "cfg": cfg, 46 - "edition": "2021", 47 "env": { 48 "RUST_MODFILE": "This is only for rust-analyzer" 49 } ··· 61 display_name, 62 deps, 63 cfg=[], 64 ): 65 append_crate( 66 display_name, ··· 69 deps, 70 cfg, 71 is_workspace_member=False, 72 ) 73 74 # NB: sysroot crates reexport items from one another so setting up our transitive dependencies 75 # here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth 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", [])) 78 append_sysroot_crate("alloc", ["core"]) 79 append_sysroot_crate("std", ["alloc", "core"]) 80 append_sysroot_crate("proc_macro", ["core", "std"]) ··· 179 parser = argparse.ArgumentParser() 180 parser.add_argument('--verbose', '-v', action='store_true') 181 parser.add_argument('--cfgs', action='append', default=[]) 182 parser.add_argument("srctree", type=pathlib.Path) 183 parser.add_argument("objtree", type=pathlib.Path) 184 parser.add_argument("sysroot", type=pathlib.Path) ··· 196 assert args.sysroot in args.sysroot_src.parents 197 198 rust_project = { 199 - "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs), 200 "sysroot": str(args.sysroot), 201 } 202
··· 19 20 return crates_cfgs 21 22 + def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edition): 23 # Generate the configuration list. 24 cfg = [] 25 with open(objtree / "include" / "generated" / "rustc_cfg") as fd: ··· 35 crates_indexes = {} 36 crates_cfgs = args_crates_cfgs(cfgs) 37 38 + def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False, edition="2021"): 39 crate = { 40 "display_name": display_name, 41 "root_module": str(root_module), ··· 43 "is_proc_macro": is_proc_macro, 44 "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps], 45 "cfg": cfg, 46 + "edition": edition, 47 "env": { 48 "RUST_MODFILE": "This is only for rust-analyzer" 49 } ··· 61 display_name, 62 deps, 63 cfg=[], 64 + edition="2021", 65 ): 66 append_crate( 67 display_name, ··· 68 deps, 69 cfg, 70 is_workspace_member=False, 71 + edition=edition, 72 ) 73 74 # NB: sysroot crates reexport items from one another so setting up our transitive dependencies 75 # here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth 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", []), edition=core_edition) 78 append_sysroot_crate("alloc", ["core"]) 79 append_sysroot_crate("std", ["alloc", "core"]) 80 append_sysroot_crate("proc_macro", ["core", "std"]) ··· 177 parser = argparse.ArgumentParser() 178 parser.add_argument('--verbose', '-v', action='store_true') 179 parser.add_argument('--cfgs', action='append', default=[]) 180 + parser.add_argument("core_edition") 181 parser.add_argument("srctree", type=pathlib.Path) 182 parser.add_argument("objtree", type=pathlib.Path) 183 parser.add_argument("sysroot", type=pathlib.Path) ··· 193 assert args.sysroot in args.sysroot_src.parents 194 195 rust_project = { 196 + "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs, args.core_edition), 197 "sysroot": str(args.sysroot), 198 } 199
+2 -2
scripts/generate_rust_target.rs
··· 209 // target feature of the same name plus the other two target features in 210 // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via 211 // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated 212 - // flag); see https://github.com/rust-lang/rust/issues/116852. 213 features += ",+retpoline-external-thunk"; 214 features += ",+retpoline-indirect-branches"; 215 features += ",+retpoline-indirect-calls"; ··· 218 // The kernel uses `-mharden-sls=all`, which Clang maps to both these target features in 219 // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via 220 // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated 221 - // flag); see https://github.com/rust-lang/rust/issues/116851. 222 features += ",+harden-sls-ijmp"; 223 features += ",+harden-sls-ret"; 224 }
··· 209 // target feature of the same name plus the other two target features in 210 // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via 211 // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated 212 + // flag); see <https://github.com/rust-lang/rust/issues/116852>. 213 features += ",+retpoline-external-thunk"; 214 features += ",+retpoline-indirect-branches"; 215 features += ",+retpoline-indirect-calls"; ··· 218 // The kernel uses `-mharden-sls=all`, which Clang maps to both these target features in 219 // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via 220 // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated 221 + // flag); see <https://github.com/rust-lang/rust/issues/116851>. 222 features += ",+harden-sls-ijmp"; 223 features += ",+harden-sls-ret"; 224 }
+5 -3
scripts/rustdoc_test_builder.rs
··· 28 // 29 // ``` 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> { 32 // ``` 33 // 34 // It should be unlikely that doctest code matches such lines (when code is formatted properly). ··· 49 50 // Qualify `Result` to avoid the collision with our own `Result` coming from the prelude. 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> {{"), 54 ); 55 56 // For tests that get generated with `Result`, like above, `rustdoc` generates an `unwrap()` on
··· 28 // 29 // ``` 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> { 32 // ``` 33 // 34 // It should be unlikely that doctest code matches such lines (when code is formatted properly). ··· 49 50 // Qualify `Result` to avoid the collision with our own `Result` coming from the prelude. 51 let body = body.replace( 52 + &format!("{rustdoc_function_name}() -> Result<(), impl ::core::fmt::Debug> {{"), 53 + &format!( 54 + "{rustdoc_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{" 55 + ), 56 ); 57 58 // For tests that get generated with `Result`, like above, `rustdoc` generates an `unwrap()` on
+10 -6
scripts/rustdoc_test_gen.rs
··· 167 rust_tests, 168 r#"/// Generated `{name}` KUnit test case from a Rust documentation test. 169 #[no_mangle] 170 - pub extern "C" fn {kunit_name}(__kunit_test: *mut kernel::bindings::kunit) {{ 171 /// Overrides the usual [`assert!`] macro with one that calls KUnit instead. 172 #[allow(unused)] 173 macro_rules! assert {{ 174 ($cond:expr $(,)?) => {{{{ 175 - kernel::kunit_assert!("{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $cond); 176 }}}} 177 }} 178 ··· 182 #[allow(unused)] 183 macro_rules! assert_eq {{ 184 ($left:expr, $right:expr $(,)?) => {{{{ 185 - kernel::kunit_assert_eq!("{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $left, $right); 186 }}}} 187 }} 188 189 // Many tests need the prelude, so provide it by default. 190 #[allow(unused)] 191 - use kernel::prelude::*; 192 193 // Unconditionally print the location of the original doctest (i.e. rather than the location in 194 // the generated file) so that developers can easily map the test back to the source code. ··· 201 // This follows the syntax for declaring test metadata in the proposed KTAP v2 spec, which may 202 // be used for the proposed KUnit test attributes API. Thus hopefully this will make migration 203 // easier later on. 204 - kernel::kunit::info(format_args!(" # {kunit_name}.location: {real_path}:{line}\n")); 205 206 /// The anchor where the test code body starts. 207 #[allow(unused)] 208 - static __DOCTEST_ANCHOR: i32 = core::line!() as i32 + {body_offset} + 1; 209 {{ 210 {body} 211 main();
··· 167 rust_tests, 168 r#"/// Generated `{name}` KUnit test case from a Rust documentation test. 169 #[no_mangle] 170 + pub extern "C" fn {kunit_name}(__kunit_test: *mut ::kernel::bindings::kunit) {{ 171 /// Overrides the usual [`assert!`] macro with one that calls KUnit instead. 172 #[allow(unused)] 173 macro_rules! assert {{ 174 ($cond:expr $(,)?) => {{{{ 175 + ::kernel::kunit_assert!( 176 + "{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $cond 177 + ); 178 }}}} 179 }} 180 ··· 180 #[allow(unused)] 181 macro_rules! assert_eq {{ 182 ($left:expr, $right:expr $(,)?) => {{{{ 183 + ::kernel::kunit_assert_eq!( 184 + "{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $left, $right 185 + ); 186 }}}} 187 }} 188 189 // Many tests need the prelude, so provide it by default. 190 #[allow(unused)] 191 + use ::kernel::prelude::*; 192 193 // Unconditionally print the location of the original doctest (i.e. rather than the location in 194 // the generated file) so that developers can easily map the test back to the source code. ··· 197 // This follows the syntax for declaring test metadata in the proposed KTAP v2 spec, which may 198 // be used for the proposed KUnit test attributes API. Thus hopefully this will make migration 199 // easier later on. 200 + ::kernel::kunit::info(format_args!(" # {kunit_name}.location: {real_path}:{line}\n")); 201 202 /// The anchor where the test code body starts. 203 #[allow(unused)] 204 + static __DOCTEST_ANCHOR: i32 = ::core::line!() as i32 + {body_offset} + 1; 205 {{ 206 {body} 207 main();
+2 -1
tools/objtool/check.c
··· 230 str_ends_with(func->name, "_7___rustc17rust_begin_unwind") || 231 strstr(func->name, "_4core9panicking13assert_failed") || 232 strstr(func->name, "_4core9panicking11panic_const24panic_const_") || 233 - (strstr(func->name, "_4core5slice5index24slice_") && 234 str_ends_with(func->name, "_fail")); 235 } 236
··· 230 str_ends_with(func->name, "_7___rustc17rust_begin_unwind") || 231 strstr(func->name, "_4core9panicking13assert_failed") || 232 strstr(func->name, "_4core9panicking11panic_const24panic_const_") || 233 + (strstr(func->name, "_4core5slice5index") && 234 + strstr(func->name, "slice_") && 235 str_ends_with(func->name, "_fail")); 236 } 237