Skip to content

Commit 798bb34

Browse files
committed
Merge tag 'rust-6.13' of https://github.com/Rust-for-Linux/linux
Pull rust updates from Miguel Ojeda: "Toolchain and infrastructure: - Enable a series of lints, including safety-related ones, e.g. the compiler will now warn about missing safety comments, as well as unnecessary ones. How safety documentation is organized is a frequent source of review comments, thus having the compiler guide new developers on where they are expected (and where not) is very nice. - Start using '#[expect]': an interesting feature in Rust (stabilized in 1.81.0) that makes the compiler warn if an expected warning was _not_ emitted. This is useful to avoid forgetting cleaning up locally ignored diagnostics ('#[allow]'s). - Introduce '.clippy.toml' configuration file for Clippy, the Rust linter, which will allow us to tweak its behaviour. For instance, our first use cases are declaring a disallowed macro and, more importantly, enabling the checking of private items. - Lints-related fixes and cleanups related to the items above. - Migrate from 'receiver_trait' to 'arbitrary_self_types': to get the kernel into stable Rust, one of the major pieces of the puzzle is the support to write custom types that can be used as 'self', i.e. as receivers, since the kernel needs to write types such as 'Arc' that common userspace Rust would not. 'arbitrary_self_types' has been accepted to become stable, and this is one of the steps required to get there. - Remove usage of the 'new_uninit' unstable feature. - Use custom C FFI types. Includes a new 'ffi' crate to contain our custom mapping, instead of using the standard library 'core::ffi' one. The actual remapping will be introduced in a later cycle. - Map '__kernel_{size_t,ssize_t,ptrdiff_t}' to 'usize'/'isize' instead of 32/64-bit integers. - Fix 'size_t' in bindgen generated prototypes of C builtins. - Warn on bindgen < 0.69.5 and libclang >= 19.1 due to a double issue in the projects, which we managed to trigger with the upcoming tracepoint support. It includes a build test since some distributions backported the fix (e.g. Debian -- thanks!). All major distributions we list should be now OK except Ubuntu non-LTS. 'macros' crate: - Adapt the build system to be able run the doctests there too; and clean up and enable the corresponding doctests. 'kernel' crate: - Add 'alloc' module with generic kernel allocator support and remove the dependency on the Rust standard library 'alloc' and the extension traits we used to provide fallible methods with flags. Add the 'Allocator' trait and its implementations '{K,V,KV}malloc'. Add the 'Box' type (a heap allocation for a single value of type 'T' that is also generic over an allocator and considers the kernel's GFP flags) and its shorthand aliases '{K,V,KV}Box'. Add 'ArrayLayout' type. Add 'Vec' (a contiguous growable array type) and its shorthand aliases '{K,V,KV}Vec', including iterator support. For instance, now we may write code such as: let mut v = KVec::new(); v.push(1, GFP_KERNEL)?; assert_eq!(&v, &[1]); Treewide, move as well old users to these new types. - 'sync' module: add global lock support, including the 'GlobalLockBackend' trait; the 'Global{Lock,Guard,LockedBy}' types and the 'global_lock!' macro. Add the 'Lock::try_lock' method. - 'error' module: optimize 'Error' type to use 'NonZeroI32' and make conversion functions public. - 'page' module: add 'page_align' function. - Add 'transmute' module with the existing 'FromBytes' and 'AsBytes' traits. - 'block::mq::request' module: improve rendered documentation. - 'types' module: extend 'Opaque' type documentation and add simple examples for the 'Either' types. drm/panic: - Clean up a series of Clippy warnings. Documentation: - Add coding guidelines for lints and the '#[expect]' feature. - Add Ubuntu to the list of distributions in the Quick Start guide. MAINTAINERS: - Add Danilo Krummrich as maintainer of the new 'alloc' module. And a few other small cleanups and fixes" * tag 'rust-6.13' of https://github.com/Rust-for-Linux/linux: (82 commits) rust: alloc: Fix `ArrayLayout` allocations docs: rust: remove spurious item in `expect` list rust: allow `clippy::needless_lifetimes` rust: warn on bindgen < 0.69.5 and libclang >= 19.1 rust: use custom FFI integer types rust: map `__kernel_size_t` and friends also to usize/isize rust: fix size_t in bindgen prototypes of C builtins rust: sync: add global lock support rust: macros: enable the rest of the tests rust: macros: enable paste! use from macro_rules! rust: enable macros::module! tests rust: kbuild: expand rusttest target for macros rust: types: extend `Opaque` documentation rust: block: fix formatting of `kernel::block::mq::request` module rust: macros: fix documentation of the paste! macro rust: kernel: fix THIS_MODULE header path in ThisModule doc comment rust: page: add Rust version of PAGE_ALIGN rust: helpers: remove unnecessary header includes rust: exports: improve grammar in commentary drm/panic: allow verbose version check ...
2 parents e68ce94 + b7ed2b6 commit 798bb34

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+3172
-897
lines changed

