Skip to content

Commit 910bfc2

Browse files
committed
Merge tag 'rust-6.11' of https://github.com/Rust-for-Linux/linux
Pull Rust updates from Miguel Ojeda: "The highlight is the establishment of a minimum version for the Rust toolchain, including 'rustc' (and bundled tools) and 'bindgen'. The initial minimum will be the pinned version we currently have, i.e. we are just widening the allowed versions. That covers three stable Rust releases: 1.78.0, 1.79.0, 1.80.0 (getting released tomorrow), plus beta, plus nightly. This should already be enough for kernel developers in distributions that provide recent Rust compiler versions routinely, such as Arch Linux, Debian Unstable (outside the freeze period), Fedora Linux, Gentoo Linux (especially the testing channel), Nix (unstable) and openSUSE Slowroll and Tumbleweed. In addition, the kernel is now being built-tested by Rust's pre-merge CI. That is, every change that is attempting to land into the Rust compiler is tested against the kernel, and it is merged only if it passes. Similarly, the bindgen tool has agreed to build the kernel in their CI too. Thus, with the pre-merge CI in place, both projects hope to avoid unintentional changes to Rust that break the kernel. This means that, in general, apart from intentional changes on their side (that we will need to workaround conditionally on our side), the upcoming Rust compiler versions should generally work. In addition, the Rust project has proposed getting the kernel into stable Rust (at least solving the main blockers) as one of its three flagship goals for 2024H2 [1]. I would like to thank Niko, Sid, Emilio et al. for their help promoting the collaboration between Rust and the kernel. Toolchain and infrastructure: - Support several Rust toolchain versions. - Support several bindgen versions. - Remove 'cargo' requirement and simplify 'rusttest', thanks to 'alloc' having been dropped last cycle. - Provide proper error reporting for the 'rust-analyzer' target. 'kernel' crate: - Add 'uaccess' module with a safe userspace pointers abstraction. - Add 'page' module with a 'struct page' abstraction. - Support more complex generics in workqueue's 'impl_has_work!' macro. 'macros' crate: - Add 'firmware' field support to the 'module!' macro. - Improve 'module!' macro documentation. Documentation: - Provide instructions on what packages should be installed to build the kernel in some popular Linux distributions. - Introduce the new kernel.org LLVM+Rust toolchains. - Explain '#[no_std]'. And a few other small bits" Link: https://rust-lang.github.io/rust-project-goals/2024h2/index.html#flagship-goals [1] * tag 'rust-6.11' of https://github.com/Rust-for-Linux/linux: (26 commits) docs: rust: quick-start: add section on Linux distributions rust: warn about `bindgen` versions 0.66.0 and 0.66.1 rust: start supporting several `bindgen` versions rust: work around `bindgen` 0.69.0 issue rust: avoid assuming a particular `bindgen` build rust: start supporting several compiler versions rust: simplify Clippy warning flags set rust: relax most deny-level lints to warnings rust: allow `dead_code` for never constructed bindings rust: init: simplify from `map_err` to `inspect_err` rust: macros: indent list item in `paste!`'s docs rust: add abstraction for `struct page` rust: uaccess: add typed accessors for userspace pointers uaccess: always export _copy_[from|to]_user with CONFIG_RUST rust: uaccess: add userspace pointers kbuild: rust-analyzer: improve comment documentation kbuild: rust-analyzer: better error handling docs: rust: no_std is used rust: alloc: add __GFP_HIGHMEM flag rust: alloc: fix typo in docs for GFP_NOWAIT ...
2 parents ff30564 + b126341 commit 910bfc2

25 files changed

+1058
-236
lines changed

Documentation/process/changes.rst

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,7 @@ docs on :ref:`Building Linux with Clang/LLVM <kbuild_llvm>`.
8989
Rust (optional)
9090
---------------
9191

