]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Mar 2025 09:46:47 +0000 (10:46 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Mar 2025 09:46:47 +0000 (10:46 +0100)
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

61 files changed:
queue-6.12/documentation-rust-add-coding-guidelines-on-lints.patch [new file with mode: 0644]
queue-6.12/documentation-rust-discuss-in-the-guidelines.patch [new file with mode: 0644]
queue-6.12/drm-panic-allow-verbose-boolean-for-clarity.patch [new file with mode: 0644]
queue-6.12/drm-panic-allow-verbose-version-check.patch [new file with mode: 0644]
queue-6.12/drm-panic-avoid-reimplementing-iterator-find.patch [new file with mode: 0644]
queue-6.12/drm-panic-correctly-indent-continuation-of-line-in-list-item.patch [new file with mode: 0644]
queue-6.12/drm-panic-prefer-eliding-lifetimes.patch [new file with mode: 0644]
queue-6.12/drm-panic-remove-redundant-field-when-assigning-value.patch [new file with mode: 0644]
queue-6.12/drm-panic-remove-unnecessary-borrow-in-alignment_pattern.patch [new file with mode: 0644]
queue-6.12/kbuild-rust-remove-the-alloc-crate-and-globalalloc.patch [new file with mode: 0644]
queue-6.12/maintainers-add-entry-for-the-rust-alloc-module.patch [new file with mode: 0644]
queue-6.12/rust-alloc-add-__gfp_nowarn-to-flags.patch [new file with mode: 0644]
queue-6.12/rust-alloc-add-allocator-trait.patch [new file with mode: 0644]
queue-6.12/rust-alloc-add-box-to-prelude.patch [new file with mode: 0644]
queue-6.12/rust-alloc-add-module-allocator_test.patch [new file with mode: 0644]
queue-6.12/rust-alloc-add-vec-to-prelude.patch [new file with mode: 0644]
queue-6.12/rust-alloc-fix-arraylayout-allocations.patch [new file with mode: 0644]
queue-6.12/rust-alloc-implement-allocator-for-kmalloc.patch [new file with mode: 0644]
queue-6.12/rust-alloc-implement-cmalloc-in-module-allocator_test.patch [new file with mode: 0644]
queue-6.12/rust-alloc-implement-collect-for-intoiter.patch [new file with mode: 0644]
queue-6.12/rust-alloc-implement-contains-for-flags.patch [new file with mode: 0644]
queue-6.12/rust-alloc-implement-intoiterator-for-vec.patch [new file with mode: 0644]
queue-6.12/rust-alloc-implement-kernel-box.patch [new file with mode: 0644]
queue-6.12/rust-alloc-implement-kernel-vec-type.patch [new file with mode: 0644]
queue-6.12/rust-alloc-implement-kvmalloc-allocator.patch [new file with mode: 0644]
queue-6.12/rust-alloc-implement-reallocfunc.patch [new file with mode: 0644]
queue-6.12/rust-alloc-implement-vmalloc-allocator.patch [new file with mode: 0644]
queue-6.12/rust-alloc-introduce-arraylayout.patch [new file with mode: 0644]
queue-6.12/rust-alloc-make-allocator-module-public.patch [new file with mode: 0644]
queue-6.12/rust-alloc-remove-extension-of-std-s-box.patch [new file with mode: 0644]
queue-6.12/rust-alloc-remove-vecext-extension.patch [new file with mode: 0644]
queue-6.12/rust-alloc-rename-kernelallocator-to-kmalloc.patch [new file with mode: 0644]
queue-6.12/rust-alloc-separate-aligned_size-from-krealloc_aligned.patch [new file with mode: 0644]
queue-6.12/rust-alloc-update-module-comment-of-alloc.rs.patch [new file with mode: 0644]
queue-6.12/rust-enable-clippy-ignored_unit_patterns-lint.patch [new file with mode: 0644]
queue-6.12/rust-enable-clippy-s-check-private-items.patch [new file with mode: 0644]
queue-6.12/rust-enable-clippy-undocumented_unsafe_blocks-lint.patch [new file with mode: 0644]
queue-6.12/rust-enable-clippy-unnecessary_safety_comment-lint.patch [new file with mode: 0644]
queue-6.12/rust-enable-clippy-unnecessary_safety_doc-lint.patch [new file with mode: 0644]
queue-6.12/rust-enable-rustdoc-unescaped_backticks-lint.patch [new file with mode: 0644]
queue-6.12/rust-error-check-for-config-test-in-error-name.patch [new file with mode: 0644]
queue-6.12/rust-error-make-conversion-functions-public.patch [new file with mode: 0644]
queue-6.12/rust-error-optimize-error-type-to-use-nonzero.patch [new file with mode: 0644]
queue-6.12/rust-error-use-core-alloc-layouterror.patch [new file with mode: 0644]
queue-6.12/rust-fix-size_t-in-bindgen-prototypes-of-c-builtins.patch [new file with mode: 0644]
queue-6.12/rust-init-remove-unneeded.patch [new file with mode: 0644]
queue-6.12/rust-introduce-.clippy.toml.patch [new file with mode: 0644]
queue-6.12/rust-kbuild-expand-rusttest-target-for-macros.patch [new file with mode: 0644]
queue-6.12/rust-map-__kernel_size_t-and-friends-also-to-usize-isize.patch [new file with mode: 0644]
queue-6.12/rust-provide-proper-code-documentation-titles.patch [new file with mode: 0644]
queue-6.12/rust-replace-clippy-dbg_macro-with-disallowed_macros.patch [new file with mode: 0644]
queue-6.12/rust-sort-global-rust-flags.patch [new file with mode: 0644]
queue-6.12/rust-start-using-the-attribute.patch [new file with mode: 0644]
queue-6.12/rust-str-test-replace-alloc-format.patch [new file with mode: 0644]
queue-6.12/rust-sync-remove-unneeded.patch [new file with mode: 0644]
queue-6.12/rust-treewide-switch-to-our-kernel-box-type.patch [new file with mode: 0644]
queue-6.12/rust-treewide-switch-to-the-kernel-vec-type.patch [new file with mode: 0644]
queue-6.12/rust-types-avoid-repetition-in-as-from-bytes-impls.patch [new file with mode: 0644]
queue-6.12/rust-use-custom-ffi-integer-types.patch [new file with mode: 0644]
queue-6.12/rust-workqueue-remove-unneeded.patch [new file with mode: 0644]
queue-6.12/series

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 (file)
index 0000000..b93b907
--- /dev/null
@@ -0,0 +1,79 @@
+From stable+bounces-121470-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:23 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:22 +0100
+Subject: Documentation: rust: add coding guidelines on lints
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-16-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <tmgross@umich.edu>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-17-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..b0e0e1d
--- /dev/null
@@ -0,0 +1,145 @@
+From stable+bounces-121472-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:27 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:24 +0100
+Subject: Documentation: rust: discuss `#[expect(...)]` in the guidelines
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-18-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-19-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..7b0a0fa
--- /dev/null
@@ -0,0 +1,61 @@
+From stable+bounces-121509-greg=kroah.com@vger.kernel.org Fri Mar  7 23:53:06 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:50:01 +0100
+Subject: drm/panic: allow verbose boolean for clarity
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-55-ojeda@kernel.org>
+
+From: Thomas Böhler <witcher@wiredspace.de>
+
+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 <ojeda@kernel.org>
+Link: https://github.com/Rust-for-Linux/linux/issues/1123
+Signed-off-by: Thomas Böhler <witcher@wiredspace.de>
+Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
+Link: https://lore.kernel.org/r/20241019084048.22336-7-witcher@wiredspace.de
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..5355d82
--- /dev/null
@@ -0,0 +1,49 @@
+From stable+bounces-121510-greg=kroah.com@vger.kernel.org Fri Mar  7 23:53:09 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:50:02 +0100
+Subject: drm/panic: allow verbose version check
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-56-ojeda@kernel.org>
+
+From: Thomas Böhler <witcher@wiredspace.de>
+
+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 <ojeda@kernel.org>
+Link: https://github.com/Rust-for-Linux/linux/issues/1123
+Signed-off-by: Thomas Böhler <witcher@wiredspace.de>
+Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
+Link: https://lore.kernel.org/r/20241019084048.22336-8-witcher@wiredspace.de
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..2a8fd7e
--- /dev/null
@@ -0,0 +1,80 @@
+From stable+bounces-121504-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:51 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:56 +0100
+Subject: drm/panic: avoid reimplementing Iterator::find
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-50-ojeda@kernel.org>
+
+From: Thomas Böhler <witcher@wiredspace.de>
+
+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 <ojeda@kernel.org>
+Link: https://github.com/Rust-for-Linux/linux/issues/1123
+Signed-off-by: Thomas Böhler <witcher@wiredspace.de>
+Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<Version> {
+-        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 (file)
index 0000000..1048aca
--- /dev/null
@@ -0,0 +1,57 @@
+From stable+bounces-121508-greg=kroah.com@vger.kernel.org Fri Mar  7 23:53:09 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:50:00 +0100
+Subject: drm/panic: correctly indent continuation of line in list item
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-54-ojeda@kernel.org>
+
+From: Thomas Böhler <witcher@wiredspace.de>
+
+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 <ojeda@kernel.org>
+Link: https://github.com/Rust-for-Linux/linux/issues/1123
+Signed-off-by: Thomas Böhler <witcher@wiredspace.de>
+Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
+Link: https://lore.kernel.org/r/20241019084048.22336-6-witcher@wiredspace.de
+[ Reworded to indent Clippy's message. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..ba0f461
--- /dev/null
@@ -0,0 +1,56 @@
+From stable+bounces-121506-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:57 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:58 +0100
+Subject: drm/panic: prefer eliding lifetimes
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-52-ojeda@kernel.org>
+
+From: Thomas Böhler <witcher@wiredspace.de>
+
+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<EncodedMsg<'a>> {
+        |                ^^                       ^^
+        |
+        = 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<EncodedMsg<'a>> {
+    479 +     fn new<'a>(segments: &[&Segment<'_>], data: &'a mut [u8]) -> Option<EncodedMsg<'a>> {
+        |
+
+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 <ojeda@kernel.org>
+Link: https://github.com/Rust-for-Linux/linux/issues/1123
+Signed-off-by: Thomas Böhler <witcher@wiredspace.de>
+Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
+Link: https://lore.kernel.org/r/20241019084048.22336-4-witcher@wiredspace.de
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<EncodedMsg<'a>> {
++    fn new<'a>(segments: &[&Segment<'_>], data: &'a mut [u8]) -> Option<EncodedMsg<'a>> {
+         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 (file)
index 0000000..60641a2
--- /dev/null
@@ -0,0 +1,54 @@
+From stable+bounces-121507-greg=kroah.com@vger.kernel.org Fri Mar  7 23:53:06 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:59 +0100
+Subject: drm/panic: remove redundant field when assigning value
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-53-ojeda@kernel.org>
+
+From: Thomas Böhler <witcher@wiredspace.de>
+
+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 <ojeda@kernel.org>
+Link: https://github.com/Rust-for-Linux/linux/issues/1123
+Signed-off-by: Thomas Böhler <witcher@wiredspace.de>
+Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..12a8e8f
--- /dev/null
@@ -0,0 +1,53 @@
+From stable+bounces-121505-greg=kroah.com@vger.kernel.org Fri Mar  7 23:53:05 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:57 +0100
+Subject: drm/panic: remove unnecessary borrow in alignment_pattern
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-51-ojeda@kernel.org>
+
+From: Thomas Böhler <witcher@wiredspace.de>
+
+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 <ojeda@kernel.org>
+Link: https://github.com/Rust-for-Linux/linux/issues/1123
+Signed-off-by: Thomas Böhler <witcher@wiredspace.de>
+Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
+Link: https://lore.kernel.org/r/20241019084048.22336-3-witcher@wiredspace.de
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..5117899
--- /dev/null
@@ -0,0 +1,306 @@
+From stable+bounces-121502-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:59 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:54 +0100
+Subject: kbuild: rust: remove the `alloc` crate and `GlobalAlloc`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-48-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-29-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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: <https://docs.kernel.org/core-api/memory-allocation.html>
+-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 <https://github.com/rust-lang/rust/pull/86844>.
+-#[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 (file)
index 0000000..ca3331e
--- /dev/null
@@ -0,0 +1,43 @@
+From stable+bounces-121503-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:51 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:55 +0100
+Subject: MAINTAINERS: add entry for the Rust `alloc` module
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-49-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-30-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <dakr@kernel.org>
++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 <dhowells@redhat.com>
+ M:    Marc Dionne <marc.dionne@auristor.com>
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 (file)
index 0000000..a8fe365
--- /dev/null
@@ -0,0 +1,49 @@
+From stable+bounces-121484-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:11 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:36 +0100
+Subject: rust: alloc: add __GFP_NOWARN to `Flags`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-30-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-11-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..ef84c4f
--- /dev/null
@@ -0,0 +1,145 @@
+From stable+bounces-121475-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:36 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:27 +0100
+Subject: rust: alloc: add `Allocator` trait
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-21-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-2-dakr@kernel.org
+[ Fixed typo. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
++    /// <https://docs.kernel.org/core-api/mm-api.html#mm-api-gfp-flags>.
++    fn alloc(layout: Layout, flags: Flags) -> Result<NonNull<[u8]>, 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<NonNull<u8>>,
++        layout: Layout,
++        old_layout: Layout,
++        flags: Flags,
++    ) -> Result<NonNull<[u8]>, 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<u8>, 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 (file)
index 0000000..55c2b73
--- /dev/null
@@ -0,0 +1,37 @@
+From stable+bounces-121488-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:17 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:40 +0100
+Subject: rust: alloc: add `Box` to prelude
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-34-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-15-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..d8d8c73
--- /dev/null
@@ -0,0 +1,79 @@
+From stable+bounces-121481-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:53 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:33 +0100
+Subject: rust: alloc: add module `allocator_test`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-27-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<NonNull<u8>>,
++        _layout: Layout,
++        _old_layout: Layout,
++        _flags: Flags,
++    ) -> Result<NonNull<[u8]>, 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 (file)
index 0000000..7bba0da
--- /dev/null
@@ -0,0 +1,37 @@
+From stable+bounces-121495-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:37 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:47 +0100
+Subject: rust: alloc: add `Vec` to prelude
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-41-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-22-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..4df7b88
--- /dev/null
@@ -0,0 +1,40 @@
+From stable+bounces-121515-greg=kroah.com@vger.kernel.org Fri Mar  7 23:53:26 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:50:07 +0100
+Subject: rust: alloc: Fix `ArrayLayout` allocations
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-61-ojeda@kernel.org>
+
+From: Asahi Lina <lina@asahilina.net>
+
+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 <j@jannau.net>
+Fixes: 9e7bbfa18276 ("rust: alloc: introduce `ArrayLayout`")
+Signed-off-by: Asahi Lina <lina@asahilina.net>
+Acked-by: Danilo Krummrich <dakr@kernel.org>
+Reviewed-by: Neal Gompa <neal@gompa.dev>
+Link: https://lore.kernel.org/r/20241123-rust-fix-arraylayout-v1-1-197e64c95bd4@asahilina.net
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T> ArrayLayout<T> {
+     /// When `len * size_of::<T>()` overflows or when `len * size_of::<T>() > isize::MAX`.
+     pub const fn new(len: usize) -> Result<Self, LayoutError> {
+         match len.checked_mul(core::mem::size_of::<T>()) {
+-            Some(len) if len <= ISIZE_MAX => {
++            Some(size) if size <= ISIZE_MAX => {
+                 // INVARIANT: We checked above that `len * size_of::<T>() <= 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 (file)
index 0000000..5530ee7
--- /dev/null
@@ -0,0 +1,87 @@
+From stable+bounces-121480-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:53 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:32 +0100
+Subject: rust: alloc: implement `Allocator` for `Kmalloc`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-26-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-7-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<NonNull<u8>>,
++        layout: Layout,
++        old_layout: Layout,
++        flags: Flags,
++    ) -> Result<NonNull<[u8]>, 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 (file)
index 0000000..d55c95b
--- /dev/null
@@ -0,0 +1,150 @@
+From stable+bounces-121499-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:44 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:51 +0100
+Subject: rust: alloc: implement `Cmalloc` in module allocator_test
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-45-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<u8> {
+     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<NonNull<u8>>,
+-        _layout: Layout,
+-        _old_layout: Layout,
+-        _flags: Flags,
++        ptr: Option<NonNull<u8>>,
++        layout: Layout,
++        old_layout: Layout,
++        flags: Flags,
+     ) -> Result<NonNull<[u8]>, 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 (file)
index 0000000..e8c08c3
--- /dev/null
@@ -0,0 +1,145 @@
+From stable+bounces-121492-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:20 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:44 +0100
+Subject: rust: alloc: implement `collect` for `IntoIter`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-38-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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<Self, AllocError>`, 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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T, A: Allocator> {
+     _p: PhantomData<A>,
+ }
++impl<T, A> IntoIter<T, A>
++where
++    A: Allocator,
++{
++    fn into_raw_parts(self) -> (*mut T, NonNull<T>, 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<Self, AllocError>`, 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<T, A> {
++        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::<T>()` bytes,
++            // - `buf.as_ptr()` is valid for writes of `len * size_of::<T>()` 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::<T>::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<T, A> Iterator for IntoIter<T, A>
+ 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 (file)
index 0000000..99f00d8
--- /dev/null
@@ -0,0 +1,52 @@
+From stable+bounces-121498-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:55 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:50 +0100
+Subject: rust: alloc: implement `contains` for `Flags`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-44-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-25-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..ed72fc7
--- /dev/null
@@ -0,0 +1,223 @@
+From stable+bounces-121491-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:19 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:43 +0100
+Subject: rust: alloc: implement `IntoIterator` for `Vec`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-37-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-18-dakr@kernel.org
+[ Fixed typos. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T, A>, [U; N],
+     [A: Allocator, const N: usize] Vec<T, A>, &[U; N],
+ }
++
++impl<'a, T, A> IntoIterator for &'a Vec<T, A>
++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<T, A>
++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<T, A: Allocator> {
++    ptr: *mut T,
++    buf: NonNull<T>,
++    len: usize,
++    layout: ArrayLayout<T>,
++    _p: PhantomData<A>,
++}
++
++impl<T, A> Iterator for IntoIter<T, A>
++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<T> {
++        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<u32> = 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<usize>) {
++        (self.len, Some(self.len))
++    }
++}
++
++impl<T, A> Drop for IntoIter<T, A>
++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<T, A> IntoIterator for Vec<T, A>
++where
++    A: Allocator,
++{
++    type Item = T;
++    type IntoIter = IntoIter<T, A>;
++
++    /// Consumes the `Vec<T, A>` 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<u32> = 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<u32> = 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::<A>,
++        }
++    }
++}
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 (file)
index 0000000..5da35cc
--- /dev/null
@@ -0,0 +1,527 @@
+From stable+bounces-121485-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:12 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:37 +0100
+Subject: rust: alloc: implement kernel `Box`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-31-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-12-dakr@kernel.org
+[ Added backticks, fixed typos. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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::<u64>::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::<Huge>::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::<Huge>::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<T: ?Sized, A: Allocator>(NonNull<T>, PhantomData<A>);
++
++/// 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<T> = Box<T, super::allocator::Kmalloc>;
++
++/// 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<T> = Box<T, super::allocator::Vmalloc>;
++
++/// 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<T> = Box<T, super::allocator::KVmalloc>;
++
++// SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`.
++unsafe impl<T, A> Send for Box<T, A>
++where
++    T: Send + ?Sized,
++    A: Allocator,
++{
++}
++
++// SAFETY: `Box` is `Sync` if `T` is `Sync` because the `Box` owns a `T`.
++unsafe impl<T, A> Sync for Box<T, A>
++where
++    T: Sync + ?Sized,
++    A: Allocator,
++{
++}
++
++impl<T, A> Box<T, A>
++where
++    T: ?Sized,
++    A: Allocator,
++{
++    /// Creates a new `Box<T, A>` 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<T, A>` 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<T, A>` 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<T, A> Box<MaybeUninit<T>, A>
++where
++    A: Allocator,
++{
++    /// Converts a `Box<MaybeUninit<T>, A>` to a `Box<T, A>`.
++    ///
++    /// 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<T, A> {
++        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<T, A>`.
++        unsafe { Box::from_raw(raw.cast()) }
++    }
++
++    /// Writes the value and converts to `Box<T, A>`.
++    pub fn write(mut self, value: T) -> Box<T, A> {
++        (*self).write(value);
++
++        // SAFETY: We've just initialized `b`'s value.
++        unsafe { self.assume_init() }
++    }
++}
++
++impl<T, A> Box<T, A>
++where
++    A: Allocator,
++{
++    /// Creates a new `Box<T, A>` 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<Self, AllocError> {
++        let b = Self::new_uninit(flags)?;
++        Ok(Box::write(b, x))
++    }
++
++    /// Creates a new `Box<T, A>` 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::<u64>::new_uninit(GFP_KERNEL)?;
++    /// let b = KBox::write(b, 24);
++    ///
++    /// assert_eq!(*b, 24_u64);
++    /// # Ok::<(), Error>(())
++    /// ```
++    pub fn new_uninit(flags: Flags) -> Result<Box<MaybeUninit<T>, A>, AllocError> {
++        let layout = Layout::new::<MaybeUninit<T>>();
++        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<Box<T, A>>`. 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<Pin<Box<T, A>>, 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<MaybeUninit<T>, 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<MaybeUninit<T>, 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<T, A> From<Box<T, A>> for Pin<Box<T, A>>
++where
++    T: ?Sized,
++    A: Allocator,
++{
++    /// Converts a `Box<T, A>` into a `Pin<Box<T, A>>`. 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<T, A>) -> Self {
++        // SAFETY: The value wrapped inside a `Pin<Box<T, A>>` cannot be moved or replaced as long
++        // as `T` does not implement `Unpin`.
++        unsafe { Pin::new_unchecked(b) }
++    }
++}
++
++impl<T, A> InPlaceWrite<T> for Box<MaybeUninit<T>, A>
++where
++    A: Allocator + 'static,
++{
++    type Initialized = Box<T, A>;
++
++    fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> {
++        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<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, 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<T, A> InPlaceInit<T> for Box<T, A>
++where
++    A: Allocator + 'static,
++{
++    type PinnedSelf = Pin<Self>;
++
++    #[inline]
++    fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E>
++    where
++        E: From<AllocError>,
++    {
++        Box::<_, A>::new_uninit(flags)?.write_pin_init(init)
++    }
++
++    #[inline]
++    fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
++    where
++        E: From<AllocError>,
++    {
++        Box::<_, A>::new_uninit(flags)?.write_init(init)
++    }
++}
++
++impl<T: 'static, A> ForeignOwnable for Box<T, A>
++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<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
++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<Box<T>>`.
++        unsafe { Pin::new_unchecked(r) }
++    }
++}
++
++impl<T, A> Deref for Box<T, A>
++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<T, A> DerefMut for Box<T, A>
++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<T, A> fmt::Debug for Box<T, A>
++where
++    T: ?Sized + fmt::Debug,
++    A: Allocator,
++{
++    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
++        fmt::Debug::fmt(&**self, f)
++    }
++}
++
++impl<T, A> Drop for Box<T, A>
++where
++    T: ?Sized,
++    A: Allocator,
++{
++    fn drop(&mut self) {
++        let layout = Layout::for_value::<T>(self);
++
++        // SAFETY: The pointer in `self.0` is guaranteed to be valid by the type invariant.
++        unsafe { core::ptr::drop_in_place::<T>(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 (file)
index 0000000..b95740b
--- /dev/null
@@ -0,0 +1,735 @@
+From stable+bounces-121490-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:17 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:42 +0100
+Subject: rust: alloc: implement kernel `Vec` type
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-36-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T, A>`.
++///
++/// 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::<T>`; 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<T, A: Allocator> {
++    ptr: NonNull<T>,
++    /// Represents the actual buffer size as `cap` times `size_of::<T>` 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<T>,
++    len: usize,
++    _p: PhantomData<A>,
++}
++
++/// 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<T> = Vec<T, Kmalloc>;
++
++/// 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<T> = Vec<T, Vmalloc>;
++
++/// 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<T> = Vec<T, KVmalloc>;
++
++// SAFETY: `Vec` is `Send` if `T` is `Send` because `Vec` owns its elements.
++unsafe impl<T, A> Send for Vec<T, A>
++where
++    T: Send,
++    A: Allocator,
++{
++}
++
++// SAFETY: `Vec` is `Sync` if `T` is `Sync` because `Vec` owns its elements.
++unsafe impl<T, A> Sync for Vec<T, A>
++where
++    T: Sync,
++    A: Allocator,
++{
++}
++
++impl<T, A> Vec<T, A>
++where
++    A: Allocator,
++{
++    #[inline]
++    const fn is_zst() -> bool {
++        core::mem::size_of::<T>() == 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<T, A>`.
++    ///
++    /// 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::<A>,
++        }
++    }
++
++    /// Returns a slice of `MaybeUninit<T>` for the remaining spare capacity of the vector.
++    pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
++        // 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<T>;
++
++        // 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::<u32>::with_capacity(20, GFP_KERNEL)?;
++    ///
++    /// assert!(v.capacity() >= 20);
++    /// # Ok::<(), Error>(())
++    /// ```
++    pub fn with_capacity(capacity: usize, flags: Flags) -> Result<Self, AllocError> {
++        let mut v = Vec::new();
++
++        v.reserve(capacity, flags)?;
++
++        Ok(v)
++    }
++
++    /// Creates a `Vec<T, A>` 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::<T>() * 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::<T>()` 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::<A>,
++        }
++    }
++
++    /// Consumes the `Vec<T, A>` 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::<T>`,
++        // - `ptr` has been created by `A::realloc` from `layout`.
++        self.ptr = ptr.cast();
++        self.layout = layout;
++
++        Ok(())
++    }
++}
++
++impl<T: Clone, A: Allocator> Vec<T, A> {
++    /// 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<T, A>` and extend it by `n` clones of `value`.
++    pub fn from_elem(value: T, n: usize, flags: Flags) -> Result<Self, AllocError> {
++        let mut v = Self::with_capacity(n, flags)?;
++
++        v.extend_with(n, value, flags)?;
++
++        Ok(v)
++    }
++}
++
++impl<T, A> Drop for Vec<T, A>
++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<T, A, const N: usize> From<Box<[T; N], A>> for Vec<T, A>
++where
++    A: Allocator,
++{
++    fn from(b: Box<[T; N], A>) -> Vec<T, A> {
++        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::<T>() * 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<T> Default for KVec<T> {
++    #[inline]
++    fn default() -> Self {
++        Self::new()
++    }
++}
++
++impl<T: fmt::Debug, A: Allocator> fmt::Debug for Vec<T, A> {
++    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
++        fmt::Debug::fmt(&**self, f)
++    }
++}
++
++impl<T, A> Deref for Vec<T, A>
++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<T, A> DerefMut for Vec<T, A>
++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<T: Eq, A> Eq for Vec<T, A> where A: Allocator {}
++
++impl<T, I: SliceIndex<[T]>, A> Index<I> for Vec<T, A>
++where
++    A: Allocator,
++{
++    type Output = I::Output;
++
++    #[inline]
++    fn index(&self, index: I) -> &Self::Output {
++        Index::index(&**self, index)
++    }
++}
++
++impl<T, I: SliceIndex<[T]>, A> IndexMut<I> for Vec<T, A>
++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<T, U, $($vars)*> PartialEq<$rhs> for $lhs
++            where
++                T: PartialEq<U>,
++            {
++                #[inline]
++                fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] }
++            }
++        )*
++    }
++}
++
++impl_slice_eq! {
++    [A1: Allocator, A2: Allocator] Vec<T, A1>, Vec<U, A2>,
++    [A: Allocator] Vec<T, A>, &[U],
++    [A: Allocator] Vec<T, A>, &mut [U],
++    [A: Allocator] &[T], Vec<U, A>,
++    [A: Allocator] &mut [T], Vec<U, A>,
++    [A: Allocator] Vec<T, A>, [U],
++    [A: Allocator] [T], Vec<U, A>,
++    [A: Allocator, const N: usize] Vec<T, A>, [U; N],
++    [A: Allocator, const N: usize] Vec<T, A>, &[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 (file)
index 0000000..e6ea16d
--- /dev/null
@@ -0,0 +1,114 @@
+From stable+bounces-121483-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:08 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:35 +0100
+Subject: rust: alloc: implement `KVmalloc` allocator
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-29-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-10-dakr@kernel.org
+[ Reworded typo. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<NonNull<u8>>,
++        layout: Layout,
++        old_layout: Layout,
++        flags: Flags,
++    ) -> Result<NonNull<[u8]>, 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 (file)
index 0000000..bdfe578
--- /dev/null
@@ -0,0 +1,139 @@
+From stable+bounces-121478-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:42 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:30 +0100
+Subject: rust: alloc: implement `ReallocFunc`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-24-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<u8> {
++    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: <https://docs.kernel.org/core-api/memory-allocation.html>
+ 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<NonNull<u8>>,
++        layout: Layout,
++        old_layout: Layout,
++        flags: Flags,
++    ) -> Result<NonNull<[u8]>, 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 (file)
index 0000000..e0700c2
--- /dev/null
@@ -0,0 +1,131 @@
+From stable+bounces-121482-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:58 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:34 +0100
+Subject: rust: alloc: implement `Vmalloc` allocator
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-28-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-9-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/vmalloc.h>
++
++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<NonNull<u8>>,
++        layout: Layout,
++        old_layout: Layout,
++        flags: Flags,
++    ) -> Result<NonNull<[u8]>, 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 (file)
index 0000000..f2616e6
--- /dev/null
@@ -0,0 +1,139 @@
+From stable+bounces-121489-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:14 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:41 +0100
+Subject: rust: alloc: introduce `ArrayLayout`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-35-ojeda@kernel.org>
+
+From: Benno Lossin <benno.lossin@proton.me>
+
+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 <gary@garyguo.net>
+Signed-off-by: Benno Lossin <benno.lossin@proton.me>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-16-dakr@kernel.org
+[ Formatted a few comments. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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::<T>() <= isize::MAX`.
++pub struct ArrayLayout<T> {
++    len: usize,
++    _phantom: PhantomData<fn() -> T>,
++}
++
++impl<T> Clone for ArrayLayout<T> {
++    fn clone(&self) -> Self {
++        *self
++    }
++}
++impl<T> Copy for ArrayLayout<T> {}
++
++const ISIZE_MAX: usize = isize::MAX as usize;
++
++impl<T> ArrayLayout<T> {
++    /// Creates a new layout for `[T; 0]`.
++    pub const fn empty() -> Self {
++        // INVARIANT: `0 * size_of::<T>() <= isize::MAX`.
++        Self {
++            len: 0,
++            _phantom: PhantomData,
++        }
++    }
++
++    /// Creates a new layout for `[T; len]`.
++    ///
++    /// # Errors
++    ///
++    /// When `len * size_of::<T>()` overflows or when `len * size_of::<T>() > isize::MAX`.
++    pub const fn new(len: usize) -> Result<Self, LayoutError> {
++        match len.checked_mul(core::mem::size_of::<T>()) {
++            Some(len) if len <= ISIZE_MAX => {
++                // INVARIANT: We checked above that `len * size_of::<T>() <= 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::<T>() <= isize::MAX` is true.
++    pub unsafe fn new_unchecked(len: usize) -> Self {
++        // INVARIANT: By the safety requirements of this function
++        // `len * size_of::<T>() <= 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<T> From<ArrayLayout<T>> for Layout {
++    fn from(value: ArrayLayout<T>) -> Self {
++        let res = Layout::array::<T>(value.len);
++        // SAFETY: By the type invariant of `ArrayLayout` we have
++        // `len * size_of::<T>() <= 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 (file)
index 0000000..b0e0a55
--- /dev/null
@@ -0,0 +1,37 @@
+From stable+bounces-121479-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:46 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:31 +0100
+Subject: rust: alloc: make `allocator` module public
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-25-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-6-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..a473a25
--- /dev/null
@@ -0,0 +1,311 @@
+From stable+bounces-121487-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:15 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:39 +0100
+Subject: rust: alloc: remove extension of std's `Box`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-33-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-14-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T>: Sized {
+-    /// Allocates a new box.
+-    ///
+-    /// The allocation may fail, in which case an error is returned.
+-    fn new(x: T, flags: Flags) -> Result<Self, AllocError>;
+-
+-    /// Allocates a new uninitialised box.
+-    ///
+-    /// The allocation may fail, in which case an error is returned.
+-    fn new_uninit(flags: Flags) -> Result<Box<MaybeUninit<T>>, 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<MaybeUninit<T>>;
+-}
+-
+-impl<T> BoxExt<T> for Box<T> {
+-    fn new(x: T, flags: Flags) -> Result<Self, AllocError> {
+-        let mut b = <Self as BoxExt<_>>::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<Box<MaybeUninit<T>>, AllocError> {
+-        Ok(Box::new_uninit())
+-    }
+-
+-    #[cfg(not(any(test, testlib)))]
+-    fn new_uninit(flags: Flags) -> Result<Box<MaybeUninit<T>>, AllocError> {
+-        let ptr = if core::mem::size_of::<MaybeUninit<T>>() == 0 {
+-            core::ptr::NonNull::<_>::dangling().as_ptr()
+-        } else {
+-            let layout = core::alloc::Layout::new::<MaybeUninit<T>>();
+-
+-            // 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::<MaybeUninit<T>>()
+-        };
+-
+-        // 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<MaybeUninit<T>> {
+-        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<T>` is a transparent wrapper of `T`.
+-        let ptr = ptr.cast::<MaybeUninit<T>>();
+-
+-        // 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<T>`.
+-        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<T> InPlaceInit<T> for Arc<T> {
+     }
+ }
+-impl<T> InPlaceInit<T> for Box<T> {
+-    type PinnedSelf = Pin<Self>;
+-
+-    #[inline]
+-    fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E>
+-    where
+-        E: From<AllocError>,
+-    {
+-        <Box<_> as BoxExt<_>>::new_uninit(flags)?.write_pin_init(init)
+-    }
+-
+-    #[inline]
+-    fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
+-    where
+-        E: From<AllocError>,
+-    {
+-        <Box<_> as BoxExt<_>>::new_uninit(flags)?.write_init(init)
+-    }
+-}
+-
+ impl<T> InPlaceInit<T> for UniqueArc<T> {
+     type PinnedSelf = Pin<Self>;
+@@ -1301,28 +1279,6 @@ pub trait InPlaceWrite<T> {
+     fn write_pin_init<E>(self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E>;
+ }
+-impl<T> InPlaceWrite<T> for Box<MaybeUninit<T>> {
+-    type Initialized = Box<T>;
+-
+-    fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> {
+-        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<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, 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<T> InPlaceWrite<T> for UniqueArc<MaybeUninit<T>> {
+     type Initialized = UniqueArc<T>;
+--- 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<T: 'static> ForeignOwnable for Box<T> {
+-    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<T: 'static> ForeignOwnable for Pin<Box<T>> {
+-    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<Box<T>>`.
+-        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 (file)
index 0000000..03c646a
--- /dev/null
@@ -0,0 +1,241 @@
+From stable+bounces-121494-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:46 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:46 +0100
+Subject: rust: alloc: remove `VecExt` extension
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-40-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+commit 405966efc789888c3e1a53cd09d2c2b338064438 upstream.
+
+Now that all existing `Vec` users were moved to the kernel `Vec` type,
+remove the `VecExt` extension.
+
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-21-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T>: Sized {
+-    /// Creates a new [`Vec`] instance with at least the given capacity.
+-    ///
+-    /// # Examples
+-    ///
+-    /// ```
+-    /// let v = Vec::<u32>::with_capacity(20, GFP_KERNEL)?;
+-    ///
+-    /// assert!(v.capacity() >= 20);
+-    /// # Ok::<(), Error>(())
+-    /// ```
+-    fn with_capacity(capacity: usize, flags: Flags) -> Result<Self, AllocError>;
+-
+-    /// 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<T> VecExt<T> for Vec<T> {
+-    fn with_capacity(capacity: usize, flags: Flags) -> Result<Self, AllocError> {
+-        let mut v = Vec::new();
+-        <Self as VecExt<_>>::reserve(&mut v, capacity, flags)?;
+-        Ok(v)
+-    }
+-
+-    fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> {
+-        <Self as VecExt<_>>::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,
+-    {
+-        <Self as VecExt<_>>::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::<T>() == 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::<T>(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<T>`'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<T>`'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::<T>(), len, new_cap) };
+-            Ok(())
+-        }
+-    }
+-}
+-
+-#[cfg(not(any(test, testlib)))]
+-fn destructure<T>(v: &mut Vec<T>) -> (*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<T>(v: &mut Vec<T>, 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 (file)
index 0000000..52b2a41
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-121477-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:40 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:29 +0100
+Subject: rust: alloc: rename `KernelAllocator` to `Kmalloc`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-23-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+commit 941e65531446c1eb5d573c5d30172117ebe96112 upstream.
+
+Subsequent patches implement `Vmalloc` and `KVmalloc` allocators, hence
+align `KernelAllocator` to this naming scheme.
+
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-4-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <https://github.com/rust-lang/rust/pull/86844>.
+ #[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 (file)
index 0000000..ed6ec40
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-121476-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:37 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:28 +0100
+Subject: rust: alloc: separate `aligned_size` from `krealloc_aligned`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-22-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-3-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..df98ffe
--- /dev/null
@@ -0,0 +1,39 @@
+From stable+bounces-121501-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:59 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:53 +0100
+Subject: rust: alloc: update module comment of alloc.rs
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-47-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-28-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..544b339
--- /dev/null
@@ -0,0 +1,65 @@
+From stable+bounces-121462-greg=kroah.com@vger.kernel.org Fri Mar  7 23:50:59 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:14 +0100
+Subject: rust: enable `clippy::ignored_unit_patterns` lint
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-8-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-8-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T, F: FnOnce(T)> ScopeGuard<T, F> {
+ 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 (file)
index 0000000..5eb5347
--- /dev/null
@@ -0,0 +1,100 @@
+From stable+bounces-121469-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:20 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:21 +0100
+Subject: rust: enable Clippy's `check-private-items`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-15-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <tmgross@umich.edu>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-16-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .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 (file)
index 0000000..d72ad51
--- /dev/null
@@ -0,0 +1,413 @@
+From stable+bounces-121459-greg=kroah.com@vger.kernel.org Fri Mar  7 23:50:50 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:11 +0100
+Subject: rust: enable `clippy::undocumented_unsafe_blocks` lint
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-5-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-5-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T>(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<T>(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<T: ?Sized, E =
+     /// }
+     ///
+     /// let foo = pin_init!(Foo {
++    ///     // SAFETY: TODO.
+     ///     raw <- unsafe {
+     ///         Opaque::ffi_init(|s| {
+     ///             init_foo(s);
+@@ -1162,6 +1164,7 @@ where
+ // SAFETY: Every type can be initialized by-value.
+ unsafe impl<T, E> Init<T, E> for T {
+     unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
++        // SAFETY: TODO.
+         unsafe { slot.write(self) };
+         Ok(())
+     }
+@@ -1170,6 +1173,7 @@ unsafe impl<T, E> Init<T, E> for T {
+ // SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`.
+ unsafe impl<T, E> PinInit<T, E> 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<T: Zeroable>() -> 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<T: ?Sized> Clone for AllData<T> {
+ impl<T: ?Sized> Copy for AllData<T> {}
++// SAFETY: TODO.
+ unsafe impl<T: ?Sized> InitData for AllData<T> {
+     type Datee = T;
+ }
++// SAFETY: TODO.
+ unsafe impl<T: ?Sized> HasInitData for T {
+     type InitData = AllData<T>;
+--- 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<T: ?Sized + ListItem<ID>, const ID:
+     ///
+     /// `item` must not be in a different linked list (with the same id).
+     pub unsafe fn remove(&mut self, item: &T) -> Option<ListArc<T, ID>> {
++        // 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<T: ?Sized, B: Backend> 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<T: AlwaysRefCounted> ARef<T> {
+     ///
+     /// struct Empty {}
+     ///
++    /// # // SAFETY: TODO.
+     /// unsafe impl AlwaysRefCounted for Empty {
+     ///     fn inc_ref(&self) {}
+     ///     unsafe fn dec_ref(_obj: NonNull<Self>) {}
+@@ -417,6 +418,7 @@ impl<T: AlwaysRefCounted> ARef<T> {
+     ///
+     /// let mut data = Empty {};
+     /// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();
++    /// # // SAFETY: TODO.
+     /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
+     /// let raw_ptr: NonNull<Empty> = 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<Self> for ClosureWork<T> { self.work }
+ }
++// SAFETY: TODO.
+ unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Arc<T>
+ where
+     T: WorkItem<ID, Pointer = Self>,
+@@ -536,6 +537,7 @@ where
+     }
+ }
++// SAFETY: TODO.
+ unsafe impl<T, const ID: u64> RawWorkItem<ID> for Arc<T>
+ where
+     T: WorkItem<ID, Pointer = Self>,
+@@ -564,6 +566,7 @@ where
+     }
+ }
++// SAFETY: TODO.
+ unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<Box<T>>
+ where
+     T: WorkItem<ID, Pointer = Self>,
+@@ -583,6 +586,7 @@ where
+     }
+ }
++// SAFETY: TODO.
+ unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<Box<T>>
+ where
+     T: WorkItem<ID, Pointer = Self>,
+--- 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 (file)
index 0000000..091c1bd
--- /dev/null
@@ -0,0 +1,77 @@
+From stable+bounces-121460-greg=kroah.com@vger.kernel.org Fri Mar  7 23:50:52 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:12 +0100
+Subject: rust: enable `clippy::unnecessary_safety_comment` lint
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-6-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-6-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T: 'static> 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<T>).unwrap();
+--- a/rust/kernel/workqueue.rs
++++ b/rust/kernel/workqueue.rs
+@@ -526,7 +526,7 @@ where
+     T: HasWork<T, ID>,
+ {
+     unsafe extern "C" fn run(ptr: *mut bindings::work_struct) {
+-        // SAFETY: The `__enqueue` method always uses a `work_struct` stored in a `Work<T, ID>`.
++        // The `__enqueue` method always uses a `work_struct` stored in a `Work<T, ID>`.
+         let ptr = ptr as *mut Work<T, ID>;
+         // 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<T, ID>,
+ {
+     unsafe extern "C" fn run(ptr: *mut bindings::work_struct) {
+-        // SAFETY: The `__enqueue` method always uses a `work_struct` stored in a `Work<T, ID>`.
++        // The `__enqueue` method always uses a `work_struct` stored in a `Work<T, ID>`.
+         let ptr = ptr as *mut Work<T, ID>;
+         // 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 (file)
index 0000000..305fc28
--- /dev/null
@@ -0,0 +1,41 @@
+From stable+bounces-121461-greg=kroah.com@vger.kernel.org Fri Mar  7 23:50:58 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:13 +0100
+Subject: rust: enable `clippy::unnecessary_safety_doc` lint
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-7-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <tmgross@umich.edu>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-7-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..f0f4971
--- /dev/null
@@ -0,0 +1,74 @@
+From stable+bounces-121463-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:00 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:15 +0100
+Subject: rust: enable `rustdoc::unescaped_backticks` lint
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-9-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <tmgross@umich.edu>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-9-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..53dc14c
--- /dev/null
@@ -0,0 +1,47 @@
+From stable+bounces-121497-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:54 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:49 +0100
+Subject: rust: error: check for config `test` in `Error::name`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-43-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-24-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..d96462a
--- /dev/null
@@ -0,0 +1,71 @@
+From stable+bounces-121473-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:29 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:25 +0100
+Subject: rust: error: make conversion functions public
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-19-ojeda@kernel.org>
+
+From: Filipe Xavier <felipe_life@live.com>
+
+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 <aliceryhl@google.com>
+Signed-off-by: Filipe Xavier <felipe_life@live.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/DM4PR14MB7276E6948E67B3B23D8EA847E9652@DM4PR14MB7276.namprd14.prod.outlook.com
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T>(self) -> *mut T {
++    pub fn to_ptr<T>(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<T>(ptr: *mut T) -> Result<*mut T> {
++pub fn from_err_ptr<T>(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<T>(ptr: *mut
+ ///     })
+ /// }
+ /// ```
+-// TODO: Remove `dead_code` marker once an in-kernel client is available.
+-#[allow(dead_code)]
+-pub(crate) fn from_result<T, F>(f: F) -> T
++pub fn from_result<T, F>(f: F) -> T
+ where
+     T: From<i16>,
+     F: FnOnce() -> Result<T>,
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 (file)
index 0000000..9414b87
--- /dev/null
@@ -0,0 +1,132 @@
+From stable+bounces-121474-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:30 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:26 +0100
+Subject: rust: error: optimize error type to use nonzero
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-20-ojeda@kernel.org>
+
+From: Filipe Xavier <felipe_life@live.com>
+
+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 <felipe_life@live.com>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Reviewed-by: Fiona Behrens <me@kloenk.dev>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<Error> {
++        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 (file)
index 0000000..2d57f73
--- /dev/null
@@ -0,0 +1,37 @@
+From stable+bounces-121496-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:38 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:48 +0100
+Subject: rust: error: use `core::alloc::LayoutError`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-42-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-23-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..2951ccc
--- /dev/null
@@ -0,0 +1,70 @@
+From stable+bounces-121512-greg=kroah.com@vger.kernel.org Fri Mar  7 23:53:18 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:50:04 +0100
+Subject: rust: fix size_t in bindgen prototypes of C builtins
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-58-ojeda@kernel.org>
+
+From: Gary Guo <gary@garyguo.net>
+
+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 <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240913213041.395655-2-gary@garyguo.net
+[ Formatted comment. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..929190b
--- /dev/null
@@ -0,0 +1,61 @@
+From stable+bounces-121464-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:07 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:16 +0100
+Subject: rust: init: remove unneeded `#[allow(clippy::disallowed_names)]`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-10-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-10-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T, E>`]:
+ //!
+ //! ```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 (file)
index 0000000..fbd50b3
--- /dev/null
@@ -0,0 +1,75 @@
+From stable+bounces-121466-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:09 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:18 +0100
+Subject: rust: introduce `.clippy.toml`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-12-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-12-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .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 (file)
index 0000000..0f89187
--- /dev/null
@@ -0,0 +1,85 @@
+From stable+bounces-121511-greg=kroah.com@vger.kernel.org Fri Mar  7 23:53:11 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:50:03 +0100
+Subject: rust: kbuild: expand rusttest target for macros
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-57-ojeda@kernel.org>
+
+From: "Ethan D. Twardy" <ethan.twardy@gmail.com>
+
+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 <ethan.twardy@gmail.com>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..b037fd3
--- /dev/null
@@ -0,0 +1,73 @@
+From stable+bounces-121513-greg=kroah.com@vger.kernel.org Fri Mar  7 23:53:16 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+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 <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-59-ojeda@kernel.org>
+
+From: Gary Guo <gary@garyguo.net>
+
+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 <gary@garyguo.net>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Link: https://lore.kernel.org/r/20240913213041.395655-3-gary@garyguo.net
+[ Formatted comment. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..a3b57e5
--- /dev/null
@@ -0,0 +1,102 @@
+From stable+bounces-121468-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:16 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:20 +0100
+Subject: rust: provide proper code documentation titles
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-14-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <https://github.com/rust-lang/rust> repository, licensed under
+    5 | | //! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details,
+    6 | | //! see <https://github.com/rust-lang/rust/blob/master/COPYRIGHT>.
+      | |_
+      |
+      = 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 <tmgross@umich.edu>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-15-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T> = PhantomData<fn(*mut T) -> *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<F, T: ?Sized, E>(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 <https://github.com/rust-lang/rust> 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 <https://github.com/rust-lang/rust> 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 (file)
index 0000000..d01c32e
--- /dev/null
@@ -0,0 +1,133 @@
+From stable+bounces-121467-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:13 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:19 +0100
+Subject: rust: replace `clippy::dbg_macro` with `disallowed_macros`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-13-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-13-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .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 (file)
index 0000000..4840ec1
--- /dev/null
@@ -0,0 +1,52 @@
+From stable+bounces-121457-greg=kroah.com@vger.kernel.org Fri Mar  7 23:50:49 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:09 +0100
+Subject: rust: sort global Rust flags
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-3-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <tmgross@umich.edu>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-3-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..44f8ecb
--- /dev/null
@@ -0,0 +1,380 @@
+From stable+bounces-121471-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:25 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:23 +0100
+Subject: rust: start using the `#[expect(...)]` attribute
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-17-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <xfrednet@gmail.com>
+Cc: Urgau <urgau@numericable.fr>
+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 <aliceryhl@google.com>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-18-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T>(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<T: ?Sized, E =
+     /// # Examples
+     ///
+     /// ```rust
+-    /// # #![allow(clippy::disallowed_names)]
++    /// # #![expect(clippy::disallowed_names)]
+     /// use kernel::{types::Opaque, init::pin_init_from_closure};
+     /// #[repr(C)]
+     /// struct RawFoo([u8; 16]);
+@@ -964,7 +964,7 @@ pub unsafe trait Init<T: ?Sized, E = Inf
+     /// # Examples
+     ///
+     /// ```rust
+-    /// # #![allow(clippy::disallowed_names)]
++    /// # #![expect(clippy::disallowed_names)]
+     /// use kernel::{types::Opaque, init::{self, init_from_closure}};
+     /// struct Foo {
+     ///     buf: [u8; 1_000_000],
+--- a/rust/kernel/init/__internal.rs
++++ b/rust/kernel/init/__internal.rs
+@@ -54,7 +54,7 @@ where
+ pub unsafe trait HasPinData {
+     type PinData: PinData;
+-    #[allow(clippy::missing_safety_doc)]
++    #[expect(clippy::missing_safety_doc)]
+     unsafe fn __pin_data() -> 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<T: ::core::ops::Drop> MustNotImplDrop for T {}
+ //!     impl<T> MustNotImplDrop for Bar<T> {}
+ //!     // 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<T: ::core::ops::Drop> 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<T: $crate::init::PinnedDrop>
+             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<T, const ID: u64> ListArcField<T, I
+     ///
+     /// The caller must have mutable access to the `ListArc<ID>` 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 (file)
index 0000000..54c464b
--- /dev/null
@@ -0,0 +1,64 @@
+From stable+bounces-121500-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:58 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:52 +0100
+Subject: rust: str: test: replace `alloc::format`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-46-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-27-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..0959ef5
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-121465-greg=kroah.com@vger.kernel.org Fri Mar  7 23:51:07 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+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 <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-11-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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<T, B>` 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 <aliceryhl@google.com>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-11-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..a608abe
--- /dev/null
@@ -0,0 +1,625 @@
+From stable+bounces-121486-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:11 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:38 +0100
+Subject: rust: treewide: switch to our kernel `Box` type
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-32-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20241004154149.93856-13-dakr@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<Box<Mutex<GenDisk<NullBlkDevice>>>>,
++    _disk: Pin<KBox<Mutex<GenDisk<NullBlkDevice>>>>,
+ }
+ 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<T>`],
+-//!   [`UniqueArc<T>`], [`Box<T>`] or any other smart pointer that implements [`InPlaceInit`]).
++//!   [`UniqueArc<T>`], [`KBox<T>`] 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<Pin<Box<Foo>>> = Box::pin_init(foo, GFP_KERNEL);
++//! let foo: Result<Pin<KBox<Foo>>> = KBox::pin_init(foo, GFP_KERNEL);
+ //! ```
+ //!
+ //! For more information see the [`pin_init!`] macro.
+@@ -92,14 +92,14 @@
+ //! struct DriverData {
+ //!     #[pin]
+ //!     status: Mutex<i32>,
+-//!     buffer: Box<[u8; 1_000_000]>,
++//!     buffer: KBox<[u8; 1_000_000]>,
+ //! }
+ //!
+ //! impl DriverData {
+ //!     fn new() -> impl PinInit<Self, Error> {
+ //!         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<usize>,
+-///     b: Box<Bar>,
++///     b: KBox<Bar>,
+ /// }
+ ///
+ /// struct Bar {
+@@ -307,7 +307,7 @@ macro_rules! stack_pin_init {
+ ///
+ /// stack_try_pin_init!(let foo: Result<Pin<&mut Foo>, 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<usize>,
+-///     b: Box<Bar>,
++///     b: KBox<Bar>,
+ /// }
+ ///
+ /// 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<Self, Error> {
+ ///         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<Self, Error> {
+ ///         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<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use the
+-/// [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc<T>`] on this.
++/// be [`KBox<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use
++/// the [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc<T>`] on this.
+ ///
+ /// Also see the [module description](self).
+ ///
+@@ -893,7 +893,7 @@ pub unsafe trait PinInit<T: ?Sized, E =
+ }
+ /// An initializer returned by [`PinInit::pin_chain`].
+-pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, Box<T>)>);
++pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, KBox<T>)>);
+ // 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<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use the
+-/// [`InPlaceInit::init`] function of a smart pointer like [`Arc<T>`] on this. Because
++/// be [`KBox<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use
++/// the [`InPlaceInit::init`] function of a smart pointer like [`Arc<T>`] on this. Because
+ /// [`PinInit<T, E>`] 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<T: ?Sized, E = Inf
+ }
+ /// An initializer returned by [`Init::chain`].
+-pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, Box<T>)>);
++pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, KBox<T>)>);
+ // SAFETY: The `__init` function is implemented such that it
+ // - returns `Ok(())` on successful initialization,
+@@ -1076,8 +1076,9 @@ pub fn uninit<T, E>() -> impl Init<Maybe
+ /// # Examples
+ ///
+ /// ```rust
+-/// use kernel::{error::Error, init::init_array_from_fn};
+-/// let array: Box<[usize; 1_000]> = Box::init::<Error>(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::<Error>(init_array_from_fn(|i| i), GFP_KERNEL).unwrap();
+ /// assert_eq!(array.len(), 1_000);
+ /// ```
+ pub fn init_array_from_fn<I, const N: usize, T, E>(
+@@ -1453,7 +1454,7 @@ impl_zeroable! {
+     //
+     // In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant.
+     {<T: ?Sized>} Option<NonNull<T>>,
+-    {<T: ?Sized>} Option<Box<T>>,
++    {<T: ?Sized>} Option<KBox<T>>,
+     // 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<T: ?Sized>(PhantomData<fn(Box<T>) -> Box<T>>);
++pub struct AllData<T: ?Sized>(PhantomData<fn(KBox<T>) -> KBox<T>>);
+ impl<T: ?Sized> Clone for AllData<T> {
+     fn clone(&self) -> Self {
+--- a/rust/kernel/rbtree.rs
++++ b/rust/kernel/rbtree.rs
+@@ -7,7 +7,6 @@
+ //! Reference: <https://docs.kernel.org/core-api/rbtree.html>
+ 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<K, V> Drop for RBTree<K, V> {
+             // 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<K, V>` objects.
+         let this = unsafe { container_of!(self.current.as_ptr(), Node<K, V>, 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<K, V>` objects.
+             let this = unsafe { container_of!(neighbor, Node<K, V>, 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<K, V> Iterator for IterRaw<K, V> {
+ /// 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<K, V> {
+-    node: Box<MaybeUninit<Node<K, V>>>,
++    node: KBox<MaybeUninit<Node<K, V>>>,
+ }
+ impl<K, V> RBTreeNodeReservation<K, V> {
+@@ -1046,7 +1045,7 @@ impl<K, V> RBTreeNodeReservation<K, V> {
+     /// call to [`RBTree::insert`].
+     pub fn new(flags: Flags) -> Result<RBTreeNodeReservation<K, V>> {
+         Ok(RBTreeNodeReservation {
+-            node: <Box<_> as BoxExt<_>>::new_uninit(flags)?,
++            node: KBox::new_uninit(flags)?,
+         })
+     }
+ }
+@@ -1062,14 +1061,15 @@ impl<K, V> RBTreeNodeReservation<K, V> {
+     /// 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<K, V> {
+-        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<K, V> {
++        let node = KBox::write(
++            self.node,
++            Node {
++                key,
++                value,
++                links: bindings::rb_node::default(),
++            },
++        );
+         RBTreeNode { node }
+     }
+ }
+@@ -1079,7 +1079,7 @@ impl<K, V> RBTreeNodeReservation<K, V> {
+ /// 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<K, V> {
+-    node: Box<Node<K, V>>,
++    node: KBox<Node<K, V>>,
+ }
+ impl<K, V> RBTreeNode<K, V> {
+@@ -1091,7 +1091,9 @@ impl<K, V> RBTreeNode<K, V> {
+     /// 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<K, V> RBTreeNode<K, V> {
+     /// may be freed (but only for the key/value; memory for the node itself is kept for reuse).
+     pub fn into_reservation(self) -> RBTreeNodeReservation<K, V> {
+         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<K, V>) -> &'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<K, V>, links).cast_mut())
++                KBox::from_raw(container_of!(self.node_links, Node<K, V>, 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<K, V>) -> RBTreeNode<K, 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.
+@@ -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<K, V>, links).cast_mut()) };
++            unsafe { KBox::from_raw(container_of!(self.node_links, Node<K, V>, 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<T> Arc<T> {
+             data: contents,
+         };
+-        let inner = <Box<_> 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<T: ?Sized> Drop for Arc<T> {
+         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<T> UniqueArc<T> {
+     /// Tries to allocate a new [`UniqueArc`] instance whose contents are not initialised yet.
+     pub fn new_uninit(flags: Flags) -> Result<UniqueArc<MaybeUninit<T>>, AllocError> {
+         // INVARIANT: The refcount is initialised to a non-zero value.
+-        let inner = Box::try_init::<AllocError>(
++        let inner = KBox::try_init::<AllocError>(
+             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<T> UniqueArc<T> {
+         )?;
+         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<Pin<Box<Example>>> {
+-///     Box::pin_init(pin_init!(Example {
++/// fn new_example() -> Result<Pin<KBox<Example>>> {
++///     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<T> ClosureWork<T> {
+ }
+ impl<T: FnOnce()> WorkItem for ClosureWork<T> {
+-    type Pointer = Pin<Box<Self>>;
++    type Pointer = Pin<KBox<Self>>;
+-    fn run(mut this: Pin<Box<Self>>) {
++    fn run(mut this: Pin<KBox<Self>>) {
+         if let Some(func) = this.as_mut().project().take() {
+             (func)()
+         }
+@@ -297,7 +297,7 @@ pub unsafe trait RawWorkItem<const ID: u
+ /// Defines the method that should be called directly when a work item is executed.
+ ///
+-/// This trait is implemented by `Pin<Box<T>>` and [`Arc<T>`], and is mainly intended to be
++/// This trait is implemented by `Pin<KBox<T>>` and [`Arc<T>`], 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<const I
+ /// This trait is used when the `work_struct` field is defined using the [`Work`] helper.
+ pub trait WorkItem<const ID: u64 = 0> {
+     /// The pointer type that this struct is wrapped in. This will typically be `Arc<Self>` or
+-    /// `Pin<Box<Self>>`.
++    /// `Pin<KBox<Self>>`.
+     type Pointer: WorkItemPointer<ID>;
+     /// The method that should be called when this work item is executed.
+@@ -567,7 +567,7 @@ where
+ }
+ // SAFETY: TODO.
+-unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<Box<T>>
++unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Pin<KBox<T>>
+ where
+     T: WorkItem<ID, Pointer = Self>,
+     T: HasWork<T, ID>,
+@@ -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<T, const ID: u64> RawWorkItem<ID> for Pin<Box<T>>
++unsafe impl<T, const ID: u64> RawWorkItem<ID> for Pin<KBox<T>>
+ where
+     T: WorkItem<ID, Pointer = Self>,
+     T: HasWork<T, ID>,
+@@ -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<Vec<Command>>,
+-///     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<Vec<Command>>,
+-///     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<Vec<Command>>,
+-///     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 (file)
index 0000000..ef90c46
--- /dev/null
@@ -0,0 +1,239 @@
+From stable+bounces-121493-greg=kroah.com@vger.kernel.org Fri Mar  7 23:52:26 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:45 +0100
+Subject: rust: treewide: switch to the kernel `Vec` type
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-39-ojeda@kernel.org>
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<u8> = Vec::new();
++    let mut v: KVec<u8> = 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<u8>,
++    buf: KVec<u8>,
+ }
+ 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 = <Vec<_> 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<CString, AllocError> {
+-        let mut buf = Vec::new();
++        let mut buf = KVec::new();
+-        <Vec<_> 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<File>,
++///     _files: KVec<File>,
+ /// }
+ ///
+ /// 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<bool> {
+ ///     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<Vec<u8>> {
++/// fn get_bytes_if_valid(uptr: UserPtr, len: usize) -> Result<KVec<u8>> {
+ ///     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<u8>, flags: Flags) -> Result {
++    pub fn read_all(self, buf: &mut KVec<u8>, 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<u8>, flags: Flags) -> Result {
++    pub fn read_all(mut self, buf: &mut KVec<u8>, flags: Flags) -> Result {
+         let len = self.length;
+-        VecExt::<u8>::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<Vec<Command>>,
++///     queue: Mutex<KVec<Command>>,
+ ///     buf: KBox<[u8; 1024 * 1024]>,
+ /// }
+ /// ```
+@@ -251,7 +251,7 @@ pub fn concat_idents(ts: TokenStream) ->
+ /// #[pin_data(PinnedDrop)]
+ /// struct DriverData {
+ ///     #[pin]
+-///     queue: Mutex<Vec<Command>>,
++///     queue: Mutex<KVec<Command>>,
+ ///     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<Vec<Command>>,
++///     queue: Mutex<KVec<Command>>,
+ ///     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<i32>,
++    numbers: KVec<i32>,
+ }
+ 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 (file)
index 0000000..ae532dd
--- /dev/null
@@ -0,0 +1,118 @@
+From stable+bounces-121458-greg=kroah.com@vger.kernel.org Fri Mar  7 23:50:48 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:10 +0100
+Subject: rust: types: avoid repetition in `{As,From}Bytes` impls
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-4-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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 <aliceryhl@google.com>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-4-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<L, R> {
+ /// 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<T: FromBytes> FromBytes for [T] {}
+-unsafe impl<T: FromBytes, const N: usize> 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: FromBytes>} [T],
++    {<T: FromBytes, const N: usize>} [T; N],
++}
+ /// Types that can be viewed as an immutable slice of initialized bytes.
+ ///
+@@ -514,21 +515,22 @@ unsafe impl<T: FromBytes, const N: usize
+ /// mutability.
+ pub unsafe trait AsBytes {}
+-// SAFETY: Instances of the following types have no uninitialized portions.
+-unsafe impl AsBytes for u8 {}
+-unsafe impl AsBytes for u16 {}
+-unsafe impl AsBytes for u32 {}
+-unsafe impl AsBytes for u64 {}
+-unsafe impl AsBytes for usize {}
+-unsafe impl AsBytes for i8 {}
+-unsafe impl AsBytes for i16 {}
+-unsafe impl AsBytes for i32 {}
+-unsafe impl AsBytes for i64 {}
+-unsafe impl AsBytes for isize {}
+-unsafe impl AsBytes for bool {}
+-unsafe impl AsBytes for char {}
+-unsafe impl AsBytes for str {}
+-// SAFETY: If individual values in an array have no uninitialized portions, then the array itself
+-// does not have any uninitialized portions either.
+-unsafe impl<T: AsBytes> AsBytes for [T] {}
+-unsafe impl<T: AsBytes, const N: usize> 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: AsBytes>} [T],
++    {<T: AsBytes, const N: usize>} [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 (file)
index 0000000..0d38b0f
--- /dev/null
@@ -0,0 +1,767 @@
+From stable+bounces-121514-greg=kroah.com@vger.kernel.org Fri Mar  7 23:53:20 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:50:06 +0100
+Subject: rust: use custom FFI integer types
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-60-ojeda@kernel.org>
+
+From: Gary Guo <gary@garyguo.net>
+
+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 <gary@garyguo.net>
+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 <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T: Operations> OperationsVTable<T>
+     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<T: Operations> OperationsVTable<T>
+     /// 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<T: Operations> OperationsVTable<T>
+     /// 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<T: Operations> OperationsVTable<T>
+     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<T: Operations> OperationsVTable<T>
+     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<const N: usize>(
+-        a: &'a mut [core::ffi::c_char; N],
++        a: &'a mut [crate::ffi::c_char; N],
+     ) -> Result<RawWriter<'a>> {
+         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<T: Operations> TagSet<T> {
+                     queue_depth: num_tags,
+                     cmd_size,
+                     flags: bindings::BLK_MQ_F_SHOULD_MERGE,
+-                    driver_data: core::ptr::null_mut::<core::ffi::c_void>(),
++                    driver_data: core::ptr::null_mut::<crate::ffi::c_void>(),
+                     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<Error> {
++    const fn try_from_errno(errno: crate::ffi::c_int) -> Option<Error> {
+         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<T = (), E = Error> = 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<T>(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<T>(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<T>(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<T: Driver> Adapter<T> {
+     /// `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<T: Driver> Adapter<T> {
+     /// # 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<T: Driver> Adapter<T> {
+     /// `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<T: Driver> Adapter<T> {
+     /// # 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<T: Driver> Adapter<T> {
+     /// # 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<T: Driver> Adapter<T> {
+     /// `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<T: Driver> Adapter<T> {
+     /// `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<T: Driver> Adapter<T> {
+     /// `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<T: ?Sized> Arc<T> {
+ impl<T: 'static> ForeignOwnable for Arc<T> {
+     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<T>).unwrap();
+@@ -346,7 +346,7 @@ impl<T: 'static> 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<Self> {
++    unsafe fn try_from_foreign(ptr: *const crate::ffi::c_void) -> Option<Self> {
+         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 (file)
index 0000000..54f981c
--- /dev/null
@@ -0,0 +1,48 @@
+From stable+bounces-121456-greg=kroah.com@vger.kernel.org Fri Mar  7 23:50:44 2025
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Fri,  7 Mar 2025 23:49:08 +0100
+Subject: rust: workqueue: remove unneeded ``#[allow(clippy::new_ret_no_self)]`
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, stable@vger.kernel.org
+Cc: Danilo Krummrich <dakr@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>, NoisyCoil <noisycoil@disroot.org>, patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
+Message-ID: <20250307225008.779961-2-ojeda@kernel.org>
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+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<Self>` [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 <aliceryhl@google.com>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Tested-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://lore.kernel.org/r/20240904204347.168520-2-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<T: ?Sized, const ID: u64> Sy
+ impl<T: ?Sized, const ID: u64> Work<T, ID> {
+     /// Creates a new instance of [`Work`].
+     #[inline]
+-    #[allow(clippy::new_ret_no_self)]
+     pub fn new(name: &'static CStr, key: &'static LockClassKey) -> impl PinInit<Self>
+     where
+         T: WorkItem<ID>,
index 571fcb345cae06a8744d94670e0db6ffaf68a2be..75f195d5c0d717264ffb23b69f02817f7d3e5cf1 100644 (file)
@@ -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