--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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.
--- /dev/null
+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;
+ }
--- /dev/null
+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 {
--- /dev/null
+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 {
--- /dev/null
+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();
--- /dev/null
+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,
--- /dev/null
+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] {
--- /dev/null
+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,
+ )
+
--- /dev/null
+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>
--- /dev/null
+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.
--- /dev/null
+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)) };
++ }
++}
--- /dev/null
+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;
--- /dev/null
+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!();
++ }
++}
--- /dev/null
+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};
--- /dev/null
+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,
--- /dev/null
+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 {
--- /dev/null
+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()))
+ }
+ }
--- /dev/null
+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,
--- /dev/null
+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 {
--- /dev/null
+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>,
++ }
++ }
++}
--- /dev/null
+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};
--- /dev/null
+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;
--- /dev/null
+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(
--- /dev/null
+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 {
--- /dev/null
+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(
--- /dev/null
+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() }
++ }
++}
--- /dev/null
+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;
+
--- /dev/null
+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> = ();
+
--- /dev/null
+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};
--- /dev/null
+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]
--- /dev/null
+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
--- /dev/null
+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;
--- /dev/null
+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())
+ }
+ }
+
--- /dev/null
+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,
--- /dev/null
+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,
--- /dev/null
+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) };
--- /dev/null
+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) \
--- /dev/null
+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)
--- /dev/null
+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
+ }
--- /dev/null
+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>,
--- /dev/null
+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 {
--- /dev/null
+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;
--- /dev/null
+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
--- /dev/null
+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]
--- /dev/null
+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
--- /dev/null
+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)
+ /// ```
+ ///
--- /dev/null
+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"));
--- /dev/null
+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,
--- /dev/null
+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::*;
+
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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\
--- /dev/null
+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 {}
+
--- /dev/null
+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,
+ /// }
+ ///
--- /dev/null
+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)?;
--- /dev/null
+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],
++}
--- /dev/null
+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
--- /dev/null
+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>,
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