92-
A particular version of the Rust toolchain is required. Newer versions may or
93-
may not work because the kernel depends on some unstable Rust features, for
94-
the moment.
95-
96-
Each Rust toolchain comes with several "components", some of which are required
97-
(like ``rustc``) and some that are optional. The ``rust-src`` component (which
98-
is optional) needs to be installed to build the kernel. Other components are
99-
useful for developing.
92+
A recent version of the Rust compiler is required.
10093

10194
Please see Documentation/rust/quick-start.rst for instructions on how to
10295
satisfy the build requirements of Rust support. In particular, the ``Makefile``

Documentation/rust/general-information.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ This document contains useful information to know when working with
77
the Rust support in the kernel.
88

99

10+
``no_std``
11+
----------
12+
13+
The Rust support in the kernel can link only `core <https://doc.rust-lang.org/core/>`_,
14+
but not `std <https://doc.rust-lang.org/std/>`_. Crates for use in the
15+
kernel must opt into this behavior using the ``#![no_std]`` attribute.
16+
17+
1018
Code documentation
1119
------------------
1220

Documentation/rust/quick-start.rst

Lines changed: 100 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,93 @@ Quick Start
55

66
This document describes how to get started with kernel development in Rust.
77

8+
There are a few ways to install a Rust toolchain needed for kernel development.
9+
A simple way is to use the packages from your Linux distribution if they are
10+
suitable -- the first section below explains this approach. An advantage of this
11+
approach is that, typically, the distribution will match the LLVM used by Rust
12+
and Clang.
13+
14+
Another way is using the prebuilt stable versions of LLVM+Rust provided on
15+
`kernel.org <https://kernel.org/pub/tools/llvm/rust/>`_. These are the same slim
16+
and fast LLVM toolchains from :ref:`Getting LLVM <getting_llvm>` with versions
17+
of Rust added to them that Rust for Linux supports. Two sets are provided: the
18+
"latest LLVM" and "matching LLVM" (please see the link for more information).
19+
20+
Alternatively, the next two "Requirements" sections explain each component and
21+
how to install them through ``rustup``, the standalone installers from Rust
22+
and/or building them.
23+
24+
The rest of the document explains other aspects on how to get started.
25+
26+
27+
Distributions
28+
-------------
29+
30+
Arch Linux
31+
**********
32+
33+
Arch Linux provides recent Rust releases and thus it should generally work out
34+
of the box, e.g.::
35+
36+
pacman -S rust rust-src rust-bindgen
37+
38+
39+
Debian
40+
******
41+
42+
Debian Unstable (Sid), outside of the freeze period, provides recent Rust
43+
releases and thus it should generally work out of the box, e.g.::
44+
45+
apt install rustc rust-src bindgen rustfmt rust-clippy
46+
47+
48+
Fedora Linux
49+
************
50+
51+
Fedora Linux provides recent Rust releases and thus it should generally work out
52+
of the box, e.g.::
53+
54+
dnf install rust rust-src bindgen-cli rustfmt clippy
55+
56+
57+
Gentoo Linux
58+
************
59+
60+
Gentoo Linux (and especially the testing branch) provides recent Rust releases
61+
and thus it should generally work out of the box, e.g.::
62+
63+
USE='rust-src rustfmt clippy' emerge dev-lang/rust dev-util/bindgen
64+
65+
``LIBCLANG_PATH`` may need to be set.
66+
67+
68+
Nix
69+
***
70+
71+
Nix (unstable channel) provides recent Rust releases and thus it should
72+
generally work out of the box, e.g.::
73+
74+
{ pkgs ? import <nixpkgs> {} }:
75+
pkgs.mkShell {
76+
nativeBuildInputs = with pkgs; [ rustc rust-bindgen rustfmt clippy ];
77+
RUST_LIB_SRC = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
78+
}
79+
80+
81+
openSUSE
82+
********
83+
84+
openSUSE Slowroll and openSUSE Tumbleweed provide recent Rust releases and thus
85+
they should generally work out of the box, e.g.::
86+
87+
zypper install rust rust1.79-src rust-bindgen clang
88+
889

990
Requirements: Building
1091
----------------------
1192

1293
This section explains how to fetch the tools needed for building.
1394