.clippy.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
3+
check-private-items = true
4+
5+
disallowed-macros = [
6+
# The `clippy::dbg_macro` lint only works with `std::dbg!`, thus we simulate
7+
# it here, see: https://github.com/rust-lang/rust-clippy/issues/11303.
8+
{ path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool" },
9+
]

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ modules.order
103103
# We don't want to ignore the following even if they are dot-files
104104
#
105105
!.clang-format
106+
!.clippy.toml
106107
!.cocciconfig
107108
!.editorconfig
108109
!.get_maintainer.ignore

Documentation/rust/coding-guidelines.rst

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,149 @@ The equivalent in Rust may look like (ignoring documentation):
227227
That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as
228228
``gpio::LineDirection::In``. In particular, it should not be named
229229
``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``.
230+
231+
232+
Lints
233+
-----
234+
235+
In Rust, it is possible to ``allow`` particular warnings (diagnostics, lints)
236+
locally, making the compiler ignore instances of a given warning within a given
237+
function, module, block, etc.
238+
239+
It is similar to ``#pragma GCC diagnostic push`` + ``ignored`` + ``pop`` in C
240+
[#]_:
241+
242+
.. code-block:: c
243+
244+
#pragma GCC diagnostic push
245+
#pragma GCC diagnostic ignored "-Wunused-function"
246+
static void f(void) {}
247+
#pragma GCC diagnostic pop
248+
249+
.. [#] In this particular case, the kernel's ``__{always,maybe}_unused``
250+
attributes (C23's ``[[maybe_unused]]``) may be used; however, the example
251+
is meant to reflect the equivalent lint in Rust discussed afterwards.
252+
253+
But way less verbose:
254+
255+
.. code-block:: rust
256+
257+
#[allow(dead_code)]
258+
fn f() {}
259+
260+
By that virtue, it makes it possible to comfortably enable more diagnostics by
261+
default (i.e. outside ``W=`` levels). In particular, those that may have some
262+
false positives but that are otherwise quite useful to keep enabled to catch
263+
potential mistakes.
264+
265+
On top of that, Rust provides the ``expect`` attribute which takes this further.
266+
It makes the compiler warn if the warning was not produced. For instance, the
267+
following will ensure that, when ``f()`` is called somewhere, we will have to
268+
remove the attribute:
269+
270+
.. code-block:: rust
271+
272+
#[expect(dead_code)]
273+
fn f() {}
274+
275+
If we do not, we get a warning from the compiler::
276+
277+
warning: this lint expectation is unfulfilled
278+
--> x.rs:3:10
279+
|
280+
3 | #[expect(dead_code)]
281+
| ^^^^^^^^^
282+
|
283+
= note: `#[warn(unfulfilled_lint_expectations)]` on by default
284+
285+
This means that ``expect``\ s do not get forgotten when they are not needed, which
286+
may happen in several situations, e.g.:
287+
288+
- Temporary attributes added while developing.
289+
290+
- Improvements in lints in the compiler, Clippy or custom tools which may
291+
remove a false positive.
292+
293+
- When the lint is not needed anymore because it was expected that it would be
294+
removed at some point, such as the ``dead_code`` example above.
295+
296+
It also increases the visibility of the remaining ``allow``\ s and reduces the
297+
chance of misapplying one.
298+
299+
Thus prefer ``expect`` over ``allow`` unless:
300+
301+
- Conditional compilation triggers the warning in some cases but not others.
302+
303+
If there are only a few cases where the warning triggers (or does not
304+
trigger) compared to the total number of cases, then one may consider using
305+
a conditional ``expect`` (i.e. ``cfg_attr(..., expect(...))``). Otherwise,
306+
it is likely simpler to just use ``allow``.
307+
308+
- Inside macros, when the different invocations may create expanded code that
309+
triggers the warning in some cases but not in others.
310+
311+
- When code may trigger a warning for some architectures but not others, such
312+
as an ``as`` cast to a C FFI type.
313+
314+
As a more developed example, consider for instance this program:
315+
316+
.. code-block:: rust
317+
318+
fn g() {}
319+
320+
fn main() {
321+
#[cfg(CONFIG_X)]
322+
g();
323+
}
324+
325+
Here, function ``g()`` is dead code if ``CONFIG_X`` is not set. Can we use
326+
``expect`` here?
327+
328+
.. code-block:: rust
329+
330+
#[expect(dead_code)]
331+
fn g() {}
332+
333+
fn main() {
334+
#[cfg(CONFIG_X)]
335+
g();
336+
}
337+
338+
This would emit a lint if ``CONFIG_X`` is set, since it is not dead code in that
339+
configuration. Therefore, in cases like this, we cannot use ``expect`` as-is.
340+
341+
A simple possibility is using ``allow``:
342+
343+
.. code-block:: rust
344+
345+
#[allow(dead_code)]
346+
fn g() {}
347+
348+
fn main() {
349+
#[cfg(CONFIG_X)]
350+
g();
351+
}
352+
353+
An alternative would be using a conditional ``expect``:
354+
355+
.. code-block:: rust
356+
357+
#[cfg_attr(not(CONFIG_X), expect(dead_code))]
358+
fn g() {}
359+
360+
fn main() {
361+
#[cfg(CONFIG_X)]
362+
g();
363+
}
364+
365+
This would ensure that, if someone introduces another call to ``g()`` somewhere
366+
(e.g. unconditionally), then it would be spotted that it is not dead code
367+
anymore. However, the ``cfg_attr`` is more complex than a simple ``allow``.
368+
369+
Therefore, it is likely that it is not worth using conditional ``expect``\ s when
370+
more than one or two configurations are involved or when the lint may be
371+
triggered due to non-local changes (such as ``dead_code``).
372+
373+
For more information about diagnostics in Rust, please see:
374+
375+
https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html

Documentation/rust/quick-start.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,23 @@ they should generally work out of the box, e.g.::
8787
zypper install rust rust1.79-src rust-bindgen clang
8888

8989

90+
Ubuntu
91+
******
92+
93+
Ubuntu LTS and non-LTS (interim) releases provide recent Rust releases and thus
94+
they should generally work out of the box, e.g.::
95+
96+
apt install rustc-1.80 rust-1.80-src bindgen-0.65 rustfmt-1.80 rust-1.80-clippy
97+
98+
``RUST_LIB_SRC`` needs to be set when using the versioned packages, e.g.::
99+
100+
RUST_LIB_SRC=/usr/src/rustc-$(rustc-1.80 --version | cut -d' ' -f2)/library
101+
102+
In addition, ``bindgen-0.65`` is available in newer releases (24.04 LTS and
103+
24.10), but it may not be available in older ones (20.04 LTS and 22.04 LTS),
104+
thus ``bindgen`` may need to be built manually (please see below).
105+
106+
90107
Requirements: Building
91108
----------------------
92109

MAINTAINERS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20368,6 +20368,7 @@ B: https://github.com/Rust-for-Linux/linux/issues
2036820368
C: zulip://rust-for-linux.zulipchat.com
2036920369
P: https://rust-for-linux.com/contributing
2037020370
T: git https://github.com/Rust-for-Linux/linux.git rust-next
20371+
F: .clippy.toml
2037120372
F: Documentation/rust/
2037220373
F: include/trace/events/rust_sample.h
2037320374
F: rust/
@@ -20376,6 +20377,13 @@ F: scripts/*rust*
2037620377
F: tools/testing/selftests/rust/
2037720378
K: \b(?i:rust)\b
2037820379

20380+
RUST [ALLOC]
20381+
M: Danilo Krummrich <dakr@kernel.org>
20382+
L: rust-for-linux@vger.kernel.org
20383+
S: Maintained
20384+
F: rust/kernel/alloc.rs
20385+
F: rust/kernel/alloc/
20386+
2037920387
RXRPC SOCKETS (AF_RXRPC)
2038020388
M: David Howells <dhowells@redhat.com>
2038120389
M: Marc Dionne <marc.dionne@auristor.com>

Makefile

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -446,18 +446,23 @@ KBUILD_USERLDFLAGS := $(USERLDFLAGS)
446446
export rust_common_flags := --edition=2021 \
447447
-Zbinary_dep_depinfo=y \
448448
-Astable_features \
449-
-Dunsafe_op_in_unsafe_fn \
450449
-Dnon_ascii_idents \
450+
-Dunsafe_op_in_unsafe_fn \
451+
-Wmissing_docs \
451452
-Wrust_2018_idioms \
452453
-Wunreachable_pub \
453-
-Wmissing_docs \
454-
-Wrustdoc::missing_crate_level_docs \
455454
-Wclippy::all \
455+
-Wclippy::ignored_unit_patterns \
456456
-Wclippy::mut_mut \
457457
-Wclippy::needless_bitwise_bool \
458458
-Wclippy::needless_continue \
459+
-Aclippy::needless_lifetimes \
459460
-Wclippy::no_mangle_with_rust_abi \
460-
-Wclippy::dbg_macro
461+
-Wclippy::undocumented_unsafe_blocks \
462+
-Wclippy::unnecessary_safety_comment \
463+
-Wclippy::unnecessary_safety_doc \
464+
-Wrustdoc::missing_crate_level_docs \
465+
-Wrustdoc::unescaped_backticks
461466

462467
KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \
463468
$(HOSTCFLAGS) -I $(srctree)/scripts/include
@@ -582,6 +587,9 @@ endif
582587
# Allows the usage of unstable features in stable compilers.
583588
export RUSTC_BOOTSTRAP := 1
584589

590+
# Allows finding `.clippy.toml` in out-of-srctree builds.
591+
export CLIPPY_CONF_DIR := $(srctree)
592+
585593
export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG
586594
export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN
587595
export HOSTRUSTC KBUILD_HOSTRUSTFLAGS

drivers/block/rnull.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ module! {
3232
}
3333

3434
struct NullBlkModule {
35-
_disk: Pin<Box<Mutex<GenDisk<NullBlkDevice>>>>,
35+
_disk: Pin<KBox<Mutex<GenDisk<NullBlkDevice>>>>,
3636
}
3737

3838
impl kernel::Module for NullBlkModule {
@@ -47,7 +47,7 @@ impl kernel::Module for NullBlkModule {
4747
.rotational(false)
4848
.build(format_args!("rnullb{}", 0), tagset)?;
4949

50-
let disk = Box::pin_init(new_mutex!(disk, "nullb:disk"), flags::GFP_KERNEL)?;
50+
let disk = KBox::pin_init(new_mutex!(disk, "nullb:disk"), flags::GFP_KERNEL)?;
5151

5252
Ok(Self { _disk: disk })
5353
}

drivers/gpu/drm/drm_panic_qr.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,9 @@ const FORMAT_INFOS_QR_L: [u16; 8] = [
209209
impl Version {
210210
/// Returns the smallest QR version than can hold these segments.
211211
fn from_segments(segments: &[&Segment<'_>]) -> Option<Version> {
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
212+
(1..=40)
213+
.map(Version)
214+
.find(|&v| v.max_data() * 8 >= segments.iter().map(|s| s.total_size_bits(v)).sum())
218215
}
219216

220217
fn width(&self) -> u8 {
@@ -242,7 +239,7 @@ impl Version {
242239
}
243240

244241
fn alignment_pattern(&self) -> &'static [u8] {
245-
&ALIGNMENT_PATTERNS[self.0 - 1]
242+
ALIGNMENT_PATTERNS[self.0 - 1]
246243
}
247244

248245
fn poly(&self) -> &'static [u8] {
@@ -479,7 +476,7 @@ struct EncodedMsg<'a> {
479476
/// Data to be put in the QR code, with correct segment encoding, padding, and
480477
/// Error Code Correction.
481478
impl EncodedMsg<'_> {
482-
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>> {
483480
let version = Version::from_segments(segments)?;
484481
let ec_size = version.ec_size();
485482
let g1_blocks = version.g1_blocks();
@@ -492,7 +489,7 @@ impl EncodedMsg<'_> {
492489
data.fill(0);
493490

494491
let mut em = EncodedMsg {
495-
data: data,
492+
data,
496493
ec_size,
497494
g1_blocks,
498495
g2_blocks,
@@ -722,7 +719,10 @@ impl QrImage<'_> {
722719

723720
fn is_finder(&self, x: u8, y: u8) -> bool {
724721
let end = self.width - 8;
725-
(x < 8 && y < 8) || (x < 8 && y >= end) || (x >= end && y < 8)
722+
#[expect(clippy::nonminimal_bool)]
723+
{
724+
(x < 8 && y < 8) || (x < 8 && y >= end) || (x >= end && y < 8)
725+
}
726726
}
727727

728728
// Alignment pattern: 5x5 squares in a grid.
@@ -979,10 +979,11 @@ pub unsafe extern "C" fn drm_panic_qr_generate(
979979
/// * `url_len`: Length of the URL.
980980
///
981981
/// * If `url_len` > 0, remove the 2 segments header/length and also count the
982-
/// conversion to numeric segments.
982+
/// conversion to numeric segments.
983983
/// * If `url_len` = 0, only removes 3 bytes for 1 binary segment.
984984
#[no_mangle]
985985
pub extern "C" fn drm_panic_qr_max_data_size(version: u8, url_len: usize) -> usize {
986+
#[expect(clippy::manual_range_contains)]
986987
if version < 1 || version > 40 {
987988
return 0;
988989
}

mm/kasan/kasan_test_rust.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ use kernel::prelude::*;
1111
/// drop the vector, and touch it.
1212
#[no_mangle]
1313
pub extern "C" fn kasan_test_rust_uaf() -> u8 {
14-
let mut v: Vec<u8> = Vec::new();
14+
let mut v: KVec<u8> = KVec::new();
1515
for _ in 0..4096 {
1616
v.push(0x42, GFP_KERNEL).unwrap();
1717
}
1818
let ptr: *mut u8 = addr_of_mut!(v[2048]);
1919
drop(v);
20+
// SAFETY: Incorrect, on purpose.
2021
unsafe { *ptr }
2122
}

0 commit comments

Comments
 (0)