From ffb2c7148fe2a6dde2040c18b3b365eee7acaead Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 9 Mar 2025 10:46:47 +0100 Subject: [PATCH] 6.12-stable patches added patches: documentation-rust-add-coding-guidelines-on-lints.patch documentation-rust-discuss-in-the-guidelines.patch drm-panic-allow-verbose-boolean-for-clarity.patch drm-panic-allow-verbose-version-check.patch drm-panic-avoid-reimplementing-iterator-find.patch drm-panic-correctly-indent-continuation-of-line-in-list-item.patch drm-panic-prefer-eliding-lifetimes.patch drm-panic-remove-redundant-field-when-assigning-value.patch drm-panic-remove-unnecessary-borrow-in-alignment_pattern.patch kbuild-rust-remove-the-alloc-crate-and-globalalloc.patch maintainers-add-entry-for-the-rust-alloc-module.patch rust-alloc-add-__gfp_nowarn-to-flags.patch rust-alloc-add-allocator-trait.patch rust-alloc-add-box-to-prelude.patch rust-alloc-add-module-allocator_test.patch rust-alloc-add-vec-to-prelude.patch rust-alloc-fix-arraylayout-allocations.patch rust-alloc-implement-allocator-for-kmalloc.patch rust-alloc-implement-cmalloc-in-module-allocator_test.patch rust-alloc-implement-collect-for-intoiter.patch rust-alloc-implement-contains-for-flags.patch rust-alloc-implement-intoiterator-for-vec.patch rust-alloc-implement-kernel-box.patch rust-alloc-implement-kernel-vec-type.patch rust-alloc-implement-kvmalloc-allocator.patch rust-alloc-implement-reallocfunc.patch rust-alloc-implement-vmalloc-allocator.patch rust-alloc-introduce-arraylayout.patch rust-alloc-make-allocator-module-public.patch rust-alloc-remove-extension-of-std-s-box.patch rust-alloc-remove-vecext-extension.patch rust-alloc-rename-kernelallocator-to-kmalloc.patch rust-alloc-separate-aligned_size-from-krealloc_aligned.patch rust-alloc-update-module-comment-of-alloc.rs.patch rust-enable-clippy-ignored_unit_patterns-lint.patch rust-enable-clippy-s-check-private-items.patch rust-enable-clippy-undocumented_unsafe_blocks-lint.patch rust-enable-clippy-unnecessary_safety_comment-lint.patch rust-enable-clippy-unnecessary_safety_doc-lint.patch rust-enable-rustdoc-unescaped_backticks-lint.patch rust-error-check-for-config-test-in-error-name.patch rust-error-make-conversion-functions-public.patch rust-error-optimize-error-type-to-use-nonzero.patch rust-error-use-core-alloc-layouterror.patch rust-fix-size_t-in-bindgen-prototypes-of-c-builtins.patch rust-init-remove-unneeded.patch rust-introduce-.clippy.toml.patch rust-kbuild-expand-rusttest-target-for-macros.patch rust-map-__kernel_size_t-and-friends-also-to-usize-isize.patch rust-provide-proper-code-documentation-titles.patch rust-replace-clippy-dbg_macro-with-disallowed_macros.patch rust-sort-global-rust-flags.patch rust-start-using-the-attribute.patch rust-str-test-replace-alloc-format.patch rust-sync-remove-unneeded.patch rust-treewide-switch-to-our-kernel-box-type.patch rust-treewide-switch-to-the-kernel-vec-type.patch rust-types-avoid-repetition-in-as-from-bytes-impls.patch rust-use-custom-ffi-integer-types.patch rust-workqueue-remove-unneeded.patch --- ...-rust-add-coding-guidelines-on-lints.patch | 79 ++ ...ation-rust-discuss-in-the-guidelines.patch | 145 ++++ ...ic-allow-verbose-boolean-for-clarity.patch | 61 ++ ...rm-panic-allow-verbose-version-check.patch | 49 ++ ...c-avoid-reimplementing-iterator-find.patch | 80 ++ ...nt-continuation-of-line-in-list-item.patch | 57 ++ .../drm-panic-prefer-eliding-lifetimes.patch | 56 ++ ...redundant-field-when-assigning-value.patch | 54 ++ ...ecessary-borrow-in-alignment_pattern.patch | 53 ++ ...move-the-alloc-crate-and-globalalloc.patch | 306 +++++++ ...-add-entry-for-the-rust-alloc-module.patch | 43 + ...rust-alloc-add-__gfp_nowarn-to-flags.patch | 49 ++ .../rust-alloc-add-allocator-trait.patch | 145 ++++ .../rust-alloc-add-box-to-prelude.patch | 37 + ...rust-alloc-add-module-allocator_test.patch | 79 ++ .../rust-alloc-add-vec-to-prelude.patch | 37 + ...st-alloc-fix-arraylayout-allocations.patch | 40 + ...lloc-implement-allocator-for-kmalloc.patch | 87 ++ ...ent-cmalloc-in-module-allocator_test.patch | 150 ++++ ...alloc-implement-collect-for-intoiter.patch | 145 ++++ ...t-alloc-implement-contains-for-flags.patch | 52 ++ ...alloc-implement-intoiterator-for-vec.patch | 223 +++++ .../rust-alloc-implement-kernel-box.patch | 527 ++++++++++++ ...rust-alloc-implement-kernel-vec-type.patch | 735 +++++++++++++++++ ...t-alloc-implement-kvmalloc-allocator.patch | 114 +++ .../rust-alloc-implement-reallocfunc.patch | 139 ++++ ...st-alloc-implement-vmalloc-allocator.patch | 131 +++ .../rust-alloc-introduce-arraylayout.patch | 139 ++++ ...t-alloc-make-allocator-module-public.patch | 37 + ...-alloc-remove-extension-of-std-s-box.patch | 311 +++++++ .../rust-alloc-remove-vecext-extension.patch | 241 ++++++ ...oc-rename-kernelallocator-to-kmalloc.patch | 55 ++ ...e-aligned_size-from-krealloc_aligned.patch | 63 ++ ...oc-update-module-comment-of-alloc.rs.patch | 39 + ...le-clippy-ignored_unit_patterns-lint.patch | 65 ++ ...-enable-clippy-s-check-private-items.patch | 100 +++ ...ippy-undocumented_unsafe_blocks-lint.patch | 413 ++++++++++ ...ippy-unnecessary_safety_comment-lint.patch | 77 ++ ...e-clippy-unnecessary_safety_doc-lint.patch | 41 + ...ble-rustdoc-unescaped_backticks-lint.patch | 74 ++ ...-check-for-config-test-in-error-name.patch | 47 ++ ...ror-make-conversion-functions-public.patch | 71 ++ ...r-optimize-error-type-to-use-nonzero.patch | 132 +++ ...ust-error-use-core-alloc-layouterror.patch | 37 + ...-in-bindgen-prototypes-of-c-builtins.patch | 70 ++ queue-6.12/rust-init-remove-unneeded.patch | 61 ++ queue-6.12/rust-introduce-.clippy.toml.patch | 75 ++ ...ld-expand-rusttest-target-for-macros.patch | 85 ++ ...ze_t-and-friends-also-to-usize-isize.patch | 73 ++ ...ide-proper-code-documentation-titles.patch | 102 +++ ...ppy-dbg_macro-with-disallowed_macros.patch | 133 +++ queue-6.12/rust-sort-global-rust-flags.patch | 52 ++ .../rust-start-using-the-attribute.patch | 380 +++++++++ .../rust-str-test-replace-alloc-format.patch | 64 ++ queue-6.12/rust-sync-remove-unneeded.patch | 55 ++ ...eewide-switch-to-our-kernel-box-type.patch | 625 ++++++++++++++ ...eewide-switch-to-the-kernel-vec-type.patch | 239 ++++++ ...id-repetition-in-as-from-bytes-impls.patch | 118 +++ .../rust-use-custom-ffi-integer-types.patch | 767 ++++++++++++++++++ .../rust-workqueue-remove-unneeded.patch | 48 ++ queue-6.12/series | 60 ++ 61 files changed, 8622 insertions(+) create mode 100644 queue-6.12/documentation-rust-add-coding-guidelines-on-lints.patch create mode 100644 queue-6.12/documentation-rust-discuss-in-the-guidelines.patch create mode 100644 queue-6.12/drm-panic-allow-verbose-boolean-for-clarity.patch create mode 100644 queue-6.12/drm-panic-allow-verbose-version-check.patch create mode 100644 queue-6.12/drm-panic-avoid-reimplementing-iterator-find.patch create mode 100644 queue-6.12/drm-panic-correctly-indent-continuation-of-line-in-list-item.patch create mode 100644 queue-6.12/drm-panic-prefer-eliding-lifetimes.patch create mode 100644 queue-6.12/drm-panic-remove-redundant-field-when-assigning-value.patch create mode 100644 queue-6.12/drm-panic-remove-unnecessary-borrow-in-alignment_pattern.patch create mode 100644 queue-6.12/kbuild-rust-remove-the-alloc-crate-and-globalalloc.patch create mode 100644 queue-6.12/maintainers-add-entry-for-the-rust-alloc-module.patch create mode 100644 queue-6.12/rust-alloc-add-__gfp_nowarn-to-flags.patch create mode 100644 queue-6.12/rust-alloc-add-allocator-trait.patch create mode 100644 queue-6.12/rust-alloc-add-box-to-prelude.patch create mode 100644 queue-6.12/rust-alloc-add-module-allocator_test.patch create mode 100644 queue-6.12/rust-alloc-add-vec-to-prelude.patch create mode 100644 queue-6.12/rust-alloc-fix-arraylayout-allocations.patch create mode 100644 queue-6.12/rust-alloc-implement-allocator-for-kmalloc.patch create mode 100644 queue-6.12/rust-alloc-implement-cmalloc-in-module-allocator_test.patch create mode 100644 queue-6.12/rust-alloc-implement-collect-for-intoiter.patch create mode 100644 queue-6.12/rust-alloc-implement-contains-for-flags.patch create mode 100644 queue-6.12/rust-alloc-implement-intoiterator-for-vec.patch create mode 100644 queue-6.12/rust-alloc-implement-kernel-box.patch create mode 100644 queue-6.12/rust-alloc-implement-kernel-vec-type.patch create mode 100644 queue-6.12/rust-alloc-implement-kvmalloc-allocator.patch create mode 100644 queue-6.12/rust-alloc-implement-reallocfunc.patch create mode 100644 queue-6.12/rust-alloc-implement-vmalloc-allocator.patch create mode 100644 queue-6.12/rust-alloc-introduce-arraylayout.patch create mode 100644 queue-6.12/rust-alloc-make-allocator-module-public.patch create mode 100644 queue-6.12/rust-alloc-remove-extension-of-std-s-box.patch create mode 100644 queue-6.12/rust-alloc-remove-vecext-extension.patch create mode 100644 queue-6.12/rust-alloc-rename-kernelallocator-to-kmalloc.patch create mode 100644 queue-6.12/rust-alloc-separate-aligned_size-from-krealloc_aligned.patch create mode 100644 queue-6.12/rust-alloc-update-module-comment-of-alloc.rs.patch create mode 100644 queue-6.12/rust-enable-clippy-ignored_unit_patterns-lint.patch create mode 100644 queue-6.12/rust-enable-clippy-s-check-private-items.patch create mode 100644 queue-6.12/rust-enable-clippy-undocumented_unsafe_blocks-lint.patch create mode 100644 queue-6.12/rust-enable-clippy-unnecessary_safety_comment-lint.patch create mode 100644 queue-6.12/rust-enable-clippy-unnecessary_safety_doc-lint.patch create mode 100644 queue-6.12/rust-enable-rustdoc-unescaped_backticks-lint.patch create mode 100644 queue-6.12/rust-error-check-for-config-test-in-error-name.patch create mode 100644 queue-6.12/rust-error-make-conversion-functions-public.patch create mode 100644 queue-6.12/rust-error-optimize-error-type-to-use-nonzero.patch create mode 100644 queue-6.12/rust-error-use-core-alloc-layouterror.patch create mode 100644 queue-6.12/rust-fix-size_t-in-bindgen-prototypes-of-c-builtins.patch create mode 100644 queue-6.12/rust-init-remove-unneeded.patch create mode 100644 queue-6.12/rust-introduce-.clippy.toml.patch create mode 100644 queue-6.12/rust-kbuild-expand-rusttest-target-for-macros.patch create mode 100644 queue-6.12/rust-map-__kernel_size_t-and-friends-also-to-usize-isize.patch create mode 100644 queue-6.12/rust-provide-proper-code-documentation-titles.patch create mode 100644 queue-6.12/rust-replace-clippy-dbg_macro-with-disallowed_macros.patch create mode 100644 queue-6.12/rust-sort-global-rust-flags.patch create mode 100644 queue-6.12/rust-start-using-the-attribute.patch create mode 100644 queue-6.12/rust-str-test-replace-alloc-format.patch create mode 100644 queue-6.12/rust-sync-remove-unneeded.patch create mode 100644 queue-6.12/rust-treewide-switch-to-our-kernel-box-type.patch create mode 100644 queue-6.12/rust-treewide-switch-to-the-kernel-vec-type.patch create mode 100644 queue-6.12/rust-types-avoid-repetition-in-as-from-bytes-impls.patch create mode 100644 queue-6.12/rust-use-custom-ffi-integer-types.patch create mode 100644 queue-6.12/rust-workqueue-remove-unneeded.patch diff --git a/queue-6.12/documentation-rust-add-coding-guidelines-on-lints.patch b/queue-6.12/documentation-rust-add-coding-guidelines-on-lints.patch new file mode 100644 index 0000000000..b93b907c46 --- /dev/null +++ b/queue-6.12/documentation-rust-add-coding-guidelines-on-lints.patch @@ -0,0 +1,79 @@ +From stable+bounces-121470-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:23 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:22 +0100 +Subject: Documentation: rust: add coding guidelines on lints +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-16-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 139d396572ec4ba6e8cc5c02f5c8d5d1139be4b7 upstream. + +In the C side, disabling diagnostics locally, i.e. within the source code, +is rare (at least in the kernel). Sometimes warnings are manipulated +via the flags at the translation unit level, but that is about it. + +In Rust, it is easier to change locally the "level" of lints +(e.g. allowing them locally). In turn, this means it is easier to +globally enable more lints that may trigger a few false positives here +and there that need to be allowed locally, but that generally can spot +issues or bugs. + +Thus document this. + +Reviewed-by: Trevor Gross +Reviewed-by: Alice Ryhl +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-17-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/rust/coding-guidelines.rst | 38 +++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +--- a/Documentation/rust/coding-guidelines.rst ++++ b/Documentation/rust/coding-guidelines.rst +@@ -227,3 +227,41 @@ The equivalent in Rust may look like (ig + That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as + ``gpio::LineDirection::In``. In particular, it should not be named + ``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``. ++ ++ ++Lints ++----- ++ ++In Rust, it is possible to ``allow`` particular warnings (diagnostics, lints) ++locally, making the compiler ignore instances of a given warning within a given ++function, module, block, etc. ++ ++It is similar to ``#pragma GCC diagnostic push`` + ``ignored`` + ``pop`` in C ++[#]_: ++ ++.. code-block:: c ++ ++ #pragma GCC diagnostic push ++ #pragma GCC diagnostic ignored "-Wunused-function" ++ static void f(void) {} ++ #pragma GCC diagnostic pop ++ ++.. [#] In this particular case, the kernel's ``__{always,maybe}_unused`` ++ attributes (C23's ``[[maybe_unused]]``) may be used; however, the example ++ is meant to reflect the equivalent lint in Rust discussed afterwards. ++ ++But way less verbose: ++ ++.. code-block:: rust ++ ++ #[allow(dead_code)] ++ fn f() {} ++ ++By that virtue, it makes it possible to comfortably enable more diagnostics by ++default (i.e. outside ``W=`` levels). In particular, those that may have some ++false positives but that are otherwise quite useful to keep enabled to catch ++potential mistakes. ++ ++For more information about diagnostics in Rust, please see: ++ ++ https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html diff --git a/queue-6.12/documentation-rust-discuss-in-the-guidelines.patch b/queue-6.12/documentation-rust-discuss-in-the-guidelines.patch new file mode 100644 index 0000000000..b0e0e1d770 --- /dev/null +++ b/queue-6.12/documentation-rust-discuss-in-the-guidelines.patch @@ -0,0 +1,145 @@ +From stable+bounces-121472-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:27 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:24 +0100 +Subject: Documentation: rust: discuss `#[expect(...)]` in the guidelines +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-18-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 04866494e936d041fd196d3a36aecd979e4ef078 upstream. + +Discuss `#[expect(...)]` in the Lints sections of the coding guidelines +document, which is an upcoming feature in Rust 1.81.0, and explain that +it is generally to be preferred over `allow` unless there is a reason +not to use it (e.g. conditional compilation being involved). + +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-19-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/rust/coding-guidelines.rst | 110 +++++++++++++++++++++++++++++++ + 1 file changed, 110 insertions(+) + +--- a/Documentation/rust/coding-guidelines.rst ++++ b/Documentation/rust/coding-guidelines.rst +@@ -262,6 +262,116 @@ default (i.e. outside ``W=`` levels). In + false positives but that are otherwise quite useful to keep enabled to catch + potential mistakes. + ++On top of that, Rust provides the ``expect`` attribute which takes this further. ++It makes the compiler warn if the warning was not produced. For instance, the ++following will ensure that, when ``f()`` is called somewhere, we will have to ++remove the attribute: ++ ++.. code-block:: rust ++ ++ #[expect(dead_code)] ++ fn f() {} ++ ++If we do not, we get a warning from the compiler:: ++ ++ warning: this lint expectation is unfulfilled ++ --> x.rs:3:10 ++ | ++ 3 | #[expect(dead_code)] ++ | ^^^^^^^^^ ++ | ++ = note: `#[warn(unfulfilled_lint_expectations)]` on by default ++ ++This means that ``expect``\ s do not get forgotten when they are not needed, which ++may happen in several situations, e.g.: ++ ++- Temporary attributes added while developing. ++ ++- Improvements in lints in the compiler, Clippy or custom tools which may ++ remove a false positive. ++ ++- When the lint is not needed anymore because it was expected that it would be ++ removed at some point, such as the ``dead_code`` example above. ++ ++It also increases the visibility of the remaining ``allow``\ s and reduces the ++chance of misapplying one. ++ ++Thus prefer ``except`` over ``allow`` unless: ++ ++- The lint attribute is intended to be temporary, e.g. while developing. ++ ++- Conditional compilation triggers the warning in some cases but not others. ++ ++ If there are only a few cases where the warning triggers (or does not ++ trigger) compared to the total number of cases, then one may consider using ++ a conditional ``expect`` (i.e. ``cfg_attr(..., expect(...))``). Otherwise, ++ it is likely simpler to just use ``allow``. ++ ++- Inside macros, when the different invocations may create expanded code that ++ triggers the warning in some cases but not in others. ++ ++- When code may trigger a warning for some architectures but not others, such ++ as an ``as`` cast to a C FFI type. ++ ++As a more developed example, consider for instance this program: ++ ++.. code-block:: rust ++ ++ fn g() {} ++ ++ fn main() { ++ #[cfg(CONFIG_X)] ++ g(); ++ } ++ ++Here, function ``g()`` is dead code if ``CONFIG_X`` is not set. Can we use ++``expect`` here? ++ ++.. code-block:: rust ++ ++ #[expect(dead_code)] ++ fn g() {} ++ ++ fn main() { ++ #[cfg(CONFIG_X)] ++ g(); ++ } ++ ++This would emit a lint if ``CONFIG_X`` is set, since it is not dead code in that ++configuration. Therefore, in cases like this, we cannot use ``expect`` as-is. ++ ++A simple possibility is using ``allow``: ++ ++.. code-block:: rust ++ ++ #[allow(dead_code)] ++ fn g() {} ++ ++ fn main() { ++ #[cfg(CONFIG_X)] ++ g(); ++ } ++ ++An alternative would be using a conditional ``expect``: ++ ++.. code-block:: rust ++ ++ #[cfg_attr(not(CONFIG_X), expect(dead_code))] ++ fn g() {} ++ ++ fn main() { ++ #[cfg(CONFIG_X)] ++ g(); ++ } ++ ++This would ensure that, if someone introduces another call to ``g()`` somewhere ++(e.g. unconditionally), then it would be spotted that it is not dead code ++anymore. However, the ``cfg_attr`` is more complex than a simple ``allow``. ++ ++Therefore, it is likely that it is not worth using conditional ``expect``\ s when ++more than one or two configurations are involved or when the lint may be ++triggered due to non-local changes (such as ``dead_code``). ++ + For more information about diagnostics in Rust, please see: + + https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html diff --git a/queue-6.12/drm-panic-allow-verbose-boolean-for-clarity.patch b/queue-6.12/drm-panic-allow-verbose-boolean-for-clarity.patch new file mode 100644 index 0000000000..7b0a0fa78b --- /dev/null +++ b/queue-6.12/drm-panic-allow-verbose-boolean-for-clarity.patch @@ -0,0 +1,61 @@ +From stable+bounces-121509-greg=kroah.com@vger.kernel.org Fri Mar 7 23:53:06 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:50:01 +0100 +Subject: drm/panic: allow verbose boolean for clarity +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-55-ojeda@kernel.org> + +From: Thomas Böhler + +commit 27aef8a52e4b7f120ce47cd638d9d83065b759d2 upstream. + +Clippy complains about a non-minimal boolean expression with +`nonminimal_bool`: + + error: this boolean expression can be simplified + --> drivers/gpu/drm/drm_panic_qr.rs:722:9 + | + 722 | (x < 8 && y < 8) || (x < 8 && y >= end) || (x >= end && y < 8) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool + = note: `-D clippy::nonminimal-bool` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]` + help: try + | + 722 | !(x >= 8 || y >= 8 && y < end) || (x >= end && y < 8) + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 722 | (y >= end || y < 8) && x < 8 || (x >= end && y < 8) + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +While this can be useful in a lot of cases, it isn't here because the +line expresses clearly what the intention is. Simplifying the expression +means losing clarity, so opt-out of this lint for the offending line. + +Fixes: cb5164ac43d0 ("drm/panic: Add a QR code panic screen") +Reported-by: Miguel Ojeda +Link: https://github.com/Rust-for-Linux/linux/issues/1123 +Signed-off-by: Thomas Böhler +Reviewed-by: Jocelyn Falempe +Link: https://lore.kernel.org/r/20241019084048.22336-7-witcher@wiredspace.de +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_panic_qr.rs | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_panic_qr.rs ++++ b/drivers/gpu/drm/drm_panic_qr.rs +@@ -719,7 +719,10 @@ impl QrImage<'_> { + + fn is_finder(&self, x: u8, y: u8) -> bool { + let end = self.width - 8; +- (x < 8 && y < 8) || (x < 8 && y >= end) || (x >= end && y < 8) ++ #[expect(clippy::nonminimal_bool)] ++ { ++ (x < 8 && y < 8) || (x < 8 && y >= end) || (x >= end && y < 8) ++ } + } + + // Alignment pattern: 5x5 squares in a grid. diff --git a/queue-6.12/drm-panic-allow-verbose-version-check.patch b/queue-6.12/drm-panic-allow-verbose-version-check.patch new file mode 100644 index 0000000000..5355d824a3 --- /dev/null +++ b/queue-6.12/drm-panic-allow-verbose-version-check.patch @@ -0,0 +1,49 @@ +From stable+bounces-121510-greg=kroah.com@vger.kernel.org Fri Mar 7 23:53:09 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:50:02 +0100 +Subject: drm/panic: allow verbose version check +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-56-ojeda@kernel.org> + +From: Thomas Böhler + +commit 06b919e3fedf4798a1f0f60e0b67caa192f724a7 upstream. + +Clippy warns about a reimplementation of `RangeInclusive::contains`: + + error: manual `!RangeInclusive::contains` implementation + --> drivers/gpu/drm/drm_panic_qr.rs:986:8 + | + 986 | if version < 1 || version > 40 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!(1..=40).contains(&version)` + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains + = note: `-D clippy::manual-range-contains` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_range_contains)]` + +Ignore this and keep the current implementation as that makes it easier +to read. + +Fixes: cb5164ac43d0 ("drm/panic: Add a QR code panic screen") +Reported-by: Miguel Ojeda +Link: https://github.com/Rust-for-Linux/linux/issues/1123 +Signed-off-by: Thomas Böhler +Reviewed-by: Jocelyn Falempe +Link: https://lore.kernel.org/r/20241019084048.22336-8-witcher@wiredspace.de +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_panic_qr.rs | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/drm_panic_qr.rs ++++ b/drivers/gpu/drm/drm_panic_qr.rs +@@ -982,6 +982,7 @@ pub unsafe extern "C" fn drm_panic_qr_ge + /// * If `url_len` = 0, only removes 3 bytes for 1 binary segment. + #[no_mangle] + pub extern "C" fn drm_panic_qr_max_data_size(version: u8, url_len: usize) -> usize { ++ #[expect(clippy::manual_range_contains)] + if version < 1 || version > 40 { + return 0; + } diff --git a/queue-6.12/drm-panic-avoid-reimplementing-iterator-find.patch b/queue-6.12/drm-panic-avoid-reimplementing-iterator-find.patch new file mode 100644 index 0000000000..2a8fd7e6d6 --- /dev/null +++ b/queue-6.12/drm-panic-avoid-reimplementing-iterator-find.patch @@ -0,0 +1,80 @@ +From stable+bounces-121504-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:51 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:56 +0100 +Subject: drm/panic: avoid reimplementing Iterator::find +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-50-ojeda@kernel.org> + +From: Thomas Böhler + +commit c408dd81678bb0a957eae96962c913c242e069f7 upstream. + +Rust's standard library's `std::iter::Iterator` trait provides a function +`find` that finds the first element that satisfies a predicate. +The function `Version::from_segments` is doing the same thing but is +implementing the same logic itself. + +Clippy complains about this in the `manual_find` lint: + + error: manual implementation of `Iterator::find` + --> drivers/gpu/drm/drm_panic_qr.rs:212:9 + | + 212 | / for v in (1..=40).map(|k| Version(k)) { + 213 | | if v.max_data() * 8 >= segments.iter().map(|s| s.total_size_bits(v)).sum() { + 214 | | return Some(v); + 215 | | } + 216 | | } + 217 | | None + | |____________^ help: replace with an iterator: `(1..=40).map(|k| Version(k)).find(|&v| v.max_data() * 8 >= segments.iter().map(|s| s.total_size_bits(v)).sum())` + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_find + = note: `-D clippy::manual-find` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_find)]` + +Use `Iterator::find` instead to make the intention clearer. + +At the same time, clean up the redundant closure that Clippy warns +about too: + + error: redundant closure + --> drivers/gpu/drm/drm_panic_qr.rs:212:31 + | + 212 | for v in (1..=40).map(|k| Version(k)) { + | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `Version` + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure + = note: `-D clippy::redundant-closure` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]` + +Fixes: cb5164ac43d0 ("drm/panic: Add a QR code panic screen") +Reported-by: Miguel Ojeda +Link: https://github.com/Rust-for-Linux/linux/issues/1123 +Signed-off-by: Thomas Böhler +Reviewed-by: Jocelyn Falempe +Link: https://lore.kernel.org/r/20241019084048.22336-2-witcher@wiredspace.de +[ Reworded to mention the redundant closure cleanup too. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_panic_qr.rs | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/drm_panic_qr.rs ++++ b/drivers/gpu/drm/drm_panic_qr.rs +@@ -209,12 +209,9 @@ const FORMAT_INFOS_QR_L: [u16; 8] = [ + impl Version { + /// Returns the smallest QR version than can hold these segments. + fn from_segments(segments: &[&Segment<'_>]) -> Option { +- for v in (1..=40).map(|k| Version(k)) { +- if v.max_data() * 8 >= segments.iter().map(|s| s.total_size_bits(v)).sum() { +- return Some(v); +- } +- } +- None ++ (1..=40) ++ .map(Version) ++ .find(|&v| v.max_data() * 8 >= segments.iter().map(|s| s.total_size_bits(v)).sum()) + } + + fn width(&self) -> u8 { diff --git a/queue-6.12/drm-panic-correctly-indent-continuation-of-line-in-list-item.patch b/queue-6.12/drm-panic-correctly-indent-continuation-of-line-in-list-item.patch new file mode 100644 index 0000000000..1048aca245 --- /dev/null +++ b/queue-6.12/drm-panic-correctly-indent-continuation-of-line-in-list-item.patch @@ -0,0 +1,57 @@ +From stable+bounces-121508-greg=kroah.com@vger.kernel.org Fri Mar 7 23:53:09 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:50:00 +0100 +Subject: drm/panic: correctly indent continuation of line in list item +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-54-ojeda@kernel.org> + +From: Thomas Böhler + +commit 5bb698e6fc514ddd9e23b6649b29a0934d8d8586 upstream. + +It is common practice in Rust to indent the next line the same amount of +space as the previous one if both belong to the same list item. Clippy +checks for this with the lint `doc_lazy_continuation`. + + error: doc list item without indentation + --> drivers/gpu/drm/drm_panic_qr.rs:979:5 + | + 979 | /// conversion to numeric segments. + | ^ + | + = help: if this is supposed to be its own paragraph, add a blank line + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation + = note: `-D clippy::doc-lazy-continuation` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_lazy_continuation)]` + help: indent this line + | + 979 | /// conversion to numeric segments. + | ++ + +Indent the offending line by 2 more spaces to remove this Clippy error. + +Fixes: cb5164ac43d0 ("drm/panic: Add a QR code panic screen") +Reported-by: Miguel Ojeda +Link: https://github.com/Rust-for-Linux/linux/issues/1123 +Signed-off-by: Thomas Böhler +Reviewed-by: Jocelyn Falempe +Link: https://lore.kernel.org/r/20241019084048.22336-6-witcher@wiredspace.de +[ Reworded to indent Clippy's message. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_panic_qr.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_panic_qr.rs ++++ b/drivers/gpu/drm/drm_panic_qr.rs +@@ -975,7 +975,7 @@ pub unsafe extern "C" fn drm_panic_qr_ge + /// * `url_len`: Length of the URL. + /// + /// * If `url_len` > 0, remove the 2 segments header/length and also count the +-/// conversion to numeric segments. ++/// conversion to numeric segments. + /// * If `url_len` = 0, only removes 3 bytes for 1 binary segment. + #[no_mangle] + pub extern "C" fn drm_panic_qr_max_data_size(version: u8, url_len: usize) -> usize { diff --git a/queue-6.12/drm-panic-prefer-eliding-lifetimes.patch b/queue-6.12/drm-panic-prefer-eliding-lifetimes.patch new file mode 100644 index 0000000000..ba0f461bca --- /dev/null +++ b/queue-6.12/drm-panic-prefer-eliding-lifetimes.patch @@ -0,0 +1,56 @@ +From stable+bounces-121506-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:57 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:58 +0100 +Subject: drm/panic: prefer eliding lifetimes +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-52-ojeda@kernel.org> + +From: Thomas Böhler + +commit ae75c40117b53ae3d91dfc9d0bf06984a079f044 upstream. + +Eliding lifetimes when possible instead of specifying them directly is +both shorter and easier to read. Clippy notes this in the +`needless_lifetimes` lint: + + error: the following explicit lifetimes could be elided: 'b + --> drivers/gpu/drm/drm_panic_qr.rs:479:16 + | + 479 | fn new<'a, 'b>(segments: &[&Segment<'b>], data: &'a mut [u8]) -> Option> { + | ^^ ^^ + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes + = note: `-D clippy::needless-lifetimes` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]` + help: elide the lifetimes + | + 479 - fn new<'a, 'b>(segments: &[&Segment<'b>], data: &'a mut [u8]) -> Option> { + 479 + fn new<'a>(segments: &[&Segment<'_>], data: &'a mut [u8]) -> Option> { + | + +Remove the explicit lifetime annotation in favour of an elided lifetime. + +Fixes: cb5164ac43d0 ("drm/panic: Add a QR code panic screen") +Reported-by: Miguel Ojeda +Link: https://github.com/Rust-for-Linux/linux/issues/1123 +Signed-off-by: Thomas Böhler +Reviewed-by: Jocelyn Falempe +Link: https://lore.kernel.org/r/20241019084048.22336-4-witcher@wiredspace.de +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_panic_qr.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_panic_qr.rs ++++ b/drivers/gpu/drm/drm_panic_qr.rs +@@ -476,7 +476,7 @@ struct EncodedMsg<'a> { + /// Data to be put in the QR code, with correct segment encoding, padding, and + /// Error Code Correction. + impl EncodedMsg<'_> { +- fn new<'a, 'b>(segments: &[&Segment<'b>], data: &'a mut [u8]) -> Option> { ++ fn new<'a>(segments: &[&Segment<'_>], data: &'a mut [u8]) -> Option> { + let version = Version::from_segments(segments)?; + let ec_size = version.ec_size(); + let g1_blocks = version.g1_blocks(); diff --git a/queue-6.12/drm-panic-remove-redundant-field-when-assigning-value.patch b/queue-6.12/drm-panic-remove-redundant-field-when-assigning-value.patch new file mode 100644 index 0000000000..60641a2f89 --- /dev/null +++ b/queue-6.12/drm-panic-remove-redundant-field-when-assigning-value.patch @@ -0,0 +1,54 @@ +From stable+bounces-121507-greg=kroah.com@vger.kernel.org Fri Mar 7 23:53:06 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:59 +0100 +Subject: drm/panic: remove redundant field when assigning value +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-53-ojeda@kernel.org> + +From: Thomas Böhler + +commit da13129a3f2a75d49469e1d6f7dcefac2d11d205 upstream. + +Rust allows initializing fields of a struct without specifying the +attribute that is assigned if the variable has the same name. In this +instance this is done for all other attributes of the struct except for +`data`. Clippy notes the redundant field name: + + error: redundant field names in struct initialization + --> drivers/gpu/drm/drm_panic_qr.rs:495:13 + | + 495 | data: data, + | ^^^^^^^^^^ help: replace it with: `data` + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names + = note: `-D clippy::redundant-field-names` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::redundant_field_names)]` + +Remove the redundant `data` in the assignment to be consistent. + +Fixes: cb5164ac43d0 ("drm/panic: Add a QR code panic screen") +Reported-by: Miguel Ojeda +Link: https://github.com/Rust-for-Linux/linux/issues/1123 +Signed-off-by: Thomas Böhler +Reviewed-by: Jocelyn Falempe +Link: https://lore.kernel.org/r/20241019084048.22336-5-witcher@wiredspace.de +[ Reworded to add Clippy warning like it is done in the rest of the + series. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_panic_qr.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_panic_qr.rs ++++ b/drivers/gpu/drm/drm_panic_qr.rs +@@ -489,7 +489,7 @@ impl EncodedMsg<'_> { + data.fill(0); + + let mut em = EncodedMsg { +- data: data, ++ data, + ec_size, + g1_blocks, + g2_blocks, diff --git a/queue-6.12/drm-panic-remove-unnecessary-borrow-in-alignment_pattern.patch b/queue-6.12/drm-panic-remove-unnecessary-borrow-in-alignment_pattern.patch new file mode 100644 index 0000000000..12a8e8f8d6 --- /dev/null +++ b/queue-6.12/drm-panic-remove-unnecessary-borrow-in-alignment_pattern.patch @@ -0,0 +1,53 @@ +From stable+bounces-121505-greg=kroah.com@vger.kernel.org Fri Mar 7 23:53:05 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:57 +0100 +Subject: drm/panic: remove unnecessary borrow in alignment_pattern +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-51-ojeda@kernel.org> + +From: Thomas Böhler + +commit 7b6de57e0b2d1e62becfa3aac063c4c58d2c2c42 upstream. + +The function `alignment_pattern` returns a static reference to a `u8` +slice. The borrow of the returned element in `ALIGNMENT_PATTERNS` is +already a reference as defined in the array definition above so this +borrow is unnecessary and removed by the compiler. Clippy notes this in +`needless_borrow`: + + error: this expression creates a reference which is immediately dereferenced by the compiler + --> drivers/gpu/drm/drm_panic_qr.rs:245:9 + | + 245 | &ALIGNMENT_PATTERNS[self.0 - 1] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: change this to: `ALIGNMENT_PATTERNS[self.0 - 1]` + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow + = note: `-D clippy::needless-borrow` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]` + +Remove the unnecessary borrow. + +Fixes: cb5164ac43d0 ("drm/panic: Add a QR code panic screen") +Reported-by: Miguel Ojeda +Link: https://github.com/Rust-for-Linux/linux/issues/1123 +Signed-off-by: Thomas Böhler +Reviewed-by: Jocelyn Falempe +Link: https://lore.kernel.org/r/20241019084048.22336-3-witcher@wiredspace.de +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_panic_qr.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_panic_qr.rs ++++ b/drivers/gpu/drm/drm_panic_qr.rs +@@ -239,7 +239,7 @@ impl Version { + } + + fn alignment_pattern(&self) -> &'static [u8] { +- &ALIGNMENT_PATTERNS[self.0 - 1] ++ ALIGNMENT_PATTERNS[self.0 - 1] + } + + fn poly(&self) -> &'static [u8] { diff --git a/queue-6.12/kbuild-rust-remove-the-alloc-crate-and-globalalloc.patch b/queue-6.12/kbuild-rust-remove-the-alloc-crate-and-globalalloc.patch new file mode 100644 index 0000000000..511789976e --- /dev/null +++ b/queue-6.12/kbuild-rust-remove-the-alloc-crate-and-globalalloc.patch @@ -0,0 +1,306 @@ +From stable+bounces-121502-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:59 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:54 +0100 +Subject: kbuild: rust: remove the `alloc` crate and `GlobalAlloc` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-48-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 392e34b6bc22077ef63abf62387ea3e9f39418c1 upstream. + +Now that we have our own `Allocator`, `Box` and `Vec` types we can remove +Rust's `alloc` crate and the `new_uninit` unstable feature. + +Also remove `Kmalloc`'s `GlobalAlloc` implementation -- we can't remove +this in a separate patch, since the `alloc` crate requires a +`#[global_allocator]` to set, that implements `GlobalAlloc`. + +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-29-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/Makefile | 43 +++++-------------------- + rust/exports.c | 1 + rust/kernel/alloc/allocator.rs | 65 +------------------------------------- + scripts/Makefile.build | 4 +- + scripts/generate_rust_analyzer.py | 11 +----- + 5 files changed, 16 insertions(+), 108 deletions(-) + +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -15,8 +15,8 @@ always-$(CONFIG_RUST) += libmacros.so + no-clean-files += libmacros.so + + always-$(CONFIG_RUST) += bindings/bindings_generated.rs bindings/bindings_helpers_generated.rs +-obj-$(CONFIG_RUST) += alloc.o bindings.o kernel.o +-always-$(CONFIG_RUST) += exports_alloc_generated.h exports_helpers_generated.h \ ++obj-$(CONFIG_RUST) += bindings.o kernel.o ++always-$(CONFIG_RUST) += exports_helpers_generated.h \ + exports_bindings_generated.h exports_kernel_generated.h + + always-$(CONFIG_RUST) += uapi/uapi_generated.rs +@@ -53,11 +53,6 @@ endif + core-cfgs = \ + --cfg no_fp_fmt_parse + +-alloc-cfgs = \ +- --cfg no_global_oom_handling \ +- --cfg no_rc \ +- --cfg no_sync +- + quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< + cmd_rustdoc = \ + OBJTREE=$(abspath $(objtree)) \ +@@ -81,7 +76,7 @@ quiet_cmd_rustdoc = RUSTDOC $(if $(rustd + # command-like flags to solve the issue. Meanwhile, we use the non-custom case + # and then retouch the generated files. + rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ +- rustdoc-alloc rustdoc-kernel ++ rustdoc-kernel + $(Q)cp $(srctree)/Documentation/images/logo.svg $(rustdoc_output)/static.files/ + $(Q)cp $(srctree)/Documentation/images/COPYING-logo $(rustdoc_output)/static.files/ + $(Q)find $(rustdoc_output) -name '*.html' -type f -print0 | xargs -0 sed -Ei \ +@@ -108,20 +103,11 @@ rustdoc-core: $(RUST_LIB_SRC)/core/src/l + rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE + +$(call if_changed,rustdoc) + +-# We need to allow `rustdoc::broken_intra_doc_links` because some +-# `no_global_oom_handling` functions refer to non-`no_global_oom_handling` +-# functions. Ideally `rustdoc` would have a way to distinguish broken links +-# due to things that are "configured out" vs. entirely non-existing ones. +-rustdoc-alloc: private rustc_target_flags = $(alloc-cfgs) \ +- -Arustdoc::broken_intra_doc_links +-rustdoc-alloc: $(RUST_LIB_SRC)/alloc/src/lib.rs rustdoc-core rustdoc-compiler_builtins FORCE +- +$(call if_changed,rustdoc) +- +-rustdoc-kernel: private rustc_target_flags = --extern alloc \ ++rustdoc-kernel: private rustc_target_flags = \ + --extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \ + --extern bindings --extern uapi + rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \ +- rustdoc-compiler_builtins rustdoc-alloc $(obj)/libmacros.so \ ++ rustdoc-compiler_builtins $(obj)/libmacros.so \ + $(obj)/bindings.o FORCE + +$(call if_changed,rustdoc) + +@@ -165,7 +151,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC + mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \ + OBJTREE=$(abspath $(objtree)) \ + $(RUSTDOC) --test $(rust_flags) \ +- -L$(objtree)/$(obj) --extern alloc --extern kernel \ ++ -L$(objtree)/$(obj) --extern kernel \ + --extern build_error --extern macros \ + --extern bindings --extern uapi \ + --no-run --crate-name kernel -Zunstable-options \ +@@ -201,7 +187,7 @@ rusttest-macros: $(src)/macros/lib.rs FO + +$(call if_changed,rustc_test) + +$(call if_changed,rustdoc_test) + +-rusttest-kernel: private rustc_target_flags = --extern alloc \ ++rusttest-kernel: private rustc_target_flags = \ + --extern build_error --extern macros --extern bindings --extern uapi + rusttest-kernel: $(src)/kernel/lib.rs \ + rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \ +@@ -328,9 +314,6 @@ quiet_cmd_exports = EXPORTS $@ + $(obj)/exports_core_generated.h: $(obj)/core.o FORCE + $(call if_changed,exports) + +-$(obj)/exports_alloc_generated.h: $(obj)/alloc.o FORCE +- $(call if_changed,exports) +- + # Even though Rust kernel modules should never use the bindings directly, + # symbols from the `bindings` crate and the C helpers need to be exported + # because Rust generics and inlined functions may not get their code generated +@@ -377,7 +360,7 @@ quiet_cmd_rustc_library = $(if $(skip_cl + + rust-analyzer: + $(Q)$(srctree)/scripts/generate_rust_analyzer.py \ +- --cfgs='core=$(core-cfgs)' --cfgs='alloc=$(alloc-cfgs)' \ ++ --cfgs='core=$(core-cfgs)' \ + $(realpath $(srctree)) $(realpath $(objtree)) \ + $(rustc_sysroot) $(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \ + $(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json +@@ -415,12 +398,6 @@ $(obj)/compiler_builtins.o: private rust + $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE + +$(call if_changed_rule,rustc_library) + +-$(obj)/alloc.o: private skip_clippy = 1 +-$(obj)/alloc.o: private skip_flags = -Wunreachable_pub +-$(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs) +-$(obj)/alloc.o: $(RUST_LIB_SRC)/alloc/src/lib.rs $(obj)/compiler_builtins.o FORCE +- +$(call if_changed_rule,rustc_library) +- + $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE + +$(call if_changed_rule,rustc_library) + +@@ -435,9 +412,9 @@ $(obj)/uapi.o: $(src)/uapi/lib.rs \ + $(obj)/uapi/uapi_generated.rs FORCE + +$(call if_changed_rule,rustc_library) + +-$(obj)/kernel.o: private rustc_target_flags = --extern alloc \ ++$(obj)/kernel.o: private rustc_target_flags = \ + --extern build_error --extern macros --extern bindings --extern uapi +-$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o $(obj)/build_error.o \ ++$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \ + $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE + +$(call if_changed_rule,rustc_library) + +--- a/rust/exports.c ++++ b/rust/exports.c +@@ -16,7 +16,6 @@ + #define EXPORT_SYMBOL_RUST_GPL(sym) extern int sym; EXPORT_SYMBOL_GPL(sym) + + #include "exports_core_generated.h" +-#include "exports_alloc_generated.h" + #include "exports_helpers_generated.h" + #include "exports_bindings_generated.h" + #include "exports_kernel_generated.h" +--- a/rust/kernel/alloc/allocator.rs ++++ b/rust/kernel/alloc/allocator.rs +@@ -8,8 +8,8 @@ + //! + //! Reference: + +-use super::{flags::*, Flags}; +-use core::alloc::{GlobalAlloc, Layout}; ++use super::Flags; ++use core::alloc::Layout; + use core::ptr; + use core::ptr::NonNull; + +@@ -54,23 +54,6 @@ fn aligned_size(new_layout: Layout) -> u + layout.size() + } + +-/// Calls `krealloc` with a proper size to alloc a new object aligned to `new_layout`'s alignment. +-/// +-/// # Safety +-/// +-/// - `ptr` can be either null or a pointer which has been allocated by this allocator. +-/// - `new_layout` must have a non-zero size. +-pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, flags: Flags) -> *mut u8 { +- let size = aligned_size(new_layout); +- +- // SAFETY: +- // - `ptr` is either null or a pointer returned from a previous `k{re}alloc()` by the +- // function safety requirement. +- // - `size` is greater than 0 since it's from `layout.size()` (which cannot be zero according +- // to the function safety requirement) +- unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags.0) as *mut u8 } +-} +- + /// # Invariants + /// + /// One of the following: `krealloc`, `vrealloc`, `kvrealloc`. +@@ -156,43 +139,6 @@ unsafe impl Allocator for Kmalloc { + } + } + +-// SAFETY: TODO. +-unsafe impl GlobalAlloc for Kmalloc { +- unsafe fn alloc(&self, layout: Layout) -> *mut u8 { +- // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety +- // requirement. +- unsafe { krealloc_aligned(ptr::null_mut(), layout, GFP_KERNEL) } +- } +- +- unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { +- // SAFETY: TODO. +- unsafe { +- bindings::kfree(ptr as *const core::ffi::c_void); +- } +- } +- +- unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { +- // SAFETY: +- // - `new_size`, when rounded up to the nearest multiple of `layout.align()`, will not +- // overflow `isize` by the function safety requirement. +- // - `layout.align()` is a proper alignment (i.e. not zero and must be a power of two). +- let layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; +- +- // SAFETY: +- // - `ptr` is either null or a pointer allocated by this allocator by the function safety +- // requirement. +- // - the size of `layout` is not zero because `new_size` is not zero by the function safety +- // requirement. +- unsafe { krealloc_aligned(ptr, layout, GFP_KERNEL) } +- } +- +- unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { +- // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety +- // requirement. +- unsafe { krealloc_aligned(ptr::null_mut(), layout, GFP_KERNEL | __GFP_ZERO) } +- } +-} +- + // SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that + // - memory remains valid until it is explicitly freed, + // - passing a pointer to a valid memory allocation is OK, +@@ -240,10 +186,3 @@ unsafe impl Allocator for KVmalloc { + unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags) } + } + } +- +-#[global_allocator] +-static ALLOCATOR: Kmalloc = Kmalloc; +- +-// See . +-#[no_mangle] +-static __rust_no_alloc_shim_is_unstable: u8 = 0; +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -248,7 +248,7 @@ $(obj)/%.lst: $(obj)/%.c FORCE + # Compile Rust sources (.rs) + # --------------------------------------------------------------------------- + +-rust_allowed_features := arbitrary_self_types,lint_reasons,new_uninit ++rust_allowed_features := arbitrary_self_types,lint_reasons + + # `--out-dir` is required to avoid temporaries being created by `rustc` in the + # current working directory, which may be not accessible in the out-of-tree +@@ -258,7 +258,7 @@ rust_common_cmd = \ + -Zallow-features=$(rust_allowed_features) \ + -Zcrate-attr=no_std \ + -Zcrate-attr='feature($(rust_allowed_features))' \ +- -Zunstable-options --extern force:alloc --extern kernel \ ++ -Zunstable-options --extern kernel \ + --crate-type rlib -L $(objtree)/rust/ \ + --crate-name $(basename $(notdir $@)) \ + --sysroot=/dev/null \ +--- a/scripts/generate_rust_analyzer.py ++++ b/scripts/generate_rust_analyzer.py +@@ -65,13 +65,6 @@ def generate_crates(srctree, objtree, sy + ) + + append_crate( +- "alloc", +- sysroot_src / "alloc" / "src" / "lib.rs", +- ["core", "compiler_builtins"], +- cfg=crates_cfgs.get("alloc", []), +- ) +- +- append_crate( + "macros", + srctree / "rust" / "macros" / "lib.rs", + [], +@@ -96,7 +89,7 @@ def generate_crates(srctree, objtree, sy + append_crate( + "kernel", + srctree / "rust" / "kernel" / "lib.rs", +- ["core", "alloc", "macros", "build_error", "bindings"], ++ ["core", "macros", "build_error", "bindings"], + cfg=cfg, + ) + crates[-1]["source"] = { +@@ -133,7 +126,7 @@ def generate_crates(srctree, objtree, sy + append_crate( + name, + path, +- ["core", "alloc", "kernel"], ++ ["core", "kernel"], + cfg=cfg, + ) + diff --git a/queue-6.12/maintainers-add-entry-for-the-rust-alloc-module.patch b/queue-6.12/maintainers-add-entry-for-the-rust-alloc-module.patch new file mode 100644 index 0000000000..ca3331e0fc --- /dev/null +++ b/queue-6.12/maintainers-add-entry-for-the-rust-alloc-module.patch @@ -0,0 +1,43 @@ +From stable+bounces-121503-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:51 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:55 +0100 +Subject: MAINTAINERS: add entry for the Rust `alloc` module +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-49-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 6ce162a002657910104c7a07fb50017681bc476c upstream. + +Add maintainers entry for the Rust `alloc` module. + +Currently, this includes the `Allocator` API itself, `Allocator` +implementations, such as `Kmalloc` or `Vmalloc`, as well as the kernel's +implementation of the primary memory allocation data structures, `Box` +and `Vec`. + +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-30-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + MAINTAINERS | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -20183,6 +20183,13 @@ F: scripts/*rust* + F: tools/testing/selftests/rust/ + K: \b(?i:rust)\b + ++RUST [ALLOC] ++M: Danilo Krummrich ++L: rust-for-linux@vger.kernel.org ++S: Maintained ++F: rust/kernel/alloc.rs ++F: rust/kernel/alloc/ ++ + RXRPC SOCKETS (AF_RXRPC) + M: David Howells + M: Marc Dionne diff --git a/queue-6.12/rust-alloc-add-__gfp_nowarn-to-flags.patch b/queue-6.12/rust-alloc-add-__gfp_nowarn-to-flags.patch new file mode 100644 index 0000000000..a8fe365df5 --- /dev/null +++ b/queue-6.12/rust-alloc-add-__gfp_nowarn-to-flags.patch @@ -0,0 +1,49 @@ +From stable+bounces-121484-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:11 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:36 +0100 +Subject: rust: alloc: add __GFP_NOWARN to `Flags` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-30-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 01b2196e5aac8af9343282d0044fa0d6b07d484c upstream. + +Some test cases in subsequent patches provoke allocation failures. Add +`__GFP_NOWARN` to enable test cases to silence unpleasant warnings. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-11-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/bindings/bindings_helper.h | 1 + + rust/kernel/alloc.rs | 5 +++++ + 2 files changed, 6 insertions(+) + +--- a/rust/bindings/bindings_helper.h ++++ b/rust/bindings/bindings_helper.h +@@ -31,4 +31,5 @@ const gfp_t RUST_CONST_HELPER_GFP_KERNEL + const gfp_t RUST_CONST_HELPER_GFP_NOWAIT = GFP_NOWAIT; + const gfp_t RUST_CONST_HELPER___GFP_ZERO = __GFP_ZERO; + const gfp_t RUST_CONST_HELPER___GFP_HIGHMEM = ___GFP_HIGHMEM; ++const gfp_t RUST_CONST_HELPER___GFP_NOWARN = ___GFP_NOWARN; + const blk_features_t RUST_CONST_HELPER_BLK_FEAT_ROTATIONAL = BLK_FEAT_ROTATIONAL; +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -91,6 +91,11 @@ pub mod flags { + /// use any filesystem callback. It is very likely to fail to allocate memory, even for very + /// small allocations. + pub const GFP_NOWAIT: Flags = Flags(bindings::GFP_NOWAIT); ++ ++ /// Suppresses allocation failure reports. ++ /// ++ /// This is normally or'd with other flags. ++ pub const __GFP_NOWARN: Flags = Flags(bindings::__GFP_NOWARN); + } + + /// The kernel's [`Allocator`] trait. diff --git a/queue-6.12/rust-alloc-add-allocator-trait.patch b/queue-6.12/rust-alloc-add-allocator-trait.patch new file mode 100644 index 0000000000..ef84c4f6da --- /dev/null +++ b/queue-6.12/rust-alloc-add-allocator-trait.patch @@ -0,0 +1,145 @@ +From stable+bounces-121475-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:36 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:27 +0100 +Subject: rust: alloc: add `Allocator` trait +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-21-ojeda@kernel.org> + +From: Danilo Krummrich + +commit b7a084ba4fbb8f416ce8d19c93a3a2bee63c9c89 upstream. + +Add a kernel specific `Allocator` trait, that in contrast to the one in +Rust's core library doesn't require unstable features and supports GFP +flags. + +Subsequent patches add the following trait implementors: `Kmalloc`, +`Vmalloc` and `KVmalloc`. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-2-dakr@kernel.org +[ Fixed typo. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 101 insertions(+) + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -11,6 +11,7 @@ pub mod vec_ext; + /// Indicates an allocation error. + #[derive(Copy, Clone, PartialEq, Eq, Debug)] + pub struct AllocError; ++use core::{alloc::Layout, ptr::NonNull}; + + /// Flags to be used when allocating memory. + /// +@@ -86,3 +87,103 @@ pub mod flags { + /// small allocations. + pub const GFP_NOWAIT: Flags = Flags(bindings::GFP_NOWAIT); + } ++ ++/// The kernel's [`Allocator`] trait. ++/// ++/// An implementation of [`Allocator`] can allocate, re-allocate and free memory buffers described ++/// via [`Layout`]. ++/// ++/// [`Allocator`] is designed to be implemented as a ZST; [`Allocator`] functions do not operate on ++/// an object instance. ++/// ++/// In order to be able to support `#[derive(SmartPointer)]` later on, we need to avoid a design ++/// that requires an `Allocator` to be instantiated, hence its functions must not contain any kind ++/// of `self` parameter. ++/// ++/// # Safety ++/// ++/// - A memory allocation returned from an allocator must remain valid until it is explicitly freed. ++/// ++/// - Any pointer to a valid memory allocation must be valid to be passed to any other [`Allocator`] ++/// function of the same type. ++/// ++/// - Implementers must ensure that all trait functions abide by the guarantees documented in the ++/// `# Guarantees` sections. ++pub unsafe trait Allocator { ++ /// Allocate memory based on `layout` and `flags`. ++ /// ++ /// On success, returns a buffer represented as `NonNull<[u8]>` that satisfies the layout ++ /// constraints (i.e. minimum size and alignment as specified by `layout`). ++ /// ++ /// This function is equivalent to `realloc` when called with `None`. ++ /// ++ /// # Guarantees ++ /// ++ /// When the return value is `Ok(ptr)`, then `ptr` is ++ /// - valid for reads and writes for `layout.size()` bytes, until it is passed to ++ /// [`Allocator::free`] or [`Allocator::realloc`], ++ /// - aligned to `layout.align()`, ++ /// ++ /// Additionally, `Flags` are honored as documented in ++ /// . ++ fn alloc(layout: Layout, flags: Flags) -> Result, AllocError> { ++ // SAFETY: Passing `None` to `realloc` is valid by its safety requirements and asks for a ++ // new memory allocation. ++ unsafe { Self::realloc(None, layout, Layout::new::<()>(), flags) } ++ } ++ ++ /// Re-allocate an existing memory allocation to satisfy the requested `layout`. ++ /// ++ /// If the requested size is zero, `realloc` behaves equivalent to `free`. ++ /// ++ /// If the requested size is larger than the size of the existing allocation, a successful call ++ /// to `realloc` guarantees that the new or grown buffer has at least `Layout::size` bytes, but ++ /// may also be larger. ++ /// ++ /// If the requested size is smaller than the size of the existing allocation, `realloc` may or ++ /// may not shrink the buffer; this is implementation specific to the allocator. ++ /// ++ /// On allocation failure, the existing buffer, if any, remains valid. ++ /// ++ /// The buffer is represented as `NonNull<[u8]>`. ++ /// ++ /// # Safety ++ /// ++ /// - If `ptr == Some(p)`, then `p` must point to an existing and valid memory allocation ++ /// created by this [`Allocator`]; if `old_layout` is zero-sized `p` does not need to be a ++ /// pointer returned by this [`Allocator`]. ++ /// - `ptr` is allowed to be `None`; in this case a new memory allocation is created and ++ /// `old_layout` is ignored. ++ /// - `old_layout` must match the `Layout` the allocation has been created with. ++ /// ++ /// # Guarantees ++ /// ++ /// This function has the same guarantees as [`Allocator::alloc`]. When `ptr == Some(p)`, then ++ /// it additionally guarantees that: ++ /// - the contents of the memory pointed to by `p` are preserved up to the lesser of the new ++ /// and old size, i.e. `ret_ptr[0..min(layout.size(), old_layout.size())] == ++ /// p[0..min(layout.size(), old_layout.size())]`. ++ /// - when the return value is `Err(AllocError)`, then `ptr` is still valid. ++ unsafe fn realloc( ++ ptr: Option>, ++ layout: Layout, ++ old_layout: Layout, ++ flags: Flags, ++ ) -> Result, AllocError>; ++ ++ /// Free an existing memory allocation. ++ /// ++ /// # Safety ++ /// ++ /// - `ptr` must point to an existing and valid memory allocation created by this [`Allocator`]; ++ /// if `old_layout` is zero-sized `p` does not need to be a pointer returned by this ++ /// [`Allocator`]. ++ /// - `layout` must match the `Layout` the allocation has been created with. ++ /// - The memory allocation at `ptr` must never again be read from or written to. ++ unsafe fn free(ptr: NonNull, layout: Layout) { ++ // SAFETY: The caller guarantees that `ptr` points at a valid allocation created by this ++ // allocator. We are passing a `Layout` with the smallest possible alignment, so it is ++ // smaller than or equal to the alignment previously used with this allocation. ++ let _ = unsafe { Self::realloc(Some(ptr), Layout::new::<()>(), layout, Flags(0)) }; ++ } ++} diff --git a/queue-6.12/rust-alloc-add-box-to-prelude.patch b/queue-6.12/rust-alloc-add-box-to-prelude.patch new file mode 100644 index 0000000000..55c2b736cf --- /dev/null +++ b/queue-6.12/rust-alloc-add-box-to-prelude.patch @@ -0,0 +1,37 @@ +From stable+bounces-121488-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:17 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:40 +0100 +Subject: rust: alloc: add `Box` to prelude +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-34-ojeda@kernel.org> + +From: Danilo Krummrich + +commit e1044c2238f54ae5bd902cac6d12e48835df418b upstream. + +Now that we removed `BoxExt` and the corresponding includes in +prelude.rs, add the new kernel `Box` type instead. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-15-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/prelude.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/rust/kernel/prelude.rs ++++ b/rust/kernel/prelude.rs +@@ -14,7 +14,7 @@ + #[doc(no_inline)] + pub use core::pin::Pin; + +-pub use crate::alloc::{flags::*, vec_ext::VecExt, KBox, KVBox, VBox}; ++pub use crate::alloc::{flags::*, vec_ext::VecExt, Box, KBox, KVBox, VBox}; + + #[doc(no_inline)] + pub use alloc::vec::Vec; diff --git a/queue-6.12/rust-alloc-add-module-allocator_test.patch b/queue-6.12/rust-alloc-add-module-allocator_test.patch new file mode 100644 index 0000000000..d8d8c73d3b --- /dev/null +++ b/queue-6.12/rust-alloc-add-module-allocator_test.patch @@ -0,0 +1,79 @@ +From stable+bounces-121481-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:53 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:33 +0100 +Subject: rust: alloc: add module `allocator_test` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-27-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 5a888c28e3b4ff6f54a53fca33951537d135e7f1 upstream. + +`Allocator`s, such as `Kmalloc`, will be used by e.g. `Box` and `Vec` in +subsequent patches, and hence this dependency propagates throughout the +whole kernel. + +Add the `allocator_test` module that provides an empty implementation +for all `Allocator`s in the kernel, such that we don't break the +`rusttest` make target in subsequent patches. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-8-dakr@kernel.org +[ Added missing `_old_layout` parameter as discussed. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 9 +++++++-- + rust/kernel/alloc/allocator_test.rs | 20 ++++++++++++++++++++ + 2 files changed, 27 insertions(+), 2 deletions(-) + create mode 100644 rust/kernel/alloc/allocator_test.rs + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -2,12 +2,17 @@ + + //! Extensions to the [`alloc`] crate. + +-#[cfg(not(test))] +-#[cfg(not(testlib))] ++#[cfg(not(any(test, testlib)))] + pub mod allocator; + pub mod box_ext; + pub mod vec_ext; + ++#[cfg(any(test, testlib))] ++pub mod allocator_test; ++ ++#[cfg(any(test, testlib))] ++pub use self::allocator_test as allocator; ++ + /// Indicates an allocation error. + #[derive(Copy, Clone, PartialEq, Eq, Debug)] + pub struct AllocError; +--- /dev/null ++++ b/rust/kernel/alloc/allocator_test.rs +@@ -0,0 +1,20 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#![allow(missing_docs)] ++ ++use super::{AllocError, Allocator, Flags}; ++use core::alloc::Layout; ++use core::ptr::NonNull; ++ ++pub struct Kmalloc; ++ ++unsafe impl Allocator for Kmalloc { ++ unsafe fn realloc( ++ _ptr: Option>, ++ _layout: Layout, ++ _old_layout: Layout, ++ _flags: Flags, ++ ) -> Result, AllocError> { ++ panic!(); ++ } ++} diff --git a/queue-6.12/rust-alloc-add-vec-to-prelude.patch b/queue-6.12/rust-alloc-add-vec-to-prelude.patch new file mode 100644 index 0000000000..7bba0da1ff --- /dev/null +++ b/queue-6.12/rust-alloc-add-vec-to-prelude.patch @@ -0,0 +1,37 @@ +From stable+bounces-121495-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:37 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:47 +0100 +Subject: rust: alloc: add `Vec` to prelude +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-41-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 3145dc91c3c0ad945f06354385a6eb89d22becdb upstream. + +Now that we removed `VecExt` and the corresponding includes in +prelude.rs, add the new kernel `Vec` type instead. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-22-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/prelude.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/rust/kernel/prelude.rs ++++ b/rust/kernel/prelude.rs +@@ -14,7 +14,7 @@ + #[doc(no_inline)] + pub use core::pin::Pin; + +-pub use crate::alloc::{flags::*, Box, KBox, KVBox, KVVec, KVec, VBox, VVec}; ++pub use crate::alloc::{flags::*, Box, KBox, KVBox, KVVec, KVec, VBox, VVec, Vec}; + + #[doc(no_inline)] + pub use macros::{module, pin_data, pinned_drop, vtable, Zeroable}; diff --git a/queue-6.12/rust-alloc-fix-arraylayout-allocations.patch b/queue-6.12/rust-alloc-fix-arraylayout-allocations.patch new file mode 100644 index 0000000000..4df7b88c19 --- /dev/null +++ b/queue-6.12/rust-alloc-fix-arraylayout-allocations.patch @@ -0,0 +1,40 @@ +From stable+bounces-121515-greg=kroah.com@vger.kernel.org Fri Mar 7 23:53:26 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:50:07 +0100 +Subject: rust: alloc: Fix `ArrayLayout` allocations +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-61-ojeda@kernel.org> + +From: Asahi Lina + +commit b7ed2b6f4e8d7f64649795e76ee9db67300de8eb upstream. + +We were accidentally allocating a layout for the *square* of the object +size due to a variable shadowing mishap. + +Fixes memory bloat and page allocation failures in drm/asahi. + +Reported-by: Janne Grunau +Fixes: 9e7bbfa18276 ("rust: alloc: introduce `ArrayLayout`") +Signed-off-by: Asahi Lina +Acked-by: Danilo Krummrich +Reviewed-by: Neal Gompa +Link: https://lore.kernel.org/r/20241123-rust-fix-arraylayout-v1-1-197e64c95bd4@asahilina.net +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc/layout.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/rust/kernel/alloc/layout.rs ++++ b/rust/kernel/alloc/layout.rs +@@ -45,7 +45,7 @@ impl ArrayLayout { + /// When `len * size_of::()` overflows or when `len * size_of::() > isize::MAX`. + pub const fn new(len: usize) -> Result { + match len.checked_mul(core::mem::size_of::()) { +- Some(len) if len <= ISIZE_MAX => { ++ Some(size) if size <= ISIZE_MAX => { + // INVARIANT: We checked above that `len * size_of::() <= isize::MAX`. + Ok(Self { + len, diff --git a/queue-6.12/rust-alloc-implement-allocator-for-kmalloc.patch b/queue-6.12/rust-alloc-implement-allocator-for-kmalloc.patch new file mode 100644 index 0000000000..5530ee7d4a --- /dev/null +++ b/queue-6.12/rust-alloc-implement-allocator-for-kmalloc.patch @@ -0,0 +1,87 @@ +From stable+bounces-121480-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:53 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:32 +0100 +Subject: rust: alloc: implement `Allocator` for `Kmalloc` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-26-ojeda@kernel.org> + +From: Danilo Krummrich + +commit a34822d1c4c93085f635b922441a017bd7e959b0 upstream. + +Implement `Allocator` for `Kmalloc`, the kernel's default allocator, +typically used for objects smaller than page size. + +All memory allocations made with `Kmalloc` end up in `krealloc()`. + +It serves as allocator for the subsequently introduced types `KBox` and +`KVec`. + +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-7-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc/allocator.rs | 31 ++++++++++++++++++++++++++++--- + 1 file changed, 28 insertions(+), 3 deletions(-) + +--- a/rust/kernel/alloc/allocator.rs ++++ b/rust/kernel/alloc/allocator.rs +@@ -13,10 +13,16 @@ use core::alloc::{GlobalAlloc, Layout}; + use core::ptr; + use core::ptr::NonNull; + +-use crate::alloc::AllocError; ++use crate::alloc::{AllocError, Allocator}; + use crate::bindings; + +-struct Kmalloc; ++/// The contiguous kernel allocator. ++/// ++/// `Kmalloc` is typically used for physically contiguous allocations up to page size, but also ++/// supports larger allocations up to `bindings::KMALLOC_MAX_SIZE`, which is hardware specific. ++/// ++/// For more details see [self]. ++pub struct Kmalloc; + + /// Returns a proper size to alloc a new object aligned to `new_layout`'s alignment. + fn aligned_size(new_layout: Layout) -> usize { +@@ -53,8 +59,10 @@ struct ReallocFunc( + unsafe extern "C" fn(*const core::ffi::c_void, usize, u32) -> *mut core::ffi::c_void, + ); + +-#[expect(dead_code)] + impl ReallocFunc { ++ // INVARIANT: `krealloc` satisfies the type invariants. ++ const KREALLOC: Self = Self(bindings::krealloc); ++ + /// # Safety + /// + /// This method has the same safety requirements as [`Allocator::realloc`]. +@@ -106,6 +114,23 @@ impl ReallocFunc { + } + } + ++// SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that ++// - memory remains valid until it is explicitly freed, ++// - passing a pointer to a valid memory allocation is OK, ++// - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same. ++unsafe impl Allocator for Kmalloc { ++ #[inline] ++ unsafe fn realloc( ++ ptr: Option>, ++ layout: Layout, ++ old_layout: Layout, ++ flags: Flags, ++ ) -> Result, AllocError> { ++ // SAFETY: `ReallocFunc::call` has the same safety requirements as `Allocator::realloc`. ++ unsafe { ReallocFunc::KREALLOC.call(ptr, layout, old_layout, flags) } ++ } ++} ++ + // SAFETY: TODO. + unsafe impl GlobalAlloc for Kmalloc { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { diff --git a/queue-6.12/rust-alloc-implement-cmalloc-in-module-allocator_test.patch b/queue-6.12/rust-alloc-implement-cmalloc-in-module-allocator_test.patch new file mode 100644 index 0000000000..d55c95b4ea --- /dev/null +++ b/queue-6.12/rust-alloc-implement-cmalloc-in-module-allocator_test.patch @@ -0,0 +1,150 @@ +From stable+bounces-121499-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:44 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:51 +0100 +Subject: rust: alloc: implement `Cmalloc` in module allocator_test +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-45-ojeda@kernel.org> + +From: Danilo Krummrich + +commit dd09538fb4093176a818fcecd45114430cc5840f upstream. + +So far the kernel's `Box` and `Vec` types can't be used by userspace +test cases, since all users of those types (e.g. `CString`) use kernel +allocators for instantiation. + +In order to allow userspace test cases to make use of such types as +well, implement the `Cmalloc` allocator within the allocator_test module +and type alias all kernel allocators to `Cmalloc`. The `Cmalloc` +allocator uses libc's `realloc()` function as allocator backend. + +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-26-dakr@kernel.org +[ Removed the temporary `allow(dead_code)` as discussed in the list and + fixed typo, added backticks. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 1 + rust/kernel/alloc/allocator_test.rs | 89 ++++++++++++++++++++++++++++++++---- + 2 files changed, 81 insertions(+), 9 deletions(-) + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -215,7 +215,6 @@ pub unsafe trait Allocator { + } + } + +-#[allow(dead_code)] + /// Returns a properly aligned dangling pointer from the given `layout`. + pub(crate) fn dangling_from_layout(layout: Layout) -> NonNull { + let ptr = layout.align() as *mut u8; +--- a/rust/kernel/alloc/allocator_test.rs ++++ b/rust/kernel/alloc/allocator_test.rs +@@ -1,22 +1,95 @@ + // SPDX-License-Identifier: GPL-2.0 + ++//! So far the kernel's `Box` and `Vec` types can't be used by userspace test cases, since all users ++//! of those types (e.g. `CString`) use kernel allocators for instantiation. ++//! ++//! In order to allow userspace test cases to make use of such types as well, implement the ++//! `Cmalloc` allocator within the allocator_test module and type alias all kernel allocators to ++//! `Cmalloc`. The `Cmalloc` allocator uses libc's `realloc()` function as allocator backend. ++ + #![allow(missing_docs)] + +-use super::{AllocError, Allocator, Flags}; ++use super::{flags::*, AllocError, Allocator, Flags}; + use core::alloc::Layout; ++use core::cmp; ++use core::ptr; + use core::ptr::NonNull; + +-pub struct Kmalloc; ++/// The userspace allocator based on libc. ++pub struct Cmalloc; ++ ++pub type Kmalloc = Cmalloc; + pub type Vmalloc = Kmalloc; + pub type KVmalloc = Kmalloc; + +-unsafe impl Allocator for Kmalloc { ++extern "C" { ++ #[link_name = "aligned_alloc"] ++ fn libc_aligned_alloc(align: usize, size: usize) -> *mut core::ffi::c_void; ++ ++ #[link_name = "free"] ++ fn libc_free(ptr: *mut core::ffi::c_void); ++} ++ ++// SAFETY: ++// - memory remains valid until it is explicitly freed, ++// - passing a pointer to a valid memory allocation created by this `Allocator` is always OK, ++// - `realloc` provides the guarantees as provided in the `# Guarantees` section. ++unsafe impl Allocator for Cmalloc { + unsafe fn realloc( +- _ptr: Option>, +- _layout: Layout, +- _old_layout: Layout, +- _flags: Flags, ++ ptr: Option>, ++ layout: Layout, ++ old_layout: Layout, ++ flags: Flags, + ) -> Result, AllocError> { +- panic!(); ++ let src = match ptr { ++ Some(src) => { ++ if old_layout.size() == 0 { ++ ptr::null_mut() ++ } else { ++ src.as_ptr() ++ } ++ } ++ None => ptr::null_mut(), ++ }; ++ ++ if layout.size() == 0 { ++ // SAFETY: `src` is either NULL or was previously allocated with this `Allocator` ++ unsafe { libc_free(src.cast()) }; ++ ++ return Ok(NonNull::slice_from_raw_parts( ++ crate::alloc::dangling_from_layout(layout), ++ 0, ++ )); ++ } ++ ++ // SAFETY: Returns either NULL or a pointer to a memory allocation that satisfies or ++ // exceeds the given size and alignment requirements. ++ let dst = unsafe { libc_aligned_alloc(layout.align(), layout.size()) } as *mut u8; ++ let dst = NonNull::new(dst).ok_or(AllocError)?; ++ ++ if flags.contains(__GFP_ZERO) { ++ // SAFETY: The preceding calls to `libc_aligned_alloc` and `NonNull::new` ++ // guarantee that `dst` points to memory of at least `layout.size()` bytes. ++ unsafe { dst.as_ptr().write_bytes(0, layout.size()) }; ++ } ++ ++ if !src.is_null() { ++ // SAFETY: ++ // - `src` has previously been allocated with this `Allocator`; `dst` has just been ++ // newly allocated, hence the memory regions do not overlap. ++ // - both` src` and `dst` are properly aligned and valid for reads and writes ++ unsafe { ++ ptr::copy_nonoverlapping( ++ src, ++ dst.as_ptr(), ++ cmp::min(layout.size(), old_layout.size()), ++ ) ++ }; ++ } ++ ++ // SAFETY: `src` is either NULL or was previously allocated with this `Allocator` ++ unsafe { libc_free(src.cast()) }; ++ ++ Ok(NonNull::slice_from_raw_parts(dst, layout.size())) + } + } diff --git a/queue-6.12/rust-alloc-implement-collect-for-intoiter.patch b/queue-6.12/rust-alloc-implement-collect-for-intoiter.patch new file mode 100644 index 0000000000..e8c08c37b1 --- /dev/null +++ b/queue-6.12/rust-alloc-implement-collect-for-intoiter.patch @@ -0,0 +1,145 @@ +From stable+bounces-121492-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:20 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:44 +0100 +Subject: rust: alloc: implement `collect` for `IntoIter` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-38-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 93e602310f87b7b515b86a8f919cc0799387e5c3 upstream. + +Currently, we can't implement `FromIterator`. There are a couple of +issues with this trait in the kernel, namely: + + - Rust's specialization feature is unstable. This prevents us to + optimize for the special case where `I::IntoIter` equals `Vec`'s + `IntoIter` type. + - We also can't use `I::IntoIter`'s type ID either to work around this, + since `FromIterator` doesn't require this type to be `'static`. + - `FromIterator::from_iter` does return `Self` instead of + `Result`, hence we can't properly handle allocation + failures. + - Neither `Iterator::collect` nor `FromIterator::from_iter` can handle + additional allocation flags. + +Instead, provide `IntoIter::collect`, such that we can at least convert +`IntoIter` into a `Vec` again. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-19-dakr@kernel.org +[ Added newline in documentation, changed case of section to be + consistent with an existing one, fixed typo. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc/kvec.rs | 95 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 95 insertions(+) + +--- a/rust/kernel/alloc/kvec.rs ++++ b/rust/kernel/alloc/kvec.rs +@@ -692,6 +692,101 @@ pub struct IntoIter { + _p: PhantomData, + } + ++impl IntoIter ++where ++ A: Allocator, ++{ ++ fn into_raw_parts(self) -> (*mut T, NonNull, usize, usize) { ++ let me = ManuallyDrop::new(self); ++ let ptr = me.ptr; ++ let buf = me.buf; ++ let len = me.len; ++ let cap = me.layout.len(); ++ (ptr, buf, len, cap) ++ } ++ ++ /// Same as `Iterator::collect` but specialized for `Vec`'s `IntoIter`. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let v = kernel::kvec![1, 2, 3]?; ++ /// let mut it = v.into_iter(); ++ /// ++ /// assert_eq!(it.next(), Some(1)); ++ /// ++ /// let v = it.collect(GFP_KERNEL); ++ /// assert_eq!(v, [2, 3]); ++ /// ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ /// ++ /// # Implementation details ++ /// ++ /// Currently, we can't implement `FromIterator`. There are a couple of issues with this trait ++ /// in the kernel, namely: ++ /// ++ /// - Rust's specialization feature is unstable. This prevents us to optimize for the special ++ /// case where `I::IntoIter` equals `Vec`'s `IntoIter` type. ++ /// - We also can't use `I::IntoIter`'s type ID either to work around this, since `FromIterator` ++ /// doesn't require this type to be `'static`. ++ /// - `FromIterator::from_iter` does return `Self` instead of `Result`, hence ++ /// we can't properly handle allocation failures. ++ /// - Neither `Iterator::collect` nor `FromIterator::from_iter` can handle additional allocation ++ /// flags. ++ /// ++ /// Instead, provide `IntoIter::collect`, such that we can at least convert a `IntoIter` into a ++ /// `Vec` again. ++ /// ++ /// Note that `IntoIter::collect` doesn't require `Flags`, since it re-uses the existing backing ++ /// buffer. However, this backing buffer may be shrunk to the actual count of elements. ++ pub fn collect(self, flags: Flags) -> Vec { ++ let old_layout = self.layout; ++ let (mut ptr, buf, len, mut cap) = self.into_raw_parts(); ++ let has_advanced = ptr != buf.as_ptr(); ++ ++ if has_advanced { ++ // Copy the contents we have advanced to at the beginning of the buffer. ++ // ++ // SAFETY: ++ // - `ptr` is valid for reads of `len * size_of::()` bytes, ++ // - `buf.as_ptr()` is valid for writes of `len * size_of::()` bytes, ++ // - `ptr` and `buf.as_ptr()` are not be subject to aliasing restrictions relative to ++ // each other, ++ // - both `ptr` and `buf.ptr()` are properly aligned. ++ unsafe { ptr::copy(ptr, buf.as_ptr(), len) }; ++ ptr = buf.as_ptr(); ++ ++ // SAFETY: `len` is guaranteed to be smaller than `self.layout.len()`. ++ let layout = unsafe { ArrayLayout::::new_unchecked(len) }; ++ ++ // SAFETY: `buf` points to the start of the backing buffer and `len` is guaranteed to be ++ // smaller than `cap`. Depending on `alloc` this operation may shrink the buffer or leaves ++ // it as it is. ++ ptr = match unsafe { ++ A::realloc(Some(buf.cast()), layout.into(), old_layout.into(), flags) ++ } { ++ // If we fail to shrink, which likely can't even happen, continue with the existing ++ // buffer. ++ Err(_) => ptr, ++ Ok(ptr) => { ++ cap = len; ++ ptr.as_ptr().cast() ++ } ++ }; ++ } ++ ++ // SAFETY: If the iterator has been advanced, the advanced elements have been copied to ++ // the beginning of the buffer and `len` has been adjusted accordingly. ++ // ++ // - `ptr` is guaranteed to point to the start of the backing buffer. ++ // - `cap` is either the original capacity or, after shrinking the buffer, equal to `len`. ++ // - `alloc` is guaranteed to be unchanged since `into_iter` has been called on the original ++ // `Vec`. ++ unsafe { Vec::from_raw_parts(ptr, len, cap) } ++ } ++} ++ + impl Iterator for IntoIter + where + A: Allocator, diff --git a/queue-6.12/rust-alloc-implement-contains-for-flags.patch b/queue-6.12/rust-alloc-implement-contains-for-flags.patch new file mode 100644 index 0000000000..99f00d8562 --- /dev/null +++ b/queue-6.12/rust-alloc-implement-contains-for-flags.patch @@ -0,0 +1,52 @@ +From stable+bounces-121498-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:55 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:50 +0100 +Subject: rust: alloc: implement `contains` for `Flags` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-44-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 909037ce0369bc3f4fd31743fd2d8d7096f06002 upstream. + +Provide a simple helper function to check whether given flags do +contain one or multiple other flags. + +This is used by a subsequent patch implementing the Cmalloc `Allocator` +to check for __GFP_ZERO. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-25-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -35,7 +35,7 @@ use core::{alloc::Layout, ptr::NonNull}; + /// They can be combined with the operators `|`, `&`, and `!`. + /// + /// Values can be used from the [`flags`] module. +-#[derive(Clone, Copy)] ++#[derive(Clone, Copy, PartialEq)] + pub struct Flags(u32); + + impl Flags { +@@ -43,6 +43,11 @@ impl Flags { + pub(crate) fn as_raw(self) -> u32 { + self.0 + } ++ ++ /// Check whether `flags` is contained in `self`. ++ pub fn contains(self, flags: Flags) -> bool { ++ (self & flags) == flags ++ } + } + + impl core::ops::BitOr for Flags { diff --git a/queue-6.12/rust-alloc-implement-intoiterator-for-vec.patch b/queue-6.12/rust-alloc-implement-intoiterator-for-vec.patch new file mode 100644 index 0000000000..ed72fc7816 --- /dev/null +++ b/queue-6.12/rust-alloc-implement-intoiterator-for-vec.patch @@ -0,0 +1,223 @@ +From stable+bounces-121491-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:19 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:43 +0100 +Subject: rust: alloc: implement `IntoIterator` for `Vec` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-37-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 1d1d223aa3b37c34271aefc2706340d0843bfcb2 upstream. + +Implement `IntoIterator` for `Vec`, `Vec`'s `IntoIter` type, as well as +`Iterator` for `IntoIter`. + +`Vec::into_iter` disassembles the `Vec` into its raw parts; additionally, +`IntoIter` keeps track of a separate pointer, which is incremented +correspondingly as the iterator advances, while the length, or the count +of elements, is decremented. + +This also means that `IntoIter` takes the ownership of the backing +buffer and is responsible to drop the remaining elements and free the +backing buffer, if it's dropped. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-18-dakr@kernel.org +[ Fixed typos. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 1 + rust/kernel/alloc/kvec.rs | 170 ++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 171 insertions(+) + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -20,6 +20,7 @@ pub use self::kbox::KBox; + pub use self::kbox::KVBox; + pub use self::kbox::VBox; + ++pub use self::kvec::IntoIter; + pub use self::kvec::KVVec; + pub use self::kvec::KVec; + pub use self::kvec::VVec; +--- a/rust/kernel/alloc/kvec.rs ++++ b/rust/kernel/alloc/kvec.rs +@@ -646,3 +646,173 @@ impl_slice_eq! { + [A: Allocator, const N: usize] Vec, [U; N], + [A: Allocator, const N: usize] Vec, &[U; N], + } ++ ++impl<'a, T, A> IntoIterator for &'a Vec ++where ++ A: Allocator, ++{ ++ type Item = &'a T; ++ type IntoIter = slice::Iter<'a, T>; ++ ++ fn into_iter(self) -> Self::IntoIter { ++ self.iter() ++ } ++} ++ ++impl<'a, T, A: Allocator> IntoIterator for &'a mut Vec ++where ++ A: Allocator, ++{ ++ type Item = &'a mut T; ++ type IntoIter = slice::IterMut<'a, T>; ++ ++ fn into_iter(self) -> Self::IntoIter { ++ self.iter_mut() ++ } ++} ++ ++/// An [`Iterator`] implementation for [`Vec`] that moves elements out of a vector. ++/// ++/// This structure is created by the [`Vec::into_iter`] method on [`Vec`] (provided by the ++/// [`IntoIterator`] trait). ++/// ++/// # Examples ++/// ++/// ``` ++/// let v = kernel::kvec![0, 1, 2]?; ++/// let iter = v.into_iter(); ++/// ++/// # Ok::<(), Error>(()) ++/// ``` ++pub struct IntoIter { ++ ptr: *mut T, ++ buf: NonNull, ++ len: usize, ++ layout: ArrayLayout, ++ _p: PhantomData, ++} ++ ++impl Iterator for IntoIter ++where ++ A: Allocator, ++{ ++ type Item = T; ++ ++ /// # Examples ++ /// ++ /// ``` ++ /// let v = kernel::kvec![1, 2, 3]?; ++ /// let mut it = v.into_iter(); ++ /// ++ /// assert_eq!(it.next(), Some(1)); ++ /// assert_eq!(it.next(), Some(2)); ++ /// assert_eq!(it.next(), Some(3)); ++ /// assert_eq!(it.next(), None); ++ /// ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ fn next(&mut self) -> Option { ++ if self.len == 0 { ++ return None; ++ } ++ ++ let current = self.ptr; ++ ++ // SAFETY: We can't overflow; decreasing `self.len` by one every time we advance `self.ptr` ++ // by one guarantees that. ++ unsafe { self.ptr = self.ptr.add(1) }; ++ ++ self.len -= 1; ++ ++ // SAFETY: `current` is guaranteed to point at a valid element within the buffer. ++ Some(unsafe { current.read() }) ++ } ++ ++ /// # Examples ++ /// ++ /// ``` ++ /// let v: KVec = kernel::kvec![1, 2, 3]?; ++ /// let mut iter = v.into_iter(); ++ /// let size = iter.size_hint().0; ++ /// ++ /// iter.next(); ++ /// assert_eq!(iter.size_hint().0, size - 1); ++ /// ++ /// iter.next(); ++ /// assert_eq!(iter.size_hint().0, size - 2); ++ /// ++ /// iter.next(); ++ /// assert_eq!(iter.size_hint().0, size - 3); ++ /// ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ fn size_hint(&self) -> (usize, Option) { ++ (self.len, Some(self.len)) ++ } ++} ++ ++impl Drop for IntoIter ++where ++ A: Allocator, ++{ ++ fn drop(&mut self) { ++ // SAFETY: `self.ptr` is guaranteed to be valid by the type invariant. ++ unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.ptr, self.len)) }; ++ ++ // SAFETY: ++ // - `self.buf` was previously allocated with `A`. ++ // - `self.layout` matches the `ArrayLayout` of the preceding allocation. ++ unsafe { A::free(self.buf.cast(), self.layout.into()) }; ++ } ++} ++ ++impl IntoIterator for Vec ++where ++ A: Allocator, ++{ ++ type Item = T; ++ type IntoIter = IntoIter; ++ ++ /// Consumes the `Vec` and creates an `Iterator`, which moves each value out of the ++ /// vector (from start to end). ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let v = kernel::kvec![1, 2]?; ++ /// let mut v_iter = v.into_iter(); ++ /// ++ /// let first_element: Option = v_iter.next(); ++ /// ++ /// assert_eq!(first_element, Some(1)); ++ /// assert_eq!(v_iter.next(), Some(2)); ++ /// assert_eq!(v_iter.next(), None); ++ /// ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ /// ++ /// ``` ++ /// let v = kernel::kvec![]; ++ /// let mut v_iter = v.into_iter(); ++ /// ++ /// let first_element: Option = v_iter.next(); ++ /// ++ /// assert_eq!(first_element, None); ++ /// ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ #[inline] ++ fn into_iter(self) -> Self::IntoIter { ++ let buf = self.ptr; ++ let layout = self.layout; ++ let (ptr, len, _) = self.into_raw_parts(); ++ ++ IntoIter { ++ ptr, ++ buf, ++ len, ++ layout, ++ _p: PhantomData::, ++ } ++ } ++} diff --git a/queue-6.12/rust-alloc-implement-kernel-box.patch b/queue-6.12/rust-alloc-implement-kernel-box.patch new file mode 100644 index 0000000000..5da35ccf8f --- /dev/null +++ b/queue-6.12/rust-alloc-implement-kernel-box.patch @@ -0,0 +1,527 @@ +From stable+bounces-121485-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:12 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:37 +0100 +Subject: rust: alloc: implement kernel `Box` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-31-ojeda@kernel.org> + +From: Danilo Krummrich + +commit c8cfa8d0c0b10be216861fe904ea68978b1dcc97 upstream. + +`Box` provides the simplest way to allocate memory for a generic type +with one of the kernel's allocators, e.g. `Kmalloc`, `Vmalloc` or +`KVmalloc`. + +In contrast to Rust's `Box` type, the kernel `Box` type considers the +kernel's GFP flags for all appropriate functions, always reports +allocation failures through `Result<_, AllocError>` and remains +independent from unstable features. + +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-12-dakr@kernel.org +[ Added backticks, fixed typos. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 6 + rust/kernel/alloc/kbox.rs | 456 ++++++++++++++++++++++++++++++++++++++++++++++ + rust/kernel/prelude.rs | 2 + 3 files changed, 463 insertions(+), 1 deletion(-) + create mode 100644 rust/kernel/alloc/kbox.rs + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -5,6 +5,7 @@ + #[cfg(not(any(test, testlib)))] + pub mod allocator; + pub mod box_ext; ++pub mod kbox; + pub mod vec_ext; + + #[cfg(any(test, testlib))] +@@ -13,6 +14,11 @@ pub mod allocator_test; + #[cfg(any(test, testlib))] + pub use self::allocator_test as allocator; + ++pub use self::kbox::Box; ++pub use self::kbox::KBox; ++pub use self::kbox::KVBox; ++pub use self::kbox::VBox; ++ + /// Indicates an allocation error. + #[derive(Copy, Clone, PartialEq, Eq, Debug)] + pub struct AllocError; +--- /dev/null ++++ b/rust/kernel/alloc/kbox.rs +@@ -0,0 +1,456 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++//! Implementation of [`Box`]. ++ ++#[allow(unused_imports)] // Used in doc comments. ++use super::allocator::{KVmalloc, Kmalloc, Vmalloc}; ++use super::{AllocError, Allocator, Flags}; ++use core::alloc::Layout; ++use core::fmt; ++use core::marker::PhantomData; ++use core::mem::ManuallyDrop; ++use core::mem::MaybeUninit; ++use core::ops::{Deref, DerefMut}; ++use core::pin::Pin; ++use core::ptr::NonNull; ++use core::result::Result; ++ ++use crate::init::{InPlaceInit, InPlaceWrite, Init, PinInit}; ++use crate::types::ForeignOwnable; ++ ++/// The kernel's [`Box`] type -- a heap allocation for a single value of type `T`. ++/// ++/// This is the kernel's version of the Rust stdlib's `Box`. There are several differences, ++/// for example no `noalias` attribute is emitted and partially moving out of a `Box` is not ++/// supported. There are also several API differences, e.g. `Box` always requires an [`Allocator`] ++/// implementation to be passed as generic, page [`Flags`] when allocating memory and all functions ++/// that may allocate memory are fallible. ++/// ++/// `Box` works with any of the kernel's allocators, e.g. [`Kmalloc`], [`Vmalloc`] or [`KVmalloc`]. ++/// There are aliases for `Box` with these allocators ([`KBox`], [`VBox`], [`KVBox`]). ++/// ++/// When dropping a [`Box`], the value is also dropped and the heap memory is automatically freed. ++/// ++/// # Examples ++/// ++/// ``` ++/// let b = KBox::::new(24_u64, GFP_KERNEL)?; ++/// ++/// assert_eq!(*b, 24_u64); ++/// # Ok::<(), Error>(()) ++/// ``` ++/// ++/// ``` ++/// # use kernel::bindings; ++/// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1; ++/// struct Huge([u8; SIZE]); ++/// ++/// assert!(KBox::::new_uninit(GFP_KERNEL | __GFP_NOWARN).is_err()); ++/// ``` ++/// ++/// ``` ++/// # use kernel::bindings; ++/// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1; ++/// struct Huge([u8; SIZE]); ++/// ++/// assert!(KVBox::::new_uninit(GFP_KERNEL).is_ok()); ++/// ``` ++/// ++/// # Invariants ++/// ++/// `self.0` is always properly aligned and either points to memory allocated with `A` or, for ++/// zero-sized types, is a dangling, well aligned pointer. ++#[repr(transparent)] ++pub struct Box(NonNull, PhantomData); ++ ++/// Type alias for [`Box`] with a [`Kmalloc`] allocator. ++/// ++/// # Examples ++/// ++/// ``` ++/// let b = KBox::new(24_u64, GFP_KERNEL)?; ++/// ++/// assert_eq!(*b, 24_u64); ++/// # Ok::<(), Error>(()) ++/// ``` ++pub type KBox = Box; ++ ++/// Type alias for [`Box`] with a [`Vmalloc`] allocator. ++/// ++/// # Examples ++/// ++/// ``` ++/// let b = VBox::new(24_u64, GFP_KERNEL)?; ++/// ++/// assert_eq!(*b, 24_u64); ++/// # Ok::<(), Error>(()) ++/// ``` ++pub type VBox = Box; ++ ++/// Type alias for [`Box`] with a [`KVmalloc`] allocator. ++/// ++/// # Examples ++/// ++/// ``` ++/// let b = KVBox::new(24_u64, GFP_KERNEL)?; ++/// ++/// assert_eq!(*b, 24_u64); ++/// # Ok::<(), Error>(()) ++/// ``` ++pub type KVBox = Box; ++ ++// SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`. ++unsafe impl Send for Box ++where ++ T: Send + ?Sized, ++ A: Allocator, ++{ ++} ++ ++// SAFETY: `Box` is `Sync` if `T` is `Sync` because the `Box` owns a `T`. ++unsafe impl Sync for Box ++where ++ T: Sync + ?Sized, ++ A: Allocator, ++{ ++} ++ ++impl Box ++where ++ T: ?Sized, ++ A: Allocator, ++{ ++ /// Creates a new `Box` from a raw pointer. ++ /// ++ /// # Safety ++ /// ++ /// For non-ZSTs, `raw` must point at an allocation allocated with `A` that is sufficiently ++ /// aligned for and holds a valid `T`. The caller passes ownership of the allocation to the ++ /// `Box`. ++ /// ++ /// For ZSTs, `raw` must be a dangling, well aligned pointer. ++ #[inline] ++ pub const unsafe fn from_raw(raw: *mut T) -> Self { ++ // INVARIANT: Validity of `raw` is guaranteed by the safety preconditions of this function. ++ // SAFETY: By the safety preconditions of this function, `raw` is not a NULL pointer. ++ Self(unsafe { NonNull::new_unchecked(raw) }, PhantomData) ++ } ++ ++ /// Consumes the `Box` and returns a raw pointer. ++ /// ++ /// This will not run the destructor of `T` and for non-ZSTs the allocation will stay alive ++ /// indefinitely. Use [`Box::from_raw`] to recover the [`Box`], drop the value and free the ++ /// allocation, if any. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let x = KBox::new(24, GFP_KERNEL)?; ++ /// let ptr = KBox::into_raw(x); ++ /// // SAFETY: `ptr` comes from a previous call to `KBox::into_raw`. ++ /// let x = unsafe { KBox::from_raw(ptr) }; ++ /// ++ /// assert_eq!(*x, 24); ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ #[inline] ++ pub fn into_raw(b: Self) -> *mut T { ++ ManuallyDrop::new(b).0.as_ptr() ++ } ++ ++ /// Consumes and leaks the `Box` and returns a mutable reference. ++ /// ++ /// See [`Box::into_raw`] for more details. ++ #[inline] ++ pub fn leak<'a>(b: Self) -> &'a mut T { ++ // SAFETY: `Box::into_raw` always returns a properly aligned and dereferenceable pointer ++ // which points to an initialized instance of `T`. ++ unsafe { &mut *Box::into_raw(b) } ++ } ++} ++ ++impl Box, A> ++where ++ A: Allocator, ++{ ++ /// Converts a `Box, A>` to a `Box`. ++ /// ++ /// It is undefined behavior to call this function while the value inside of `b` is not yet ++ /// fully initialized. ++ /// ++ /// # Safety ++ /// ++ /// Callers must ensure that the value inside of `b` is in an initialized state. ++ pub unsafe fn assume_init(self) -> Box { ++ let raw = Self::into_raw(self); ++ ++ // SAFETY: `raw` comes from a previous call to `Box::into_raw`. By the safety requirements ++ // of this function, the value inside the `Box` is in an initialized state. Hence, it is ++ // safe to reconstruct the `Box` as `Box`. ++ unsafe { Box::from_raw(raw.cast()) } ++ } ++ ++ /// Writes the value and converts to `Box`. ++ pub fn write(mut self, value: T) -> Box { ++ (*self).write(value); ++ ++ // SAFETY: We've just initialized `b`'s value. ++ unsafe { self.assume_init() } ++ } ++} ++ ++impl Box ++where ++ A: Allocator, ++{ ++ /// Creates a new `Box` and initializes its contents with `x`. ++ /// ++ /// New memory is allocated with `A`. The allocation may fail, in which case an error is ++ /// returned. For ZSTs no memory is allocated. ++ pub fn new(x: T, flags: Flags) -> Result { ++ let b = Self::new_uninit(flags)?; ++ Ok(Box::write(b, x)) ++ } ++ ++ /// Creates a new `Box` with uninitialized contents. ++ /// ++ /// New memory is allocated with `A`. The allocation may fail, in which case an error is ++ /// returned. For ZSTs no memory is allocated. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let b = KBox::::new_uninit(GFP_KERNEL)?; ++ /// let b = KBox::write(b, 24); ++ /// ++ /// assert_eq!(*b, 24_u64); ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ pub fn new_uninit(flags: Flags) -> Result, A>, AllocError> { ++ let layout = Layout::new::>(); ++ let ptr = A::alloc(layout, flags)?; ++ ++ // INVARIANT: `ptr` is either a dangling pointer or points to memory allocated with `A`, ++ // which is sufficient in size and alignment for storing a `T`. ++ Ok(Box(ptr.cast(), PhantomData)) ++ } ++ ++ /// Constructs a new `Pin>`. If `T` does not implement [`Unpin`], then `x` will be ++ /// pinned in memory and can't be moved. ++ #[inline] ++ pub fn pin(x: T, flags: Flags) -> Result>, AllocError> ++ where ++ A: 'static, ++ { ++ Ok(Self::new(x, flags)?.into()) ++ } ++ ++ /// Forgets the contents (does not run the destructor), but keeps the allocation. ++ fn forget_contents(this: Self) -> Box, A> { ++ let ptr = Self::into_raw(this); ++ ++ // SAFETY: `ptr` is valid, because it came from `Box::into_raw`. ++ unsafe { Box::from_raw(ptr.cast()) } ++ } ++ ++ /// Drops the contents, but keeps the allocation. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let value = KBox::new([0; 32], GFP_KERNEL)?; ++ /// assert_eq!(*value, [0; 32]); ++ /// let value = KBox::drop_contents(value); ++ /// // Now we can re-use `value`: ++ /// let value = KBox::write(value, [1; 32]); ++ /// assert_eq!(*value, [1; 32]); ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ pub fn drop_contents(this: Self) -> Box, A> { ++ let ptr = this.0.as_ptr(); ++ ++ // SAFETY: `ptr` is valid, because it came from `this`. After this call we never access the ++ // value stored in `this` again. ++ unsafe { core::ptr::drop_in_place(ptr) }; ++ ++ Self::forget_contents(this) ++ } ++ ++ /// Moves the `Box`'s value out of the `Box` and consumes the `Box`. ++ pub fn into_inner(b: Self) -> T { ++ // SAFETY: By the type invariant `&*b` is valid for `read`. ++ let value = unsafe { core::ptr::read(&*b) }; ++ let _ = Self::forget_contents(b); ++ value ++ } ++} ++ ++impl From> for Pin> ++where ++ T: ?Sized, ++ A: Allocator, ++{ ++ /// Converts a `Box` into a `Pin>`. If `T` does not implement [`Unpin`], then ++ /// `*b` will be pinned in memory and can't be moved. ++ /// ++ /// This moves `b` into `Pin` without moving `*b` or allocating and copying any memory. ++ fn from(b: Box) -> Self { ++ // SAFETY: The value wrapped inside a `Pin>` cannot be moved or replaced as long ++ // as `T` does not implement `Unpin`. ++ unsafe { Pin::new_unchecked(b) } ++ } ++} ++ ++impl InPlaceWrite for Box, A> ++where ++ A: Allocator + 'static, ++{ ++ type Initialized = Box; ++ ++ fn write_init(mut self, init: impl Init) -> Result { ++ let slot = self.as_mut_ptr(); ++ // SAFETY: When init errors/panics, slot will get deallocated but not dropped, ++ // slot is valid. ++ unsafe { init.__init(slot)? }; ++ // SAFETY: All fields have been initialized. ++ Ok(unsafe { Box::assume_init(self) }) ++ } ++ ++ fn write_pin_init(mut self, init: impl PinInit) -> Result, E> { ++ let slot = self.as_mut_ptr(); ++ // SAFETY: When init errors/panics, slot will get deallocated but not dropped, ++ // slot is valid and will not be moved, because we pin it later. ++ unsafe { init.__pinned_init(slot)? }; ++ // SAFETY: All fields have been initialized. ++ Ok(unsafe { Box::assume_init(self) }.into()) ++ } ++} ++ ++impl InPlaceInit for Box ++where ++ A: Allocator + 'static, ++{ ++ type PinnedSelf = Pin; ++ ++ #[inline] ++ fn try_pin_init(init: impl PinInit, flags: Flags) -> Result, E> ++ where ++ E: From, ++ { ++ Box::<_, A>::new_uninit(flags)?.write_pin_init(init) ++ } ++ ++ #[inline] ++ fn try_init(init: impl Init, flags: Flags) -> Result ++ where ++ E: From, ++ { ++ Box::<_, A>::new_uninit(flags)?.write_init(init) ++ } ++} ++ ++impl ForeignOwnable for Box ++where ++ A: Allocator, ++{ ++ type Borrowed<'a> = &'a T; ++ ++ fn into_foreign(self) -> *const core::ffi::c_void { ++ Box::into_raw(self) as _ ++ } ++ ++ unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { ++ // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous ++ // call to `Self::into_foreign`. ++ unsafe { Box::from_raw(ptr as _) } ++ } ++ ++ unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { ++ // SAFETY: The safety requirements of this method ensure that the object remains alive and ++ // immutable for the duration of 'a. ++ unsafe { &*ptr.cast() } ++ } ++} ++ ++impl ForeignOwnable for Pin> ++where ++ A: Allocator, ++{ ++ type Borrowed<'a> = Pin<&'a T>; ++ ++ fn into_foreign(self) -> *const core::ffi::c_void { ++ // SAFETY: We are still treating the box as pinned. ++ Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _ ++ } ++ ++ unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { ++ // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous ++ // call to `Self::into_foreign`. ++ unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) } ++ } ++ ++ unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Pin<&'a T> { ++ // SAFETY: The safety requirements for this function ensure that the object is still alive, ++ // so it is safe to dereference the raw pointer. ++ // The safety requirements of `from_foreign` also ensure that the object remains alive for ++ // the lifetime of the returned value. ++ let r = unsafe { &*ptr.cast() }; ++ ++ // SAFETY: This pointer originates from a `Pin>`. ++ unsafe { Pin::new_unchecked(r) } ++ } ++} ++ ++impl Deref for Box ++where ++ T: ?Sized, ++ A: Allocator, ++{ ++ type Target = T; ++ ++ fn deref(&self) -> &T { ++ // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized ++ // instance of `T`. ++ unsafe { self.0.as_ref() } ++ } ++} ++ ++impl DerefMut for Box ++where ++ T: ?Sized, ++ A: Allocator, ++{ ++ fn deref_mut(&mut self) -> &mut T { ++ // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized ++ // instance of `T`. ++ unsafe { self.0.as_mut() } ++ } ++} ++ ++impl fmt::Debug for Box ++where ++ T: ?Sized + fmt::Debug, ++ A: Allocator, ++{ ++ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ++ fmt::Debug::fmt(&**self, f) ++ } ++} ++ ++impl Drop for Box ++where ++ T: ?Sized, ++ A: Allocator, ++{ ++ fn drop(&mut self) { ++ let layout = Layout::for_value::(self); ++ ++ // SAFETY: The pointer in `self.0` is guaranteed to be valid by the type invariant. ++ unsafe { core::ptr::drop_in_place::(self.deref_mut()) }; ++ ++ // SAFETY: ++ // - `self.0` was previously allocated with `A`. ++ // - `layout` is equal to the `Layout´ `self.0` was allocated with. ++ unsafe { A::free(self.0.cast(), layout) }; ++ } ++} +--- a/rust/kernel/prelude.rs ++++ b/rust/kernel/prelude.rs +@@ -14,7 +14,7 @@ + #[doc(no_inline)] + pub use core::pin::Pin; + +-pub use crate::alloc::{box_ext::BoxExt, flags::*, vec_ext::VecExt}; ++pub use crate::alloc::{box_ext::BoxExt, flags::*, vec_ext::VecExt, KBox, KVBox, VBox}; + + #[doc(no_inline)] + pub use alloc::{boxed::Box, vec::Vec}; diff --git a/queue-6.12/rust-alloc-implement-kernel-vec-type.patch b/queue-6.12/rust-alloc-implement-kernel-vec-type.patch new file mode 100644 index 0000000000..b95740b39c --- /dev/null +++ b/queue-6.12/rust-alloc-implement-kernel-vec-type.patch @@ -0,0 +1,735 @@ +From stable+bounces-121490-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:17 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:42 +0100 +Subject: rust: alloc: implement kernel `Vec` type +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-36-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 2aac4cd7dae3d7bb0e0ddec2561b2ee4cbe6c8f6 upstream. + +`Vec` provides a contiguous growable array type with contents allocated +with the kernel's allocators (e.g. `Kmalloc`, `Vmalloc` or `KVmalloc`). + +In contrast to Rust's stdlib `Vec` type, the kernel `Vec` type considers +the kernel's GFP flags for all appropriate functions, always reports +allocation failures through `Result<_, AllocError>` and remains +independent from unstable features. + +[ This patch starts using a new unstable feature, `inline_const`, but + it was stabilized in Rust 1.79.0, i.e. the next version after the + minimum one, thus it will not be an issue. - Miguel ] + +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-17-dakr@kernel.org +[ Cleaned `rustdoc` unescaped backtick warning, added a couple more + backticks elsewhere, fixed typos, sorted `feature`s, rewrapped + documentation lines. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 6 + rust/kernel/alloc/kvec.rs | 648 ++++++++++++++++++++++++++++++++++++++++++++++ + rust/kernel/lib.rs | 1 + rust/kernel/prelude.rs | 2 + 4 files changed, 656 insertions(+), 1 deletion(-) + create mode 100644 rust/kernel/alloc/kvec.rs + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -5,6 +5,7 @@ + #[cfg(not(any(test, testlib)))] + pub mod allocator; + pub mod kbox; ++pub mod kvec; + pub mod layout; + pub mod vec_ext; + +@@ -19,6 +20,11 @@ pub use self::kbox::KBox; + pub use self::kbox::KVBox; + pub use self::kbox::VBox; + ++pub use self::kvec::KVVec; ++pub use self::kvec::KVec; ++pub use self::kvec::VVec; ++pub use self::kvec::Vec; ++ + /// Indicates an allocation error. + #[derive(Copy, Clone, PartialEq, Eq, Debug)] + pub struct AllocError; +--- /dev/null ++++ b/rust/kernel/alloc/kvec.rs +@@ -0,0 +1,648 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++//! Implementation of [`Vec`]. ++ ++use super::{ ++ allocator::{KVmalloc, Kmalloc, Vmalloc}, ++ layout::ArrayLayout, ++ AllocError, Allocator, Box, Flags, ++}; ++use core::{ ++ fmt, ++ marker::PhantomData, ++ mem::{ManuallyDrop, MaybeUninit}, ++ ops::Deref, ++ ops::DerefMut, ++ ops::Index, ++ ops::IndexMut, ++ ptr, ++ ptr::NonNull, ++ slice, ++ slice::SliceIndex, ++}; ++ ++/// Create a [`KVec`] containing the arguments. ++/// ++/// New memory is allocated with `GFP_KERNEL`. ++/// ++/// # Examples ++/// ++/// ``` ++/// let mut v = kernel::kvec![]; ++/// v.push(1, GFP_KERNEL)?; ++/// assert_eq!(v, [1]); ++/// ++/// let mut v = kernel::kvec![1; 3]?; ++/// v.push(4, GFP_KERNEL)?; ++/// assert_eq!(v, [1, 1, 1, 4]); ++/// ++/// let mut v = kernel::kvec![1, 2, 3]?; ++/// v.push(4, GFP_KERNEL)?; ++/// assert_eq!(v, [1, 2, 3, 4]); ++/// ++/// # Ok::<(), Error>(()) ++/// ``` ++#[macro_export] ++macro_rules! kvec { ++ () => ( ++ $crate::alloc::KVec::new() ++ ); ++ ($elem:expr; $n:expr) => ( ++ $crate::alloc::KVec::from_elem($elem, $n, GFP_KERNEL) ++ ); ++ ($($x:expr),+ $(,)?) => ( ++ match $crate::alloc::KBox::new_uninit(GFP_KERNEL) { ++ Ok(b) => Ok($crate::alloc::KVec::from($crate::alloc::KBox::write(b, [$($x),+]))), ++ Err(e) => Err(e), ++ } ++ ); ++} ++ ++/// The kernel's [`Vec`] type. ++/// ++/// A contiguous growable array type with contents allocated with the kernel's allocators (e.g. ++/// [`Kmalloc`], [`Vmalloc`] or [`KVmalloc`]), written `Vec`. ++/// ++/// For non-zero-sized values, a [`Vec`] will use the given allocator `A` for its allocation. For ++/// the most common allocators the type aliases [`KVec`], [`VVec`] and [`KVVec`] exist. ++/// ++/// For zero-sized types the [`Vec`]'s pointer must be `dangling_mut::`; no memory is allocated. ++/// ++/// Generally, [`Vec`] consists of a pointer that represents the vector's backing buffer, the ++/// capacity of the vector (the number of elements that currently fit into the vector), its length ++/// (the number of elements that are currently stored in the vector) and the `Allocator` type used ++/// to allocate (and free) the backing buffer. ++/// ++/// A [`Vec`] can be deconstructed into and (re-)constructed from its previously named raw parts ++/// and manually modified. ++/// ++/// [`Vec`]'s backing buffer gets, if required, automatically increased (re-allocated) when elements ++/// are added to the vector. ++/// ++/// # Invariants ++/// ++/// - `self.ptr` is always properly aligned and either points to memory allocated with `A` or, for ++/// zero-sized types, is a dangling, well aligned pointer. ++/// ++/// - `self.len` always represents the exact number of elements stored in the vector. ++/// ++/// - `self.layout` represents the absolute number of elements that can be stored within the vector ++/// without re-allocation. For ZSTs `self.layout`'s capacity is zero. However, it is legal for the ++/// backing buffer to be larger than `layout`. ++/// ++/// - The `Allocator` type `A` of the vector is the exact same `Allocator` type the backing buffer ++/// was allocated with (and must be freed with). ++pub struct Vec { ++ ptr: NonNull, ++ /// Represents the actual buffer size as `cap` times `size_of::` bytes. ++ /// ++ /// Note: This isn't quite the same as `Self::capacity`, which in contrast returns the number of ++ /// elements we can still store without reallocating. ++ layout: ArrayLayout, ++ len: usize, ++ _p: PhantomData, ++} ++ ++/// Type alias for [`Vec`] with a [`Kmalloc`] allocator. ++/// ++/// # Examples ++/// ++/// ``` ++/// let mut v = KVec::new(); ++/// v.push(1, GFP_KERNEL)?; ++/// assert_eq!(&v, &[1]); ++/// ++/// # Ok::<(), Error>(()) ++/// ``` ++pub type KVec = Vec; ++ ++/// Type alias for [`Vec`] with a [`Vmalloc`] allocator. ++/// ++/// # Examples ++/// ++/// ``` ++/// let mut v = VVec::new(); ++/// v.push(1, GFP_KERNEL)?; ++/// assert_eq!(&v, &[1]); ++/// ++/// # Ok::<(), Error>(()) ++/// ``` ++pub type VVec = Vec; ++ ++/// Type alias for [`Vec`] with a [`KVmalloc`] allocator. ++/// ++/// # Examples ++/// ++/// ``` ++/// let mut v = KVVec::new(); ++/// v.push(1, GFP_KERNEL)?; ++/// assert_eq!(&v, &[1]); ++/// ++/// # Ok::<(), Error>(()) ++/// ``` ++pub type KVVec = Vec; ++ ++// SAFETY: `Vec` is `Send` if `T` is `Send` because `Vec` owns its elements. ++unsafe impl Send for Vec ++where ++ T: Send, ++ A: Allocator, ++{ ++} ++ ++// SAFETY: `Vec` is `Sync` if `T` is `Sync` because `Vec` owns its elements. ++unsafe impl Sync for Vec ++where ++ T: Sync, ++ A: Allocator, ++{ ++} ++ ++impl Vec ++where ++ A: Allocator, ++{ ++ #[inline] ++ const fn is_zst() -> bool { ++ core::mem::size_of::() == 0 ++ } ++ ++ /// Returns the number of elements that can be stored within the vector without allocating ++ /// additional memory. ++ pub fn capacity(&self) -> usize { ++ if const { Self::is_zst() } { ++ usize::MAX ++ } else { ++ self.layout.len() ++ } ++ } ++ ++ /// Returns the number of elements stored within the vector. ++ #[inline] ++ pub fn len(&self) -> usize { ++ self.len ++ } ++ ++ /// Forcefully sets `self.len` to `new_len`. ++ /// ++ /// # Safety ++ /// ++ /// - `new_len` must be less than or equal to [`Self::capacity`]. ++ /// - If `new_len` is greater than `self.len`, all elements within the interval ++ /// [`self.len`,`new_len`) must be initialized. ++ #[inline] ++ pub unsafe fn set_len(&mut self, new_len: usize) { ++ debug_assert!(new_len <= self.capacity()); ++ self.len = new_len; ++ } ++ ++ /// Returns a slice of the entire vector. ++ #[inline] ++ pub fn as_slice(&self) -> &[T] { ++ self ++ } ++ ++ /// Returns a mutable slice of the entire vector. ++ #[inline] ++ pub fn as_mut_slice(&mut self) -> &mut [T] { ++ self ++ } ++ ++ /// Returns a mutable raw pointer to the vector's backing buffer, or, if `T` is a ZST, a ++ /// dangling raw pointer. ++ #[inline] ++ pub fn as_mut_ptr(&mut self) -> *mut T { ++ self.ptr.as_ptr() ++ } ++ ++ /// Returns a raw pointer to the vector's backing buffer, or, if `T` is a ZST, a dangling raw ++ /// pointer. ++ #[inline] ++ pub fn as_ptr(&self) -> *const T { ++ self.ptr.as_ptr() ++ } ++ ++ /// Returns `true` if the vector contains no elements, `false` otherwise. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let mut v = KVec::new(); ++ /// assert!(v.is_empty()); ++ /// ++ /// v.push(1, GFP_KERNEL); ++ /// assert!(!v.is_empty()); ++ /// ``` ++ #[inline] ++ pub fn is_empty(&self) -> bool { ++ self.len() == 0 ++ } ++ ++ /// Creates a new, empty `Vec`. ++ /// ++ /// This method does not allocate by itself. ++ #[inline] ++ pub const fn new() -> Self { ++ // INVARIANT: Since this is a new, empty `Vec` with no backing memory yet, ++ // - `ptr` is a properly aligned dangling pointer for type `T`, ++ // - `layout` is an empty `ArrayLayout` (zero capacity) ++ // - `len` is zero, since no elements can be or have been stored, ++ // - `A` is always valid. ++ Self { ++ ptr: NonNull::dangling(), ++ layout: ArrayLayout::empty(), ++ len: 0, ++ _p: PhantomData::, ++ } ++ } ++ ++ /// Returns a slice of `MaybeUninit` for the remaining spare capacity of the vector. ++ pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit] { ++ // SAFETY: ++ // - `self.len` is smaller than `self.capacity` and hence, the resulting pointer is ++ // guaranteed to be part of the same allocated object. ++ // - `self.len` can not overflow `isize`. ++ let ptr = unsafe { self.as_mut_ptr().add(self.len) } as *mut MaybeUninit; ++ ++ // SAFETY: The memory between `self.len` and `self.capacity` is guaranteed to be allocated ++ // and valid, but uninitialized. ++ unsafe { slice::from_raw_parts_mut(ptr, self.capacity() - self.len) } ++ } ++ ++ /// Appends an element to the back of the [`Vec`] instance. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let mut v = KVec::new(); ++ /// v.push(1, GFP_KERNEL)?; ++ /// assert_eq!(&v, &[1]); ++ /// ++ /// v.push(2, GFP_KERNEL)?; ++ /// assert_eq!(&v, &[1, 2]); ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ pub fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> { ++ self.reserve(1, flags)?; ++ ++ // SAFETY: ++ // - `self.len` is smaller than `self.capacity` and hence, the resulting pointer is ++ // guaranteed to be part of the same allocated object. ++ // - `self.len` can not overflow `isize`. ++ let ptr = unsafe { self.as_mut_ptr().add(self.len) }; ++ ++ // SAFETY: ++ // - `ptr` is properly aligned and valid for writes. ++ unsafe { core::ptr::write(ptr, v) }; ++ ++ // SAFETY: We just initialised the first spare entry, so it is safe to increase the length ++ // by 1. We also know that the new length is <= capacity because of the previous call to ++ // `reserve` above. ++ unsafe { self.set_len(self.len() + 1) }; ++ Ok(()) ++ } ++ ++ /// Creates a new [`Vec`] instance with at least the given capacity. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let v = KVec::::with_capacity(20, GFP_KERNEL)?; ++ /// ++ /// assert!(v.capacity() >= 20); ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ pub fn with_capacity(capacity: usize, flags: Flags) -> Result { ++ let mut v = Vec::new(); ++ ++ v.reserve(capacity, flags)?; ++ ++ Ok(v) ++ } ++ ++ /// Creates a `Vec` from a pointer, a length and a capacity using the allocator `A`. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let mut v = kernel::kvec![1, 2, 3]?; ++ /// v.reserve(1, GFP_KERNEL)?; ++ /// ++ /// let (mut ptr, mut len, cap) = v.into_raw_parts(); ++ /// ++ /// // SAFETY: We've just reserved memory for another element. ++ /// unsafe { ptr.add(len).write(4) }; ++ /// len += 1; ++ /// ++ /// // SAFETY: We only wrote an additional element at the end of the `KVec`'s buffer and ++ /// // correspondingly increased the length of the `KVec` by one. Otherwise, we construct it ++ /// // from the exact same raw parts. ++ /// let v = unsafe { KVec::from_raw_parts(ptr, len, cap) }; ++ /// ++ /// assert_eq!(v, [1, 2, 3, 4]); ++ /// ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ /// ++ /// # Safety ++ /// ++ /// If `T` is a ZST: ++ /// ++ /// - `ptr` must be a dangling, well aligned pointer. ++ /// ++ /// Otherwise: ++ /// ++ /// - `ptr` must have been allocated with the allocator `A`. ++ /// - `ptr` must satisfy or exceed the alignment requirements of `T`. ++ /// - `ptr` must point to memory with a size of at least `size_of::() * capacity` bytes. ++ /// - The allocated size in bytes must not be larger than `isize::MAX`. ++ /// - `length` must be less than or equal to `capacity`. ++ /// - The first `length` elements must be initialized values of type `T`. ++ /// ++ /// It is also valid to create an empty `Vec` passing a dangling pointer for `ptr` and zero for ++ /// `cap` and `len`. ++ pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self { ++ let layout = if Self::is_zst() { ++ ArrayLayout::empty() ++ } else { ++ // SAFETY: By the safety requirements of this function, `capacity * size_of::()` is ++ // smaller than `isize::MAX`. ++ unsafe { ArrayLayout::new_unchecked(capacity) } ++ }; ++ ++ // INVARIANT: For ZSTs, we store an empty `ArrayLayout`, all other type invariants are ++ // covered by the safety requirements of this function. ++ Self { ++ // SAFETY: By the safety requirements, `ptr` is either dangling or pointing to a valid ++ // memory allocation, allocated with `A`. ++ ptr: unsafe { NonNull::new_unchecked(ptr) }, ++ layout, ++ len: length, ++ _p: PhantomData::, ++ } ++ } ++ ++ /// Consumes the `Vec` and returns its raw components `pointer`, `length` and `capacity`. ++ /// ++ /// This will not run the destructor of the contained elements and for non-ZSTs the allocation ++ /// will stay alive indefinitely. Use [`Vec::from_raw_parts`] to recover the [`Vec`], drop the ++ /// elements and free the allocation, if any. ++ pub fn into_raw_parts(self) -> (*mut T, usize, usize) { ++ let mut me = ManuallyDrop::new(self); ++ let len = me.len(); ++ let capacity = me.capacity(); ++ let ptr = me.as_mut_ptr(); ++ (ptr, len, capacity) ++ } ++ ++ /// Ensures that the capacity exceeds the length by at least `additional` elements. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let mut v = KVec::new(); ++ /// v.push(1, GFP_KERNEL)?; ++ /// ++ /// v.reserve(10, GFP_KERNEL)?; ++ /// let cap = v.capacity(); ++ /// assert!(cap >= 10); ++ /// ++ /// v.reserve(10, GFP_KERNEL)?; ++ /// let new_cap = v.capacity(); ++ /// assert_eq!(new_cap, cap); ++ /// ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ pub fn reserve(&mut self, additional: usize, flags: Flags) -> Result<(), AllocError> { ++ let len = self.len(); ++ let cap = self.capacity(); ++ ++ if cap - len >= additional { ++ return Ok(()); ++ } ++ ++ if Self::is_zst() { ++ // The capacity is already `usize::MAX` for ZSTs, we can't go higher. ++ return Err(AllocError); ++ } ++ ++ // We know that `cap <= isize::MAX` because of the type invariants of `Self`. So the ++ // multiplication by two won't overflow. ++ let new_cap = core::cmp::max(cap * 2, len.checked_add(additional).ok_or(AllocError)?); ++ let layout = ArrayLayout::new(new_cap).map_err(|_| AllocError)?; ++ ++ // SAFETY: ++ // - `ptr` is valid because it's either `None` or comes from a previous call to ++ // `A::realloc`. ++ // - `self.layout` matches the `ArrayLayout` of the preceding allocation. ++ let ptr = unsafe { ++ A::realloc( ++ Some(self.ptr.cast()), ++ layout.into(), ++ self.layout.into(), ++ flags, ++ )? ++ }; ++ ++ // INVARIANT: ++ // - `layout` is some `ArrayLayout::`, ++ // - `ptr` has been created by `A::realloc` from `layout`. ++ self.ptr = ptr.cast(); ++ self.layout = layout; ++ ++ Ok(()) ++ } ++} ++ ++impl Vec { ++ /// Extend the vector by `n` clones of `value`. ++ pub fn extend_with(&mut self, n: usize, value: T, flags: Flags) -> Result<(), AllocError> { ++ if n == 0 { ++ return Ok(()); ++ } ++ ++ self.reserve(n, flags)?; ++ ++ let spare = self.spare_capacity_mut(); ++ ++ for item in spare.iter_mut().take(n - 1) { ++ item.write(value.clone()); ++ } ++ ++ // We can write the last element directly without cloning needlessly. ++ spare[n - 1].write(value); ++ ++ // SAFETY: ++ // - `self.len() + n < self.capacity()` due to the call to reserve above, ++ // - the loop and the line above initialized the next `n` elements. ++ unsafe { self.set_len(self.len() + n) }; ++ ++ Ok(()) ++ } ++ ++ /// Pushes clones of the elements of slice into the [`Vec`] instance. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// let mut v = KVec::new(); ++ /// v.push(1, GFP_KERNEL)?; ++ /// ++ /// v.extend_from_slice(&[20, 30, 40], GFP_KERNEL)?; ++ /// assert_eq!(&v, &[1, 20, 30, 40]); ++ /// ++ /// v.extend_from_slice(&[50, 60], GFP_KERNEL)?; ++ /// assert_eq!(&v, &[1, 20, 30, 40, 50, 60]); ++ /// # Ok::<(), Error>(()) ++ /// ``` ++ pub fn extend_from_slice(&mut self, other: &[T], flags: Flags) -> Result<(), AllocError> { ++ self.reserve(other.len(), flags)?; ++ for (slot, item) in core::iter::zip(self.spare_capacity_mut(), other) { ++ slot.write(item.clone()); ++ } ++ ++ // SAFETY: ++ // - `other.len()` spare entries have just been initialized, so it is safe to increase ++ // the length by the same number. ++ // - `self.len() + other.len() <= self.capacity()` is guaranteed by the preceding `reserve` ++ // call. ++ unsafe { self.set_len(self.len() + other.len()) }; ++ Ok(()) ++ } ++ ++ /// Create a new `Vec` and extend it by `n` clones of `value`. ++ pub fn from_elem(value: T, n: usize, flags: Flags) -> Result { ++ let mut v = Self::with_capacity(n, flags)?; ++ ++ v.extend_with(n, value, flags)?; ++ ++ Ok(v) ++ } ++} ++ ++impl Drop for Vec ++where ++ A: Allocator, ++{ ++ fn drop(&mut self) { ++ // SAFETY: `self.as_mut_ptr` is guaranteed to be valid by the type invariant. ++ unsafe { ++ ptr::drop_in_place(core::ptr::slice_from_raw_parts_mut( ++ self.as_mut_ptr(), ++ self.len, ++ )) ++ }; ++ ++ // SAFETY: ++ // - `self.ptr` was previously allocated with `A`. ++ // - `self.layout` matches the `ArrayLayout` of the preceding allocation. ++ unsafe { A::free(self.ptr.cast(), self.layout.into()) }; ++ } ++} ++ ++impl From> for Vec ++where ++ A: Allocator, ++{ ++ fn from(b: Box<[T; N], A>) -> Vec { ++ let len = b.len(); ++ let ptr = Box::into_raw(b); ++ ++ // SAFETY: ++ // - `b` has been allocated with `A`, ++ // - `ptr` fulfills the alignment requirements for `T`, ++ // - `ptr` points to memory with at least a size of `size_of::() * len`, ++ // - all elements within `b` are initialized values of `T`, ++ // - `len` does not exceed `isize::MAX`. ++ unsafe { Vec::from_raw_parts(ptr as _, len, len) } ++ } ++} ++ ++impl Default for KVec { ++ #[inline] ++ fn default() -> Self { ++ Self::new() ++ } ++} ++ ++impl fmt::Debug for Vec { ++ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ++ fmt::Debug::fmt(&**self, f) ++ } ++} ++ ++impl Deref for Vec ++where ++ A: Allocator, ++{ ++ type Target = [T]; ++ ++ #[inline] ++ fn deref(&self) -> &[T] { ++ // SAFETY: The memory behind `self.as_ptr()` is guaranteed to contain `self.len` ++ // initialized elements of type `T`. ++ unsafe { slice::from_raw_parts(self.as_ptr(), self.len) } ++ } ++} ++ ++impl DerefMut for Vec ++where ++ A: Allocator, ++{ ++ #[inline] ++ fn deref_mut(&mut self) -> &mut [T] { ++ // SAFETY: The memory behind `self.as_ptr()` is guaranteed to contain `self.len` ++ // initialized elements of type `T`. ++ unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } ++ } ++} ++ ++impl Eq for Vec where A: Allocator {} ++ ++impl, A> Index for Vec ++where ++ A: Allocator, ++{ ++ type Output = I::Output; ++ ++ #[inline] ++ fn index(&self, index: I) -> &Self::Output { ++ Index::index(&**self, index) ++ } ++} ++ ++impl, A> IndexMut for Vec ++where ++ A: Allocator, ++{ ++ #[inline] ++ fn index_mut(&mut self, index: I) -> &mut Self::Output { ++ IndexMut::index_mut(&mut **self, index) ++ } ++} ++ ++macro_rules! impl_slice_eq { ++ ($([$($vars:tt)*] $lhs:ty, $rhs:ty,)*) => { ++ $( ++ impl PartialEq<$rhs> for $lhs ++ where ++ T: PartialEq, ++ { ++ #[inline] ++ fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] } ++ } ++ )* ++ } ++} ++ ++impl_slice_eq! { ++ [A1: Allocator, A2: Allocator] Vec, Vec, ++ [A: Allocator] Vec, &[U], ++ [A: Allocator] Vec, &mut [U], ++ [A: Allocator] &[T], Vec, ++ [A: Allocator] &mut [T], Vec, ++ [A: Allocator] Vec, [U], ++ [A: Allocator] [T], Vec, ++ [A: Allocator, const N: usize] Vec, [U; N], ++ [A: Allocator, const N: usize] Vec, &[U; N], ++} +--- a/rust/kernel/lib.rs ++++ b/rust/kernel/lib.rs +@@ -15,6 +15,7 @@ + #![feature(arbitrary_self_types)] + #![feature(coerce_unsized)] + #![feature(dispatch_from_dyn)] ++#![feature(inline_const)] + #![feature(lint_reasons)] + #![feature(unsize)] + +--- a/rust/kernel/prelude.rs ++++ b/rust/kernel/prelude.rs +@@ -14,7 +14,7 @@ + #[doc(no_inline)] + pub use core::pin::Pin; + +-pub use crate::alloc::{flags::*, vec_ext::VecExt, Box, KBox, KVBox, VBox}; ++pub use crate::alloc::{flags::*, vec_ext::VecExt, Box, KBox, KVBox, KVVec, KVec, VBox, VVec}; + + #[doc(no_inline)] + pub use alloc::vec::Vec; diff --git a/queue-6.12/rust-alloc-implement-kvmalloc-allocator.patch b/queue-6.12/rust-alloc-implement-kvmalloc-allocator.patch new file mode 100644 index 0000000000..e6ea16ddd1 --- /dev/null +++ b/queue-6.12/rust-alloc-implement-kvmalloc-allocator.patch @@ -0,0 +1,114 @@ +From stable+bounces-121483-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:08 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:35 +0100 +Subject: rust: alloc: implement `KVmalloc` allocator +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-29-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 8362c2608ba1be635ffa22a256dfcfe51c6238cc upstream. + +Implement `Allocator` for `KVmalloc`, an `Allocator` that tries to +allocate memory with `kmalloc` first and, on failure, falls back to +`vmalloc`. + +All memory allocations made with `KVmalloc` end up in +`kvrealloc_noprof()`; all frees in `kvfree()`. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-10-dakr@kernel.org +[ Reworded typo. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/helpers/slab.c | 6 ++++++ + rust/kernel/alloc/allocator.rs | 36 ++++++++++++++++++++++++++++++++++++ + rust/kernel/alloc/allocator_test.rs | 1 + + 3 files changed, 43 insertions(+) + +--- a/rust/helpers/slab.c ++++ b/rust/helpers/slab.c +@@ -7,3 +7,9 @@ rust_helper_krealloc(const void *objp, s + { + return krealloc(objp, new_size, flags); + } ++ ++void * __must_check __realloc_size(2) ++rust_helper_kvrealloc(const void *p, size_t size, gfp_t flags) ++{ ++ return kvrealloc(p, size, flags); ++} +--- a/rust/kernel/alloc/allocator.rs ++++ b/rust/kernel/alloc/allocator.rs +@@ -34,6 +34,15 @@ pub struct Kmalloc; + /// For more details see [self]. + pub struct Vmalloc; + ++/// The kvmalloc kernel allocator. ++/// ++/// `KVmalloc` attempts to allocate memory with `Kmalloc` first, but falls back to `Vmalloc` upon ++/// failure. This allocator is typically used when the size for the requested allocation is not ++/// known and may exceed the capabilities of `Kmalloc`. ++/// ++/// For more details see [self]. ++pub struct KVmalloc; ++ + /// Returns a proper size to alloc a new object aligned to `new_layout`'s alignment. + fn aligned_size(new_layout: Layout) -> usize { + // Customized layouts from `Layout::from_size_align()` can have size < align, so pad first. +@@ -76,6 +85,9 @@ impl ReallocFunc { + // INVARIANT: `vrealloc` satisfies the type invariants. + const VREALLOC: Self = Self(bindings::vrealloc); + ++ // INVARIANT: `kvrealloc` satisfies the type invariants. ++ const KVREALLOC: Self = Self(bindings::kvrealloc); ++ + /// # Safety + /// + /// This method has the same safety requirements as [`Allocator::realloc`]. +@@ -205,6 +217,30 @@ unsafe impl Allocator for Vmalloc { + } + } + ++// SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that ++// - memory remains valid until it is explicitly freed, ++// - passing a pointer to a valid memory allocation is OK, ++// - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same. ++unsafe impl Allocator for KVmalloc { ++ #[inline] ++ unsafe fn realloc( ++ ptr: Option>, ++ layout: Layout, ++ old_layout: Layout, ++ flags: Flags, ++ ) -> Result, AllocError> { ++ // TODO: Support alignments larger than PAGE_SIZE. ++ if layout.align() > bindings::PAGE_SIZE { ++ pr_warn!("KVmalloc does not support alignments larger than PAGE_SIZE yet.\n"); ++ return Err(AllocError); ++ } ++ ++ // SAFETY: If not `None`, `ptr` is guaranteed to point to valid memory, which was previously ++ // allocated with this `Allocator`. ++ unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags) } ++ } ++} ++ + #[global_allocator] + static ALLOCATOR: Kmalloc = Kmalloc; + +--- a/rust/kernel/alloc/allocator_test.rs ++++ b/rust/kernel/alloc/allocator_test.rs +@@ -8,6 +8,7 @@ use core::ptr::NonNull; + + pub struct Kmalloc; + pub type Vmalloc = Kmalloc; ++pub type KVmalloc = Kmalloc; + + unsafe impl Allocator for Kmalloc { + unsafe fn realloc( diff --git a/queue-6.12/rust-alloc-implement-reallocfunc.patch b/queue-6.12/rust-alloc-implement-reallocfunc.patch new file mode 100644 index 0000000000..bdfe57826c --- /dev/null +++ b/queue-6.12/rust-alloc-implement-reallocfunc.patch @@ -0,0 +1,139 @@ +From stable+bounces-121478-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:42 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:30 +0100 +Subject: rust: alloc: implement `ReallocFunc` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-24-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 8a799831fc63c988eec90d334fdd68ff5f2c7eb5 upstream. + +`ReallocFunc` is an abstraction for the kernel's realloc derivates, such +as `krealloc`, `vrealloc` and `kvrealloc`. + +All of the named functions share the same function signature and +implement the same semantics. The `ReallocFunc` abstractions provides a +generalized wrapper around those, to trivialize the implementation of +`Kmalloc`, `Vmalloc` and `KVmalloc` in subsequent patches. + +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-5-dakr@kernel.org +[ Added temporary `allow(dead_code)` for `dangling_from_layout` to clean + warning in `rusttest` target as discussed in the list (but it is + needed earlier, i.e. in this patch already). Added colon. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 9 +++++ + rust/kernel/alloc/allocator.rs | 70 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 79 insertions(+) + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -187,3 +187,12 @@ pub unsafe trait Allocator { + let _ = unsafe { Self::realloc(Some(ptr), Layout::new::<()>(), layout, Flags(0)) }; + } + } ++ ++#[allow(dead_code)] ++/// Returns a properly aligned dangling pointer from the given `layout`. ++pub(crate) fn dangling_from_layout(layout: Layout) -> NonNull { ++ let ptr = layout.align() as *mut u8; ++ ++ // SAFETY: `layout.align()` (and hence `ptr`) is guaranteed to be non-zero. ++ unsafe { NonNull::new_unchecked(ptr) } ++} +--- a/rust/kernel/alloc/allocator.rs ++++ b/rust/kernel/alloc/allocator.rs +@@ -1,10 +1,20 @@ + // SPDX-License-Identifier: GPL-2.0 + + //! Allocator support. ++//! ++//! Documentation for the kernel's memory allocators can found in the "Memory Allocation Guide" ++//! linked below. For instance, this includes the concept of "get free page" (GFP) flags and the ++//! typical application of the different kernel allocators. ++//! ++//! Reference: + + use super::{flags::*, Flags}; + use core::alloc::{GlobalAlloc, Layout}; + use core::ptr; ++use core::ptr::NonNull; ++ ++use crate::alloc::AllocError; ++use crate::bindings; + + struct Kmalloc; + +@@ -36,6 +46,66 @@ pub(crate) unsafe fn krealloc_aligned(pt + unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags.0) as *mut u8 } + } + ++/// # Invariants ++/// ++/// One of the following: `krealloc`, `vrealloc`, `kvrealloc`. ++struct ReallocFunc( ++ unsafe extern "C" fn(*const core::ffi::c_void, usize, u32) -> *mut core::ffi::c_void, ++); ++ ++#[expect(dead_code)] ++impl ReallocFunc { ++ /// # Safety ++ /// ++ /// This method has the same safety requirements as [`Allocator::realloc`]. ++ /// ++ /// # Guarantees ++ /// ++ /// This method has the same guarantees as `Allocator::realloc`. Additionally ++ /// - it accepts any pointer to a valid memory allocation allocated by this function. ++ /// - memory allocated by this function remains valid until it is passed to this function. ++ unsafe fn call( ++ &self, ++ ptr: Option>, ++ layout: Layout, ++ old_layout: Layout, ++ flags: Flags, ++ ) -> Result, AllocError> { ++ let size = aligned_size(layout); ++ let ptr = match ptr { ++ Some(ptr) => { ++ if old_layout.size() == 0 { ++ ptr::null() ++ } else { ++ ptr.as_ptr() ++ } ++ } ++ None => ptr::null(), ++ }; ++ ++ // SAFETY: ++ // - `self.0` is one of `krealloc`, `vrealloc`, `kvrealloc` and thus only requires that ++ // `ptr` is NULL or valid. ++ // - `ptr` is either NULL or valid by the safety requirements of this function. ++ // ++ // GUARANTEE: ++ // - `self.0` is one of `krealloc`, `vrealloc`, `kvrealloc`. ++ // - Those functions provide the guarantees of this function. ++ let raw_ptr = unsafe { ++ // If `size == 0` and `ptr != NULL` the memory behind the pointer is freed. ++ self.0(ptr.cast(), size, flags.0).cast() ++ }; ++ ++ let ptr = if size == 0 { ++ crate::alloc::dangling_from_layout(layout) ++ } else { ++ NonNull::new(raw_ptr).ok_or(AllocError)? ++ }; ++ ++ Ok(NonNull::slice_from_raw_parts(ptr, size)) ++ } ++} ++ + // SAFETY: TODO. + unsafe impl GlobalAlloc for Kmalloc { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { diff --git a/queue-6.12/rust-alloc-implement-vmalloc-allocator.patch b/queue-6.12/rust-alloc-implement-vmalloc-allocator.patch new file mode 100644 index 0000000000..e0700c2ac4 --- /dev/null +++ b/queue-6.12/rust-alloc-implement-vmalloc-allocator.patch @@ -0,0 +1,131 @@ +From stable+bounces-121482-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:58 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:34 +0100 +Subject: rust: alloc: implement `Vmalloc` allocator +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-28-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 61c004781d6b928443052e7a6cf84b35d4f61401 upstream. + +Implement `Allocator` for `Vmalloc`, the kernel's virtually contiguous +allocator, typically used for larger objects, (much) larger than page +size. + +All memory allocations made with `Vmalloc` end up in `vrealloc()`. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-9-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/helpers/helpers.c | 1 + rust/helpers/vmalloc.c | 9 ++++++++ + rust/kernel/alloc/allocator.rs | 37 ++++++++++++++++++++++++++++++++++++ + rust/kernel/alloc/allocator_test.rs | 1 + 4 files changed, 48 insertions(+) + create mode 100644 rust/helpers/vmalloc.c + +--- a/rust/helpers/helpers.c ++++ b/rust/helpers/helpers.c +@@ -22,5 +22,6 @@ + #include "spinlock.c" + #include "task.c" + #include "uaccess.c" ++#include "vmalloc.c" + #include "wait.c" + #include "workqueue.c" +--- /dev/null ++++ b/rust/helpers/vmalloc.c +@@ -0,0 +1,9 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#include ++ ++void * __must_check __realloc_size(2) ++rust_helper_vrealloc(const void *p, size_t size, gfp_t flags) ++{ ++ return vrealloc(p, size, flags); ++} +--- a/rust/kernel/alloc/allocator.rs ++++ b/rust/kernel/alloc/allocator.rs +@@ -15,6 +15,7 @@ use core::ptr::NonNull; + + use crate::alloc::{AllocError, Allocator}; + use crate::bindings; ++use crate::pr_warn; + + /// The contiguous kernel allocator. + /// +@@ -24,6 +25,15 @@ use crate::bindings; + /// For more details see [self]. + pub struct Kmalloc; + ++/// The virtually contiguous kernel allocator. ++/// ++/// `Vmalloc` allocates pages from the page level allocator and maps them into the contiguous kernel ++/// virtual space. It is typically used for large allocations. The memory allocated with this ++/// allocator is not physically contiguous. ++/// ++/// For more details see [self]. ++pub struct Vmalloc; ++ + /// Returns a proper size to alloc a new object aligned to `new_layout`'s alignment. + fn aligned_size(new_layout: Layout) -> usize { + // Customized layouts from `Layout::from_size_align()` can have size < align, so pad first. +@@ -63,6 +73,9 @@ impl ReallocFunc { + // INVARIANT: `krealloc` satisfies the type invariants. + const KREALLOC: Self = Self(bindings::krealloc); + ++ // INVARIANT: `vrealloc` satisfies the type invariants. ++ const VREALLOC: Self = Self(bindings::vrealloc); ++ + /// # Safety + /// + /// This method has the same safety requirements as [`Allocator::realloc`]. +@@ -168,6 +181,30 @@ unsafe impl GlobalAlloc for Kmalloc { + } + } + ++// SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that ++// - memory remains valid until it is explicitly freed, ++// - passing a pointer to a valid memory allocation is OK, ++// - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same. ++unsafe impl Allocator for Vmalloc { ++ #[inline] ++ unsafe fn realloc( ++ ptr: Option>, ++ layout: Layout, ++ old_layout: Layout, ++ flags: Flags, ++ ) -> Result, AllocError> { ++ // TODO: Support alignments larger than PAGE_SIZE. ++ if layout.align() > bindings::PAGE_SIZE { ++ pr_warn!("Vmalloc does not support alignments larger than PAGE_SIZE yet.\n"); ++ return Err(AllocError); ++ } ++ ++ // SAFETY: If not `None`, `ptr` is guaranteed to point to valid memory, which was previously ++ // allocated with this `Allocator`. ++ unsafe { ReallocFunc::VREALLOC.call(ptr, layout, old_layout, flags) } ++ } ++} ++ + #[global_allocator] + static ALLOCATOR: Kmalloc = Kmalloc; + +--- a/rust/kernel/alloc/allocator_test.rs ++++ b/rust/kernel/alloc/allocator_test.rs +@@ -7,6 +7,7 @@ use core::alloc::Layout; + use core::ptr::NonNull; + + pub struct Kmalloc; ++pub type Vmalloc = Kmalloc; + + unsafe impl Allocator for Kmalloc { + unsafe fn realloc( diff --git a/queue-6.12/rust-alloc-introduce-arraylayout.patch b/queue-6.12/rust-alloc-introduce-arraylayout.patch new file mode 100644 index 0000000000..f2616e6377 --- /dev/null +++ b/queue-6.12/rust-alloc-introduce-arraylayout.patch @@ -0,0 +1,139 @@ +From stable+bounces-121489-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:14 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:41 +0100 +Subject: rust: alloc: introduce `ArrayLayout` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-35-ojeda@kernel.org> + +From: Benno Lossin + +commit 9e7bbfa182767f638ba61dba3518ff78da9f31ff upstream. + +When allocating memory for arrays using allocators, the `Layout::array` +function is typically used. It returns a result, since the given size +might be too big. However, `Vec` and its iterators store their allocated +capacity and thus they already did check that the size is not too big. + +The `ArrayLayout` type provides this exact behavior, as it can be +infallibly converted into a `Layout`. Instead of a `usize` capacity, +`Vec` and other similar array-storing types can use `ArrayLayout` +instead. + +Reviewed-by: Gary Guo +Signed-off-by: Benno Lossin +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-16-dakr@kernel.org +[ Formatted a few comments. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 1 + rust/kernel/alloc/layout.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 92 insertions(+) + create mode 100644 rust/kernel/alloc/layout.rs + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -5,6 +5,7 @@ + #[cfg(not(any(test, testlib)))] + pub mod allocator; + pub mod kbox; ++pub mod layout; + pub mod vec_ext; + + #[cfg(any(test, testlib))] +--- /dev/null ++++ b/rust/kernel/alloc/layout.rs +@@ -0,0 +1,91 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++//! Memory layout. ++//! ++//! Custom layout types extending or improving [`Layout`]. ++ ++use core::{alloc::Layout, marker::PhantomData}; ++ ++/// Error when constructing an [`ArrayLayout`]. ++pub struct LayoutError; ++ ++/// A layout for an array `[T; n]`. ++/// ++/// # Invariants ++/// ++/// - `len * size_of::() <= isize::MAX`. ++pub struct ArrayLayout { ++ len: usize, ++ _phantom: PhantomData T>, ++} ++ ++impl Clone for ArrayLayout { ++ fn clone(&self) -> Self { ++ *self ++ } ++} ++impl Copy for ArrayLayout {} ++ ++const ISIZE_MAX: usize = isize::MAX as usize; ++ ++impl ArrayLayout { ++ /// Creates a new layout for `[T; 0]`. ++ pub const fn empty() -> Self { ++ // INVARIANT: `0 * size_of::() <= isize::MAX`. ++ Self { ++ len: 0, ++ _phantom: PhantomData, ++ } ++ } ++ ++ /// Creates a new layout for `[T; len]`. ++ /// ++ /// # Errors ++ /// ++ /// When `len * size_of::()` overflows or when `len * size_of::() > isize::MAX`. ++ pub const fn new(len: usize) -> Result { ++ match len.checked_mul(core::mem::size_of::()) { ++ Some(len) if len <= ISIZE_MAX => { ++ // INVARIANT: We checked above that `len * size_of::() <= isize::MAX`. ++ Ok(Self { ++ len, ++ _phantom: PhantomData, ++ }) ++ } ++ _ => Err(LayoutError), ++ } ++ } ++ ++ /// Creates a new layout for `[T; len]`. ++ /// ++ /// # Safety ++ /// ++ /// `len` must be a value, for which `len * size_of::() <= isize::MAX` is true. ++ pub unsafe fn new_unchecked(len: usize) -> Self { ++ // INVARIANT: By the safety requirements of this function ++ // `len * size_of::() <= isize::MAX`. ++ Self { ++ len, ++ _phantom: PhantomData, ++ } ++ } ++ ++ /// Returns the number of array elements represented by this layout. ++ pub const fn len(&self) -> usize { ++ self.len ++ } ++ ++ /// Returns `true` when no array elements are represented by this layout. ++ pub const fn is_empty(&self) -> bool { ++ self.len == 0 ++ } ++} ++ ++impl From> for Layout { ++ fn from(value: ArrayLayout) -> Self { ++ let res = Layout::array::(value.len); ++ // SAFETY: By the type invariant of `ArrayLayout` we have ++ // `len * size_of::() <= isize::MAX` and thus the result must be `Ok`. ++ unsafe { res.unwrap_unchecked() } ++ } ++} diff --git a/queue-6.12/rust-alloc-make-allocator-module-public.patch b/queue-6.12/rust-alloc-make-allocator-module-public.patch new file mode 100644 index 0000000000..b0e0a5585e --- /dev/null +++ b/queue-6.12/rust-alloc-make-allocator-module-public.patch @@ -0,0 +1,37 @@ +From stable+bounces-121479-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:46 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:31 +0100 +Subject: rust: alloc: make `allocator` module public +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-25-ojeda@kernel.org> + +From: Danilo Krummrich + +commit a87a36f0bf517dae22f3e3790b05c979070f776a upstream. + +Subsequent patches implement allocators such as `Kmalloc`, `Vmalloc`, +`KVmalloc`; we need them to be available outside of the kernel crate as +well. + +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-6-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -4,7 +4,7 @@ + + #[cfg(not(test))] + #[cfg(not(testlib))] +-mod allocator; ++pub mod allocator; + pub mod box_ext; + pub mod vec_ext; + diff --git a/queue-6.12/rust-alloc-remove-extension-of-std-s-box.patch b/queue-6.12/rust-alloc-remove-extension-of-std-s-box.patch new file mode 100644 index 0000000000..a473a258ec --- /dev/null +++ b/queue-6.12/rust-alloc-remove-extension-of-std-s-box.patch @@ -0,0 +1,311 @@ +From stable+bounces-121487-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:15 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:39 +0100 +Subject: rust: alloc: remove extension of std's `Box` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-33-ojeda@kernel.org> + +From: Danilo Krummrich + +commit e8c6ccdbcaaf31f26c0fffd4073edd0b0147cdc6 upstream. + +Now that all existing `Box` users were moved to the kernel `Box` type, +remove the `BoxExt` extension and all other related extensions. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-14-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 1 + rust/kernel/alloc/box_ext.rs | 89 ------------------------------------------- + rust/kernel/init.rs | 46 ---------------------- + rust/kernel/lib.rs | 1 + rust/kernel/prelude.rs | 4 - + rust/kernel/types.rs | 50 ------------------------ + 6 files changed, 3 insertions(+), 188 deletions(-) + delete mode 100644 rust/kernel/alloc/box_ext.rs + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -4,7 +4,6 @@ + + #[cfg(not(any(test, testlib)))] + pub mod allocator; +-pub mod box_ext; + pub mod kbox; + pub mod vec_ext; + +--- a/rust/kernel/alloc/box_ext.rs ++++ /dev/null +@@ -1,89 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +- +-//! Extensions to [`Box`] for fallible allocations. +- +-use super::{AllocError, Flags}; +-use alloc::boxed::Box; +-use core::{mem::MaybeUninit, ptr, result::Result}; +- +-/// Extensions to [`Box`]. +-pub trait BoxExt: Sized { +- /// Allocates a new box. +- /// +- /// The allocation may fail, in which case an error is returned. +- fn new(x: T, flags: Flags) -> Result; +- +- /// Allocates a new uninitialised box. +- /// +- /// The allocation may fail, in which case an error is returned. +- fn new_uninit(flags: Flags) -> Result>, AllocError>; +- +- /// Drops the contents, but keeps the allocation. +- /// +- /// # Examples +- /// +- /// ``` +- /// use kernel::alloc::{flags, box_ext::BoxExt}; +- /// let value = Box::new([0; 32], flags::GFP_KERNEL)?; +- /// assert_eq!(*value, [0; 32]); +- /// let mut value = Box::drop_contents(value); +- /// // Now we can re-use `value`: +- /// value.write([1; 32]); +- /// // SAFETY: We just wrote to it. +- /// let value = unsafe { value.assume_init() }; +- /// assert_eq!(*value, [1; 32]); +- /// # Ok::<(), Error>(()) +- /// ``` +- fn drop_contents(this: Self) -> Box>; +-} +- +-impl BoxExt for Box { +- fn new(x: T, flags: Flags) -> Result { +- let mut b = >::new_uninit(flags)?; +- b.write(x); +- // SAFETY: We just wrote to it. +- Ok(unsafe { b.assume_init() }) +- } +- +- #[cfg(any(test, testlib))] +- fn new_uninit(_flags: Flags) -> Result>, AllocError> { +- Ok(Box::new_uninit()) +- } +- +- #[cfg(not(any(test, testlib)))] +- fn new_uninit(flags: Flags) -> Result>, AllocError> { +- let ptr = if core::mem::size_of::>() == 0 { +- core::ptr::NonNull::<_>::dangling().as_ptr() +- } else { +- let layout = core::alloc::Layout::new::>(); +- +- // SAFETY: Memory is being allocated (first arg is null). The only other source of +- // safety issues is sleeping on atomic context, which is addressed by klint. Lastly, +- // the type is not a SZT (checked above). +- let ptr = +- unsafe { super::allocator::krealloc_aligned(core::ptr::null_mut(), layout, flags) }; +- if ptr.is_null() { +- return Err(AllocError); +- } +- +- ptr.cast::>() +- }; +- +- // SAFETY: For non-zero-sized types, we allocate above using the global allocator. For +- // zero-sized types, we use `NonNull::dangling`. +- Ok(unsafe { Box::from_raw(ptr) }) +- } +- +- fn drop_contents(this: Self) -> Box> { +- let ptr = Box::into_raw(this); +- // SAFETY: `ptr` is valid, because it came from `Box::into_raw`. +- unsafe { ptr::drop_in_place(ptr) }; +- +- // CAST: `MaybeUninit` is a transparent wrapper of `T`. +- let ptr = ptr.cast::>(); +- +- // SAFETY: `ptr` is valid for writes, because it came from `Box::into_raw` and it is valid for +- // reads, since the pointer came from `Box::into_raw` and the type is `MaybeUninit`. +- unsafe { Box::from_raw(ptr) } +- } +-} +--- a/rust/kernel/init.rs ++++ b/rust/kernel/init.rs +@@ -211,13 +211,12 @@ + //! [`pin_init!`]: crate::pin_init! + + use crate::{ +- alloc::{box_ext::BoxExt, AllocError, Flags, KBox}, ++ alloc::{AllocError, Flags, KBox}, + error::{self, Error}, + sync::Arc, + sync::UniqueArc, + types::{Opaque, ScopeGuard}, + }; +-use alloc::boxed::Box; + use core::{ + cell::UnsafeCell, + convert::Infallible, +@@ -588,7 +587,6 @@ macro_rules! pin_init { + /// # Examples + /// + /// ```rust +-/// # #![feature(new_uninit)] + /// use kernel::{init::{self, PinInit}, error::Error}; + /// #[pin_data] + /// struct BigBuf { +@@ -1245,26 +1243,6 @@ impl InPlaceInit for Arc { + } + } + +-impl InPlaceInit for Box { +- type PinnedSelf = Pin; +- +- #[inline] +- fn try_pin_init(init: impl PinInit, flags: Flags) -> Result +- where +- E: From, +- { +- as BoxExt<_>>::new_uninit(flags)?.write_pin_init(init) +- } +- +- #[inline] +- fn try_init(init: impl Init, flags: Flags) -> Result +- where +- E: From, +- { +- as BoxExt<_>>::new_uninit(flags)?.write_init(init) +- } +-} +- + impl InPlaceInit for UniqueArc { + type PinnedSelf = Pin; + +@@ -1301,28 +1279,6 @@ pub trait InPlaceWrite { + fn write_pin_init(self, init: impl PinInit) -> Result, E>; + } + +-impl InPlaceWrite for Box> { +- type Initialized = Box; +- +- fn write_init(mut self, init: impl Init) -> Result { +- let slot = self.as_mut_ptr(); +- // SAFETY: When init errors/panics, slot will get deallocated but not dropped, +- // slot is valid. +- unsafe { init.__init(slot)? }; +- // SAFETY: All fields have been initialized. +- Ok(unsafe { self.assume_init() }) +- } +- +- fn write_pin_init(mut self, init: impl PinInit) -> Result, E> { +- let slot = self.as_mut_ptr(); +- // SAFETY: When init errors/panics, slot will get deallocated but not dropped, +- // slot is valid and will not be moved, because we pin it later. +- unsafe { init.__pinned_init(slot)? }; +- // SAFETY: All fields have been initialized. +- Ok(unsafe { self.assume_init() }.into()) +- } +-} +- + impl InPlaceWrite for UniqueArc> { + type Initialized = UniqueArc; + +--- a/rust/kernel/lib.rs ++++ b/rust/kernel/lib.rs +@@ -16,7 +16,6 @@ + #![feature(coerce_unsized)] + #![feature(dispatch_from_dyn)] + #![feature(lint_reasons)] +-#![feature(new_uninit)] + #![feature(unsize)] + + // Ensure conditional compilation based on the kernel configuration works; +--- a/rust/kernel/prelude.rs ++++ b/rust/kernel/prelude.rs +@@ -14,10 +14,10 @@ + #[doc(no_inline)] + pub use core::pin::Pin; + +-pub use crate::alloc::{box_ext::BoxExt, flags::*, vec_ext::VecExt, KBox, KVBox, VBox}; ++pub use crate::alloc::{flags::*, vec_ext::VecExt, KBox, KVBox, VBox}; + + #[doc(no_inline)] +-pub use alloc::{boxed::Box, vec::Vec}; ++pub use alloc::vec::Vec; + + #[doc(no_inline)] + pub use macros::{module, pin_data, pinned_drop, vtable, Zeroable}; +--- a/rust/kernel/types.rs ++++ b/rust/kernel/types.rs +@@ -3,13 +3,11 @@ + //! Kernel types. + + use crate::init::{self, PinInit}; +-use alloc::boxed::Box; + use core::{ + cell::UnsafeCell, + marker::{PhantomData, PhantomPinned}, + mem::{ManuallyDrop, MaybeUninit}, + ops::{Deref, DerefMut}, +- pin::Pin, + ptr::NonNull, + }; + +@@ -71,54 +69,6 @@ pub trait ForeignOwnable: Sized { + } + } + +-impl ForeignOwnable for Box { +- type Borrowed<'a> = &'a T; +- +- fn into_foreign(self) -> *const core::ffi::c_void { +- Box::into_raw(self) as _ +- } +- +- unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { +- // SAFETY: The safety requirements for this function ensure that the object is still alive, +- // so it is safe to dereference the raw pointer. +- // The safety requirements of `from_foreign` also ensure that the object remains alive for +- // the lifetime of the returned value. +- unsafe { &*ptr.cast() } +- } +- +- unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { +- // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous +- // call to `Self::into_foreign`. +- unsafe { Box::from_raw(ptr as _) } +- } +-} +- +-impl ForeignOwnable for Pin> { +- type Borrowed<'a> = Pin<&'a T>; +- +- fn into_foreign(self) -> *const core::ffi::c_void { +- // SAFETY: We are still treating the box as pinned. +- Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _ +- } +- +- unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Pin<&'a T> { +- // SAFETY: The safety requirements for this function ensure that the object is still alive, +- // so it is safe to dereference the raw pointer. +- // The safety requirements of `from_foreign` also ensure that the object remains alive for +- // the lifetime of the returned value. +- let r = unsafe { &*ptr.cast() }; +- +- // SAFETY: This pointer originates from a `Pin>`. +- unsafe { Pin::new_unchecked(r) } +- } +- +- unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { +- // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous +- // call to `Self::into_foreign`. +- unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) } +- } +-} +- + impl ForeignOwnable for () { + type Borrowed<'a> = (); + diff --git a/queue-6.12/rust-alloc-remove-vecext-extension.patch b/queue-6.12/rust-alloc-remove-vecext-extension.patch new file mode 100644 index 0000000000..03c646a82f --- /dev/null +++ b/queue-6.12/rust-alloc-remove-vecext-extension.patch @@ -0,0 +1,241 @@ +From stable+bounces-121494-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:46 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:46 +0100 +Subject: rust: alloc: remove `VecExt` extension +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-40-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 405966efc789888c3e1a53cd09d2c2b338064438 upstream. + +Now that all existing `Vec` users were moved to the kernel `Vec` type, +remove the `VecExt` extension. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-21-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 1 + rust/kernel/alloc/vec_ext.rs | 185 ------------------------------------------- + rust/kernel/prelude.rs | 5 - + 3 files changed, 1 insertion(+), 190 deletions(-) + delete mode 100644 rust/kernel/alloc/vec_ext.rs + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -7,7 +7,6 @@ pub mod allocator; + pub mod kbox; + pub mod kvec; + pub mod layout; +-pub mod vec_ext; + + #[cfg(any(test, testlib))] + pub mod allocator_test; +--- a/rust/kernel/alloc/vec_ext.rs ++++ /dev/null +@@ -1,185 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +- +-//! Extensions to [`Vec`] for fallible allocations. +- +-use super::{AllocError, Flags}; +-use alloc::vec::Vec; +- +-/// Extensions to [`Vec`]. +-pub trait VecExt: Sized { +- /// Creates a new [`Vec`] instance with at least the given capacity. +- /// +- /// # Examples +- /// +- /// ``` +- /// let v = Vec::::with_capacity(20, GFP_KERNEL)?; +- /// +- /// assert!(v.capacity() >= 20); +- /// # Ok::<(), Error>(()) +- /// ``` +- fn with_capacity(capacity: usize, flags: Flags) -> Result; +- +- /// Appends an element to the back of the [`Vec`] instance. +- /// +- /// # Examples +- /// +- /// ``` +- /// let mut v = Vec::new(); +- /// v.push(1, GFP_KERNEL)?; +- /// assert_eq!(&v, &[1]); +- /// +- /// v.push(2, GFP_KERNEL)?; +- /// assert_eq!(&v, &[1, 2]); +- /// # Ok::<(), Error>(()) +- /// ``` +- fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError>; +- +- /// Pushes clones of the elements of slice into the [`Vec`] instance. +- /// +- /// # Examples +- /// +- /// ``` +- /// let mut v = Vec::new(); +- /// v.push(1, GFP_KERNEL)?; +- /// +- /// v.extend_from_slice(&[20, 30, 40], GFP_KERNEL)?; +- /// assert_eq!(&v, &[1, 20, 30, 40]); +- /// +- /// v.extend_from_slice(&[50, 60], GFP_KERNEL)?; +- /// assert_eq!(&v, &[1, 20, 30, 40, 50, 60]); +- /// # Ok::<(), Error>(()) +- /// ``` +- fn extend_from_slice(&mut self, other: &[T], flags: Flags) -> Result<(), AllocError> +- where +- T: Clone; +- +- /// Ensures that the capacity exceeds the length by at least `additional` elements. +- /// +- /// # Examples +- /// +- /// ``` +- /// let mut v = Vec::new(); +- /// v.push(1, GFP_KERNEL)?; +- /// +- /// v.reserve(10, GFP_KERNEL)?; +- /// let cap = v.capacity(); +- /// assert!(cap >= 10); +- /// +- /// v.reserve(10, GFP_KERNEL)?; +- /// let new_cap = v.capacity(); +- /// assert_eq!(new_cap, cap); +- /// +- /// # Ok::<(), Error>(()) +- /// ``` +- fn reserve(&mut self, additional: usize, flags: Flags) -> Result<(), AllocError>; +-} +- +-impl VecExt for Vec { +- fn with_capacity(capacity: usize, flags: Flags) -> Result { +- let mut v = Vec::new(); +- >::reserve(&mut v, capacity, flags)?; +- Ok(v) +- } +- +- fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> { +- >::reserve(self, 1, flags)?; +- let s = self.spare_capacity_mut(); +- s[0].write(v); +- +- // SAFETY: We just initialised the first spare entry, so it is safe to increase the length +- // by 1. We also know that the new length is <= capacity because of the previous call to +- // `reserve` above. +- unsafe { self.set_len(self.len() + 1) }; +- Ok(()) +- } +- +- fn extend_from_slice(&mut self, other: &[T], flags: Flags) -> Result<(), AllocError> +- where +- T: Clone, +- { +- >::reserve(self, other.len(), flags)?; +- for (slot, item) in core::iter::zip(self.spare_capacity_mut(), other) { +- slot.write(item.clone()); +- } +- +- // SAFETY: We just initialised the `other.len()` spare entries, so it is safe to increase +- // the length by the same amount. We also know that the new length is <= capacity because +- // of the previous call to `reserve` above. +- unsafe { self.set_len(self.len() + other.len()) }; +- Ok(()) +- } +- +- #[cfg(any(test, testlib))] +- fn reserve(&mut self, additional: usize, _flags: Flags) -> Result<(), AllocError> { +- Vec::reserve(self, additional); +- Ok(()) +- } +- +- #[cfg(not(any(test, testlib)))] +- fn reserve(&mut self, additional: usize, flags: Flags) -> Result<(), AllocError> { +- let len = self.len(); +- let cap = self.capacity(); +- +- if cap - len >= additional { +- return Ok(()); +- } +- +- if core::mem::size_of::() == 0 { +- // The capacity is already `usize::MAX` for SZTs, we can't go higher. +- return Err(AllocError); +- } +- +- // We know cap is <= `isize::MAX` because `Layout::array` fails if the resulting byte size +- // is greater than `isize::MAX`. So the multiplication by two won't overflow. +- let new_cap = core::cmp::max(cap * 2, len.checked_add(additional).ok_or(AllocError)?); +- let layout = core::alloc::Layout::array::(new_cap).map_err(|_| AllocError)?; +- +- let (old_ptr, len, cap) = destructure(self); +- +- // We need to make sure that `ptr` is either NULL or comes from a previous call to +- // `krealloc_aligned`. A `Vec`'s `ptr` value is not guaranteed to be NULL and might be +- // dangling after being created with `Vec::new`. Instead, we can rely on `Vec`'s capacity +- // to be zero if no memory has been allocated yet. +- let ptr = if cap == 0 { +- core::ptr::null_mut() +- } else { +- old_ptr +- }; +- +- // SAFETY: `ptr` is valid because it's either NULL or comes from a previous call to +- // `krealloc_aligned`. We also verified that the type is not a ZST. +- let new_ptr = unsafe { super::allocator::krealloc_aligned(ptr.cast(), layout, flags) }; +- if new_ptr.is_null() { +- // SAFETY: We are just rebuilding the existing `Vec` with no changes. +- unsafe { rebuild(self, old_ptr, len, cap) }; +- Err(AllocError) +- } else { +- // SAFETY: `ptr` has been reallocated with the layout for `new_cap` elements. New cap +- // is greater than `cap`, so it continues to be >= `len`. +- unsafe { rebuild(self, new_ptr.cast::(), len, new_cap) }; +- Ok(()) +- } +- } +-} +- +-#[cfg(not(any(test, testlib)))] +-fn destructure(v: &mut Vec) -> (*mut T, usize, usize) { +- let mut tmp = Vec::new(); +- core::mem::swap(&mut tmp, v); +- let mut tmp = core::mem::ManuallyDrop::new(tmp); +- let len = tmp.len(); +- let cap = tmp.capacity(); +- (tmp.as_mut_ptr(), len, cap) +-} +- +-/// Rebuilds a `Vec` from a pointer, length, and capacity. +-/// +-/// # Safety +-/// +-/// The same as [`Vec::from_raw_parts`]. +-#[cfg(not(any(test, testlib)))] +-unsafe fn rebuild(v: &mut Vec, ptr: *mut T, len: usize, cap: usize) { +- // SAFETY: The safety requirements from this function satisfy those of `from_raw_parts`. +- let mut tmp = unsafe { Vec::from_raw_parts(ptr, len, cap) }; +- core::mem::swap(&mut tmp, v); +-} +--- a/rust/kernel/prelude.rs ++++ b/rust/kernel/prelude.rs +@@ -14,10 +14,7 @@ + #[doc(no_inline)] + pub use core::pin::Pin; + +-pub use crate::alloc::{flags::*, vec_ext::VecExt, Box, KBox, KVBox, KVVec, KVec, VBox, VVec}; +- +-#[doc(no_inline)] +-pub use alloc::vec::Vec; ++pub use crate::alloc::{flags::*, Box, KBox, KVBox, KVVec, KVec, VBox, VVec}; + + #[doc(no_inline)] + pub use macros::{module, pin_data, pinned_drop, vtable, Zeroable}; diff --git a/queue-6.12/rust-alloc-rename-kernelallocator-to-kmalloc.patch b/queue-6.12/rust-alloc-rename-kernelallocator-to-kmalloc.patch new file mode 100644 index 0000000000..52b2a4175b --- /dev/null +++ b/queue-6.12/rust-alloc-rename-kernelallocator-to-kmalloc.patch @@ -0,0 +1,55 @@ +From stable+bounces-121477-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:40 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:29 +0100 +Subject: rust: alloc: rename `KernelAllocator` to `Kmalloc` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-23-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 941e65531446c1eb5d573c5d30172117ebe96112 upstream. + +Subsequent patches implement `Vmalloc` and `KVmalloc` allocators, hence +align `KernelAllocator` to this naming scheme. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-4-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc/allocator.rs | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/rust/kernel/alloc/allocator.rs ++++ b/rust/kernel/alloc/allocator.rs +@@ -6,7 +6,7 @@ use super::{flags::*, Flags}; + use core::alloc::{GlobalAlloc, Layout}; + use core::ptr; + +-struct KernelAllocator; ++struct Kmalloc; + + /// Returns a proper size to alloc a new object aligned to `new_layout`'s alignment. + fn aligned_size(new_layout: Layout) -> usize { +@@ -37,7 +37,7 @@ pub(crate) unsafe fn krealloc_aligned(pt + } + + // SAFETY: TODO. +-unsafe impl GlobalAlloc for KernelAllocator { ++unsafe impl GlobalAlloc for Kmalloc { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety + // requirement. +@@ -74,7 +74,7 @@ unsafe impl GlobalAlloc for KernelAlloca + } + + #[global_allocator] +-static ALLOCATOR: KernelAllocator = KernelAllocator; ++static ALLOCATOR: Kmalloc = Kmalloc; + + // See . + #[no_mangle] diff --git a/queue-6.12/rust-alloc-separate-aligned_size-from-krealloc_aligned.patch b/queue-6.12/rust-alloc-separate-aligned_size-from-krealloc_aligned.patch new file mode 100644 index 0000000000..ed6ec400ac --- /dev/null +++ b/queue-6.12/rust-alloc-separate-aligned_size-from-krealloc_aligned.patch @@ -0,0 +1,63 @@ +From stable+bounces-121476-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:37 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:28 +0100 +Subject: rust: alloc: separate `aligned_size` from `krealloc_aligned` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-22-ojeda@kernel.org> + +From: Danilo Krummrich + +commit a654a6e09644266e38ac05415ef7737d299c4497 upstream. + +Separate `aligned_size` from `krealloc_aligned`. + +Subsequent patches implement `Allocator` derivates, such as `Kmalloc`, +that require `aligned_size` and replace the original `krealloc_aligned`. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-3-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc/allocator.rs | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/rust/kernel/alloc/allocator.rs ++++ b/rust/kernel/alloc/allocator.rs +@@ -8,6 +8,17 @@ use core::ptr; + + struct KernelAllocator; + ++/// Returns a proper size to alloc a new object aligned to `new_layout`'s alignment. ++fn aligned_size(new_layout: Layout) -> usize { ++ // Customized layouts from `Layout::from_size_align()` can have size < align, so pad first. ++ let layout = new_layout.pad_to_align(); ++ ++ // Note that `layout.size()` (after padding) is guaranteed to be a multiple of `layout.align()` ++ // which together with the slab guarantees means the `krealloc` will return a properly aligned ++ // object (see comments in `kmalloc()` for more information). ++ layout.size() ++} ++ + /// Calls `krealloc` with a proper size to alloc a new object aligned to `new_layout`'s alignment. + /// + /// # Safety +@@ -15,13 +26,7 @@ struct KernelAllocator; + /// - `ptr` can be either null or a pointer which has been allocated by this allocator. + /// - `new_layout` must have a non-zero size. + pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, flags: Flags) -> *mut u8 { +- // Customized layouts from `Layout::from_size_align()` can have size < align, so pad first. +- let layout = new_layout.pad_to_align(); +- +- // Note that `layout.size()` (after padding) is guaranteed to be a multiple of `layout.align()` +- // which together with the slab guarantees means the `krealloc` will return a properly aligned +- // object (see comments in `kmalloc()` for more information). +- let size = layout.size(); ++ let size = aligned_size(new_layout); + + // SAFETY: + // - `ptr` is either null or a pointer returned from a previous `k{re}alloc()` by the diff --git a/queue-6.12/rust-alloc-update-module-comment-of-alloc.rs.patch b/queue-6.12/rust-alloc-update-module-comment-of-alloc.rs.patch new file mode 100644 index 0000000000..df98ffe104 --- /dev/null +++ b/queue-6.12/rust-alloc-update-module-comment-of-alloc.rs.patch @@ -0,0 +1,39 @@ +From stable+bounces-121501-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:59 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:53 +0100 +Subject: rust: alloc: update module comment of alloc.rs +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-47-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 8ae740c3917ff92108df17236b3cf1b9a74bd359 upstream. + +Before we remove Rust's alloc crate, rewrite the module comment in +alloc.rs to avoid a rustdoc warning. + +Besides that, the module comment in alloc.rs isn't correct anymore, +we're no longer extending Rust's alloc crate. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-28-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/alloc.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/rust/kernel/alloc.rs ++++ b/rust/kernel/alloc.rs +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + +-//! Extensions to the [`alloc`] crate. ++//! Implementation of the kernel's memory allocation infrastructure. + + #[cfg(not(any(test, testlib)))] + pub mod allocator; diff --git a/queue-6.12/rust-enable-clippy-ignored_unit_patterns-lint.patch b/queue-6.12/rust-enable-clippy-ignored_unit_patterns-lint.patch new file mode 100644 index 0000000000..544b339d37 --- /dev/null +++ b/queue-6.12/rust-enable-clippy-ignored_unit_patterns-lint.patch @@ -0,0 +1,65 @@ +From stable+bounces-121462-greg=kroah.com@vger.kernel.org Fri Mar 7 23:50:59 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:14 +0100 +Subject: rust: enable `clippy::ignored_unit_patterns` lint +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-8-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 3fcc23397628c2357dbe66df59644e09f72ac725 upstream. + +In Rust 1.73.0, Clippy introduced the `ignored_unit_patterns` lint [1]: + +> Matching with `()` explicitly instead of `_` outlines the fact that +> the pattern contains no data. Also it would detect a type change +> that `_` would ignore. + +There is only a single case that requires a change: + + error: matching over `()` is more explicit + --> rust/kernel/types.rs:176:45 + | + 176 | ScopeGuard::new_with_data((), move |_| cleanup()) + | ^ help: use `()` instead of `_`: `()` + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ignored_unit_patterns + = note: requested on the command line with `-D clippy::ignored-unit-patterns` + +Thus clean it up and enable the lint -- no functional change intended. + +Link: https://rust-lang.github.io/rust-clippy/master/index.html#/ignored_unit_patterns [1] +Reviewed-by: Alice Ryhl +Reviewed-by: Trevor Gross +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-8-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 1 + + rust/kernel/types.rs | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/Makefile ++++ b/Makefile +@@ -453,6 +453,7 @@ export rust_common_flags := --edition=20 + -Wunreachable_pub \ + -Wclippy::all \ + -Wclippy::dbg_macro \ ++ -Wclippy::ignored_unit_patterns \ + -Wclippy::mut_mut \ + -Wclippy::needless_bitwise_bool \ + -Wclippy::needless_continue \ +--- a/rust/kernel/types.rs ++++ b/rust/kernel/types.rs +@@ -225,7 +225,7 @@ impl ScopeGuard { + impl ScopeGuard<(), fn(())> { + /// Creates a new guarded object with the given cleanup function. + pub fn new(cleanup: impl FnOnce()) -> ScopeGuard<(), impl FnOnce(())> { +- ScopeGuard::new_with_data((), move |_| cleanup()) ++ ScopeGuard::new_with_data((), move |()| cleanup()) + } + } + diff --git a/queue-6.12/rust-enable-clippy-s-check-private-items.patch b/queue-6.12/rust-enable-clippy-s-check-private-items.patch new file mode 100644 index 0000000000..5eb5347edc --- /dev/null +++ b/queue-6.12/rust-enable-clippy-s-check-private-items.patch @@ -0,0 +1,100 @@ +From stable+bounces-121469-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:20 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:21 +0100 +Subject: rust: enable Clippy's `check-private-items` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-15-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 624063b9ac97f40cadca32a896aafeb28b1220fd upstream. + +In Rust 1.76.0, Clippy added the `check-private-items` lint configuration +option. When turned on (the default is off), it makes several lints +check private items as well. + +In our case, it affects two lints we have enabled [1]: +`missing_safety_doc` and `unnecessary_safety_doc`. + +It also seems to affect the new `too_long_first_doc_paragraph` lint [2], +even though the documentation does not mention it. + +Thus allow the few instances remaining we currently hit and enable +the lint. + +Link: https://doc.rust-lang.org/nightly/clippy/lint_configuration.html#check-private-items [1] +Link: https://rust-lang.github.io/rust-clippy/master/index.html#/too_long_first_doc_paragraph [2] +Reviewed-by: Trevor Gross +Reviewed-by: Alice Ryhl +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-16-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + .clippy.toml | 2 ++ + rust/kernel/init.rs | 1 + + rust/kernel/init/__internal.rs | 2 ++ + rust/kernel/init/macros.rs | 1 + + rust/kernel/print.rs | 1 + + 5 files changed, 7 insertions(+) + +--- a/.clippy.toml ++++ b/.clippy.toml +@@ -1,5 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + ++check-private-items = true ++ + disallowed-macros = [ + # The `clippy::dbg_macro` lint only works with `std::dbg!`, thus we simulate + # it here, see: https://github.com/rust-lang/rust-clippy/issues/11303. +--- a/rust/kernel/init.rs ++++ b/rust/kernel/init.rs +@@ -125,6 +125,7 @@ + //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin}; + //! # mod bindings { + //! # #![allow(non_camel_case_types)] ++//! # #![allow(clippy::missing_safety_doc)] + //! # pub struct foo; + //! # pub unsafe fn init_foo(_ptr: *mut foo) {} + //! # pub unsafe fn destroy_foo(_ptr: *mut foo) {} +--- a/rust/kernel/init/__internal.rs ++++ b/rust/kernel/init/__internal.rs +@@ -54,6 +54,7 @@ where + pub unsafe trait HasPinData { + type PinData: PinData; + ++ #[allow(clippy::missing_safety_doc)] + unsafe fn __pin_data() -> Self::PinData; + } + +@@ -83,6 +84,7 @@ pub unsafe trait PinData: Copy { + pub unsafe trait HasInitData { + type InitData: InitData; + ++ #[allow(clippy::missing_safety_doc)] + unsafe fn __init_data() -> Self::InitData; + } + +--- a/rust/kernel/init/macros.rs ++++ b/rust/kernel/init/macros.rs +@@ -989,6 +989,7 @@ macro_rules! __pin_data { + // + // The functions are `unsafe` to prevent accidentally calling them. + #[allow(dead_code)] ++ #[allow(clippy::missing_safety_doc)] + impl<$($impl_generics)*> $pin_data<$($ty_generics)*> + where $($whr)* + { +--- a/rust/kernel/print.rs ++++ b/rust/kernel/print.rs +@@ -14,6 +14,7 @@ use core::{ + use crate::str::RawFormatter; + + // Called from `vsprintf` with format specifier `%pA`. ++#[allow(clippy::missing_safety_doc)] + #[no_mangle] + unsafe extern "C" fn rust_fmt_argument( + buf: *mut c_char, diff --git a/queue-6.12/rust-enable-clippy-undocumented_unsafe_blocks-lint.patch b/queue-6.12/rust-enable-clippy-undocumented_unsafe_blocks-lint.patch new file mode 100644 index 0000000000..d72ad51604 --- /dev/null +++ b/queue-6.12/rust-enable-clippy-undocumented_unsafe_blocks-lint.patch @@ -0,0 +1,413 @@ +From stable+bounces-121459-greg=kroah.com@vger.kernel.org Fri Mar 7 23:50:50 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:11 +0100 +Subject: rust: enable `clippy::undocumented_unsafe_blocks` lint +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-5-ojeda@kernel.org> + +From: Miguel Ojeda + +commit db4f72c904cb116e2bf56afdd67fc5167a607a7b upstream. + +Checking that we are not missing any `// SAFETY` comments in our `unsafe` +blocks is something we have wanted to do for a long time, as well as +cleaning up the remaining cases that were not documented [1]. + +Back when Rust for Linux started, this was something that could have +been done via a script, like Rust's `tidy`. Soon after, in Rust 1.58.0, +Clippy implemented the `undocumented_unsafe_blocks` lint [2]. + +Even though the lint has a few false positives, e.g. in some cases where +attributes appear between the comment and the `unsafe` block [3], there +are workarounds and the lint seems quite usable already. + +Thus enable the lint now. + +We still have a few cases to clean up, so just allow those for the moment +by writing a `TODO` comment -- some of those may be good candidates for +new contributors. + +Link: https://github.com/Rust-for-Linux/linux/issues/351 [1] +Link: https://rust-lang.github.io/rust-clippy/master/#/undocumented_unsafe_blocks [2] +Link: https://github.com/rust-lang/rust-clippy/issues/13189 [3] +Reviewed-by: Alice Ryhl +Reviewed-by: Trevor Gross +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-5-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 1 + + mm/kasan/kasan_test_rust.rs | 1 + + rust/bindings/lib.rs | 1 + + rust/kernel/alloc/allocator.rs | 2 ++ + rust/kernel/error.rs | 9 ++++++--- + rust/kernel/init.rs | 5 +++++ + rust/kernel/init/__internal.rs | 2 ++ + rust/kernel/init/macros.rs | 9 +++++++++ + rust/kernel/list.rs | 1 + + rust/kernel/print.rs | 2 ++ + rust/kernel/str.rs | 7 ++++--- + rust/kernel/sync/condvar.rs | 2 +- + rust/kernel/sync/lock.rs | 6 +++--- + rust/kernel/types.rs | 4 ++++ + rust/kernel/workqueue.rs | 4 ++++ + rust/uapi/lib.rs | 1 + + 16 files changed, 47 insertions(+), 10 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -458,6 +458,7 @@ export rust_common_flags := --edition=20 + -Wclippy::needless_continue \ + -Aclippy::needless_lifetimes \ + -Wclippy::no_mangle_with_rust_abi \ ++ -Wclippy::undocumented_unsafe_blocks \ + -Wrustdoc::missing_crate_level_docs + + KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \ +--- a/mm/kasan/kasan_test_rust.rs ++++ b/mm/kasan/kasan_test_rust.rs +@@ -17,5 +17,6 @@ pub extern "C" fn kasan_test_rust_uaf() + } + let ptr: *mut u8 = addr_of_mut!(v[2048]); + drop(v); ++ // SAFETY: Incorrect, on purpose. + unsafe { *ptr } + } +--- a/rust/bindings/lib.rs ++++ b/rust/bindings/lib.rs +@@ -25,6 +25,7 @@ + )] + + #[allow(dead_code)] ++#[allow(clippy::undocumented_unsafe_blocks)] + mod bindings_raw { + // Use glob import here to expose all helpers. + // Symbols defined within the module will take precedence to the glob import. +--- a/rust/kernel/alloc/allocator.rs ++++ b/rust/kernel/alloc/allocator.rs +@@ -31,6 +31,7 @@ pub(crate) unsafe fn krealloc_aligned(pt + unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags.0) as *mut u8 } + } + ++// SAFETY: TODO. + unsafe impl GlobalAlloc for KernelAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety +@@ -39,6 +40,7 @@ unsafe impl GlobalAlloc for KernelAlloca + } + + unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { ++ // SAFETY: TODO. + unsafe { + bindings::kfree(ptr as *const core::ffi::c_void); + } +--- a/rust/kernel/error.rs ++++ b/rust/kernel/error.rs +@@ -171,9 +171,11 @@ impl fmt::Debug for Error { + match self.name() { + // Print out number if no name can be found. + None => f.debug_tuple("Error").field(&-self.0).finish(), +- // SAFETY: These strings are ASCII-only. + Some(name) => f +- .debug_tuple(unsafe { core::str::from_utf8_unchecked(name) }) ++ .debug_tuple( ++ // SAFETY: These strings are ASCII-only. ++ unsafe { core::str::from_utf8_unchecked(name) }, ++ ) + .finish(), + } + } +@@ -277,6 +279,8 @@ pub(crate) fn from_err_ptr(ptr: *mut + if unsafe { bindings::IS_ERR(const_ptr) } { + // SAFETY: The FFI function does not deref the pointer. + let err = unsafe { bindings::PTR_ERR(const_ptr) }; ++ ++ #[allow(clippy::unnecessary_cast)] + // CAST: If `IS_ERR()` returns `true`, + // then `PTR_ERR()` is guaranteed to return a + // negative value greater-or-equal to `-bindings::MAX_ERRNO`, +@@ -286,7 +290,6 @@ pub(crate) fn from_err_ptr(ptr: *mut + // + // SAFETY: `IS_ERR()` ensures `err` is a + // negative value greater-or-equal to `-bindings::MAX_ERRNO`. +- #[allow(clippy::unnecessary_cast)] + return Err(unsafe { Error::from_errno_unchecked(err as core::ffi::c_int) }); + } + Ok(ptr) +--- a/rust/kernel/init.rs ++++ b/rust/kernel/init.rs +@@ -541,6 +541,7 @@ macro_rules! stack_try_pin_init { + /// } + /// pin_init!(&this in Buf { + /// buf: [0; 64], ++/// // SAFETY: TODO. + /// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() }, + /// pin: PhantomPinned, + /// }); +@@ -875,6 +876,7 @@ pub unsafe trait PinInit Init for T { + unsafe fn __init(self, slot: *mut T) -> Result<(), E> { ++ // SAFETY: TODO. + unsafe { slot.write(self) }; + Ok(()) + } +@@ -1170,6 +1173,7 @@ unsafe impl Init for T { + // SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`. + unsafe impl PinInit for T { + unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { ++ // SAFETY: TODO. + unsafe { self.__init(slot) } + } + } +@@ -1411,6 +1415,7 @@ pub fn zeroed() -> impl Ini + + macro_rules! impl_zeroable { + ($($({$($generics:tt)*})? $t:ty, )*) => { ++ // SAFETY: Safety comments written in the macro invocation. + $(unsafe impl$($($generics)*)? Zeroable for $t {})* + }; + } +--- a/rust/kernel/init/__internal.rs ++++ b/rust/kernel/init/__internal.rs +@@ -112,10 +112,12 @@ impl Clone for AllData { + + impl Copy for AllData {} + ++// SAFETY: TODO. + unsafe impl InitData for AllData { + type Datee = T; + } + ++// SAFETY: TODO. + unsafe impl HasInitData for T { + type InitData = AllData; + +--- a/rust/kernel/init/macros.rs ++++ b/rust/kernel/init/macros.rs +@@ -513,6 +513,7 @@ macro_rules! __pinned_drop { + } + ), + ) => { ++ // SAFETY: TODO. + unsafe $($impl_sig)* { + // Inherit all attributes and the type/ident tokens for the signature. + $(#[$($attr)*])* +@@ -872,6 +873,7 @@ macro_rules! __pin_data { + } + } + ++ // SAFETY: TODO. + unsafe impl<$($impl_generics)*> + $crate::init::__internal::PinData for __ThePinData<$($ty_generics)*> + where $($whr)* +@@ -997,6 +999,7 @@ macro_rules! __pin_data { + slot: *mut $p_type, + init: impl $crate::init::PinInit<$p_type, E>, + ) -> ::core::result::Result<(), E> { ++ // SAFETY: TODO. + unsafe { $crate::init::PinInit::__pinned_init(init, slot) } + } + )* +@@ -1007,6 +1010,7 @@ macro_rules! __pin_data { + slot: *mut $type, + init: impl $crate::init::Init<$type, E>, + ) -> ::core::result::Result<(), E> { ++ // SAFETY: TODO. + unsafe { $crate::init::Init::__init(init, slot) } + } + )* +@@ -1121,6 +1125,8 @@ macro_rules! __init_internal { + // no possibility of returning without `unsafe`. + struct __InitOk; + // Get the data about fields from the supplied type. ++ // ++ // SAFETY: TODO. + let data = unsafe { + use $crate::init::__internal::$has_data; + // Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal +@@ -1176,6 +1182,7 @@ macro_rules! __init_internal { + let init = move |slot| -> ::core::result::Result<(), $err> { + init(slot).map(|__InitOk| ()) + }; ++ // SAFETY: TODO. + let init = unsafe { $crate::init::$construct_closure::<_, $err>(init) }; + init + }}; +@@ -1324,6 +1331,8 @@ macro_rules! __init_internal { + // Endpoint, nothing more to munch, create the initializer. + // Since we are in the closure that is never called, this will never get executed. + // We abuse `slot` to get the correct type inference here: ++ // ++ // SAFETY: TODO. + unsafe { + // Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal + // information that is associated to already parsed fragments, so a path fragment +--- a/rust/kernel/list.rs ++++ b/rust/kernel/list.rs +@@ -354,6 +354,7 @@ impl, const ID: + /// + /// `item` must not be in a different linked list (with the same id). + pub unsafe fn remove(&mut self, item: &T) -> Option> { ++ // SAFETY: TODO. + let mut item = unsafe { ListLinks::fields(T::view_links(item)) }; + // SAFETY: The user provided a reference, and reference are never dangling. + // +--- a/rust/kernel/print.rs ++++ b/rust/kernel/print.rs +@@ -23,6 +23,7 @@ unsafe extern "C" fn rust_fmt_argument( + use fmt::Write; + // SAFETY: The C contract guarantees that `buf` is valid if it's less than `end`. + let mut w = unsafe { RawFormatter::from_ptrs(buf.cast(), end.cast()) }; ++ // SAFETY: TODO. + let _ = w.write_fmt(unsafe { *(ptr as *const fmt::Arguments<'_>) }); + w.pos().cast() + } +@@ -102,6 +103,7 @@ pub unsafe fn call_printk( + ) { + // `_printk` does not seem to fail in any path. + #[cfg(CONFIG_PRINTK)] ++ // SAFETY: TODO. + unsafe { + bindings::_printk( + format_string.as_ptr() as _, +--- a/rust/kernel/str.rs ++++ b/rust/kernel/str.rs +@@ -162,10 +162,10 @@ impl CStr { + /// Returns the length of this string with `NUL`. + #[inline] + pub const fn len_with_nul(&self) -> usize { +- // SAFETY: This is one of the invariant of `CStr`. +- // We add a `unreachable_unchecked` here to hint the optimizer that +- // the value returned from this function is non-zero. + if self.0.is_empty() { ++ // SAFETY: This is one of the invariant of `CStr`. ++ // We add a `unreachable_unchecked` here to hint the optimizer that ++ // the value returned from this function is non-zero. + unsafe { core::hint::unreachable_unchecked() }; + } + self.0.len() +@@ -301,6 +301,7 @@ impl CStr { + /// ``` + #[inline] + pub unsafe fn as_str_unchecked(&self) -> &str { ++ // SAFETY: TODO. + unsafe { core::str::from_utf8_unchecked(self.as_bytes()) } + } + +--- a/rust/kernel/sync/condvar.rs ++++ b/rust/kernel/sync/condvar.rs +@@ -92,8 +92,8 @@ pub struct CondVar { + _pin: PhantomPinned, + } + +-// SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on any thread. + #[allow(clippy::non_send_fields_in_send_ty)] ++// SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on any thread. + unsafe impl Send for CondVar {} + + // SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on multiple threads +--- a/rust/kernel/sync/lock.rs ++++ b/rust/kernel/sync/lock.rs +@@ -150,9 +150,9 @@ impl Guard<'_, T, + // SAFETY: The caller owns the lock, so it is safe to unlock it. + unsafe { B::unlock(self.lock.state.get(), &self.state) }; + +- // SAFETY: The lock was just unlocked above and is being relocked now. +- let _relock = +- ScopeGuard::new(|| unsafe { B::relock(self.lock.state.get(), &mut self.state) }); ++ let _relock = ScopeGuard::new(|| ++ // SAFETY: The lock was just unlocked above and is being relocked now. ++ unsafe { B::relock(self.lock.state.get(), &mut self.state) }); + + cb() + } +--- a/rust/kernel/types.rs ++++ b/rust/kernel/types.rs +@@ -410,6 +410,7 @@ impl ARef { + /// + /// struct Empty {} + /// ++ /// # // SAFETY: TODO. + /// unsafe impl AlwaysRefCounted for Empty { + /// fn inc_ref(&self) {} + /// unsafe fn dec_ref(_obj: NonNull) {} +@@ -417,6 +418,7 @@ impl ARef { + /// + /// let mut data = Empty {}; + /// let ptr = NonNull::::new(&mut data as *mut _).unwrap(); ++ /// # // SAFETY: TODO. + /// let data_ref: ARef = unsafe { ARef::from_raw(ptr) }; + /// let raw_ptr: NonNull = ARef::into_raw(data_ref); + /// +@@ -483,6 +485,7 @@ pub unsafe trait FromBytes {} + + macro_rules! impl_frombytes { + ($($({$($generics:tt)*})? $t:ty, )*) => { ++ // SAFETY: Safety comments written in the macro invocation. + $(unsafe impl$($($generics)*)? FromBytes for $t {})* + }; + } +@@ -517,6 +520,7 @@ pub unsafe trait AsBytes {} + + macro_rules! impl_asbytes { + ($($({$($generics:tt)*})? $t:ty, )*) => { ++ // SAFETY: Safety comments written in the macro invocation. + $(unsafe impl$($($generics)*)? AsBytes for $t {})* + }; + } +--- a/rust/kernel/workqueue.rs ++++ b/rust/kernel/workqueue.rs +@@ -519,6 +519,7 @@ impl_has_work! { + impl{T} HasWork for ClosureWork { self.work } + } + ++// SAFETY: TODO. + unsafe impl WorkItemPointer for Arc + where + T: WorkItem, +@@ -536,6 +537,7 @@ where + } + } + ++// SAFETY: TODO. + unsafe impl RawWorkItem for Arc + where + T: WorkItem, +@@ -564,6 +566,7 @@ where + } + } + ++// SAFETY: TODO. + unsafe impl WorkItemPointer for Pin> + where + T: WorkItem, +@@ -583,6 +586,7 @@ where + } + } + ++// SAFETY: TODO. + unsafe impl RawWorkItem for Pin> + where + T: WorkItem, +--- a/rust/uapi/lib.rs ++++ b/rust/uapi/lib.rs +@@ -14,6 +14,7 @@ + #![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))] + #![allow( + clippy::all, ++ clippy::undocumented_unsafe_blocks, + dead_code, + missing_docs, + non_camel_case_types, diff --git a/queue-6.12/rust-enable-clippy-unnecessary_safety_comment-lint.patch b/queue-6.12/rust-enable-clippy-unnecessary_safety_comment-lint.patch new file mode 100644 index 0000000000..091c1bddf5 --- /dev/null +++ b/queue-6.12/rust-enable-clippy-unnecessary_safety_comment-lint.patch @@ -0,0 +1,77 @@ +From stable+bounces-121460-greg=kroah.com@vger.kernel.org Fri Mar 7 23:50:52 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:12 +0100 +Subject: rust: enable `clippy::unnecessary_safety_comment` lint +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-6-ojeda@kernel.org> + +From: Miguel Ojeda + +commit c28bfe76e4ba707775a205b0274710de7aa1e31c upstream. + +In Rust 1.67.0, Clippy added the `unnecessary_safety_comment` lint [1], +which is the "inverse" of `undocumented_unsafe_blocks`: it finds places +where safe code has a `// SAFETY` comment attached. + +The lint currently finds 3 places where we had such mistakes, thus it +seems already quite useful. + +Thus clean those and enable it. + +Link: https://rust-lang.github.io/rust-clippy/master/index.html#/unnecessary_safety_comment [1] +Reviewed-by: Alice Ryhl +Reviewed-by: Trevor Gross +Reviewed-by: Vincenzo Palazzo +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-6-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 1 + + rust/kernel/sync/arc.rs | 2 +- + rust/kernel/workqueue.rs | 4 ++-- + 3 files changed, 4 insertions(+), 3 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -459,6 +459,7 @@ export rust_common_flags := --edition=20 + -Aclippy::needless_lifetimes \ + -Wclippy::no_mangle_with_rust_abi \ + -Wclippy::undocumented_unsafe_blocks \ ++ -Wclippy::unnecessary_safety_comment \ + -Wrustdoc::missing_crate_level_docs + + KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \ +--- a/rust/kernel/sync/arc.rs ++++ b/rust/kernel/sync/arc.rs +@@ -338,7 +338,7 @@ impl ForeignOwnable for Arc< + } + + unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> ArcBorrow<'a, T> { +- // SAFETY: By the safety requirement of this function, we know that `ptr` came from ++ // By the safety requirement of this function, we know that `ptr` came from + // a previous call to `Arc::into_foreign`. + let inner = NonNull::new(ptr as *mut ArcInner).unwrap(); + +--- a/rust/kernel/workqueue.rs ++++ b/rust/kernel/workqueue.rs +@@ -526,7 +526,7 @@ where + T: HasWork, + { + unsafe extern "C" fn run(ptr: *mut bindings::work_struct) { +- // SAFETY: The `__enqueue` method always uses a `work_struct` stored in a `Work`. ++ // The `__enqueue` method always uses a `work_struct` stored in a `Work`. + let ptr = ptr as *mut Work; + // SAFETY: This computes the pointer that `__enqueue` got from `Arc::into_raw`. + let ptr = unsafe { T::work_container_of(ptr) }; +@@ -573,7 +573,7 @@ where + T: HasWork, + { + unsafe extern "C" fn run(ptr: *mut bindings::work_struct) { +- // SAFETY: The `__enqueue` method always uses a `work_struct` stored in a `Work`. ++ // The `__enqueue` method always uses a `work_struct` stored in a `Work`. + let ptr = ptr as *mut Work; + // SAFETY: This computes the pointer that `__enqueue` got from `Arc::into_raw`. + let ptr = unsafe { T::work_container_of(ptr) }; diff --git a/queue-6.12/rust-enable-clippy-unnecessary_safety_doc-lint.patch b/queue-6.12/rust-enable-clippy-unnecessary_safety_doc-lint.patch new file mode 100644 index 0000000000..305fc2809c --- /dev/null +++ b/queue-6.12/rust-enable-clippy-unnecessary_safety_doc-lint.patch @@ -0,0 +1,41 @@ +From stable+bounces-121461-greg=kroah.com@vger.kernel.org Fri Mar 7 23:50:58 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:13 +0100 +Subject: rust: enable `clippy::unnecessary_safety_doc` lint +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-7-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 23f42dc054b3c550373eae0c9ae97f1ce1501e0a upstream. + +In Rust 1.67.0, Clippy added the `unnecessary_safety_doc` lint [1], +which is similar to `unnecessary_safety_comment`, but for `# Safety` +sections, i.e. safety preconditions in the documentation. + +This is something that should not happen with our coding guidelines in +mind. Thus enable the lint to have it machine-checked. + +Link: https://rust-lang.github.io/rust-clippy/master/index.html#/unnecessary_safety_doc [1] +Reviewed-by: Trevor Gross +Reviewed-by: Alice Ryhl +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-7-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 1 + + 1 file changed, 1 insertion(+) + +--- a/Makefile ++++ b/Makefile +@@ -460,6 +460,7 @@ export rust_common_flags := --edition=20 + -Wclippy::no_mangle_with_rust_abi \ + -Wclippy::undocumented_unsafe_blocks \ + -Wclippy::unnecessary_safety_comment \ ++ -Wclippy::unnecessary_safety_doc \ + -Wrustdoc::missing_crate_level_docs + + KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \ diff --git a/queue-6.12/rust-enable-rustdoc-unescaped_backticks-lint.patch b/queue-6.12/rust-enable-rustdoc-unescaped_backticks-lint.patch new file mode 100644 index 0000000000..f0f497117a --- /dev/null +++ b/queue-6.12/rust-enable-rustdoc-unescaped_backticks-lint.patch @@ -0,0 +1,74 @@ +From stable+bounces-121463-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:00 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:15 +0100 +Subject: rust: enable `rustdoc::unescaped_backticks` lint +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-9-ojeda@kernel.org> + +From: Miguel Ojeda + +commit bef83245f5ed434932aaf07f890142b576dc5d85 upstream. + +In Rust 1.71.0, `rustdoc` added the `unescaped_backticks` lint, which +detects what are typically typos in Markdown formatting regarding inline +code [1], e.g. from the Rust standard library: + + /// ... to `deref`/`deref_mut`` must ... + + /// ... use [`from_mut`]`. Specifically, ... + +It does not seem to have almost any false positives, from the experience +of enabling it in the Rust standard library [2], which will be checked +starting with Rust 1.82.0. The maintainers also confirmed it is ready +to be used. + +Thus enable it. + +Link: https://doc.rust-lang.org/rustdoc/lints.html#unescaped_backticks [1] +Link: https://github.com/rust-lang/rust/pull/128307 [2] +Reviewed-by: Trevor Gross +Reviewed-by: Alice Ryhl +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-9-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 3 ++- + rust/Makefile | 5 ++++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -462,7 +462,8 @@ export rust_common_flags := --edition=20 + -Wclippy::undocumented_unsafe_blocks \ + -Wclippy::unnecessary_safety_comment \ + -Wclippy::unnecessary_safety_doc \ +- -Wrustdoc::missing_crate_level_docs ++ -Wrustdoc::missing_crate_level_docs \ ++ -Wrustdoc::unescaped_backticks + + KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \ + $(HOSTCFLAGS) -I $(srctree)/scripts/include +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -61,7 +61,7 @@ alloc-cfgs = \ + quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< + cmd_rustdoc = \ + OBJTREE=$(abspath $(objtree)) \ +- $(RUSTDOC) $(if $(rustdoc_host),$(rust_common_flags),$(rust_flags)) \ ++ $(RUSTDOC) $(filter-out $(skip_flags),$(if $(rustdoc_host),$(rust_common_flags),$(rust_flags))) \ + $(rustc_target_flags) -L$(objtree)/$(obj) \ + -Zunstable-options --generate-link-to-definition \ + --output $(rustdoc_output) \ +@@ -98,6 +98,9 @@ rustdoc-macros: private rustc_target_fla + rustdoc-macros: $(src)/macros/lib.rs FORCE + +$(call if_changed,rustdoc) + ++# Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should ++# not be needed -- see https://github.com/rust-lang/rust/pull/128307. ++rustdoc-core: private skip_flags = -Wrustdoc::unescaped_backticks + rustdoc-core: private rustc_target_flags = $(core-cfgs) + rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE + +$(call if_changed,rustdoc) diff --git a/queue-6.12/rust-error-check-for-config-test-in-error-name.patch b/queue-6.12/rust-error-check-for-config-test-in-error-name.patch new file mode 100644 index 0000000000..53dc14c288 --- /dev/null +++ b/queue-6.12/rust-error-check-for-config-test-in-error-name.patch @@ -0,0 +1,47 @@ +From stable+bounces-121497-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:54 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:49 +0100 +Subject: rust: error: check for config `test` in `Error::name` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-43-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 4a28ab469ff01855eb819dfd94754d1792f03f2a upstream. + +Additional to `testlib` also check for `test` in `Error::name`. This is +required by a subsequent patch that (indirectly) uses `Error` in test +cases. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-24-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/error.rs | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/rust/kernel/error.rs ++++ b/rust/kernel/error.rs +@@ -161,7 +161,7 @@ impl Error { + } + + /// Returns a string representing the error, if one exists. +- #[cfg(not(testlib))] ++ #[cfg(not(any(test, testlib)))] + pub fn name(&self) -> Option<&'static CStr> { + // SAFETY: Just an FFI call, there are no extra safety requirements. + let ptr = unsafe { bindings::errname(-self.0.get()) }; +@@ -178,7 +178,7 @@ impl Error { + /// When `testlib` is configured, this always returns `None` to avoid the dependency on a + /// kernel function so that tests that use this (e.g., by calling [`Result::unwrap`]) can still + /// run in userspace. +- #[cfg(testlib)] ++ #[cfg(any(test, testlib))] + pub fn name(&self) -> Option<&'static CStr> { + None + } diff --git a/queue-6.12/rust-error-make-conversion-functions-public.patch b/queue-6.12/rust-error-make-conversion-functions-public.patch new file mode 100644 index 0000000000..d96462a07b --- /dev/null +++ b/queue-6.12/rust-error-make-conversion-functions-public.patch @@ -0,0 +1,71 @@ +From stable+bounces-121473-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:29 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:25 +0100 +Subject: rust: error: make conversion functions public +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-19-ojeda@kernel.org> + +From: Filipe Xavier + +commit 5ed147473458f8c20f908a03227d8f5bb3cb8f7d upstream. + +Change visibility to public of functions in error.rs: +from_err_ptr, from_errno, from_result and to_ptr. +Additionally, remove dead_code annotations. + +Link: https://github.com/Rust-for-Linux/linux/issues/1105 +Reviewed-by: Alice Ryhl +Signed-off-by: Filipe Xavier +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/DM4PR14MB7276E6948E67B3B23D8EA847E9652@DM4PR14MB7276.namprd14.prod.outlook.com +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/error.rs | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +--- a/rust/kernel/error.rs ++++ b/rust/kernel/error.rs +@@ -95,7 +95,7 @@ impl Error { + /// + /// It is a bug to pass an out-of-range `errno`. `EINVAL` would + /// be returned in such a case. +- pub(crate) fn from_errno(errno: core::ffi::c_int) -> Error { ++ pub fn from_errno(errno: core::ffi::c_int) -> Error { + if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 { + // TODO: Make it a `WARN_ONCE` once available. + crate::pr_warn!( +@@ -133,8 +133,7 @@ impl Error { + } + + /// Returns the error encoded as a pointer. +- #[expect(dead_code)] +- pub(crate) fn to_ptr(self) -> *mut T { ++ pub fn to_ptr(self) -> *mut T { + #[cfg_attr(target_pointer_width = "32", allow(clippy::useless_conversion))] + // SAFETY: `self.0` is a valid error due to its invariant. + unsafe { +@@ -270,9 +269,7 @@ pub fn to_result(err: core::ffi::c_int) + /// from_err_ptr(unsafe { bindings::devm_platform_ioremap_resource(pdev.to_ptr(), index) }) + /// } + /// ``` +-// TODO: Remove `dead_code` marker once an in-kernel client is available. +-#[allow(dead_code)] +-pub(crate) fn from_err_ptr(ptr: *mut T) -> Result<*mut T> { ++pub fn from_err_ptr(ptr: *mut T) -> Result<*mut T> { + // CAST: Casting a pointer to `*const core::ffi::c_void` is always valid. + let const_ptr: *const core::ffi::c_void = ptr.cast(); + // SAFETY: The FFI function does not deref the pointer. +@@ -318,9 +315,7 @@ pub(crate) fn from_err_ptr(ptr: *mut + /// }) + /// } + /// ``` +-// TODO: Remove `dead_code` marker once an in-kernel client is available. +-#[allow(dead_code)] +-pub(crate) fn from_result(f: F) -> T ++pub fn from_result(f: F) -> T + where + T: From, + F: FnOnce() -> Result, diff --git a/queue-6.12/rust-error-optimize-error-type-to-use-nonzero.patch b/queue-6.12/rust-error-optimize-error-type-to-use-nonzero.patch new file mode 100644 index 0000000000..9414b87866 --- /dev/null +++ b/queue-6.12/rust-error-optimize-error-type-to-use-nonzero.patch @@ -0,0 +1,132 @@ +From stable+bounces-121474-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:30 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:26 +0100 +Subject: rust: error: optimize error type to use nonzero +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-20-ojeda@kernel.org> + +From: Filipe Xavier + +commit e9759c5b9ea555d09f426c70c880e9522e9b0576 upstream. + +Optimize `Result<(), Error>` size by changing `Error` type to +`NonZero*` for niche optimization. + +This reduces the space used by the `Result` type, as the `NonZero*` +type enables the compiler to apply more efficient memory layout. +For example, the `Result<(), Error>` changes size from 8 to 4 bytes. + +Link: https://github.com/Rust-for-Linux/linux/issues/1120 +Signed-off-by: Filipe Xavier +Reviewed-by: Gary Guo +Reviewed-by: Alice Ryhl +Reviewed-by: Fiona Behrens +Link: https://lore.kernel.org/r/BL0PR02MB4914B9B088865CF237731207E9732@BL0PR02MB4914.namprd02.prod.outlook.com +[ Removed unneeded block around `match`, added backticks in panic + message and added intra-doc link. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/error.rs | 37 ++++++++++++++++++++++++++++--------- + 1 file changed, 28 insertions(+), 9 deletions(-) + +--- a/rust/kernel/error.rs ++++ b/rust/kernel/error.rs +@@ -9,6 +9,7 @@ use crate::{alloc::AllocError, str::CStr + use alloc::alloc::LayoutError; + + use core::fmt; ++use core::num::NonZeroI32; + use core::num::TryFromIntError; + use core::str::Utf8Error; + +@@ -20,7 +21,11 @@ pub mod code { + $( + #[doc = $doc] + )* +- pub const $err: super::Error = super::Error(-(crate::bindings::$err as i32)); ++ pub const $err: super::Error = ++ match super::Error::try_from_errno(-(crate::bindings::$err as i32)) { ++ Some(err) => err, ++ None => panic!("Invalid errno in `declare_err!`"), ++ }; + }; + } + +@@ -88,7 +93,7 @@ pub mod code { + /// + /// The value is a valid `errno` (i.e. `>= -MAX_ERRNO && < 0`). + #[derive(Clone, Copy, PartialEq, Eq)] +-pub struct Error(core::ffi::c_int); ++pub struct Error(NonZeroI32); + + impl Error { + /// Creates an [`Error`] from a kernel error code. +@@ -107,7 +112,20 @@ impl Error { + + // INVARIANT: The check above ensures the type invariant + // will hold. +- Error(errno) ++ // SAFETY: `errno` is checked above to be in a valid range. ++ unsafe { Error::from_errno_unchecked(errno) } ++ } ++ ++ /// Creates an [`Error`] from a kernel error code. ++ /// ++ /// Returns [`None`] if `errno` is out-of-range. ++ const fn try_from_errno(errno: core::ffi::c_int) -> Option { ++ if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 { ++ return None; ++ } ++ ++ // SAFETY: `errno` is checked above to be in a valid range. ++ Some(unsafe { Error::from_errno_unchecked(errno) }) + } + + /// Creates an [`Error`] from a kernel error code. +@@ -115,21 +133,22 @@ impl Error { + /// # Safety + /// + /// `errno` must be within error code range (i.e. `>= -MAX_ERRNO && < 0`). +- unsafe fn from_errno_unchecked(errno: core::ffi::c_int) -> Error { ++ const unsafe fn from_errno_unchecked(errno: core::ffi::c_int) -> Error { + // INVARIANT: The contract ensures the type invariant + // will hold. +- Error(errno) ++ // SAFETY: The caller guarantees `errno` is non-zero. ++ Error(unsafe { NonZeroI32::new_unchecked(errno) }) + } + + /// Returns the kernel error code. + pub fn to_errno(self) -> core::ffi::c_int { +- self.0 ++ self.0.get() + } + + #[cfg(CONFIG_BLOCK)] + pub(crate) fn to_blk_status(self) -> bindings::blk_status_t { + // SAFETY: `self.0` is a valid error due to its invariant. +- unsafe { bindings::errno_to_blk_status(self.0) } ++ unsafe { bindings::errno_to_blk_status(self.0.get()) } + } + + /// Returns the error encoded as a pointer. +@@ -137,7 +156,7 @@ impl Error { + #[cfg_attr(target_pointer_width = "32", allow(clippy::useless_conversion))] + // SAFETY: `self.0` is a valid error due to its invariant. + unsafe { +- bindings::ERR_PTR(self.0.into()) as *mut _ ++ bindings::ERR_PTR(self.0.get().into()) as *mut _ + } + } + +@@ -145,7 +164,7 @@ impl Error { + #[cfg(not(testlib))] + pub fn name(&self) -> Option<&'static CStr> { + // SAFETY: Just an FFI call, there are no extra safety requirements. +- let ptr = unsafe { bindings::errname(-self.0) }; ++ let ptr = unsafe { bindings::errname(-self.0.get()) }; + if ptr.is_null() { + None + } else { diff --git a/queue-6.12/rust-error-use-core-alloc-layouterror.patch b/queue-6.12/rust-error-use-core-alloc-layouterror.patch new file mode 100644 index 0000000000..2d57f73c26 --- /dev/null +++ b/queue-6.12/rust-error-use-core-alloc-layouterror.patch @@ -0,0 +1,37 @@ +From stable+bounces-121496-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:38 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:48 +0100 +Subject: rust: error: use `core::alloc::LayoutError` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-42-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 29a48d25ff53c183482dc88a99133a0fb5aa541a upstream. + +Use `core::alloc::LayoutError` instead of `alloc::alloc::LayoutError` in +preparation to get rid of Rust's alloc crate. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-23-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/error.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/rust/kernel/error.rs ++++ b/rust/kernel/error.rs +@@ -6,7 +6,7 @@ + + use crate::{alloc::AllocError, str::CStr}; + +-use alloc::alloc::LayoutError; ++use core::alloc::LayoutError; + + use core::fmt; + use core::num::NonZeroI32; diff --git a/queue-6.12/rust-fix-size_t-in-bindgen-prototypes-of-c-builtins.patch b/queue-6.12/rust-fix-size_t-in-bindgen-prototypes-of-c-builtins.patch new file mode 100644 index 0000000000..2951cccbc7 --- /dev/null +++ b/queue-6.12/rust-fix-size_t-in-bindgen-prototypes-of-c-builtins.patch @@ -0,0 +1,70 @@ +From stable+bounces-121512-greg=kroah.com@vger.kernel.org Fri Mar 7 23:53:18 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:50:04 +0100 +Subject: rust: fix size_t in bindgen prototypes of C builtins +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-58-ojeda@kernel.org> + +From: Gary Guo + +commit 75c1fd41a671a0843b89d1526411a837a7163fa2 upstream. + +Without `-fno-builtin`, for functions like memcpy/memmove (and many +others), bindgen seems to be using the clang-provided prototype. This +prototype is ABI-wise compatible, but the issue is that it does not have +the same information as the source code w.r.t. typedefs. + +For example, bindgen generates the following: + + extern "C" { + pub fn strlen(s: *const core::ffi::c_char) -> core::ffi::c_ulong; + } + +note that the return type is `c_ulong` (i.e. unsigned long), despite the +size_t-is-usize behavior (this is default, and we have not opted out +from it using --no-size_t-is-usize). + +Similarly, memchr's size argument should be of type `__kernel_size_t`, +but bindgen generates `c_ulong` directly. + +We want to ensure any `size_t` is translated to Rust `usize` so that we +can avoid having them be different type on 32-bit and 64-bit +architectures, and hence would require a lot of excessive type casts +when calling FFI functions. + +I found that this bindgen behavior (which probably is caused by +libclang) can be disabled by `-fno-builtin`. Using the flag for compiled +code can result in less optimisation because compiler cannot assume +about their properties anymore, but this should not affect bindgen. + +[ Trevor asked: "I wonder how reliable this behavior is. Maybe bindgen + could do a better job controlling this, is there an open issue?". + + Gary replied: ..."apparently this is indeed the suggested approach in + https://github.com/rust-lang/rust-bindgen/issues/1770". - Miguel ] + +Signed-off-by: Gary Guo +Link: https://lore.kernel.org/r/20240913213041.395655-2-gary@garyguo.net +[ Formatted comment. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/Makefile | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -264,7 +264,11 @@ else + bindgen_c_flags_lto = $(bindgen_c_flags) + endif + +-bindgen_c_flags_final = $(bindgen_c_flags_lto) -D__BINDGEN__ ++# `-fno-builtin` is passed to avoid `bindgen` from using `clang` builtin ++# prototypes for functions like `memcpy` -- if this flag is not passed, ++# `bindgen`-generated prototypes use `c_ulong` or `c_uint` depending on ++# architecture instead of generating `usize`. ++bindgen_c_flags_final = $(bindgen_c_flags_lto) -fno-builtin -D__BINDGEN__ + + # Each `bindgen` release may upgrade the list of Rust target versions. By + # default, the highest stable release in their list is used. Thus we need to set diff --git a/queue-6.12/rust-init-remove-unneeded.patch b/queue-6.12/rust-init-remove-unneeded.patch new file mode 100644 index 0000000000..929190b8f0 --- /dev/null +++ b/queue-6.12/rust-init-remove-unneeded.patch @@ -0,0 +1,61 @@ +From stable+bounces-121464-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:07 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:16 +0100 +Subject: rust: init: remove unneeded `#[allow(clippy::disallowed_names)]` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-10-ojeda@kernel.org> + +From: Miguel Ojeda + +commit d5cc7ab0a0a99496de1bd933dac242699a417809 upstream. + +These few cases, unlike others in the same file, did not need the `allow`. + +Thus clean them up. + +Reviewed-by: Alice Ryhl +Reviewed-by: Trevor Gross +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-10-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/init.rs | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/rust/kernel/init.rs ++++ b/rust/kernel/init.rs +@@ -87,7 +87,6 @@ + //! To declare an init macro/function you just return an [`impl PinInit`]: + //! + //! ```rust +-//! # #![allow(clippy::disallowed_names)] + //! # use kernel::{sync::Mutex, new_mutex, init::PinInit, try_pin_init}; + //! #[pin_data] + //! struct DriverData { +@@ -368,7 +367,6 @@ macro_rules! stack_try_pin_init { + /// The syntax is almost identical to that of a normal `struct` initializer: + /// + /// ```rust +-/// # #![allow(clippy::disallowed_names)] + /// # use kernel::{init, pin_init, macros::pin_data, init::*}; + /// # use core::pin::Pin; + /// #[pin_data] +@@ -413,7 +411,6 @@ macro_rules! stack_try_pin_init { + /// To create an initializer function, simply declare it like this: + /// + /// ```rust +-/// # #![allow(clippy::disallowed_names)] + /// # use kernel::{init, pin_init, init::*}; + /// # use core::pin::Pin; + /// # #[pin_data] +@@ -468,7 +465,6 @@ macro_rules! stack_try_pin_init { + /// They can also easily embed it into their own `struct`s: + /// + /// ```rust +-/// # #![allow(clippy::disallowed_names)] + /// # use kernel::{init, pin_init, macros::pin_data, init::*}; + /// # use core::pin::Pin; + /// # #[pin_data] diff --git a/queue-6.12/rust-introduce-.clippy.toml.patch b/queue-6.12/rust-introduce-.clippy.toml.patch new file mode 100644 index 0000000000..fbd50b3980 --- /dev/null +++ b/queue-6.12/rust-introduce-.clippy.toml.patch @@ -0,0 +1,75 @@ +From stable+bounces-121466-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:09 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:18 +0100 +Subject: rust: introduce `.clippy.toml` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-12-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 7d56786edcbdf58b6367fd7f01d5861214ad1c95 upstream. + +Some Clippy lints can be configured/tweaked. We will use these knobs to +our advantage in later commits. + +This is done via a configuration file, `.clippy.toml` [1]. The file is +currently unstable. This may be a problem in the future, but we can adapt +as needed. In addition, we proposed adding Clippy to the Rust CI's RFL +job [2], so we should be able to catch issues pre-merge. + +Thus introduce the file. + +Link: https://doc.rust-lang.org/clippy/configuration.html [1] +Link: https://github.com/rust-lang/rust/pull/128928 [2] +Reviewed-by: Alice Ryhl +Reviewed-by: Trevor Gross +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-12-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + .clippy.toml | 1 + + .gitignore | 1 + + MAINTAINERS | 1 + + Makefile | 3 +++ + 4 files changed, 6 insertions(+) + create mode 100644 .clippy.toml + +--- /dev/null ++++ b/.clippy.toml +@@ -0,0 +1 @@ ++# SPDX-License-Identifier: GPL-2.0 +--- a/.gitignore ++++ b/.gitignore +@@ -103,6 +103,7 @@ modules.order + # We don't want to ignore the following even if they are dot-files + # + !.clang-format ++!.clippy.toml + !.cocciconfig + !.editorconfig + !.get_maintainer.ignore +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -20175,6 +20175,7 @@ B: https://github.com/Rust-for-Linux/lin + C: zulip://rust-for-linux.zulipchat.com + P: https://rust-for-linux.com/contributing + T: git https://github.com/Rust-for-Linux/linux.git rust-next ++F: .clippy.toml + F: Documentation/rust/ + F: rust/ + F: samples/rust/ +--- a/Makefile ++++ b/Makefile +@@ -588,6 +588,9 @@ endif + # Allows the usage of unstable features in stable compilers. + export RUSTC_BOOTSTRAP := 1 + ++# Allows finding `.clippy.toml` in out-of-srctree builds. ++export CLIPPY_CONF_DIR := $(srctree) ++ + export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG + export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN + export HOSTRUSTC KBUILD_HOSTRUSTFLAGS diff --git a/queue-6.12/rust-kbuild-expand-rusttest-target-for-macros.patch b/queue-6.12/rust-kbuild-expand-rusttest-target-for-macros.patch new file mode 100644 index 0000000000..0f89187fd0 --- /dev/null +++ b/queue-6.12/rust-kbuild-expand-rusttest-target-for-macros.patch @@ -0,0 +1,85 @@ +From stable+bounces-121511-greg=kroah.com@vger.kernel.org Fri Mar 7 23:53:11 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:50:03 +0100 +Subject: rust: kbuild: expand rusttest target for macros +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-57-ojeda@kernel.org> + +From: "Ethan D. Twardy" + +commit b2c261fa8629dff2bd1143fa790797a773ace102 upstream. + +Previously, the rusttest target for the macros crate did not specify +the dependencies necessary to run the rustdoc tests. These tests rely on +the kernel crate, so add the dependencies. + +Signed-off-by: Ethan D. Twardy +Link: https://github.com/Rust-for-Linux/linux/issues/1076 +Link: https://lore.kernel.org/r/20240704145607.17732-2-ethan.twardy@gmail.com +[ Rebased (`alloc` is gone nowadays, sysroot handling is simpler) and + simplified (reused `rustdoc_test` rule instead of adding a new one, + no need for `rustdoc-compiler_builtins`, removed unneeded `macros` + explicit path). Made `vtable` example fail (avoiding to increase + the complexity in the `rusttest` target). Removed unstable + `-Zproc-macro-backtrace` option. Reworded accordingly. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/Makefile | 17 +++++++++++++---- + rust/macros/lib.rs | 2 +- + 2 files changed, 14 insertions(+), 5 deletions(-) + +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -129,6 +129,14 @@ rusttestlib-macros: private rustc_test_l + rusttestlib-macros: $(src)/macros/lib.rs FORCE + +$(call if_changed,rustc_test_library) + ++rusttestlib-kernel: private rustc_target_flags = \ ++ --extern build_error --extern macros \ ++ --extern bindings --extern uapi ++rusttestlib-kernel: $(src)/kernel/lib.rs \ ++ rusttestlib-bindings rusttestlib-uapi rusttestlib-build_error \ ++ $(obj)/libmacros.so $(obj)/bindings.o FORCE ++ +$(call if_changed,rustc_test_library) ++ + rusttestlib-bindings: $(src)/bindings/lib.rs FORCE + +$(call if_changed,rustc_test_library) + +@@ -181,19 +189,20 @@ quiet_cmd_rustc_test = RUSTC T $< + + rusttest: rusttest-macros rusttest-kernel + +-rusttest-macros: private rustc_target_flags = --extern proc_macro ++rusttest-macros: private rustc_target_flags = --extern proc_macro \ ++ --extern macros --extern kernel + rusttest-macros: private rustdoc_test_target_flags = --crate-type proc-macro +-rusttest-macros: $(src)/macros/lib.rs FORCE ++rusttest-macros: $(src)/macros/lib.rs \ ++ rusttestlib-macros rusttestlib-kernel FORCE + +$(call if_changed,rustc_test) + +$(call if_changed,rustdoc_test) + + rusttest-kernel: private rustc_target_flags = \ + --extern build_error --extern macros --extern bindings --extern uapi +-rusttest-kernel: $(src)/kernel/lib.rs \ ++rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-kernel \ + rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \ + rusttestlib-uapi FORCE + +$(call if_changed,rustc_test) +- +$(call if_changed,rustc_test_library) + + ifdef CONFIG_CC_IS_CLANG + bindgen_c_flags = $(c_flags) +--- a/rust/macros/lib.rs ++++ b/rust/macros/lib.rs +@@ -132,7 +132,7 @@ pub fn module(ts: TokenStream) -> TokenS + /// calls to this function at compile time: + /// + /// ```compile_fail +-/// # use kernel::error::VTABLE_DEFAULT_ERROR; ++/// # // Intentionally missing `use`s to simplify `rusttest`. + /// kernel::build_error(VTABLE_DEFAULT_ERROR) + /// ``` + /// diff --git a/queue-6.12/rust-map-__kernel_size_t-and-friends-also-to-usize-isize.patch b/queue-6.12/rust-map-__kernel_size_t-and-friends-also-to-usize-isize.patch new file mode 100644 index 0000000000..b037fd3517 --- /dev/null +++ b/queue-6.12/rust-map-__kernel_size_t-and-friends-also-to-usize-isize.patch @@ -0,0 +1,73 @@ +From stable+bounces-121513-greg=kroah.com@vger.kernel.org Fri Mar 7 23:53:16 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:50:05 +0100 +Subject: rust: map `__kernel_size_t` and friends also to usize/isize +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-59-ojeda@kernel.org> + +From: Gary Guo + +commit 2fd6f55c048d0c863ffbc8590b1bd2edb5ff13e5 upstream. + +Currently bindgen has special logic to recognise `size_t` and `ssize_t` +and map them to Rust `usize` and `isize`. Similarly, `ptrdiff_t` is +mapped to `isize`. + +However this falls short for `__kernel_size_t`, `__kernel_ssize_t` and +`__kernel_ptrdiff_t`. To ensure that they are mapped to usize/isize +rather than 32/64 integers depending on platform, blocklist them in +bindgen parameters and manually provide their definition. + +Signed-off-by: Gary Guo +Reviewed-by: Alice Ryhl +Reviewed-by: Trevor Gross +Link: https://lore.kernel.org/r/20240913213041.395655-3-gary@garyguo.net +[ Formatted comment. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/bindgen_parameters | 5 +++++ + rust/bindings/lib.rs | 5 +++++ + rust/uapi/lib.rs | 5 +++++ + 3 files changed, 15 insertions(+) + +--- a/rust/bindgen_parameters ++++ b/rust/bindgen_parameters +@@ -1,5 +1,10 @@ + # SPDX-License-Identifier: GPL-2.0 + ++# We want to map these types to `isize`/`usize` manually, instead of ++# define them as `int`/`long` depending on platform bitwidth. ++--blocklist-type __kernel_s?size_t ++--blocklist-type __kernel_ptrdiff_t ++ + --opaque-type xregs_state + --opaque-type desc_struct + --opaque-type arch_lbr_state +--- a/rust/bindings/lib.rs ++++ b/rust/bindings/lib.rs +@@ -27,6 +27,11 @@ + #[allow(dead_code)] + #[allow(clippy::undocumented_unsafe_blocks)] + mod bindings_raw { ++ // Manual definition for blocklisted types. ++ type __kernel_size_t = usize; ++ type __kernel_ssize_t = isize; ++ type __kernel_ptrdiff_t = isize; ++ + // Use glob import here to expose all helpers. + // Symbols defined within the module will take precedence to the glob import. + pub use super::bindings_helper::*; +--- a/rust/uapi/lib.rs ++++ b/rust/uapi/lib.rs +@@ -25,4 +25,9 @@ + unsafe_op_in_unsafe_fn + )] + ++// Manual definition of blocklisted types. ++type __kernel_size_t = usize; ++type __kernel_ssize_t = isize; ++type __kernel_ptrdiff_t = isize; ++ + include!(concat!(env!("OBJTREE"), "/rust/uapi/uapi_generated.rs")); diff --git a/queue-6.12/rust-provide-proper-code-documentation-titles.patch b/queue-6.12/rust-provide-proper-code-documentation-titles.patch new file mode 100644 index 0000000000..a3b57e5bb5 --- /dev/null +++ b/queue-6.12/rust-provide-proper-code-documentation-titles.patch @@ -0,0 +1,102 @@ +From stable+bounces-121468-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:16 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:20 +0100 +Subject: rust: provide proper code documentation titles +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-14-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 2f390cc589433dfcfedc307a141e103929a6fd4d upstream. + +Rust 1.82.0's Clippy is introducing [1][2] a new warn-by-default lint, +`too_long_first_doc_paragraph` [3], which is intended to catch titles +of code documentation items that are too long (likely because no title +was provided and the item documentation starts with a paragraph). + +This lint does not currently trigger anywhere, but it does detect a couple +cases if checking for private items gets enabled (which we will do in +the next commit): + + error: first doc comment paragraph is too long + --> rust/kernel/init/__internal.rs:18:1 + | + 18 | / /// This is the module-internal type implementing `PinInit` and `Init`. It is unsafe to create this + 19 | | /// type, since the closure needs to fulfill the same safety requirement as the + 20 | | /// `__pinned_init`/`__init` functions. + | |_ + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#too_long_first_doc_paragraph + = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]` + + error: first doc comment paragraph is too long + --> rust/kernel/sync/arc/std_vendor.rs:3:1 + | + 3 | / //! The contents of this file come from the Rust standard library, hosted in + 4 | | //! the repository, licensed under + 5 | | //! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details, + 6 | | //! see . + | |_ + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#too_long_first_doc_paragraph + +Thus clean those two instances. + +In addition, since we have a second `std_vendor.rs` file with a similar +header, do the same there too (even if that one does not trigger the lint, +because it is `doc(hidden)`). + +Link: https://github.com/rust-lang/rust/pull/129531 [1] +Link: https://github.com/rust-lang/rust-clippy/pull/12993 [2] +Link: https://rust-lang.github.io/rust-clippy/master/index.html#/too_long_first_doc_paragraph [3] +Reviewed-by: Trevor Gross +Reviewed-by: Alice Ryhl +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-15-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/init/__internal.rs | 7 ++++--- + rust/kernel/std_vendor.rs | 2 ++ + rust/kernel/sync/arc/std_vendor.rs | 2 ++ + 3 files changed, 8 insertions(+), 3 deletions(-) + +--- a/rust/kernel/init/__internal.rs ++++ b/rust/kernel/init/__internal.rs +@@ -15,9 +15,10 @@ use super::*; + /// [this table]: https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns + pub(super) type Invariant = PhantomData *mut T>; + +-/// This is the module-internal type implementing `PinInit` and `Init`. It is unsafe to create this +-/// type, since the closure needs to fulfill the same safety requirement as the +-/// `__pinned_init`/`__init` functions. ++/// Module-internal type implementing `PinInit` and `Init`. ++/// ++/// It is unsafe to create this type, since the closure needs to fulfill the same safety ++/// requirement as the `__pinned_init`/`__init` functions. + pub(crate) struct InitClosure(pub(crate) F, pub(crate) Invariant<(E, T)>); + + // SAFETY: While constructing the `InitClosure`, the user promised that it upholds the +--- a/rust/kernel/std_vendor.rs ++++ b/rust/kernel/std_vendor.rs +@@ -1,5 +1,7 @@ + // SPDX-License-Identifier: Apache-2.0 OR MIT + ++//! Rust standard library vendored code. ++//! + //! The contents of this file come from the Rust standard library, hosted in + //! the repository, licensed under + //! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details, +--- a/rust/kernel/sync/arc/std_vendor.rs ++++ b/rust/kernel/sync/arc/std_vendor.rs +@@ -1,5 +1,7 @@ + // SPDX-License-Identifier: Apache-2.0 OR MIT + ++//! Rust standard library vendored code. ++//! + //! The contents of this file come from the Rust standard library, hosted in + //! the repository, licensed under + //! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details, diff --git a/queue-6.12/rust-replace-clippy-dbg_macro-with-disallowed_macros.patch b/queue-6.12/rust-replace-clippy-dbg_macro-with-disallowed_macros.patch new file mode 100644 index 0000000000..d01c32e2d2 --- /dev/null +++ b/queue-6.12/rust-replace-clippy-dbg_macro-with-disallowed_macros.patch @@ -0,0 +1,133 @@ +From stable+bounces-121467-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:13 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:19 +0100 +Subject: rust: replace `clippy::dbg_macro` with `disallowed_macros` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-13-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 8577c9dca799bd74377f7c30015d8cdc53a53ca2 upstream. + +Back when we used Rust 1.60.0 (before Rust was merged in the kernel), +we added `-Wclippy::dbg_macro` to the compilation flags. This worked +great with our custom `dbg!` macro (vendored from `std`, but slightly +modified to use the kernel printing facilities). + +However, in the very next version, 1.61.0, it stopped working [1] since +the lint started to use a Rust diagnostic item rather than a path to find +the `dbg!` macro [1]. This behavior remains until the current nightly +(1.83.0). + +Therefore, currently, the `dbg_macro` is not doing anything, which +explains why we can invoke `dbg!` in samples/rust/rust_print.rs`, as well +as why changing the `#[allow()]`s to `#[expect()]`s in `std_vendor.rs` +doctests does not work since they are not fulfilled. + +One possible workaround is using `rustc_attrs` like the standard library +does. However, this is intended to be internal, and we just started +supporting several Rust compiler versions, so it is best to avoid it. + +Therefore, instead, use `disallowed_macros`. It is a stable lint and +is more flexible (in that we can provide different macros), although +its diagnostic message(s) are not as nice as the specialized one (yet), +and does not allow to set different lint levels per macro/path [2]. + +In turn, this requires allowing the (intentional) `dbg!` use in the +sample, as one would have expected. + +Finally, in a single case, the `allow` is fixed to be an inner attribute, +since otherwise it was not being applied. + +Link: https://github.com/rust-lang/rust-clippy/issues/11303 [1] +Link: https://github.com/rust-lang/rust-clippy/issues/11307 [2] +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-13-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + .clippy.toml | 6 ++++++ + Makefile | 1 - + rust/kernel/std_vendor.rs | 10 +++++----- + samples/rust/rust_print.rs | 1 + + 4 files changed, 12 insertions(+), 6 deletions(-) + +--- a/.clippy.toml ++++ b/.clippy.toml +@@ -1 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 ++ ++disallowed-macros = [ ++ # The `clippy::dbg_macro` lint only works with `std::dbg!`, thus we simulate ++ # it here, see: https://github.com/rust-lang/rust-clippy/issues/11303. ++ { path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool" }, ++] +--- a/Makefile ++++ b/Makefile +@@ -452,7 +452,6 @@ export rust_common_flags := --edition=20 + -Wrust_2018_idioms \ + -Wunreachable_pub \ + -Wclippy::all \ +- -Wclippy::dbg_macro \ + -Wclippy::ignored_unit_patterns \ + -Wclippy::mut_mut \ + -Wclippy::needless_bitwise_bool \ +--- a/rust/kernel/std_vendor.rs ++++ b/rust/kernel/std_vendor.rs +@@ -14,7 +14,7 @@ + /// + /// ```rust + /// let a = 2; +-/// # #[allow(clippy::dbg_macro)] ++/// # #[allow(clippy::disallowed_macros)] + /// let b = dbg!(a * 2) + 1; + /// // ^-- prints: [src/main.rs:2] a * 2 = 4 + /// assert_eq!(b, 5); +@@ -52,7 +52,7 @@ + /// With a method call: + /// + /// ```rust +-/// # #[allow(clippy::dbg_macro)] ++/// # #[allow(clippy::disallowed_macros)] + /// fn foo(n: usize) { + /// if dbg!(n.checked_sub(4)).is_some() { + /// // ... +@@ -71,7 +71,7 @@ + /// Naive factorial implementation: + /// + /// ```rust +-/// # #[allow(clippy::dbg_macro)] ++/// # #[allow(clippy::disallowed_macros)] + /// # { + /// fn factorial(n: u32) -> u32 { + /// if dbg!(n <= 1) { +@@ -118,7 +118,7 @@ + /// a tuple (and return it, too): + /// + /// ``` +-/// # #[allow(clippy::dbg_macro)] ++/// # #![allow(clippy::disallowed_macros)] + /// assert_eq!(dbg!(1usize, 2u32), (1, 2)); + /// ``` + /// +@@ -127,7 +127,7 @@ + /// invocations. You can use a 1-tuple directly if you need one: + /// + /// ``` +-/// # #[allow(clippy::dbg_macro)] ++/// # #[allow(clippy::disallowed_macros)] + /// # { + /// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored + /// assert_eq!((1,), dbg!((1u32,))); // 1-tuple +--- a/samples/rust/rust_print.rs ++++ b/samples/rust/rust_print.rs +@@ -15,6 +15,7 @@ module! { + + struct RustPrint; + ++#[allow(clippy::disallowed_macros)] + fn arc_print() -> Result { + use kernel::sync::*; + diff --git a/queue-6.12/rust-sort-global-rust-flags.patch b/queue-6.12/rust-sort-global-rust-flags.patch new file mode 100644 index 0000000000..4840ec1594 --- /dev/null +++ b/queue-6.12/rust-sort-global-rust-flags.patch @@ -0,0 +1,52 @@ +From stable+bounces-121457-greg=kroah.com@vger.kernel.org Fri Mar 7 23:50:49 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:09 +0100 +Subject: rust: sort global Rust flags +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-3-ojeda@kernel.org> + +From: Miguel Ojeda + +commit a135aa3d30d28f26eb28a0ff5d48b387b0e0755f upstream. + +Sort the global Rust flags so that it is easier to follow along when we +have more, like this patch series does. + +Reviewed-by: Trevor Gross +Reviewed-by: Alice Ryhl +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-3-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -446,19 +446,19 @@ KBUILD_USERLDFLAGS := $(USERLDFLAGS) + export rust_common_flags := --edition=2021 \ + -Zbinary_dep_depinfo=y \ + -Astable_features \ +- -Dunsafe_op_in_unsafe_fn \ + -Dnon_ascii_idents \ ++ -Dunsafe_op_in_unsafe_fn \ ++ -Wmissing_docs \ + -Wrust_2018_idioms \ + -Wunreachable_pub \ +- -Wmissing_docs \ +- -Wrustdoc::missing_crate_level_docs \ + -Wclippy::all \ ++ -Wclippy::dbg_macro \ + -Wclippy::mut_mut \ + -Wclippy::needless_bitwise_bool \ + -Wclippy::needless_continue \ + -Aclippy::needless_lifetimes \ + -Wclippy::no_mangle_with_rust_abi \ +- -Wclippy::dbg_macro ++ -Wrustdoc::missing_crate_level_docs + + KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \ + $(HOSTCFLAGS) -I $(srctree)/scripts/include diff --git a/queue-6.12/rust-start-using-the-attribute.patch b/queue-6.12/rust-start-using-the-attribute.patch new file mode 100644 index 0000000000..44f8ecb0d0 --- /dev/null +++ b/queue-6.12/rust-start-using-the-attribute.patch @@ -0,0 +1,380 @@ +From stable+bounces-121471-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:25 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:23 +0100 +Subject: rust: start using the `#[expect(...)]` attribute +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-17-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 1f9ed172545687e5c04c77490a45896be6d2e459 upstream. + +In Rust, it is possible to `allow` particular warnings (diagnostics, +lints) locally, making the compiler ignore instances of a given warning +within a given function, module, block, etc. + +It is similar to `#pragma GCC diagnostic push` + `ignored` + `pop` in C: + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" + static void f(void) {} + #pragma GCC diagnostic pop + +But way less verbose: + + #[allow(dead_code)] + fn f() {} + +By that virtue, it makes it possible to comfortably enable more +diagnostics by default (i.e. outside `W=` levels) that may have some +false positives but that are otherwise quite useful to keep enabled to +catch potential mistakes. + +The `#[expect(...)]` attribute [1] takes this further, and makes the +compiler warn if the diagnostic was _not_ produced. For instance, the +following will ensure that, when `f()` is called somewhere, we will have +to remove the attribute: + + #[expect(dead_code)] + fn f() {} + +If we do not, we get a warning from the compiler: + + warning: this lint expectation is unfulfilled + --> x.rs:3:10 + | + 3 | #[expect(dead_code)] + | ^^^^^^^^^ + | + = note: `#[warn(unfulfilled_lint_expectations)]` on by default + +This means that `expect`s do not get forgotten when they are not needed. + +See the next commit for more details, nuances on its usage and +documentation on the feature. + +The attribute requires the `lint_reasons` [2] unstable feature, but it +is becoming stable in 1.81.0 (to be released on 2024-09-05) and it has +already been useful to clean things up in this patch series, finding +cases where the `allow`s should not have been there. + +Thus, enable `lint_reasons` and convert some of our `allow`s to `expect`s +where possible. + +This feature was also an example of the ongoing collaboration between +Rust and the kernel -- we tested it in the kernel early on and found an +issue that was quickly resolved [3]. + +Cc: Fridtjof Stoldt +Cc: Urgau +Link: https://rust-lang.github.io/rfcs/2383-lint-reasons.html#expect-lint-attribute [1] +Link: https://github.com/rust-lang/rust/issues/54503 [2] +Link: https://github.com/rust-lang/rust/issues/114557 [3] +Reviewed-by: Alice Ryhl +Reviewed-by: Trevor Gross +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-18-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/error.rs | 2 +- + rust/kernel/init.rs | 22 +++++++++++----------- + rust/kernel/init/__internal.rs | 4 ++-- + rust/kernel/init/macros.rs | 10 +++++----- + rust/kernel/ioctl.rs | 2 +- + rust/kernel/lib.rs | 1 + + rust/kernel/list/arc_field.rs | 2 +- + rust/kernel/print.rs | 4 ++-- + rust/kernel/std_vendor.rs | 10 +++++----- + samples/rust/rust_print.rs | 2 +- + scripts/Makefile.build | 2 +- + 11 files changed, 31 insertions(+), 30 deletions(-) + +--- a/rust/kernel/error.rs ++++ b/rust/kernel/error.rs +@@ -133,7 +133,7 @@ impl Error { + } + + /// Returns the error encoded as a pointer. +- #[allow(dead_code)] ++ #[expect(dead_code)] + pub(crate) fn to_ptr(self) -> *mut T { + #[cfg_attr(target_pointer_width = "32", allow(clippy::useless_conversion))] + // SAFETY: `self.0` is a valid error due to its invariant. +--- a/rust/kernel/init.rs ++++ b/rust/kernel/init.rs +@@ -35,7 +35,7 @@ + //! that you need to write `<-` instead of `:` for fields that you want to initialize in-place. + //! + //! ```rust +-//! # #![allow(clippy::disallowed_names)] ++//! # #![expect(clippy::disallowed_names)] + //! use kernel::sync::{new_mutex, Mutex}; + //! # use core::pin::Pin; + //! #[pin_data] +@@ -55,7 +55,7 @@ + //! (or just the stack) to actually initialize a `Foo`: + //! + //! ```rust +-//! # #![allow(clippy::disallowed_names)] ++//! # #![expect(clippy::disallowed_names)] + //! # use kernel::sync::{new_mutex, Mutex}; + //! # use core::pin::Pin; + //! # #[pin_data] +@@ -120,12 +120,12 @@ + //! `slot` gets called. + //! + //! ```rust +-//! # #![allow(unreachable_pub, clippy::disallowed_names)] ++//! # #![expect(unreachable_pub, clippy::disallowed_names)] + //! use kernel::{init, types::Opaque}; + //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin}; + //! # mod bindings { +-//! # #![allow(non_camel_case_types)] +-//! # #![allow(clippy::missing_safety_doc)] ++//! # #![expect(non_camel_case_types)] ++//! # #![expect(clippy::missing_safety_doc)] + //! # pub struct foo; + //! # pub unsafe fn init_foo(_ptr: *mut foo) {} + //! # pub unsafe fn destroy_foo(_ptr: *mut foo) {} +@@ -238,7 +238,7 @@ pub mod macros; + /// # Examples + /// + /// ```rust +-/// # #![allow(clippy::disallowed_names)] ++/// # #![expect(clippy::disallowed_names)] + /// # use kernel::{init, macros::pin_data, pin_init, stack_pin_init, init::*, sync::Mutex, new_mutex}; + /// # use core::pin::Pin; + /// #[pin_data] +@@ -290,7 +290,7 @@ macro_rules! stack_pin_init { + /// # Examples + /// + /// ```rust,ignore +-/// # #![allow(clippy::disallowed_names)] ++/// # #![expect(clippy::disallowed_names)] + /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex}; + /// # use macros::pin_data; + /// # use core::{alloc::AllocError, pin::Pin}; +@@ -316,7 +316,7 @@ macro_rules! stack_pin_init { + /// ``` + /// + /// ```rust,ignore +-/// # #![allow(clippy::disallowed_names)] ++/// # #![expect(clippy::disallowed_names)] + /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex}; + /// # use macros::pin_data; + /// # use core::{alloc::AllocError, pin::Pin}; +@@ -438,7 +438,7 @@ macro_rules! stack_try_pin_init { + /// Users of `Foo` can now create it like this: + /// + /// ```rust +-/// # #![allow(clippy::disallowed_names)] ++/// # #![expect(clippy::disallowed_names)] + /// # use kernel::{init, pin_init, macros::pin_data, init::*}; + /// # use core::pin::Pin; + /// # #[pin_data] +@@ -852,7 +852,7 @@ pub unsafe trait PinInit Self::PinData; + } + +@@ -84,7 +84,7 @@ pub unsafe trait PinData: Copy { + pub unsafe trait HasInitData { + type InitData: InitData; + +- #[allow(clippy::missing_safety_doc)] ++ #[expect(clippy::missing_safety_doc)] + unsafe fn __init_data() -> Self::InitData; + } + +--- a/rust/kernel/init/macros.rs ++++ b/rust/kernel/init/macros.rs +@@ -182,13 +182,13 @@ + //! // Normally `Drop` bounds do not have the correct semantics, but for this purpose they do + //! // (normally people want to know if a type has any kind of drop glue at all, here we want + //! // to know if it has any kind of custom drop glue, which is exactly what this bound does). +-//! #[allow(drop_bounds)] ++//! #[expect(drop_bounds)] + //! impl MustNotImplDrop for T {} + //! impl MustNotImplDrop for Bar {} + //! // Here comes a convenience check, if one implemented `PinnedDrop`, but forgot to add it to + //! // `#[pin_data]`, then this will error with the same mechanic as above, this is not needed + //! // for safety, but a good sanity check, since no normal code calls `PinnedDrop::drop`. +-//! #[allow(non_camel_case_types)] ++//! #[expect(non_camel_case_types)] + //! trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {} + //! impl< + //! T: ::kernel::init::PinnedDrop, +@@ -925,14 +925,14 @@ macro_rules! __pin_data { + // `Drop`. Additionally we will implement this trait for the struct leading to a conflict, + // if it also implements `Drop` + trait MustNotImplDrop {} +- #[allow(drop_bounds)] ++ #[expect(drop_bounds)] + impl MustNotImplDrop for T {} + impl<$($impl_generics)*> MustNotImplDrop for $name<$($ty_generics)*> + where $($whr)* {} + // We also take care to prevent users from writing a useless `PinnedDrop` implementation. + // They might implement `PinnedDrop` correctly for the struct, but forget to give + // `PinnedDrop` as the parameter to `#[pin_data]`. +- #[allow(non_camel_case_types)] ++ #[expect(non_camel_case_types)] + trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {} + impl + UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {} +@@ -989,7 +989,7 @@ macro_rules! __pin_data { + // + // The functions are `unsafe` to prevent accidentally calling them. + #[allow(dead_code)] +- #[allow(clippy::missing_safety_doc)] ++ #[expect(clippy::missing_safety_doc)] + impl<$($impl_generics)*> $pin_data<$($ty_generics)*> + where $($whr)* + { +--- a/rust/kernel/ioctl.rs ++++ b/rust/kernel/ioctl.rs +@@ -4,7 +4,7 @@ + //! + //! C header: [`include/asm-generic/ioctl.h`](srctree/include/asm-generic/ioctl.h) + +-#![allow(non_snake_case)] ++#![expect(non_snake_case)] + + use crate::build_assert; + +--- a/rust/kernel/lib.rs ++++ b/rust/kernel/lib.rs +@@ -15,6 +15,7 @@ + #![feature(arbitrary_self_types)] + #![feature(coerce_unsized)] + #![feature(dispatch_from_dyn)] ++#![feature(lint_reasons)] + #![feature(new_uninit)] + #![feature(unsize)] + +--- a/rust/kernel/list/arc_field.rs ++++ b/rust/kernel/list/arc_field.rs +@@ -56,7 +56,7 @@ impl ListArcField` containing the struct with this + /// field for the duration of the returned reference. +- #[allow(clippy::mut_from_ref)] ++ #[expect(clippy::mut_from_ref)] + pub unsafe fn assert_mut(&self) -> &mut T { + // SAFETY: The caller has exclusive access to the `ListArc`, so they also have exclusive + // access to this field. +--- a/rust/kernel/print.rs ++++ b/rust/kernel/print.rs +@@ -14,7 +14,7 @@ use core::{ + use crate::str::RawFormatter; + + // Called from `vsprintf` with format specifier `%pA`. +-#[allow(clippy::missing_safety_doc)] ++#[expect(clippy::missing_safety_doc)] + #[no_mangle] + unsafe extern "C" fn rust_fmt_argument( + buf: *mut c_char, +@@ -140,7 +140,7 @@ pub fn call_printk_cont(args: fmt::Argum + #[doc(hidden)] + #[cfg(not(testlib))] + #[macro_export] +-#[allow(clippy::crate_in_macro_def)] ++#[expect(clippy::crate_in_macro_def)] + macro_rules! print_macro ( + // The non-continuation cases (most of them, e.g. `INFO`). + ($format_string:path, false, $($arg:tt)+) => ( +--- a/rust/kernel/std_vendor.rs ++++ b/rust/kernel/std_vendor.rs +@@ -16,7 +16,7 @@ + /// + /// ```rust + /// let a = 2; +-/// # #[allow(clippy::disallowed_macros)] ++/// # #[expect(clippy::disallowed_macros)] + /// let b = dbg!(a * 2) + 1; + /// // ^-- prints: [src/main.rs:2] a * 2 = 4 + /// assert_eq!(b, 5); +@@ -54,7 +54,7 @@ + /// With a method call: + /// + /// ```rust +-/// # #[allow(clippy::disallowed_macros)] ++/// # #[expect(clippy::disallowed_macros)] + /// fn foo(n: usize) { + /// if dbg!(n.checked_sub(4)).is_some() { + /// // ... +@@ -73,7 +73,7 @@ + /// Naive factorial implementation: + /// + /// ```rust +-/// # #[allow(clippy::disallowed_macros)] ++/// # #[expect(clippy::disallowed_macros)] + /// # { + /// fn factorial(n: u32) -> u32 { + /// if dbg!(n <= 1) { +@@ -120,7 +120,7 @@ + /// a tuple (and return it, too): + /// + /// ``` +-/// # #![allow(clippy::disallowed_macros)] ++/// # #![expect(clippy::disallowed_macros)] + /// assert_eq!(dbg!(1usize, 2u32), (1, 2)); + /// ``` + /// +@@ -129,7 +129,7 @@ + /// invocations. You can use a 1-tuple directly if you need one: + /// + /// ``` +-/// # #[allow(clippy::disallowed_macros)] ++/// # #[expect(clippy::disallowed_macros)] + /// # { + /// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored + /// assert_eq!((1,), dbg!((1u32,))); // 1-tuple +--- a/samples/rust/rust_print.rs ++++ b/samples/rust/rust_print.rs +@@ -15,7 +15,7 @@ module! { + + struct RustPrint; + +-#[allow(clippy::disallowed_macros)] ++#[expect(clippy::disallowed_macros)] + fn arc_print() -> Result { + use kernel::sync::*; + +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -248,7 +248,7 @@ $(obj)/%.lst: $(obj)/%.c FORCE + # Compile Rust sources (.rs) + # --------------------------------------------------------------------------- + +-rust_allowed_features := arbitrary_self_types,new_uninit ++rust_allowed_features := arbitrary_self_types,lint_reasons,new_uninit + + # `--out-dir` is required to avoid temporaries being created by `rustc` in the + # current working directory, which may be not accessible in the out-of-tree diff --git a/queue-6.12/rust-str-test-replace-alloc-format.patch b/queue-6.12/rust-str-test-replace-alloc-format.patch new file mode 100644 index 0000000000..54c464b17d --- /dev/null +++ b/queue-6.12/rust-str-test-replace-alloc-format.patch @@ -0,0 +1,64 @@ +From stable+bounces-121500-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:58 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:52 +0100 +Subject: rust: str: test: replace `alloc::format` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-46-ojeda@kernel.org> + +From: Danilo Krummrich + +commit eb6f92cd3f755c179204ea1f933b07cf992892fd upstream. + +The current implementation of tests in str.rs use `format!` to format +strings for comparison, which, internally, creates a new `String`. + +In order to prepare for getting rid of Rust's alloc crate, we have to +cut this dependency. Instead, implement `format!` for `CString`. + +Note that for userspace tests, `Kmalloc`, which is backing `CString`'s +memory, is just a type alias to `Cmalloc`. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-27-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/str.rs | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +--- a/rust/kernel/str.rs ++++ b/rust/kernel/str.rs +@@ -524,7 +524,28 @@ macro_rules! c_str { + #[cfg(test)] + mod tests { + use super::*; +- use alloc::format; ++ ++ struct String(CString); ++ ++ impl String { ++ fn from_fmt(args: fmt::Arguments<'_>) -> Self { ++ String(CString::try_from_fmt(args).unwrap()) ++ } ++ } ++ ++ impl Deref for String { ++ type Target = str; ++ ++ fn deref(&self) -> &str { ++ self.0.to_str().unwrap() ++ } ++ } ++ ++ macro_rules! format { ++ ($($f:tt)*) => ({ ++ &*String::from_fmt(kernel::fmt!($($f)*)) ++ }) ++ } + + const ALL_ASCII_CHARS: &'static str = + "\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\x0f\ diff --git a/queue-6.12/rust-sync-remove-unneeded.patch b/queue-6.12/rust-sync-remove-unneeded.patch new file mode 100644 index 0000000000..0959ef50f9 --- /dev/null +++ b/queue-6.12/rust-sync-remove-unneeded.patch @@ -0,0 +1,55 @@ +From stable+bounces-121465-greg=kroah.com@vger.kernel.org Fri Mar 7 23:51:07 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:17 +0100 +Subject: rust: sync: remove unneeded `#[allow(clippy::non_send_fields_in_send_ty)]` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-11-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 5e7c9b84ad08cc7a41b2ddbbbaccb60057da3860 upstream. + +Rust 1.58.0 (before Rust was merged into the kernel) made Clippy's +`non_send_fields_in_send_ty` lint part of the `suspicious` lint group for +a brief window of time [1] until the minor version 1.58.1 got released +a week after, where the lint was moved back to `nursery`. + +By that time, we had already upgraded to that Rust version, and thus we +had `allow`ed the lint here for `CondVar`. + +Nowadays, Clippy's `non_send_fields_in_send_ty` would still trigger here +if it were enabled. + +Moreover, if enabled, `Lock` and `Task` would also require an +`allow`. Therefore, it does not seem like someone is actually enabling it +(in, e.g., a custom flags build). + +Finally, the lint does not appear to have had major improvements since +then [2]. + +Thus remove the `allow` since it is unneeded. + +Link: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1581-2022-01-20 [1] +Link: https://github.com/rust-lang/rust-clippy/issues/8045 [2] +Reviewed-by: Alice Ryhl +Reviewed-by: Trevor Gross +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-11-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/sync/condvar.rs | 1 - + 1 file changed, 1 deletion(-) + +--- a/rust/kernel/sync/condvar.rs ++++ b/rust/kernel/sync/condvar.rs +@@ -92,7 +92,6 @@ pub struct CondVar { + _pin: PhantomPinned, + } + +-#[allow(clippy::non_send_fields_in_send_ty)] + // SAFETY: `CondVar` only uses a `struct wait_queue_head`, which is safe to use on any thread. + unsafe impl Send for CondVar {} + diff --git a/queue-6.12/rust-treewide-switch-to-our-kernel-box-type.patch b/queue-6.12/rust-treewide-switch-to-our-kernel-box-type.patch new file mode 100644 index 0000000000..a608abea75 --- /dev/null +++ b/queue-6.12/rust-treewide-switch-to-our-kernel-box-type.patch @@ -0,0 +1,625 @@ +From stable+bounces-121486-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:11 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:38 +0100 +Subject: rust: treewide: switch to our kernel `Box` type +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-32-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 8373147ce4961665c5700016b1c76299e962d077 upstream. + +Now that we got the kernel `Box` type in place, convert all existing +`Box` users to make use of it. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-13-dakr@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + drivers/block/rnull.rs | 4 +- + rust/kernel/init.rs | 51 +++++++++++++++++++------------------- + rust/kernel/init/__internal.rs | 2 - + rust/kernel/rbtree.rs | 49 ++++++++++++++++++++---------------- + rust/kernel/sync/arc.rs | 17 +++++------- + rust/kernel/sync/condvar.rs | 4 +- + rust/kernel/sync/lock/mutex.rs | 2 - + rust/kernel/sync/lock/spinlock.rs | 2 - + rust/kernel/workqueue.rs | 20 +++++++------- + rust/macros/lib.rs | 6 ++-- + 10 files changed, 81 insertions(+), 76 deletions(-) + +--- a/drivers/block/rnull.rs ++++ b/drivers/block/rnull.rs +@@ -32,7 +32,7 @@ module! { + } + + struct NullBlkModule { +- _disk: Pin>>>, ++ _disk: Pin>>>, + } + + impl kernel::Module for NullBlkModule { +@@ -47,7 +47,7 @@ impl kernel::Module for NullBlkModule { + .rotational(false) + .build(format_args!("rnullb{}", 0), tagset)?; + +- let disk = Box::pin_init(new_mutex!(disk, "nullb:disk"), flags::GFP_KERNEL)?; ++ let disk = KBox::pin_init(new_mutex!(disk, "nullb:disk"), flags::GFP_KERNEL)?; + + Ok(Self { _disk: disk }) + } +--- a/rust/kernel/init.rs ++++ b/rust/kernel/init.rs +@@ -13,7 +13,7 @@ + //! To initialize a `struct` with an in-place constructor you will need two things: + //! - an in-place constructor, + //! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc`], +-//! [`UniqueArc`], [`Box`] or any other smart pointer that implements [`InPlaceInit`]). ++//! [`UniqueArc`], [`KBox`] or any other smart pointer that implements [`InPlaceInit`]). + //! + //! To get an in-place constructor there are generally three options: + //! - directly creating an in-place constructor using the [`pin_init!`] macro, +@@ -68,7 +68,7 @@ + //! # a <- new_mutex!(42, "Foo::a"), + //! # b: 24, + //! # }); +-//! let foo: Result>> = Box::pin_init(foo, GFP_KERNEL); ++//! let foo: Result>> = KBox::pin_init(foo, GFP_KERNEL); + //! ``` + //! + //! For more information see the [`pin_init!`] macro. +@@ -92,14 +92,14 @@ + //! struct DriverData { + //! #[pin] + //! status: Mutex, +-//! buffer: Box<[u8; 1_000_000]>, ++//! buffer: KBox<[u8; 1_000_000]>, + //! } + //! + //! impl DriverData { + //! fn new() -> impl PinInit { + //! try_pin_init!(Self { + //! status <- new_mutex!(0, "DriverData::status"), +-//! buffer: Box::init(kernel::init::zeroed(), GFP_KERNEL)?, ++//! buffer: KBox::init(kernel::init::zeroed(), GFP_KERNEL)?, + //! }) + //! } + //! } +@@ -211,7 +211,7 @@ + //! [`pin_init!`]: crate::pin_init! + + use crate::{ +- alloc::{box_ext::BoxExt, AllocError, Flags}, ++ alloc::{box_ext::BoxExt, AllocError, Flags, KBox}, + error::{self, Error}, + sync::Arc, + sync::UniqueArc, +@@ -298,7 +298,7 @@ macro_rules! stack_pin_init { + /// struct Foo { + /// #[pin] + /// a: Mutex, +-/// b: Box, ++/// b: KBox, + /// } + /// + /// struct Bar { +@@ -307,7 +307,7 @@ macro_rules! stack_pin_init { + /// + /// stack_try_pin_init!(let foo: Result, AllocError> = pin_init!(Foo { + /// a <- new_mutex!(42), +-/// b: Box::new(Bar { ++/// b: KBox::new(Bar { + /// x: 64, + /// }, GFP_KERNEL)?, + /// })); +@@ -324,7 +324,7 @@ macro_rules! stack_pin_init { + /// struct Foo { + /// #[pin] + /// a: Mutex, +-/// b: Box, ++/// b: KBox, + /// } + /// + /// struct Bar { +@@ -333,7 +333,7 @@ macro_rules! stack_pin_init { + /// + /// stack_try_pin_init!(let foo: Pin<&mut Foo> =? pin_init!(Foo { + /// a <- new_mutex!(42), +-/// b: Box::new(Bar { ++/// b: KBox::new(Bar { + /// x: 64, + /// }, GFP_KERNEL)?, + /// })); +@@ -391,7 +391,7 @@ macro_rules! stack_try_pin_init { + /// }, + /// }); + /// # initializer } +-/// # Box::pin_init(demo(), GFP_KERNEL).unwrap(); ++/// # KBox::pin_init(demo(), GFP_KERNEL).unwrap(); + /// ``` + /// + /// Arbitrary Rust expressions can be used to set the value of a variable. +@@ -460,7 +460,7 @@ macro_rules! stack_try_pin_init { + /// # }) + /// # } + /// # } +-/// let foo = Box::pin_init(Foo::new(), GFP_KERNEL); ++/// let foo = KBox::pin_init(Foo::new(), GFP_KERNEL); + /// ``` + /// + /// They can also easily embed it into their own `struct`s: +@@ -592,7 +592,7 @@ macro_rules! pin_init { + /// use kernel::{init::{self, PinInit}, error::Error}; + /// #[pin_data] + /// struct BigBuf { +-/// big: Box<[u8; 1024 * 1024 * 1024]>, ++/// big: KBox<[u8; 1024 * 1024 * 1024]>, + /// small: [u8; 1024 * 1024], + /// ptr: *mut u8, + /// } +@@ -600,7 +600,7 @@ macro_rules! pin_init { + /// impl BigBuf { + /// fn new() -> impl PinInit { + /// try_pin_init!(Self { +-/// big: Box::init(init::zeroed(), GFP_KERNEL)?, ++/// big: KBox::init(init::zeroed(), GFP_KERNEL)?, + /// small: [0; 1024 * 1024], + /// ptr: core::ptr::null_mut(), + /// }? Error) +@@ -692,16 +692,16 @@ macro_rules! init { + /// # Examples + /// + /// ```rust +-/// use kernel::{init::{PinInit, zeroed}, error::Error}; ++/// use kernel::{alloc::KBox, init::{PinInit, zeroed}, error::Error}; + /// struct BigBuf { +-/// big: Box<[u8; 1024 * 1024 * 1024]>, ++/// big: KBox<[u8; 1024 * 1024 * 1024]>, + /// small: [u8; 1024 * 1024], + /// } + /// + /// impl BigBuf { + /// fn new() -> impl Init { + /// try_init!(Self { +-/// big: Box::init(zeroed(), GFP_KERNEL)?, ++/// big: KBox::init(zeroed(), GFP_KERNEL)?, + /// small: [0; 1024 * 1024], + /// }? Error) + /// } +@@ -812,8 +812,8 @@ macro_rules! assert_pinned { + /// A pin-initializer for the type `T`. + /// + /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can +-/// be [`Box`], [`Arc`], [`UniqueArc`] or even the stack (see [`stack_pin_init!`]). Use the +-/// [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc`] on this. ++/// be [`KBox`], [`Arc`], [`UniqueArc`] or even the stack (see [`stack_pin_init!`]). Use ++/// the [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc`] on this. + /// + /// Also see the [module description](self). + /// +@@ -893,7 +893,7 @@ pub unsafe trait PinInit(I, F, __internal::Invariant<(E, Box)>); ++pub struct ChainPinInit(I, F, __internal::Invariant<(E, KBox)>); + + // SAFETY: The `__pinned_init` function is implemented such that it + // - returns `Ok(())` on successful initialization, +@@ -919,8 +919,8 @@ where + /// An initializer for `T`. + /// + /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can +-/// be [`Box`], [`Arc`], [`UniqueArc`] or even the stack (see [`stack_pin_init!`]). Use the +-/// [`InPlaceInit::init`] function of a smart pointer like [`Arc`] on this. Because ++/// be [`KBox`], [`Arc`], [`UniqueArc`] or even the stack (see [`stack_pin_init!`]). Use ++/// the [`InPlaceInit::init`] function of a smart pointer like [`Arc`] on this. Because + /// [`PinInit`] is a super trait, you can use every function that takes it as well. + /// + /// Also see the [module description](self). +@@ -992,7 +992,7 @@ pub unsafe trait Init(I, F, __internal::Invariant<(E, Box)>); ++pub struct ChainInit(I, F, __internal::Invariant<(E, KBox)>); + + // SAFETY: The `__init` function is implemented such that it + // - returns `Ok(())` on successful initialization, +@@ -1076,8 +1076,9 @@ pub fn uninit() -> impl Init = Box::init::(init_array_from_fn(|i| i), GFP_KERNEL).unwrap(); ++/// use kernel::{alloc::KBox, error::Error, init::init_array_from_fn}; ++/// let array: KBox<[usize; 1_000]> = ++/// KBox::init::(init_array_from_fn(|i| i), GFP_KERNEL).unwrap(); + /// assert_eq!(array.len(), 1_000); + /// ``` + pub fn init_array_from_fn( +@@ -1453,7 +1454,7 @@ impl_zeroable! { + // + // In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant. + {} Option>, +- {} Option>, ++ {} Option>, + + // SAFETY: `null` pointer is valid. + // +--- a/rust/kernel/init/__internal.rs ++++ b/rust/kernel/init/__internal.rs +@@ -105,7 +105,7 @@ pub unsafe trait InitData: Copy { + } + } + +-pub struct AllData(PhantomData) -> Box>); ++pub struct AllData(PhantomData) -> KBox>); + + impl Clone for AllData { + fn clone(&self) -> Self { +--- a/rust/kernel/rbtree.rs ++++ b/rust/kernel/rbtree.rs +@@ -7,7 +7,6 @@ + //! Reference: + + use crate::{alloc::Flags, bindings, container_of, error::Result, prelude::*}; +-use alloc::boxed::Box; + use core::{ + cmp::{Ord, Ordering}, + marker::PhantomData, +@@ -497,7 +496,7 @@ impl Drop for RBTree { + // but it is not observable. The loop invariant is still maintained. + + // SAFETY: `this` is valid per the loop invariant. +- unsafe { drop(Box::from_raw(this.cast_mut())) }; ++ unsafe { drop(KBox::from_raw(this.cast_mut())) }; + } + } + } +@@ -764,7 +763,7 @@ impl<'a, K, V> Cursor<'a, K, V> { + // point to the links field of `Node` objects. + let this = unsafe { container_of!(self.current.as_ptr(), Node, links) }.cast_mut(); + // SAFETY: `this` is valid by the type invariants as described above. +- let node = unsafe { Box::from_raw(this) }; ++ let node = unsafe { KBox::from_raw(this) }; + let node = RBTreeNode { node }; + // SAFETY: The reference to the tree used to create the cursor outlives the cursor, so + // the tree cannot change. By the tree invariant, all nodes are valid. +@@ -809,7 +808,7 @@ impl<'a, K, V> Cursor<'a, K, V> { + // point to the links field of `Node` objects. + let this = unsafe { container_of!(neighbor, Node, links) }.cast_mut(); + // SAFETY: `this` is valid by the type invariants as described above. +- let node = unsafe { Box::from_raw(this) }; ++ let node = unsafe { KBox::from_raw(this) }; + return Some(RBTreeNode { node }); + } + None +@@ -1038,7 +1037,7 @@ impl Iterator for IterRaw { + /// It contains the memory needed to hold a node that can be inserted into a red-black tree. One + /// can be obtained by directly allocating it ([`RBTreeNodeReservation::new`]). + pub struct RBTreeNodeReservation { +- node: Box>>, ++ node: KBox>>, + } + + impl RBTreeNodeReservation { +@@ -1046,7 +1045,7 @@ impl RBTreeNodeReservation { + /// call to [`RBTree::insert`]. + pub fn new(flags: Flags) -> Result> { + Ok(RBTreeNodeReservation { +- node: as BoxExt<_>>::new_uninit(flags)?, ++ node: KBox::new_uninit(flags)?, + }) + } + } +@@ -1062,14 +1061,15 @@ impl RBTreeNodeReservation { + /// Initialises a node reservation. + /// + /// It then becomes an [`RBTreeNode`] that can be inserted into a tree. +- pub fn into_node(mut self, key: K, value: V) -> RBTreeNode { +- self.node.write(Node { +- key, +- value, +- links: bindings::rb_node::default(), +- }); +- // SAFETY: We just wrote to it. +- let node = unsafe { self.node.assume_init() }; ++ pub fn into_node(self, key: K, value: V) -> RBTreeNode { ++ let node = KBox::write( ++ self.node, ++ Node { ++ key, ++ value, ++ links: bindings::rb_node::default(), ++ }, ++ ); + RBTreeNode { node } + } + } +@@ -1079,7 +1079,7 @@ impl RBTreeNodeReservation { + /// The node is fully initialised (with key and value) and can be inserted into a tree without any + /// extra allocations or failure paths. + pub struct RBTreeNode { +- node: Box>, ++ node: KBox>, + } + + impl RBTreeNode { +@@ -1091,7 +1091,9 @@ impl RBTreeNode { + + /// Get the key and value from inside the node. + pub fn to_key_value(self) -> (K, V) { +- (self.node.key, self.node.value) ++ let node = KBox::into_inner(self.node); ++ ++ (node.key, node.value) + } + } + +@@ -1113,7 +1115,7 @@ impl RBTreeNode { + /// may be freed (but only for the key/value; memory for the node itself is kept for reuse). + pub fn into_reservation(self) -> RBTreeNodeReservation { + RBTreeNodeReservation { +- node: Box::drop_contents(self.node), ++ node: KBox::drop_contents(self.node), + } + } + } +@@ -1164,7 +1166,7 @@ impl<'a, K, V> RawVacantEntry<'a, K, V> + /// The `node` must have a key such that inserting it here does not break the ordering of this + /// [`RBTree`]. + fn insert(self, node: RBTreeNode) -> &'a mut V { +- let node = Box::into_raw(node.node); ++ let node = KBox::into_raw(node.node); + + // SAFETY: `node` is valid at least until we call `Box::from_raw`, which only happens when + // the node is removed or replaced. +@@ -1238,21 +1240,24 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { + // SAFETY: The node was a node in the tree, but we removed it, so we can convert it + // back into a box. + node: unsafe { +- Box::from_raw(container_of!(self.node_links, Node, links).cast_mut()) ++ KBox::from_raw(container_of!(self.node_links, Node, links).cast_mut()) + }, + } + } + + /// Takes the value of the entry out of the map, and returns it. + pub fn remove(self) -> V { +- self.remove_node().node.value ++ let rb_node = self.remove_node(); ++ let node = KBox::into_inner(rb_node.node); ++ ++ node.value + } + + /// Swap the current node for the provided node. + /// + /// The key of both nodes must be equal. + fn replace(self, node: RBTreeNode) -> RBTreeNode { +- let node = Box::into_raw(node.node); ++ let node = KBox::into_raw(node.node); + + // SAFETY: `node` is valid at least until we call `Box::from_raw`, which only happens when + // the node is removed or replaced. +@@ -1268,7 +1273,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { + // - `self.node_ptr` produces a valid pointer to a node in the tree. + // - Now that we removed this entry from the tree, we can convert the node to a box. + let old_node = +- unsafe { Box::from_raw(container_of!(self.node_links, Node, links).cast_mut()) }; ++ unsafe { KBox::from_raw(container_of!(self.node_links, Node, links).cast_mut()) }; + + RBTreeNode { node: old_node } + } +--- a/rust/kernel/sync/arc.rs ++++ b/rust/kernel/sync/arc.rs +@@ -17,13 +17,12 @@ + //! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html + + use crate::{ +- alloc::{box_ext::BoxExt, AllocError, Flags}, ++ alloc::{AllocError, Flags, KBox}, + bindings, + init::{self, InPlaceInit, Init, PinInit}, + try_init, + types::{ForeignOwnable, Opaque}, + }; +-use alloc::boxed::Box; + use core::{ + alloc::Layout, + fmt, +@@ -201,11 +200,11 @@ impl Arc { + data: contents, + }; + +- let inner = as BoxExt<_>>::new(value, flags)?; ++ let inner = KBox::new(value, flags)?; + + // SAFETY: We just created `inner` with a reference count of 1, which is owned by the new + // `Arc` object. +- Ok(unsafe { Self::from_inner(Box::leak(inner).into()) }) ++ Ok(unsafe { Self::from_inner(KBox::leak(inner).into()) }) + } + } + +@@ -398,8 +397,8 @@ impl Drop for Arc { + if is_zero { + // The count reached zero, we must free the memory. + // +- // SAFETY: The pointer was initialised from the result of `Box::leak`. +- unsafe { drop(Box::from_raw(self.ptr.as_ptr())) }; ++ // SAFETY: The pointer was initialised from the result of `KBox::leak`. ++ unsafe { drop(KBox::from_raw(self.ptr.as_ptr())) }; + } + } + } +@@ -641,7 +640,7 @@ impl UniqueArc { + /// Tries to allocate a new [`UniqueArc`] instance whose contents are not initialised yet. + pub fn new_uninit(flags: Flags) -> Result>, AllocError> { + // INVARIANT: The refcount is initialised to a non-zero value. +- let inner = Box::try_init::( ++ let inner = KBox::try_init::( + try_init!(ArcInner { + // SAFETY: There are no safety requirements for this FFI call. + refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }), +@@ -651,8 +650,8 @@ impl UniqueArc { + )?; + Ok(UniqueArc { + // INVARIANT: The newly-created object has a refcount of 1. +- // SAFETY: The pointer from the `Box` is valid. +- inner: unsafe { Arc::from_inner(Box::leak(inner).into()) }, ++ // SAFETY: The pointer from the `KBox` is valid. ++ inner: unsafe { Arc::from_inner(KBox::leak(inner).into()) }, + }) + } + } +--- a/rust/kernel/sync/condvar.rs ++++ b/rust/kernel/sync/condvar.rs +@@ -70,8 +70,8 @@ pub use new_condvar; + /// } + /// + /// /// Allocates a new boxed `Example`. +-/// fn new_example() -> Result>> { +-/// Box::pin_init(pin_init!(Example { ++/// fn new_example() -> Result>> { ++/// KBox::pin_init(pin_init!(Example { + /// value <- new_mutex!(0), + /// value_changed <- new_condvar!(), + /// }), GFP_KERNEL) +--- a/rust/kernel/sync/lock/mutex.rs ++++ b/rust/kernel/sync/lock/mutex.rs +@@ -58,7 +58,7 @@ pub use new_mutex; + /// } + /// + /// // Allocate a boxed `Example`. +-/// let e = Box::pin_init(Example::new(), GFP_KERNEL)?; ++/// let e = KBox::pin_init(Example::new(), GFP_KERNEL)?; + /// assert_eq!(e.c, 10); + /// assert_eq!(e.d.lock().a, 20); + /// assert_eq!(e.d.lock().b, 30); +--- a/rust/kernel/sync/lock/spinlock.rs ++++ b/rust/kernel/sync/lock/spinlock.rs +@@ -56,7 +56,7 @@ pub use new_spinlock; + /// } + /// + /// // Allocate a boxed `Example`. +-/// let e = Box::pin_init(Example::new(), GFP_KERNEL)?; ++/// let e = KBox::pin_init(Example::new(), GFP_KERNEL)?; + /// assert_eq!(e.c, 10); + /// assert_eq!(e.d.lock().a, 20); + /// assert_eq!(e.d.lock().b, 30); +--- a/rust/kernel/workqueue.rs ++++ b/rust/kernel/workqueue.rs +@@ -216,7 +216,7 @@ impl Queue { + func: Some(func), + }); + +- self.enqueue(Box::pin_init(init, flags).map_err(|_| AllocError)?); ++ self.enqueue(KBox::pin_init(init, flags).map_err(|_| AllocError)?); + Ok(()) + } + } +@@ -239,9 +239,9 @@ impl ClosureWork { + } + + impl WorkItem for ClosureWork { +- type Pointer = Pin>; ++ type Pointer = Pin>; + +- fn run(mut this: Pin>) { ++ fn run(mut this: Pin>) { + if let Some(func) = this.as_mut().project().take() { + (func)() + } +@@ -297,7 +297,7 @@ pub unsafe trait RawWorkItem>` and [`Arc`], and is mainly intended to be ++/// This trait is implemented by `Pin>` and [`Arc`], and is mainly intended to be + /// implemented for smart pointer types. For your own structs, you would implement [`WorkItem`] + /// instead. The [`run`] method on this trait will usually just perform the appropriate + /// `container_of` translation and then call into the [`run`][WorkItem::run] method from the +@@ -329,7 +329,7 @@ pub unsafe trait WorkItemPointer { + /// The pointer type that this struct is wrapped in. This will typically be `Arc` or +- /// `Pin>`. ++ /// `Pin>`. + type Pointer: WorkItemPointer; + + /// The method that should be called when this work item is executed. +@@ -567,7 +567,7 @@ where + } + + // SAFETY: TODO. +-unsafe impl WorkItemPointer for Pin> ++unsafe impl WorkItemPointer for Pin> + where + T: WorkItem, + T: HasWork, +@@ -578,7 +578,7 @@ where + // SAFETY: This computes the pointer that `__enqueue` got from `Arc::into_raw`. + let ptr = unsafe { T::work_container_of(ptr) }; + // SAFETY: This pointer comes from `Arc::into_raw` and we've been given back ownership. +- let boxed = unsafe { Box::from_raw(ptr) }; ++ let boxed = unsafe { KBox::from_raw(ptr) }; + // SAFETY: The box was already pinned when it was enqueued. + let pinned = unsafe { Pin::new_unchecked(boxed) }; + +@@ -587,7 +587,7 @@ where + } + + // SAFETY: TODO. +-unsafe impl RawWorkItem for Pin> ++unsafe impl RawWorkItem for Pin> + where + T: WorkItem, + T: HasWork, +@@ -601,9 +601,9 @@ where + // SAFETY: We're not going to move `self` or any of its fields, so its okay to temporarily + // remove the `Pin` wrapper. + let boxed = unsafe { Pin::into_inner_unchecked(self) }; +- let ptr = Box::into_raw(boxed); ++ let ptr = KBox::into_raw(boxed); + +- // SAFETY: Pointers into a `Box` point at a valid value. ++ // SAFETY: Pointers into a `KBox` point at a valid value. + let work_ptr = unsafe { T::raw_get_work(ptr) }; + // SAFETY: `raw_get_work` returns a pointer to a valid value. + let work_ptr = unsafe { Work::raw_get(work_ptr) }; +--- a/rust/macros/lib.rs ++++ b/rust/macros/lib.rs +@@ -243,7 +243,7 @@ pub fn concat_idents(ts: TokenStream) -> + /// struct DriverData { + /// #[pin] + /// queue: Mutex>, +-/// buf: Box<[u8; 1024 * 1024]>, ++/// buf: KBox<[u8; 1024 * 1024]>, + /// } + /// ``` + /// +@@ -252,7 +252,7 @@ pub fn concat_idents(ts: TokenStream) -> + /// struct DriverData { + /// #[pin] + /// queue: Mutex>, +-/// buf: Box<[u8; 1024 * 1024]>, ++/// buf: KBox<[u8; 1024 * 1024]>, + /// raw_info: *mut Info, + /// } + /// +@@ -282,7 +282,7 @@ pub fn pin_data(inner: TokenStream, item + /// struct DriverData { + /// #[pin] + /// queue: Mutex>, +-/// buf: Box<[u8; 1024 * 1024]>, ++/// buf: KBox<[u8; 1024 * 1024]>, + /// raw_info: *mut Info, + /// } + /// diff --git a/queue-6.12/rust-treewide-switch-to-the-kernel-vec-type.patch b/queue-6.12/rust-treewide-switch-to-the-kernel-vec-type.patch new file mode 100644 index 0000000000..ef90c468c7 --- /dev/null +++ b/queue-6.12/rust-treewide-switch-to-the-kernel-vec-type.patch @@ -0,0 +1,239 @@ +From stable+bounces-121493-greg=kroah.com@vger.kernel.org Fri Mar 7 23:52:26 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:45 +0100 +Subject: rust: treewide: switch to the kernel `Vec` type +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-39-ojeda@kernel.org> + +From: Danilo Krummrich + +commit 58eff8e872bd04ccb3adcf99aec7334ffad06cfd upstream. + +Now that we got the kernel `Vec` in place, convert all existing `Vec` +users to make use of it. + +Reviewed-by: Alice Ryhl +Reviewed-by: Benno Lossin +Reviewed-by: Gary Guo +Signed-off-by: Danilo Krummrich +Link: https://lore.kernel.org/r/20241004154149.93856-20-dakr@kernel.org +[ Converted `kasan_test_rust.rs` too, as discussed. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + mm/kasan/kasan_test_rust.rs | 2 +- + rust/kernel/str.rs | 12 +++++------- + rust/kernel/sync/locked_by.rs | 2 +- + rust/kernel/types.rs | 2 +- + rust/kernel/uaccess.rs | 17 +++++++---------- + rust/macros/lib.rs | 6 +++--- + samples/rust/rust_minimal.rs | 4 ++-- + 7 files changed, 20 insertions(+), 25 deletions(-) + +--- a/mm/kasan/kasan_test_rust.rs ++++ b/mm/kasan/kasan_test_rust.rs +@@ -11,7 +11,7 @@ use kernel::prelude::*; + /// drop the vector, and touch it. + #[no_mangle] + pub extern "C" fn kasan_test_rust_uaf() -> u8 { +- let mut v: Vec = Vec::new(); ++ let mut v: KVec = KVec::new(); + for _ in 0..4096 { + v.push(0x42, GFP_KERNEL).unwrap(); + } +--- a/rust/kernel/str.rs ++++ b/rust/kernel/str.rs +@@ -2,8 +2,7 @@ + + //! String representations. + +-use crate::alloc::{flags::*, vec_ext::VecExt, AllocError}; +-use alloc::vec::Vec; ++use crate::alloc::{flags::*, AllocError, KVec}; + use core::fmt::{self, Write}; + use core::ops::{self, Deref, DerefMut, Index}; + +@@ -791,7 +790,7 @@ impl fmt::Write for Formatter { + /// assert_eq!(s.is_ok(), false); + /// ``` + pub struct CString { +- buf: Vec, ++ buf: KVec, + } + + impl CString { +@@ -804,7 +803,7 @@ impl CString { + let size = f.bytes_written(); + + // Allocate a vector with the required number of bytes, and write to it. +- let mut buf = as VecExt<_>>::with_capacity(size, GFP_KERNEL)?; ++ let mut buf = KVec::with_capacity(size, GFP_KERNEL)?; + // SAFETY: The buffer stored in `buf` is at least of size `size` and is valid for writes. + let mut f = unsafe { Formatter::from_buffer(buf.as_mut_ptr(), size) }; + f.write_fmt(args)?; +@@ -851,10 +850,9 @@ impl<'a> TryFrom<&'a CStr> for CString { + type Error = AllocError; + + fn try_from(cstr: &'a CStr) -> Result { +- let mut buf = Vec::new(); ++ let mut buf = KVec::new(); + +- as VecExt<_>>::extend_from_slice(&mut buf, cstr.as_bytes_with_nul(), GFP_KERNEL) +- .map_err(|_| AllocError)?; ++ buf.extend_from_slice(cstr.as_bytes_with_nul(), GFP_KERNEL)?; + + // INVARIANT: The `CStr` and `CString` types have the same invariants for + // the string data, and we copied it over without changes. +--- a/rust/kernel/sync/locked_by.rs ++++ b/rust/kernel/sync/locked_by.rs +@@ -43,7 +43,7 @@ use core::{cell::UnsafeCell, mem::size_o + /// struct InnerDirectory { + /// /// The sum of the bytes used by all files. + /// bytes_used: u64, +-/// _files: Vec, ++/// _files: KVec, + /// } + /// + /// struct Directory { +--- a/rust/kernel/types.rs ++++ b/rust/kernel/types.rs +@@ -135,7 +135,7 @@ impl ForeignOwnable for () { + /// # use kernel::types::ScopeGuard; + /// fn example3(arg: bool) -> Result { + /// let mut vec = +-/// ScopeGuard::new_with_data(Vec::new(), |v| pr_info!("vec had {} elements\n", v.len())); ++/// ScopeGuard::new_with_data(KVec::new(), |v| pr_info!("vec had {} elements\n", v.len())); + /// + /// vec.push(10u8, GFP_KERNEL)?; + /// if arg { +--- a/rust/kernel/uaccess.rs ++++ b/rust/kernel/uaccess.rs +@@ -11,7 +11,6 @@ use crate::{ + prelude::*, + types::{AsBytes, FromBytes}, + }; +-use alloc::vec::Vec; + use core::ffi::{c_ulong, c_void}; + use core::mem::{size_of, MaybeUninit}; + +@@ -46,7 +45,6 @@ pub type UserPtr = usize; + /// every byte in the region. + /// + /// ```no_run +-/// use alloc::vec::Vec; + /// use core::ffi::c_void; + /// use kernel::error::Result; + /// use kernel::uaccess::{UserPtr, UserSlice}; +@@ -54,7 +52,7 @@ pub type UserPtr = usize; + /// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result<()> { + /// let (read, mut write) = UserSlice::new(uptr, len).reader_writer(); + /// +-/// let mut buf = Vec::new(); ++/// let mut buf = KVec::new(); + /// read.read_all(&mut buf, GFP_KERNEL)?; + /// + /// for b in &mut buf { +@@ -69,7 +67,6 @@ pub type UserPtr = usize; + /// Example illustrating a TOCTOU (time-of-check to time-of-use) bug. + /// + /// ```no_run +-/// use alloc::vec::Vec; + /// use core::ffi::c_void; + /// use kernel::error::{code::EINVAL, Result}; + /// use kernel::uaccess::{UserPtr, UserSlice}; +@@ -78,21 +75,21 @@ pub type UserPtr = usize; + /// fn is_valid(uptr: UserPtr, len: usize) -> Result { + /// let read = UserSlice::new(uptr, len).reader(); + /// +-/// let mut buf = Vec::new(); ++/// let mut buf = KVec::new(); + /// read.read_all(&mut buf, GFP_KERNEL)?; + /// + /// todo!() + /// } + /// + /// /// Returns the bytes behind this user pointer if they are valid. +-/// fn get_bytes_if_valid(uptr: UserPtr, len: usize) -> Result> { ++/// fn get_bytes_if_valid(uptr: UserPtr, len: usize) -> Result> { + /// if !is_valid(uptr, len)? { + /// return Err(EINVAL); + /// } + /// + /// let read = UserSlice::new(uptr, len).reader(); + /// +-/// let mut buf = Vec::new(); ++/// let mut buf = KVec::new(); + /// read.read_all(&mut buf, GFP_KERNEL)?; + /// + /// // THIS IS A BUG! The bytes could have changed since we checked them. +@@ -130,7 +127,7 @@ impl UserSlice { + /// Reads the entirety of the user slice, appending it to the end of the provided buffer. + /// + /// Fails with [`EFAULT`] if the read happens on a bad address. +- pub fn read_all(self, buf: &mut Vec, flags: Flags) -> Result { ++ pub fn read_all(self, buf: &mut KVec, flags: Flags) -> Result { + self.reader().read_all(buf, flags) + } + +@@ -291,9 +288,9 @@ impl UserSliceReader { + /// Reads the entirety of the user slice, appending it to the end of the provided buffer. + /// + /// Fails with [`EFAULT`] if the read happens on a bad address. +- pub fn read_all(mut self, buf: &mut Vec, flags: Flags) -> Result { ++ pub fn read_all(mut self, buf: &mut KVec, flags: Flags) -> Result { + let len = self.length; +- VecExt::::reserve(buf, len, flags)?; ++ buf.reserve(len, flags)?; + + // The call to `try_reserve` was successful, so the spare capacity is at least `len` bytes + // long. +--- a/rust/macros/lib.rs ++++ b/rust/macros/lib.rs +@@ -242,7 +242,7 @@ pub fn concat_idents(ts: TokenStream) -> + /// #[pin_data] + /// struct DriverData { + /// #[pin] +-/// queue: Mutex>, ++/// queue: Mutex>, + /// buf: KBox<[u8; 1024 * 1024]>, + /// } + /// ``` +@@ -251,7 +251,7 @@ pub fn concat_idents(ts: TokenStream) -> + /// #[pin_data(PinnedDrop)] + /// struct DriverData { + /// #[pin] +-/// queue: Mutex>, ++/// queue: Mutex>, + /// buf: KBox<[u8; 1024 * 1024]>, + /// raw_info: *mut Info, + /// } +@@ -281,7 +281,7 @@ pub fn pin_data(inner: TokenStream, item + /// #[pin_data(PinnedDrop)] + /// struct DriverData { + /// #[pin] +-/// queue: Mutex>, ++/// queue: Mutex>, + /// buf: KBox<[u8; 1024 * 1024]>, + /// raw_info: *mut Info, + /// } +--- a/samples/rust/rust_minimal.rs ++++ b/samples/rust/rust_minimal.rs +@@ -13,7 +13,7 @@ module! { + } + + struct RustMinimal { +- numbers: Vec, ++ numbers: KVec, + } + + impl kernel::Module for RustMinimal { +@@ -21,7 +21,7 @@ impl kernel::Module for RustMinimal { + pr_info!("Rust minimal sample (init)\n"); + pr_info!("Am I built-in? {}\n", !cfg!(MODULE)); + +- let mut numbers = Vec::new(); ++ let mut numbers = KVec::new(); + numbers.push(72, GFP_KERNEL)?; + numbers.push(108, GFP_KERNEL)?; + numbers.push(200, GFP_KERNEL)?; diff --git a/queue-6.12/rust-types-avoid-repetition-in-as-from-bytes-impls.patch b/queue-6.12/rust-types-avoid-repetition-in-as-from-bytes-impls.patch new file mode 100644 index 0000000000..ae532dddb6 --- /dev/null +++ b/queue-6.12/rust-types-avoid-repetition-in-as-from-bytes-impls.patch @@ -0,0 +1,118 @@ +From stable+bounces-121458-greg=kroah.com@vger.kernel.org Fri Mar 7 23:50:48 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:10 +0100 +Subject: rust: types: avoid repetition in `{As,From}Bytes` impls +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-4-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 567cdff53e71de56ae67eaf4309db38778b7bcd3 upstream. + +In order to provide `// SAFETY` comments for every `unsafe impl`, we would +need to repeat them, which is not very useful and would be harder to read. + +We could perhaps allow the lint (ideally within a small module), but we +can take the chance to avoid the repetition of the `impl`s themselves +too by using a small local macro, like in other places where we have +had to do this sort of thing. + +Thus add the straightforward `impl_{from,as}bytes!` macros and use them +to implement `FromBytes`. + +This, in turn, will allow us in the next patch to place a `// SAFETY` +comment that defers to the actual invocation of the macro. + +Reviewed-by: Alice Ryhl +Reviewed-by: Trevor Gross +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-4-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/types.rs | 68 ++++++++++++++++++++++++++------------------------- + 1 file changed, 35 insertions(+), 33 deletions(-) + +--- a/rust/kernel/types.rs ++++ b/rust/kernel/types.rs +@@ -481,21 +481,22 @@ pub enum Either { + /// All bit-patterns must be valid for this type. This type must not have interior mutability. + pub unsafe trait FromBytes {} + +-// SAFETY: All bit patterns are acceptable values of the types below. +-unsafe impl FromBytes for u8 {} +-unsafe impl FromBytes for u16 {} +-unsafe impl FromBytes for u32 {} +-unsafe impl FromBytes for u64 {} +-unsafe impl FromBytes for usize {} +-unsafe impl FromBytes for i8 {} +-unsafe impl FromBytes for i16 {} +-unsafe impl FromBytes for i32 {} +-unsafe impl FromBytes for i64 {} +-unsafe impl FromBytes for isize {} +-// SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit +-// patterns are also acceptable for arrays of that type. +-unsafe impl FromBytes for [T] {} +-unsafe impl FromBytes for [T; N] {} ++macro_rules! impl_frombytes { ++ ($($({$($generics:tt)*})? $t:ty, )*) => { ++ $(unsafe impl$($($generics)*)? FromBytes for $t {})* ++ }; ++} ++ ++impl_frombytes! { ++ // SAFETY: All bit patterns are acceptable values of the types below. ++ u8, u16, u32, u64, usize, ++ i8, i16, i32, i64, isize, ++ ++ // SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit ++ // patterns are also acceptable for arrays of that type. ++ {} [T], ++ {} [T; N], ++} + + /// Types that can be viewed as an immutable slice of initialized bytes. + /// +@@ -514,21 +515,22 @@ unsafe impl AsBytes for [T] {} +-unsafe impl AsBytes for [T; N] {} ++macro_rules! impl_asbytes { ++ ($($({$($generics:tt)*})? $t:ty, )*) => { ++ $(unsafe impl$($($generics)*)? AsBytes for $t {})* ++ }; ++} ++ ++impl_asbytes! { ++ // SAFETY: Instances of the following types have no uninitialized portions. ++ u8, u16, u32, u64, usize, ++ i8, i16, i32, i64, isize, ++ bool, ++ char, ++ str, ++ ++ // SAFETY: If individual values in an array have no uninitialized portions, then the array ++ // itself does not have any uninitialized portions either. ++ {} [T], ++ {} [T; N], ++} diff --git a/queue-6.12/rust-use-custom-ffi-integer-types.patch b/queue-6.12/rust-use-custom-ffi-integer-types.patch new file mode 100644 index 0000000000..0d38b0f724 --- /dev/null +++ b/queue-6.12/rust-use-custom-ffi-integer-types.patch @@ -0,0 +1,767 @@ +From stable+bounces-121514-greg=kroah.com@vger.kernel.org Fri Mar 7 23:53:20 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:50:06 +0100 +Subject: rust: use custom FFI integer types +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-60-ojeda@kernel.org> + +From: Gary Guo + +commit d072acda4862f095ec9056979b654cc06a22cc68 upstream. + +Currently FFI integer types are defined in libcore. This commit creates +the `ffi` crate and asks bindgen to use that crate for FFI integer types +instead of `core::ffi`. + +This commit is preparatory and no type changes are made in this commit +yet. + +Signed-off-by: Gary Guo +Link: https://lore.kernel.org/r/20240913213041.395655-4-gary@garyguo.net +[ Added `rustdoc`, `rusttest` and KUnit tests support. Rebased on top of + `rust-next` (e.g. migrated more `core::ffi` cases). Reworded crate + docs slightly and formatted. - Miguel ] +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/Makefile | 39 ++++++++++++++++++++++++------------ + rust/ffi.rs | 13 ++++++++++++ + rust/kernel/alloc/allocator.rs | 2 - + rust/kernel/alloc/allocator_test.rs | 4 +-- + rust/kernel/alloc/kbox.rs | 12 +++++------ + rust/kernel/block/mq/operations.rs | 18 ++++++++-------- + rust/kernel/block/mq/raw_writer.rs | 2 - + rust/kernel/block/mq/tag_set.rs | 2 - + rust/kernel/error.rs | 20 +++++++++--------- + rust/kernel/init.rs | 2 - + rust/kernel/lib.rs | 2 + + rust/kernel/net/phy.rs | 16 +++++++------- + rust/kernel/str.rs | 4 +-- + rust/kernel/sync/arc.rs | 6 ++--- + rust/kernel/sync/condvar.rs | 2 - + rust/kernel/sync/lock.rs | 2 - + rust/kernel/sync/lock/mutex.rs | 2 - + rust/kernel/sync/lock/spinlock.rs | 2 - + rust/kernel/task.rs | 8 +------ + rust/kernel/time.rs | 4 +-- + rust/kernel/types.rs | 14 ++++++------ + rust/kernel/uaccess.rs | 6 ++--- + rust/macros/module.rs | 8 +++---- + 23 files changed, 107 insertions(+), 83 deletions(-) + create mode 100644 rust/ffi.rs + +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -3,7 +3,7 @@ + # Where to place rustdoc generated documentation + rustdoc_output := $(objtree)/Documentation/output/rust/rustdoc + +-obj-$(CONFIG_RUST) += core.o compiler_builtins.o ++obj-$(CONFIG_RUST) += core.o compiler_builtins.o ffi.o + always-$(CONFIG_RUST) += exports_core_generated.h + + # Missing prototypes are expected in the helpers since these are exported +@@ -103,10 +103,13 @@ rustdoc-core: $(RUST_LIB_SRC)/core/src/l + rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE + +$(call if_changed,rustdoc) + +-rustdoc-kernel: private rustc_target_flags = \ ++rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE ++ +$(call if_changed,rustdoc) ++ ++rustdoc-kernel: private rustc_target_flags = --extern ffi \ + --extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \ + --extern bindings --extern uapi +-rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \ ++rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-ffi rustdoc-macros \ + rustdoc-compiler_builtins $(obj)/libmacros.so \ + $(obj)/bindings.o FORCE + +$(call if_changed,rustdoc) +@@ -124,12 +127,15 @@ quiet_cmd_rustc_test_library = RUSTC TL + rusttestlib-build_error: $(src)/build_error.rs FORCE + +$(call if_changed,rustc_test_library) + ++rusttestlib-ffi: $(src)/ffi.rs FORCE ++ +$(call if_changed,rustc_test_library) ++ + rusttestlib-macros: private rustc_target_flags = --extern proc_macro + rusttestlib-macros: private rustc_test_library_proc = yes + rusttestlib-macros: $(src)/macros/lib.rs FORCE + +$(call if_changed,rustc_test_library) + +-rusttestlib-kernel: private rustc_target_flags = \ ++rusttestlib-kernel: private rustc_target_flags = --extern ffi \ + --extern build_error --extern macros \ + --extern bindings --extern uapi + rusttestlib-kernel: $(src)/kernel/lib.rs \ +@@ -137,10 +143,12 @@ rusttestlib-kernel: $(src)/kernel/lib.rs + $(obj)/libmacros.so $(obj)/bindings.o FORCE + +$(call if_changed,rustc_test_library) + +-rusttestlib-bindings: $(src)/bindings/lib.rs FORCE ++rusttestlib-bindings: private rustc_target_flags = --extern ffi ++rusttestlib-bindings: $(src)/bindings/lib.rs rusttestlib-ffi FORCE + +$(call if_changed,rustc_test_library) + +-rusttestlib-uapi: $(src)/uapi/lib.rs FORCE ++rusttestlib-uapi: private rustc_target_flags = --extern ffi ++rusttestlib-uapi: $(src)/uapi/lib.rs rusttestlib-ffi FORCE + +$(call if_changed,rustc_test_library) + + quiet_cmd_rustdoc_test = RUSTDOC T $< +@@ -159,7 +167,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC + mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \ + OBJTREE=$(abspath $(objtree)) \ + $(RUSTDOC) --test $(rust_flags) \ +- -L$(objtree)/$(obj) --extern kernel \ ++ -L$(objtree)/$(obj) --extern ffi --extern kernel \ + --extern build_error --extern macros \ + --extern bindings --extern uapi \ + --no-run --crate-name kernel -Zunstable-options \ +@@ -197,9 +205,9 @@ rusttest-macros: $(src)/macros/lib.rs \ + +$(call if_changed,rustc_test) + +$(call if_changed,rustdoc_test) + +-rusttest-kernel: private rustc_target_flags = \ ++rusttest-kernel: private rustc_target_flags = --extern ffi \ + --extern build_error --extern macros --extern bindings --extern uapi +-rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-kernel \ ++rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-ffi rusttestlib-kernel \ + rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \ + rusttestlib-uapi FORCE + +$(call if_changed,rustc_test) +@@ -286,7 +294,7 @@ bindgen_c_flags_final = $(bindgen_c_flag + quiet_cmd_bindgen = BINDGEN $@ + cmd_bindgen = \ + $(BINDGEN) $< $(bindgen_target_flags) --rust-target 1.68 \ +- --use-core --with-derive-default --ctypes-prefix core::ffi --no-layout-tests \ ++ --use-core --with-derive-default --ctypes-prefix ffi --no-layout-tests \ + --no-debug '.*' --enable-function-attribute-detection \ + -o $@ -- $(bindgen_c_flags_final) -DMODULE \ + $(bindgen_target_cflags) $(bindgen_target_extra) +@@ -414,18 +422,23 @@ $(obj)/compiler_builtins.o: $(src)/compi + $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE + +$(call if_changed_rule,rustc_library) + ++$(obj)/ffi.o: $(src)/ffi.rs $(obj)/compiler_builtins.o FORCE ++ +$(call if_changed_rule,rustc_library) ++ ++$(obj)/bindings.o: private rustc_target_flags = --extern ffi + $(obj)/bindings.o: $(src)/bindings/lib.rs \ +- $(obj)/compiler_builtins.o \ ++ $(obj)/ffi.o \ + $(obj)/bindings/bindings_generated.rs \ + $(obj)/bindings/bindings_helpers_generated.rs FORCE + +$(call if_changed_rule,rustc_library) + ++$(obj)/uapi.o: private rustc_target_flags = --extern ffi + $(obj)/uapi.o: $(src)/uapi/lib.rs \ +- $(obj)/compiler_builtins.o \ ++ $(obj)/ffi.o \ + $(obj)/uapi/uapi_generated.rs FORCE + +$(call if_changed_rule,rustc_library) + +-$(obj)/kernel.o: private rustc_target_flags = \ ++$(obj)/kernel.o: private rustc_target_flags = --extern ffi \ + --extern build_error --extern macros --extern bindings --extern uapi + $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \ + $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE +--- /dev/null ++++ b/rust/ffi.rs +@@ -0,0 +1,13 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++//! Foreign function interface (FFI) types. ++//! ++//! This crate provides mapping from C primitive types to Rust ones. ++//! ++//! The Rust [`core`] crate provides [`core::ffi`], which maps integer types to the platform default ++//! C ABI. The kernel does not use [`core::ffi`], so it can customise the mapping that deviates from ++//! the platform default. ++ ++#![no_std] ++ ++pub use core::ffi::*; +--- a/rust/kernel/alloc/allocator.rs ++++ b/rust/kernel/alloc/allocator.rs +@@ -58,7 +58,7 @@ fn aligned_size(new_layout: Layout) -> u + /// + /// One of the following: `krealloc`, `vrealloc`, `kvrealloc`. + struct ReallocFunc( +- unsafe extern "C" fn(*const core::ffi::c_void, usize, u32) -> *mut core::ffi::c_void, ++ unsafe extern "C" fn(*const crate::ffi::c_void, usize, u32) -> *mut crate::ffi::c_void, + ); + + impl ReallocFunc { +--- a/rust/kernel/alloc/allocator_test.rs ++++ b/rust/kernel/alloc/allocator_test.rs +@@ -24,10 +24,10 @@ pub type KVmalloc = Kmalloc; + + extern "C" { + #[link_name = "aligned_alloc"] +- fn libc_aligned_alloc(align: usize, size: usize) -> *mut core::ffi::c_void; ++ fn libc_aligned_alloc(align: usize, size: usize) -> *mut crate::ffi::c_void; + + #[link_name = "free"] +- fn libc_free(ptr: *mut core::ffi::c_void); ++ fn libc_free(ptr: *mut crate::ffi::c_void); + } + + // SAFETY: +--- a/rust/kernel/alloc/kbox.rs ++++ b/rust/kernel/alloc/kbox.rs +@@ -355,17 +355,17 @@ where + { + type Borrowed<'a> = &'a T; + +- fn into_foreign(self) -> *const core::ffi::c_void { ++ fn into_foreign(self) -> *const crate::ffi::c_void { + Box::into_raw(self) as _ + } + +- unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { ++ unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self { + // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous + // call to `Self::into_foreign`. + unsafe { Box::from_raw(ptr as _) } + } + +- unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { ++ unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T { + // SAFETY: The safety requirements of this method ensure that the object remains alive and + // immutable for the duration of 'a. + unsafe { &*ptr.cast() } +@@ -378,18 +378,18 @@ where + { + type Borrowed<'a> = Pin<&'a T>; + +- fn into_foreign(self) -> *const core::ffi::c_void { ++ fn into_foreign(self) -> *const crate::ffi::c_void { + // SAFETY: We are still treating the box as pinned. + Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _ + } + +- unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { ++ unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self { + // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous + // call to `Self::into_foreign`. + unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) } + } + +- unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Pin<&'a T> { ++ unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> { + // SAFETY: The safety requirements for this function ensure that the object is still alive, + // so it is safe to dereference the raw pointer. + // The safety requirements of `from_foreign` also ensure that the object remains alive for +--- a/rust/kernel/block/mq/operations.rs ++++ b/rust/kernel/block/mq/operations.rs +@@ -131,7 +131,7 @@ impl OperationsVTable + unsafe extern "C" fn poll_callback( + _hctx: *mut bindings::blk_mq_hw_ctx, + _iob: *mut bindings::io_comp_batch, +- ) -> core::ffi::c_int { ++ ) -> crate::ffi::c_int { + T::poll().into() + } + +@@ -145,9 +145,9 @@ impl OperationsVTable + /// for the same context. + unsafe extern "C" fn init_hctx_callback( + _hctx: *mut bindings::blk_mq_hw_ctx, +- _tagset_data: *mut core::ffi::c_void, +- _hctx_idx: core::ffi::c_uint, +- ) -> core::ffi::c_int { ++ _tagset_data: *mut crate::ffi::c_void, ++ _hctx_idx: crate::ffi::c_uint, ++ ) -> crate::ffi::c_int { + from_result(|| Ok(0)) + } + +@@ -159,7 +159,7 @@ impl OperationsVTable + /// This function may only be called by blk-mq C infrastructure. + unsafe extern "C" fn exit_hctx_callback( + _hctx: *mut bindings::blk_mq_hw_ctx, +- _hctx_idx: core::ffi::c_uint, ++ _hctx_idx: crate::ffi::c_uint, + ) { + } + +@@ -176,9 +176,9 @@ impl OperationsVTable + unsafe extern "C" fn init_request_callback( + _set: *mut bindings::blk_mq_tag_set, + rq: *mut bindings::request, +- _hctx_idx: core::ffi::c_uint, +- _numa_node: core::ffi::c_uint, +- ) -> core::ffi::c_int { ++ _hctx_idx: crate::ffi::c_uint, ++ _numa_node: crate::ffi::c_uint, ++ ) -> crate::ffi::c_int { + from_result(|| { + // SAFETY: By the safety requirements of this function, `rq` points + // to a valid allocation. +@@ -203,7 +203,7 @@ impl OperationsVTable + unsafe extern "C" fn exit_request_callback( + _set: *mut bindings::blk_mq_tag_set, + rq: *mut bindings::request, +- _hctx_idx: core::ffi::c_uint, ++ _hctx_idx: crate::ffi::c_uint, + ) { + // SAFETY: The tagset invariants guarantee that all requests are allocated with extra memory + // for the request data. +--- a/rust/kernel/block/mq/raw_writer.rs ++++ b/rust/kernel/block/mq/raw_writer.rs +@@ -25,7 +25,7 @@ impl<'a> RawWriter<'a> { + } + + pub(crate) fn from_array( +- a: &'a mut [core::ffi::c_char; N], ++ a: &'a mut [crate::ffi::c_char; N], + ) -> Result> { + Self::new( + // SAFETY: the buffer of `a` is valid for read and write as `u8` for +--- a/rust/kernel/block/mq/tag_set.rs ++++ b/rust/kernel/block/mq/tag_set.rs +@@ -53,7 +53,7 @@ impl TagSet { + queue_depth: num_tags, + cmd_size, + flags: bindings::BLK_MQ_F_SHOULD_MERGE, +- driver_data: core::ptr::null_mut::(), ++ driver_data: core::ptr::null_mut::(), + nr_maps: num_maps, + ..tag_set + } +--- a/rust/kernel/error.rs ++++ b/rust/kernel/error.rs +@@ -100,7 +100,7 @@ impl Error { + /// + /// It is a bug to pass an out-of-range `errno`. `EINVAL` would + /// be returned in such a case. +- pub fn from_errno(errno: core::ffi::c_int) -> Error { ++ pub fn from_errno(errno: crate::ffi::c_int) -> Error { + if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 { + // TODO: Make it a `WARN_ONCE` once available. + crate::pr_warn!( +@@ -119,7 +119,7 @@ impl Error { + /// Creates an [`Error`] from a kernel error code. + /// + /// Returns [`None`] if `errno` is out-of-range. +- const fn try_from_errno(errno: core::ffi::c_int) -> Option { ++ const fn try_from_errno(errno: crate::ffi::c_int) -> Option { + if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 { + return None; + } +@@ -133,7 +133,7 @@ impl Error { + /// # Safety + /// + /// `errno` must be within error code range (i.e. `>= -MAX_ERRNO && < 0`). +- const unsafe fn from_errno_unchecked(errno: core::ffi::c_int) -> Error { ++ const unsafe fn from_errno_unchecked(errno: crate::ffi::c_int) -> Error { + // INVARIANT: The contract ensures the type invariant + // will hold. + // SAFETY: The caller guarantees `errno` is non-zero. +@@ -141,7 +141,7 @@ impl Error { + } + + /// Returns the kernel error code. +- pub fn to_errno(self) -> core::ffi::c_int { ++ pub fn to_errno(self) -> crate::ffi::c_int { + self.0.get() + } + +@@ -259,7 +259,7 @@ pub type Result = cor + + /// Converts an integer as returned by a C kernel function to an error if it's negative, and + /// `Ok(())` otherwise. +-pub fn to_result(err: core::ffi::c_int) -> Result { ++pub fn to_result(err: crate::ffi::c_int) -> Result { + if err < 0 { + Err(Error::from_errno(err)) + } else { +@@ -282,15 +282,15 @@ pub fn to_result(err: core::ffi::c_int) + /// fn devm_platform_ioremap_resource( + /// pdev: &mut PlatformDevice, + /// index: u32, +-/// ) -> Result<*mut core::ffi::c_void> { ++/// ) -> Result<*mut kernel::ffi::c_void> { + /// // SAFETY: `pdev` points to a valid platform device. There are no safety requirements + /// // on `index`. + /// from_err_ptr(unsafe { bindings::devm_platform_ioremap_resource(pdev.to_ptr(), index) }) + /// } + /// ``` + pub fn from_err_ptr(ptr: *mut T) -> Result<*mut T> { +- // CAST: Casting a pointer to `*const core::ffi::c_void` is always valid. +- let const_ptr: *const core::ffi::c_void = ptr.cast(); ++ // CAST: Casting a pointer to `*const crate::ffi::c_void` is always valid. ++ let const_ptr: *const crate::ffi::c_void = ptr.cast(); + // SAFETY: The FFI function does not deref the pointer. + if unsafe { bindings::IS_ERR(const_ptr) } { + // SAFETY: The FFI function does not deref the pointer. +@@ -306,7 +306,7 @@ pub fn from_err_ptr(ptr: *mut T) -> R + // + // SAFETY: `IS_ERR()` ensures `err` is a + // negative value greater-or-equal to `-bindings::MAX_ERRNO`. +- return Err(unsafe { Error::from_errno_unchecked(err as core::ffi::c_int) }); ++ return Err(unsafe { Error::from_errno_unchecked(err as crate::ffi::c_int) }); + } + Ok(ptr) + } +@@ -326,7 +326,7 @@ pub fn from_err_ptr(ptr: *mut T) -> R + /// # use kernel::bindings; + /// unsafe extern "C" fn probe_callback( + /// pdev: *mut bindings::platform_device, +-/// ) -> core::ffi::c_int { ++/// ) -> kernel::ffi::c_int { + /// from_result(|| { + /// let ptr = devm_alloc(pdev)?; + /// bindings::platform_set_drvdata(pdev, ptr); +--- a/rust/kernel/init.rs ++++ b/rust/kernel/init.rs +@@ -133,7 +133,7 @@ + //! # } + //! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround. + //! # trait FromErrno { +-//! # fn from_errno(errno: core::ffi::c_int) -> Error { ++//! # fn from_errno(errno: kernel::ffi::c_int) -> Error { + //! # // Dummy error that can be constructed outside the `kernel` crate. + //! # Error::from(core::fmt::Error) + //! # } +--- a/rust/kernel/lib.rs ++++ b/rust/kernel/lib.rs +@@ -27,6 +27,8 @@ compile_error!("Missing kernel configura + // Allow proc-macros to refer to `::kernel` inside the `kernel` crate (this crate). + extern crate self as kernel; + ++pub use ffi; ++ + pub mod alloc; + #[cfg(CONFIG_BLOCK)] + pub mod block; +--- a/rust/kernel/net/phy.rs ++++ b/rust/kernel/net/phy.rs +@@ -314,7 +314,7 @@ impl Adapter { + /// `phydev` must be passed by the corresponding callback in `phy_driver`. + unsafe extern "C" fn soft_reset_callback( + phydev: *mut bindings::phy_device, +- ) -> core::ffi::c_int { ++ ) -> crate::ffi::c_int { + from_result(|| { + // SAFETY: This callback is called only in contexts + // where we hold `phy_device->lock`, so the accessors on +@@ -328,7 +328,7 @@ impl Adapter { + /// # Safety + /// + /// `phydev` must be passed by the corresponding callback in `phy_driver`. +- unsafe extern "C" fn probe_callback(phydev: *mut bindings::phy_device) -> core::ffi::c_int { ++ unsafe extern "C" fn probe_callback(phydev: *mut bindings::phy_device) -> crate::ffi::c_int { + from_result(|| { + // SAFETY: This callback is called only in contexts + // where we can exclusively access `phy_device` because +@@ -345,7 +345,7 @@ impl Adapter { + /// `phydev` must be passed by the corresponding callback in `phy_driver`. + unsafe extern "C" fn get_features_callback( + phydev: *mut bindings::phy_device, +- ) -> core::ffi::c_int { ++ ) -> crate::ffi::c_int { + from_result(|| { + // SAFETY: This callback is called only in contexts + // where we hold `phy_device->lock`, so the accessors on +@@ -359,7 +359,7 @@ impl Adapter { + /// # Safety + /// + /// `phydev` must be passed by the corresponding callback in `phy_driver`. +- unsafe extern "C" fn suspend_callback(phydev: *mut bindings::phy_device) -> core::ffi::c_int { ++ unsafe extern "C" fn suspend_callback(phydev: *mut bindings::phy_device) -> crate::ffi::c_int { + from_result(|| { + // SAFETY: The C core code ensures that the accessors on + // `Device` are okay to call even though `phy_device->lock` +@@ -373,7 +373,7 @@ impl Adapter { + /// # Safety + /// + /// `phydev` must be passed by the corresponding callback in `phy_driver`. +- unsafe extern "C" fn resume_callback(phydev: *mut bindings::phy_device) -> core::ffi::c_int { ++ unsafe extern "C" fn resume_callback(phydev: *mut bindings::phy_device) -> crate::ffi::c_int { + from_result(|| { + // SAFETY: The C core code ensures that the accessors on + // `Device` are okay to call even though `phy_device->lock` +@@ -389,7 +389,7 @@ impl Adapter { + /// `phydev` must be passed by the corresponding callback in `phy_driver`. + unsafe extern "C" fn config_aneg_callback( + phydev: *mut bindings::phy_device, +- ) -> core::ffi::c_int { ++ ) -> crate::ffi::c_int { + from_result(|| { + // SAFETY: This callback is called only in contexts + // where we hold `phy_device->lock`, so the accessors on +@@ -405,7 +405,7 @@ impl Adapter { + /// `phydev` must be passed by the corresponding callback in `phy_driver`. + unsafe extern "C" fn read_status_callback( + phydev: *mut bindings::phy_device, +- ) -> core::ffi::c_int { ++ ) -> crate::ffi::c_int { + from_result(|| { + // SAFETY: This callback is called only in contexts + // where we hold `phy_device->lock`, so the accessors on +@@ -421,7 +421,7 @@ impl Adapter { + /// `phydev` must be passed by the corresponding callback in `phy_driver`. + unsafe extern "C" fn match_phy_device_callback( + phydev: *mut bindings::phy_device, +- ) -> core::ffi::c_int { ++ ) -> crate::ffi::c_int { + // SAFETY: This callback is called only in contexts + // where we hold `phy_device->lock`, so the accessors on + // `Device` are okay to call. +--- a/rust/kernel/str.rs ++++ b/rust/kernel/str.rs +@@ -184,7 +184,7 @@ impl CStr { + /// last at least `'a`. When `CStr` is alive, the memory pointed by `ptr` + /// must not be mutated. + #[inline] +- pub unsafe fn from_char_ptr<'a>(ptr: *const core::ffi::c_char) -> &'a Self { ++ pub unsafe fn from_char_ptr<'a>(ptr: *const crate::ffi::c_char) -> &'a Self { + // SAFETY: The safety precondition guarantees `ptr` is a valid pointer + // to a `NUL`-terminated C string. + let len = unsafe { bindings::strlen(ptr) } + 1; +@@ -247,7 +247,7 @@ impl CStr { + + /// Returns a C pointer to the string. + #[inline] +- pub const fn as_char_ptr(&self) -> *const core::ffi::c_char { ++ pub const fn as_char_ptr(&self) -> *const crate::ffi::c_char { + self.0.as_ptr() as _ + } + +--- a/rust/kernel/sync/arc.rs ++++ b/rust/kernel/sync/arc.rs +@@ -332,11 +332,11 @@ impl Arc { + impl ForeignOwnable for Arc { + type Borrowed<'a> = ArcBorrow<'a, T>; + +- fn into_foreign(self) -> *const core::ffi::c_void { ++ fn into_foreign(self) -> *const crate::ffi::c_void { + ManuallyDrop::new(self).ptr.as_ptr() as _ + } + +- unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> ArcBorrow<'a, T> { ++ unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> ArcBorrow<'a, T> { + // By the safety requirement of this function, we know that `ptr` came from + // a previous call to `Arc::into_foreign`. + let inner = NonNull::new(ptr as *mut ArcInner).unwrap(); +@@ -346,7 +346,7 @@ impl ForeignOwnable for Arc< + unsafe { ArcBorrow::new(inner) } + } + +- unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { ++ unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self { + // SAFETY: By the safety requirement of this function, we know that `ptr` came from + // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and + // holds a reference count increment that is transferrable to us. +--- a/rust/kernel/sync/condvar.rs ++++ b/rust/kernel/sync/condvar.rs +@@ -7,6 +7,7 @@ + + use super::{lock::Backend, lock::Guard, LockClassKey}; + use crate::{ ++ ffi::{c_int, c_long}, + init::PinInit, + pin_init, + str::CStr, +@@ -14,7 +15,6 @@ use crate::{ + time::Jiffies, + types::Opaque, + }; +-use core::ffi::{c_int, c_long}; + use core::marker::PhantomPinned; + use core::ptr; + use macros::pin_data; +--- a/rust/kernel/sync/lock.rs ++++ b/rust/kernel/sync/lock.rs +@@ -46,7 +46,7 @@ pub unsafe trait Backend { + /// remain valid for read indefinitely. + unsafe fn init( + ptr: *mut Self::State, +- name: *const core::ffi::c_char, ++ name: *const crate::ffi::c_char, + key: *mut bindings::lock_class_key, + ); + +--- a/rust/kernel/sync/lock/mutex.rs ++++ b/rust/kernel/sync/lock/mutex.rs +@@ -96,7 +96,7 @@ unsafe impl super::Backend for MutexBack + + unsafe fn init( + ptr: *mut Self::State, +- name: *const core::ffi::c_char, ++ name: *const crate::ffi::c_char, + key: *mut bindings::lock_class_key, + ) { + // SAFETY: The safety requirements ensure that `ptr` is valid for writes, and `name` and +--- a/rust/kernel/sync/lock/spinlock.rs ++++ b/rust/kernel/sync/lock/spinlock.rs +@@ -95,7 +95,7 @@ unsafe impl super::Backend for SpinLockB + + unsafe fn init( + ptr: *mut Self::State, +- name: *const core::ffi::c_char, ++ name: *const crate::ffi::c_char, + key: *mut bindings::lock_class_key, + ) { + // SAFETY: The safety requirements ensure that `ptr` is valid for writes, and `name` and +--- a/rust/kernel/task.rs ++++ b/rust/kernel/task.rs +@@ -4,13 +4,9 @@ + //! + //! C header: [`include/linux/sched.h`](srctree/include/linux/sched.h). + ++use crate::ffi::{c_int, c_long, c_uint}; + use crate::types::Opaque; +-use core::{ +- ffi::{c_int, c_long, c_uint}, +- marker::PhantomData, +- ops::Deref, +- ptr, +-}; ++use core::{marker::PhantomData, ops::Deref, ptr}; + + /// A sentinel value used for infinite timeouts. + pub const MAX_SCHEDULE_TIMEOUT: c_long = c_long::MAX; +--- a/rust/kernel/time.rs ++++ b/rust/kernel/time.rs +@@ -12,10 +12,10 @@ + pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64; + + /// The time unit of Linux kernel. One jiffy equals (1/HZ) second. +-pub type Jiffies = core::ffi::c_ulong; ++pub type Jiffies = crate::ffi::c_ulong; + + /// The millisecond time unit. +-pub type Msecs = core::ffi::c_uint; ++pub type Msecs = crate::ffi::c_uint; + + /// Converts milliseconds to jiffies. + #[inline] +--- a/rust/kernel/types.rs ++++ b/rust/kernel/types.rs +@@ -29,7 +29,7 @@ pub trait ForeignOwnable: Sized { + /// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in + /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`], + /// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior. +- fn into_foreign(self) -> *const core::ffi::c_void; ++ fn into_foreign(self) -> *const crate::ffi::c_void; + + /// Borrows a foreign-owned object. + /// +@@ -37,7 +37,7 @@ pub trait ForeignOwnable: Sized { + /// + /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for + /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. +- unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Self::Borrowed<'a>; ++ unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Self::Borrowed<'a>; + + /// Converts a foreign-owned object back to a Rust-owned one. + /// +@@ -47,7 +47,7 @@ pub trait ForeignOwnable: Sized { + /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. + /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for + /// this object must have been dropped. +- unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self; ++ unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self; + + /// Tries to convert a foreign-owned object back to a Rust-owned one. + /// +@@ -58,7 +58,7 @@ pub trait ForeignOwnable: Sized { + /// + /// `ptr` must either be null or satisfy the safety requirements for + /// [`ForeignOwnable::from_foreign`]. +- unsafe fn try_from_foreign(ptr: *const core::ffi::c_void) -> Option { ++ unsafe fn try_from_foreign(ptr: *const crate::ffi::c_void) -> Option { + if ptr.is_null() { + None + } else { +@@ -72,13 +72,13 @@ pub trait ForeignOwnable: Sized { + impl ForeignOwnable for () { + type Borrowed<'a> = (); + +- fn into_foreign(self) -> *const core::ffi::c_void { ++ fn into_foreign(self) -> *const crate::ffi::c_void { + core::ptr::NonNull::dangling().as_ptr() + } + +- unsafe fn borrow<'a>(_: *const core::ffi::c_void) -> Self::Borrowed<'a> {} ++ unsafe fn borrow<'a>(_: *const crate::ffi::c_void) -> Self::Borrowed<'a> {} + +- unsafe fn from_foreign(_: *const core::ffi::c_void) -> Self {} ++ unsafe fn from_foreign(_: *const crate::ffi::c_void) -> Self {} + } + + /// Runs a cleanup function/closure when dropped. +--- a/rust/kernel/uaccess.rs ++++ b/rust/kernel/uaccess.rs +@@ -8,10 +8,10 @@ use crate::{ + alloc::Flags, + bindings, + error::Result, ++ ffi::{c_ulong, c_void}, + prelude::*, + types::{AsBytes, FromBytes}, + }; +-use core::ffi::{c_ulong, c_void}; + use core::mem::{size_of, MaybeUninit}; + + /// The type used for userspace addresses. +@@ -45,7 +45,7 @@ pub type UserPtr = usize; + /// every byte in the region. + /// + /// ```no_run +-/// use core::ffi::c_void; ++/// use kernel::ffi::c_void; + /// use kernel::error::Result; + /// use kernel::uaccess::{UserPtr, UserSlice}; + /// +@@ -67,7 +67,7 @@ pub type UserPtr = usize; + /// Example illustrating a TOCTOU (time-of-check to time-of-use) bug. + /// + /// ```no_run +-/// use core::ffi::c_void; ++/// use kernel::ffi::c_void; + /// use kernel::error::{code::EINVAL, Result}; + /// use kernel::uaccess::{UserPtr, UserSlice}; + /// +--- a/rust/macros/module.rs ++++ b/rust/macros/module.rs +@@ -253,7 +253,7 @@ pub(crate) fn module(ts: TokenStream) -> + #[doc(hidden)] + #[no_mangle] + #[link_section = \".init.text\"] +- pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{ ++ pub unsafe extern \"C\" fn init_module() -> kernel::ffi::c_int {{ + // SAFETY: This function is inaccessible to the outside due to the double + // module wrapping it. It is called exactly once by the C side via its + // unique name. +@@ -292,7 +292,7 @@ pub(crate) fn module(ts: TokenStream) -> + #[doc(hidden)] + #[link_section = \"{initcall_section}\"] + #[used] +- pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init; ++ pub static __{name}_initcall: extern \"C\" fn() -> kernel::ffi::c_int = __{name}_init; + + #[cfg(not(MODULE))] + #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] +@@ -307,7 +307,7 @@ pub(crate) fn module(ts: TokenStream) -> + #[cfg(not(MODULE))] + #[doc(hidden)] + #[no_mangle] +- pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{ ++ pub extern \"C\" fn __{name}_init() -> kernel::ffi::c_int {{ + // SAFETY: This function is inaccessible to the outside due to the double + // module wrapping it. It is called exactly once by the C side via its + // placement above in the initcall section. +@@ -330,7 +330,7 @@ pub(crate) fn module(ts: TokenStream) -> + /// # Safety + /// + /// This function must only be called once. +- unsafe fn __init() -> core::ffi::c_int {{ ++ unsafe fn __init() -> kernel::ffi::c_int {{ + match <{type_} as kernel::Module>::init(&super::super::THIS_MODULE) {{ + Ok(m) => {{ + // SAFETY: No data race, since `__MOD` can only be accessed by this diff --git a/queue-6.12/rust-workqueue-remove-unneeded.patch b/queue-6.12/rust-workqueue-remove-unneeded.patch new file mode 100644 index 0000000000..54f981c4d6 --- /dev/null +++ b/queue-6.12/rust-workqueue-remove-unneeded.patch @@ -0,0 +1,48 @@ +From stable+bounces-121456-greg=kroah.com@vger.kernel.org Fri Mar 7 23:50:44 2025 +From: Miguel Ojeda +Date: Fri, 7 Mar 2025 23:49:08 +0100 +Subject: rust: workqueue: remove unneeded ``#[allow(clippy::new_ret_no_self)]` +To: Greg Kroah-Hartman , Sasha Levin , stable@vger.kernel.org +Cc: Danilo Krummrich , Alice Ryhl , Alyssa Ross , NoisyCoil , patches@lists.linux.dev, Miguel Ojeda +Message-ID: <20250307225008.779961-2-ojeda@kernel.org> + +From: Miguel Ojeda + +commit 024f9676a6d236132119832a90fb9a1a9115b41a upstream. + +Perform the same clean commit b2516f7af9d2 ("rust: kernel: remove +`#[allow(clippy::new_ret_no_self)]`") did for a case that appeared in +workqueue in parallel in commit 7324b88975c5 ("rust: workqueue: add +helper for defining work_struct fields"): + + Clippy triggered a false positive on its `new_ret_no_self` lint + when using the `pin_init!` macro. Since Rust 1.67.0, that does + not happen anymore, since Clippy learnt to not warn about + `-> impl Trait` [1][2]. + + The kernel nowadays uses Rust 1.72.1, thus remove the `#[allow]`. + + Link: https://github.com/rust-lang/rust-clippy/issues/7344 [1] + Link: https://github.com/rust-lang/rust-clippy/pull/9733 [2] + +Reviewed-by: Alice Ryhl +Reviewed-by: Trevor Gross +Tested-by: Gary Guo +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240904204347.168520-2-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/workqueue.rs | 1 - + 1 file changed, 1 deletion(-) + +--- a/rust/kernel/workqueue.rs ++++ b/rust/kernel/workqueue.rs +@@ -366,7 +366,6 @@ unsafe impl Sy + impl Work { + /// Creates a new instance of [`Work`]. + #[inline] +- #[allow(clippy::new_ret_no_self)] + pub fn new(name: &'static CStr, key: &'static LockClassKey) -> impl PinInit + where + T: WorkItem, diff --git a/queue-6.12/series b/queue-6.12/series index 571fcb345c..75f195d5c0 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -9,3 +9,63 @@ smb311-failure-to-open-files-of-length-1040-when-mou.patch btrfs-fix-data-overwriting-bug-during-buffered-write.patch x86-microcode-amd-add-some-forgotten-models-to-the-sha-check.patch loongarch-use-asm_reachable.patch +rust-workqueue-remove-unneeded.patch +rust-sort-global-rust-flags.patch +rust-types-avoid-repetition-in-as-from-bytes-impls.patch +rust-enable-clippy-undocumented_unsafe_blocks-lint.patch +rust-enable-clippy-unnecessary_safety_comment-lint.patch +rust-enable-clippy-unnecessary_safety_doc-lint.patch +rust-enable-clippy-ignored_unit_patterns-lint.patch +rust-enable-rustdoc-unescaped_backticks-lint.patch +rust-init-remove-unneeded.patch +rust-sync-remove-unneeded.patch +rust-introduce-.clippy.toml.patch +rust-replace-clippy-dbg_macro-with-disallowed_macros.patch +rust-provide-proper-code-documentation-titles.patch +rust-enable-clippy-s-check-private-items.patch +documentation-rust-add-coding-guidelines-on-lints.patch +rust-start-using-the-attribute.patch +documentation-rust-discuss-in-the-guidelines.patch +rust-error-make-conversion-functions-public.patch +rust-error-optimize-error-type-to-use-nonzero.patch +rust-alloc-add-allocator-trait.patch +rust-alloc-separate-aligned_size-from-krealloc_aligned.patch +rust-alloc-rename-kernelallocator-to-kmalloc.patch +rust-alloc-implement-reallocfunc.patch +rust-alloc-make-allocator-module-public.patch +rust-alloc-implement-allocator-for-kmalloc.patch +rust-alloc-add-module-allocator_test.patch +rust-alloc-implement-vmalloc-allocator.patch +rust-alloc-implement-kvmalloc-allocator.patch +rust-alloc-add-__gfp_nowarn-to-flags.patch +rust-alloc-implement-kernel-box.patch +rust-treewide-switch-to-our-kernel-box-type.patch +rust-alloc-remove-extension-of-std-s-box.patch +rust-alloc-add-box-to-prelude.patch +rust-alloc-introduce-arraylayout.patch +rust-alloc-implement-kernel-vec-type.patch +rust-alloc-implement-intoiterator-for-vec.patch +rust-alloc-implement-collect-for-intoiter.patch +rust-treewide-switch-to-the-kernel-vec-type.patch +rust-alloc-remove-vecext-extension.patch +rust-alloc-add-vec-to-prelude.patch +rust-error-use-core-alloc-layouterror.patch +rust-error-check-for-config-test-in-error-name.patch +rust-alloc-implement-contains-for-flags.patch +rust-alloc-implement-cmalloc-in-module-allocator_test.patch +rust-str-test-replace-alloc-format.patch +rust-alloc-update-module-comment-of-alloc.rs.patch +kbuild-rust-remove-the-alloc-crate-and-globalalloc.patch +maintainers-add-entry-for-the-rust-alloc-module.patch +drm-panic-avoid-reimplementing-iterator-find.patch +drm-panic-remove-unnecessary-borrow-in-alignment_pattern.patch +drm-panic-prefer-eliding-lifetimes.patch +drm-panic-remove-redundant-field-when-assigning-value.patch +drm-panic-correctly-indent-continuation-of-line-in-list-item.patch +drm-panic-allow-verbose-boolean-for-clarity.patch +drm-panic-allow-verbose-version-check.patch +rust-kbuild-expand-rusttest-target-for-macros.patch +rust-fix-size_t-in-bindgen-prototypes-of-c-builtins.patch +rust-map-__kernel_size_t-and-friends-also-to-usize-isize.patch +rust-use-custom-ffi-integer-types.patch +rust-alloc-fix-arraylayout-allocations.patch -- 2.47.3