14-
Some of these requirements might be available from Linux distributions
15-
under names like ``rustc``, ``rust-src``, ``rust-bindgen``, etc. However,
16-
at the time of writing, they are likely not to be recent enough unless
17-
the distribution tracks the latest releases.
18-
1995
To easily check whether the requirements are met, the following target
2096
can be used::
2197

@@ -29,16 +105,15 @@ if that is the case.
29105
rustc
30106
*****
31107

32-
A particular version of the Rust compiler is required. Newer versions may or
33-
may not work because, for the moment, the kernel depends on some unstable
34-
Rust features.
108+
A recent version of the Rust compiler is required.
35109

36110
If ``rustup`` is being used, enter the kernel build directory (or use
37-
``--path=<build-dir>`` argument to the ``set`` sub-command) and run::
111+
``--path=<build-dir>`` argument to the ``set`` sub-command) and run,
112+
for instance::
38113

39-
rustup override set $(scripts/min-tool-version.sh rustc)
114+
rustup override set stable
40115

41-
This will configure your working directory to use the correct version of
116+
This will configure your working directory to use the given version of
42117
``rustc`` without affecting your default toolchain.
43118

44119
Note that the override applies to the current working directory (and its
@@ -65,9 +140,9 @@ version later on requires re-adding the component.
65140
Otherwise, if a standalone installer is used, the Rust source tree may be
66141
downloaded into the toolchain's installation folder::
67142

68-
curl -L "https://static.rust-lang.org/dist/rust-src-$(scripts/min-tool-version.sh rustc).tar.gz" |
143+
curl -L "https://static.rust-lang.org/dist/rust-src-$(rustc --version | cut -d' ' -f2).tar.gz" |
69144
tar -xzf - -C "$(rustc --print sysroot)/lib" \
70-
"rust-src-$(scripts/min-tool-version.sh rustc)/rust-src/lib/" \
145+
"rust-src-$(rustc --version | cut -d' ' -f2)/rust-src/lib/" \
71146
--strip-components=3
72147

73148
In this case, upgrading the Rust compiler version later on requires manually
@@ -101,26 +176,22 @@ bindgen
101176
*******
102177

103178
The bindings to the C side of the kernel are generated at build time using
104-
the ``bindgen`` tool. A particular version is required.
179+
the ``bindgen`` tool.
105180

106-
Install it via (note that this will download and build the tool from source)::
181+
Install it, for instance, via (note that this will download and build the tool
182+
from source)::
107183

108-
cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli
184+
cargo install --locked bindgen-cli
109185

110-
``bindgen`` needs to find a suitable ``libclang`` in order to work. If it is
111-
not found (or a different ``libclang`` than the one found should be used),
112-
the process can be tweaked using the environment variables understood by
113-
``clang-sys`` (the Rust bindings crate that ``bindgen`` uses to access
114-
``libclang``):
186+
``bindgen`` uses the ``clang-sys`` crate to find a suitable ``libclang`` (which
187+
may be linked statically, dynamically or loaded at runtime). By default, the
188+
``cargo`` command above will produce a ``bindgen`` binary that will load
189+
``libclang`` at runtime. If it is not found (or a different ``libclang`` than
190+
the one found should be used), the process can be tweaked, e.g. by using the
191+
``LIBCLANG_PATH`` environment variable. For details, please see ``clang-sys``'s
192+
documentation at:
115193

116-
* ``LLVM_CONFIG_PATH`` can be pointed to an ``llvm-config`` executable.
117-
118-
* Or ``LIBCLANG_PATH`` can be pointed to a ``libclang`` shared library
119-
or to the directory containing it.
120-
121-
* Or ``CLANG_PATH`` can be pointed to a ``clang`` executable.
122-
123-
For details, please see ``clang-sys``'s documentation at:
194+
https://github.com/KyleMayes/clang-sys#linking
124195

125196
https://github.com/KyleMayes/clang-sys#environment-variables
126197

@@ -164,20 +235,6 @@ can be installed manually::
164235
The standalone installers also come with ``clippy``.
165236

166237

167-
cargo
168-
*****
169-
170-
``cargo`` is the Rust native build system. It is currently required to run
171-
the tests since it is used to build a custom standard library that contains
172-
the facilities provided by the custom ``alloc`` in the kernel. The tests can
173-
be run using the ``rusttest`` Make target.
174-
175-
If ``rustup`` is being used, all the profiles already install the tool,
176-
thus nothing needs to be done.
177-
178-
The standalone installers also come with ``cargo``.
179-
180-
181238
rustdoc
182239
*******
183240

Documentation/rust/testing.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,8 @@ Additionally, there are the ``#[test]`` tests. These can be run using the
131131

132132
make LLVM=1 rusttest
133133

134-
This requires the kernel ``.config`` and downloads external repositories. It
135-
runs the ``#[test]`` tests on the host (currently) and thus is fairly limited in
136-
what these tests can test.
134+
This requires the kernel ``.config``. It runs the ``#[test]`` tests on the host
135+
(currently) and thus is fairly limited in what these tests can test.
137136

138137
The Kselftests
139138
--------------

Makefile

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -445,17 +445,17 @@ KBUILD_USERLDFLAGS := $(USERLDFLAGS)
445445
# host programs.
446446
export rust_common_flags := --edition=2021 \
447447
-Zbinary_dep_depinfo=y \
448-
-Dunsafe_op_in_unsafe_fn -Drust_2018_idioms \
449-
-Dunreachable_pub -Dnon_ascii_idents \
448+
-Dunsafe_op_in_unsafe_fn \
449+
-Dnon_ascii_idents \
450+
-Wrust_2018_idioms \
451+
-Wunreachable_pub \
450452
-Wmissing_docs \
451-
-Drustdoc::missing_crate_level_docs \
452-
-Dclippy::correctness -Dclippy::style \
453-
-Dclippy::suspicious -Dclippy::complexity \
454-
-Dclippy::perf \
455-
-Dclippy::let_unit_value -Dclippy::mut_mut \
456-
-Dclippy::needless_bitwise_bool \
457-
-Dclippy::needless_continue \
458-
-Dclippy::no_mangle_with_rust_abi \
453+
-Wrustdoc::missing_crate_level_docs \
454+
-Wclippy::all \
455+
-Wclippy::mut_mut \
456+
-Wclippy::needless_bitwise_bool \
457+
-Wclippy::needless_continue \
458+
-Wclippy::no_mangle_with_rust_abi \
459459
-Wclippy::dbg_macro
460460

461461
KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \
@@ -493,7 +493,6 @@ RUSTDOC = rustdoc
493493
RUSTFMT = rustfmt
494494
CLIPPY_DRIVER = clippy-driver
495495
BINDGEN = bindgen
496-
CARGO = cargo
497496
PAHOLE = pahole
498497
RESOLVE_BTFIDS = $(objtree)/tools/bpf/resolve_btfids/resolve_btfids
499498
LEX = flex
@@ -559,7 +558,7 @@ KBUILD_RUSTFLAGS := $(rust_common_flags) \
559558
-Csymbol-mangling-version=v0 \
560559
-Crelocation-model=static \
561560
-Zfunction-sections=n \
562-
-Dclippy::float_arithmetic
561+
-Wclippy::float_arithmetic
563562

564563
KBUILD_AFLAGS_KERNEL :=
565564
KBUILD_CFLAGS_KERNEL :=
@@ -587,7 +586,7 @@ endif
587586
export RUSTC_BOOTSTRAP := 1
588587

589588
export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG
590-
export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN CARGO
589+
export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN
591590
export HOSTRUSTC KBUILD_HOSTRUSTFLAGS
592591
export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
593592
export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
@@ -1959,9 +1958,12 @@ quiet_cmd_tags = GEN $@
19591958
tags TAGS cscope gtags: FORCE
19601959
$(call cmd,tags)
19611960

1962-
# IDE support targets
1961+
# Generate rust-project.json (a file that describes the structure of non-Cargo
1962+
# Rust projects) for rust-analyzer (an implementation of the Language Server
1963+
# Protocol).
19631964
PHONY += rust-analyzer
19641965
rust-analyzer:
1966+
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh
19651967
$(Q)$(MAKE) $(build)=rust $@
19661968

19671969
# Script to generate missing namespace dependencies

include/linux/uaccess.h

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/fault-inject-usercopy.h>
66
#include <linux/instrumented.h>
77
#include <linux/minmax.h>
8+
#include <linux/nospec.h>
89
#include <linux/sched.h>
910
#include <linux/thread_info.h>
1011

@@ -138,13 +139,26 @@ __copy_to_user(void __user *to, const void *from, unsigned long n)
138139
return raw_copy_to_user(to, from, n);
139140
}
140141

141-
#ifdef INLINE_COPY_FROM_USER
142+
/*
143+
* Architectures that #define INLINE_COPY_TO_USER use this function
144+
* directly in the normal copy_to/from_user(), the other ones go
145+
* through an extern _copy_to/from_user(), which expands the same code
146+
* here.
147+
*
148+
* Rust code always uses the extern definition.
149+
*/
142150
static inline __must_check unsigned long
143-
_copy_from_user(void *to, const void __user *from, unsigned long n)
151+
_inline_copy_from_user(void *to, const void __user *from, unsigned long n)
144152
{
145153
unsigned long res = n;
146154
might_fault();
147155
if (!should_fail_usercopy() && likely(access_ok(from, n))) {
156+
/*
157+
* Ensure that bad access_ok() speculation will not
158+
* lead to nasty side effects *after* the copy is
159+
* finished:
160+
*/
161+
barrier_nospec();
148162
instrument_copy_from_user_before(to, from, n);
149163
res = raw_copy_from_user(to, from, n);
150164
instrument_copy_from_user_after(to, from, n, res);
@@ -153,14 +167,11 @@ _copy_from_user(void *to, const void __user *from, unsigned long n)
153167
memset(to + (n - res), 0, res);
154168
return res;
155169
}
156-
#else
157170
extern __must_check unsigned long
158171
_copy_from_user(void *, const void __user *, unsigned long);
159-
#endif
160172

161-
#ifdef INLINE_COPY_TO_USER
162173
static inline __must_check unsigned long
163-
_copy_to_user(void __user *to, const void *from, unsigned long n)
174+
_inline_copy_to_user(void __user *to, const void *from, unsigned long n)
164175
{
165176
might_fault();
166177
if (should_fail_usercopy())
@@ -171,25 +182,32 @@ _copy_to_user(void __user *to, const void *from, unsigned long n)
171182
}
172183
return n;
173184
}
174-
#else
175185
extern __must_check unsigned long
176186
_copy_to_user(void __user *, const void *, unsigned long);
177-
#endif
178187

179188
static __always_inline unsigned long __must_check
180189
copy_from_user(void *to, const void __user *from, unsigned long n)
181190
{
182-
if (check_copy_size(to, n, false))
183-
n = _copy_from_user(to, from, n);
184-
return n;
191+
if (!check_copy_size(to, n, false))
192+
return n;
193+
#ifdef INLINE_COPY_FROM_USER
194+
return _inline_copy_from_user(to, from, n);
195+
#else
196+
return _copy_from_user(to, from, n);
197+
#endif
185198
}
186199

187200
static __always_inline unsigned long __must_check
188201
copy_to_user(void __user *to, const void *from, unsigned long n)
189202
{
190-
if (check_copy_size(from, n, true))
191-
n = _copy_to_user(to, from, n);
192-
return n;
203+
if (!check_copy_size(from, n, true))
204+
return n;
205+
206+
#ifdef INLINE_COPY_TO_USER
207+
return _inline_copy_to_user(to, from, n);
208+
#else
209+
return _copy_to_user(to, from, n);
210+
#endif
193211
}
194212

195213
#ifndef copy_mc_to_kernel

0 commit comments

Comments
 (0)