rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v9 00/27] Rust support
@ 2022-08-05 15:41 Miguel Ojeda
  2022-08-05 15:41 ` [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size Miguel Ojeda
                   ` (26 more replies)
  0 siblings, 27 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, linux-doc, linux-kbuild,
	linux-perf-users, live-patching

Rust support

This is the patch series (v9) to add support for Rust as a second
language to the Linux kernel.

If you are interested in following this effort, please join us in
the mailing list at:

    rust-for-linux@vger.kernel.org

and take a look at the project itself at:

    https://github.com/Rust-for-Linux

As usual, special thanks go to ISRG (Internet Security Research Group)
and Google for their financial support on this endeavor.

Cheers,
Miguel

--

# Rust support

This cover letter explains the major changes and updates done since
the previous ones. For those, please see:

    RFC: https://lore.kernel.org/lkml/20210414184604.23473-1-ojeda@kernel.org/
    v1:  https://lore.kernel.org/lkml/20210704202756.29107-1-ojeda@kernel.org/
    v2:  https://lore.kernel.org/lkml/20211206140313.5653-1-ojeda@kernel.org/
    v3:  https://lore.kernel.org/lkml/20220117053349.6804-1-ojeda@kernel.org/
    v4:  https://lore.kernel.org/lkml/20220212130410.6901-1-ojeda@kernel.org/
    v5:  https://lore.kernel.org/lkml/20220317181032.15436-1-ojeda@kernel.org/
    v6:  https://lore.kernel.org/lkml/20220507052451.12890-1-ojeda@kernel.org/
    v7:  https://lore.kernel.org/lkml/20220523020209.11810-1-ojeda@kernel.org/
    v8:  https://lore.kernel.org/lkml/20220802015052.10452-1-ojeda@kernel.org/

This is a trimmed down v8. It has enough support to compile a minimal
Rust kernel module, with the aim to get the "core" support in first
and then start upstreaming the rest piece by piece.

The kernel module is able to create a `Vec<i32>` (a contiguous,
growable array type), push some numbers and print them on unload to
the kernel log with the `pr_info!` macro.

The patch series could be made even more minimal by removing some of
that too, but this seemed like a good balance.

After the diet regime, 3% of the `kernel` crate remains (down to 500
lines), 60% of `alloc`, and the "adapt `alloc`" commit is 100 lines.
Overall, we went from 40 to 13 klines.

Most of the code has been around in linux-next for some months now,
but to trim down things I had to do minor changes. In any case, please
let me know if this selection is in line with what you expected.


## Patch series status

The Rust support is still to be considered experimental. However,
support is good enough that kernel developers can start working on the
Rust abstractions for subsystems and write drivers and other modules.

The current series will appear in the next `linux-next`, as usual.

I have kept the docs as they were in v8 since they showcase best what
the docs would eventually look like:

    https://rust-for-linux.github.io/docs/kernel/

As usual, please see the following link for the live list of unstable
Rust features we are using (note that this trimmed version does not
require all of them):

    https://github.com/Rust-for-Linux/linux/issues/2


## Conferences, meetings and liaisons

Join us in LPC 2022 (Linux Plumbers Conference) for the Rust MC
(microconference)! The schedule is available at:

    https://lpc.events/event/16/sessions/150/

We will be talking about GCC Rust (the Rust frontend for GCC),
`rustc_codegen_gcc` (the GCC backend for `rustc`), Rust for Linux,
the Rust NVMe driver, the integration of Rust with the Kernel Testing
Service and Rust in the Kernel (via eBPF).

In addition, I would like to personally thank Google and ISRG
(Internet Security Research Group) for sponsoring Kangrejos,
the Rust for Linux workshop:

    https://kangrejos.com


## Acknowledgements

The signatures in the main commits correspond to the people that
wrote code that has ended up in them at the present time. For details
on contributions to code and discussions, please see our repository:

    https://github.com/Rust-for-Linux/linux

However, we would like to give credit to everyone that has contributed
in one way or another to the Rust for Linux project. Since the
previous cover letter:

  - Boqun Feng, Konstantin Shelekhin and David Laight for their
    reviews of some of the v8 patches.

  - Matthew Wilcox, Greg Kroah-Hartman, Rasmus Villemoes and Christoph
    Hellwig for their feedback on v8.

  - Björn Roy Baron, Gary Guo and Boqun Feng for stepping up as
    reviewers in `MAINTAINERS`.

  - Jon Olson for working on a `cpu` module with utilities for
    SMP systems.

  - Alice Ryhl for working on adding `BINDER_TYPE_PTR` support.

  - FUJITA Tomonori for working on PCI support for a NVMe Rust driver.

  - Andreas Reindl for working on adding missing `SAFETY` comments.

  - Wei Liu for taking the time to answer questions from newcomers
    in Zulip.

  - Philip Li, Yujie Liu et al. for continuing their work on adding
    Rust support to the Intel 0DAY/LKP kernel test robot.

  - Philip Herron and Arthur Cohen (and his supporters Open Source
    Security and Embecosm) et al. for their ongoing work on GCC Rust.

  - Antoni Boucher (and his supporters) et al. for their ongoing
    work on `rustc_codegen_gcc`.

  - Emilio Cobos Álvarez et al. for their work on `bindgen`, including
    on issues that affect the kernel.

  - Mats Larsen, Marc Poulhiès et al. for their ongoing work on
    improving Rust support in Compiler Explorer.

  - Many folks that have reported issues, tested the project,
    helped spread the word, joined discussions and contributed in
    other ways!

Please see also the acknowledgements on the previous cover letters.


Boqun Feng (2):
  kallsyms: use `sizeof` instead of hardcoded size
  kallsyms: avoid hardcoding buffer size

Daniel Xu (1):
  scripts: add `is_rust_module.sh`

Gary Guo (1):
  vsprintf: add new `%pA` format specifier

Miguel Ojeda (22):
  kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}`
  kallsyms: support "big" kernel symbols
  kallsyms: increase maximum kernel symbol length to 512
  rust: add C helpers
  rust: import upstream `alloc` crate
  rust: adapt `alloc` crate to the kernel
  rust: add `compiler_builtins` crate
  rust: add `macros` crate
  rust: add `bindings` crate
  rust: export generated symbols
  scripts: checkpatch: diagnose uses of `%pA` in the C side as errors
  scripts: checkpatch: enable language-independent checks for Rust
  scripts: decode_stacktrace: demangle Rust symbols
  scripts: add `generate_rust_analyzer.py`
  scripts: add `generate_rust_target.rs`
  scripts: add `rust_is_available.sh`
  rust: add `.rustfmt.toml`
  Kbuild: add Rust support
  docs: add Rust documentation
  x86: enable initial Rust support
  samples: add first Rust examples
  MAINTAINERS: Rust

Wedson Almeida Filho (1):
  rust: add `kernel` crate

 .gitignore                                   |    6 +
 .rustfmt.toml                                |   12 +
 Documentation/core-api/printk-formats.rst    |   10 +
 Documentation/doc-guide/kernel-doc.rst       |    3 +
 Documentation/index.rst                      |    1 +
 Documentation/kbuild/kbuild.rst              |   17 +
 Documentation/kbuild/makefiles.rst           |   50 +-
 Documentation/process/changes.rst            |   41 +
 Documentation/rust/arch-support.rst          |   19 +
 Documentation/rust/coding-guidelines.rst     |  216 ++
 Documentation/rust/general-information.rst   |   79 +
 Documentation/rust/index.rst                 |   22 +
 Documentation/rust/quick-start.rst           |  232 ++
 MAINTAINERS                                  |   18 +
 Makefile                                     |  172 +-
 arch/Kconfig                                 |    6 +
 arch/x86/Kconfig                             |    1 +
 arch/x86/Makefile                            |   10 +
 include/linux/compiler_types.h               |    6 +-
 include/linux/kallsyms.h                     |    2 +-
 init/Kconfig                                 |   46 +-
 kernel/configs/rust.config                   |    1 +
 kernel/kallsyms.c                            |   26 +-
 kernel/livepatch/core.c                      |    4 +-
 lib/Kconfig.debug                            |   34 +
 lib/vsprintf.c                               |   13 +
 rust/.gitignore                              |    8 +
 rust/Makefile                                |  381 +++
 rust/alloc/README.md                         |   33 +
 rust/alloc/alloc.rs                          |  440 +++
 rust/alloc/borrow.rs                         |  498 +++
 rust/alloc/boxed.rs                          | 2028 +++++++++++
 rust/alloc/collections/mod.rs                |  156 +
 rust/alloc/lib.rs                            |  244 ++
 rust/alloc/raw_vec.rs                        |  527 +++
 rust/alloc/slice.rs                          | 1204 +++++++
 rust/alloc/vec/drain.rs                      |  186 ++
 rust/alloc/vec/drain_filter.rs               |  145 +
 rust/alloc/vec/into_iter.rs                  |  366 ++
 rust/alloc/vec/is_zero.rs                    |  120 +
 rust/alloc/vec/mod.rs                        | 3140 ++++++++++++++++++
 rust/alloc/vec/partial_eq.rs                 |   49 +
 rust/bindgen_parameters                      |   21 +
 rust/bindings/bindings_helper.h              |   13 +
 rust/bindings/lib.rs                         |   53 +
 rust/compiler_builtins.rs                    |   63 +
 rust/exports.c                               |   21 +
 rust/helpers.c                               |   51 +
 rust/kernel/allocator.rs                     |   64 +
 rust/kernel/error.rs                         |   59 +
 rust/kernel/lib.rs                           |   78 +
 rust/kernel/prelude.rs                       |   20 +
 rust/kernel/print.rs                         |  198 ++
 rust/kernel/str.rs                           |   72 +
 rust/macros/helpers.rs                       |   51 +
 rust/macros/lib.rs                           |   72 +
 rust/macros/module.rs                        |  282 ++
 samples/Kconfig                              |    2 +
 samples/Makefile                             |    1 +
 samples/rust/Kconfig                         |   30 +
 samples/rust/Makefile                        |    5 +
 samples/rust/hostprogs/.gitignore            |    3 +
 samples/rust/hostprogs/Makefile              |    5 +
 samples/rust/hostprogs/a.rs                  |    7 +
 samples/rust/hostprogs/b.rs                  |    5 +
 samples/rust/hostprogs/single.rs             |   12 +
 samples/rust/rust_minimal.rs                 |   38 +
 scripts/.gitignore                           |    1 +
 scripts/Kconfig.include                      |    6 +-
 scripts/Makefile                             |    3 +
 scripts/Makefile.build                       |   60 +
 scripts/Makefile.debug                       |   10 +
 scripts/Makefile.host                        |   34 +-
 scripts/Makefile.lib                         |   12 +
 scripts/Makefile.modfinal                    |    8 +-
 scripts/cc-version.sh                        |   12 +-
 scripts/checkpatch.pl                        |   12 +-
 scripts/decode_stacktrace.sh                 |   14 +
 scripts/generate_rust_analyzer.py            |  135 +
 scripts/generate_rust_target.rs              |  182 +
 scripts/is_rust_module.sh                    |   16 +
 scripts/kallsyms.c                           |   47 +-
 scripts/kconfig/confdata.c                   |   75 +
 scripts/min-tool-version.sh                  |    6 +
 scripts/rust_is_available.sh                 |  160 +
 scripts/rust_is_available_bindgen_libclang.h |    2 +
 tools/include/linux/kallsyms.h               |    2 +-
 tools/lib/perf/include/perf/event.h          |    2 +-
 tools/lib/symbol/kallsyms.h                  |    2 +-
 89 files changed, 12548 insertions(+), 51 deletions(-)
 create mode 100644 .rustfmt.toml
 create mode 100644 Documentation/rust/arch-support.rst
 create mode 100644 Documentation/rust/coding-guidelines.rst
 create mode 100644 Documentation/rust/general-information.rst
 create mode 100644 Documentation/rust/index.rst
 create mode 100644 Documentation/rust/quick-start.rst
 create mode 100644 kernel/configs/rust.config
 create mode 100644 rust/.gitignore
 create mode 100644 rust/Makefile
 create mode 100644 rust/alloc/README.md
 create mode 100644 rust/alloc/alloc.rs
 create mode 100644 rust/alloc/borrow.rs
 create mode 100644 rust/alloc/boxed.rs
 create mode 100644 rust/alloc/collections/mod.rs
 create mode 100644 rust/alloc/lib.rs
 create mode 100644 rust/alloc/raw_vec.rs
 create mode 100644 rust/alloc/slice.rs
 create mode 100644 rust/alloc/vec/drain.rs
 create mode 100644 rust/alloc/vec/drain_filter.rs
 create mode 100644 rust/alloc/vec/into_iter.rs
 create mode 100644 rust/alloc/vec/is_zero.rs
 create mode 100644 rust/alloc/vec/mod.rs
 create mode 100644 rust/alloc/vec/partial_eq.rs
 create mode 100644 rust/bindgen_parameters
 create mode 100644 rust/bindings/bindings_helper.h
 create mode 100644 rust/bindings/lib.rs
 create mode 100644 rust/compiler_builtins.rs
 create mode 100644 rust/exports.c
 create mode 100644 rust/helpers.c
 create mode 100644 rust/kernel/allocator.rs
 create mode 100644 rust/kernel/error.rs
 create mode 100644 rust/kernel/lib.rs
 create mode 100644 rust/kernel/prelude.rs
 create mode 100644 rust/kernel/print.rs
 create mode 100644 rust/kernel/str.rs
 create mode 100644 rust/macros/helpers.rs
 create mode 100644 rust/macros/lib.rs
 create mode 100644 rust/macros/module.rs
 create mode 100644 samples/rust/Kconfig
 create mode 100644 samples/rust/Makefile
 create mode 100644 samples/rust/hostprogs/.gitignore
 create mode 100644 samples/rust/hostprogs/Makefile
 create mode 100644 samples/rust/hostprogs/a.rs
 create mode 100644 samples/rust/hostprogs/b.rs
 create mode 100644 samples/rust/hostprogs/single.rs
 create mode 100644 samples/rust/rust_minimal.rs
 create mode 100755 scripts/generate_rust_analyzer.py
 create mode 100644 scripts/generate_rust_target.rs
 create mode 100755 scripts/is_rust_module.sh
 create mode 100755 scripts/rust_is_available.sh
 create mode 100644 scripts/rust_is_available_bindgen_libclang.h


base-commit: 3d7cb6b04c3f3115719235cc6866b10326de34cd
-- 
2.37.1


^ permalink raw reply	[flat|nested] 102+ messages in thread

* [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-05 16:48   ` Geert Stappers
  2022-08-05 22:40   ` Konstantin Shelekhin
  2022-08-05 15:41 ` [PATCH v9 02/27] kallsyms: avoid hardcoding buffer size Miguel Ojeda
                   ` (25 subsequent siblings)
  26 siblings, 2 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Boqun Feng

From: Boqun Feng <boqun.feng@gmail.com>

This removes one place where the `500` constant is hardcoded.

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Co-developed-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 scripts/kallsyms.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index f18e6dfc68c5..52f5488c61bc 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -206,7 +206,7 @@ static struct sym_entry *read_symbol(FILE *in)
 
 	rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
 	if (rc != 3) {
-		if (rc != EOF && fgets(name, 500, in) == NULL)
+		if (rc != EOF && fgets(name, sizeof(name), in) == NULL)
 			fprintf(stderr, "Read error or end of file.\n");
 		return NULL;
 	}
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 02/27] kallsyms: avoid hardcoding buffer size
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
  2022-08-05 15:41 ` [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-17 19:37   ` Kees Cook
  2022-08-05 15:41 ` [PATCH v9 03/27] kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}` Miguel Ojeda
                   ` (24 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Boqun Feng

From: Boqun Feng <boqun.feng@gmail.com>

This introduces `KSYM_NAME_LEN_BUFFER` in place of the previously
hardcoded size of the input buffer.

It will also make it easier to update the size in a single place
in a later patch.

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Co-developed-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 scripts/kallsyms.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 52f5488c61bc..f3c5a2623f71 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -27,8 +27,14 @@
 
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
 
+#define _stringify_1(x)	#x
+#define _stringify(x)	_stringify_1(x)
+
 #define KSYM_NAME_LEN		128
 
+/* A substantially bigger size than the current maximum. */
+#define KSYM_NAME_LEN_BUFFER	499
+
 struct sym_entry {
 	unsigned long long addr;
 	unsigned int len;
@@ -198,13 +204,13 @@ static void check_symbol_range(const char *sym, unsigned long long addr,
 
 static struct sym_entry *read_symbol(FILE *in)
 {
-	char name[500], type;
+	char name[KSYM_NAME_LEN_BUFFER+1], type;
 	unsigned long long addr;
 	unsigned int len;
 	struct sym_entry *sym;
 	int rc;
 
-	rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
+	rc = fscanf(in, "%llx %c %" _stringify(KSYM_NAME_LEN_BUFFER) "s\n", &addr, &type, name);
 	if (rc != 3) {
 		if (rc != EOF && fgets(name, sizeof(name), in) == NULL)
 			fprintf(stderr, "Read error or end of file.\n");
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 03/27] kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}`
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
  2022-08-05 15:41 ` [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size Miguel Ojeda
  2022-08-05 15:41 ` [PATCH v9 02/27] kallsyms: avoid hardcoding buffer size Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-17 19:39   ` Kees Cook
  2022-08-05 15:41 ` [PATCH v9 04/27] kallsyms: support "big" kernel symbols Miguel Ojeda
                   ` (23 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Boqun Feng

This adds a static assert to ensure `KSYM_NAME_LEN_BUFFER`
gets updated when `KSYM_NAME_LEN` changes.

The relationship used is one that keeps the new size (512+1)
close to the original buffer size (500).

Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 scripts/kallsyms.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index f3c5a2623f71..f543b1c4f99f 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -33,7 +33,11 @@
 #define KSYM_NAME_LEN		128
 
 /* A substantially bigger size than the current maximum. */
-#define KSYM_NAME_LEN_BUFFER	499
+#define KSYM_NAME_LEN_BUFFER	512
+_Static_assert(
+	KSYM_NAME_LEN_BUFFER == KSYM_NAME_LEN * 4,
+	"Please keep KSYM_NAME_LEN_BUFFER in sync with KSYM_NAME_LEN"
+);
 
 struct sym_entry {
 	unsigned long long addr;
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 04/27] kallsyms: support "big" kernel symbols
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (2 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 03/27] kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}` Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-05 15:41 ` [PATCH v9 05/27] kallsyms: increase maximum kernel symbol length to 512 Miguel Ojeda
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Kees Cook, Alex Gaynor,
	Wedson Almeida Filho, Gary Guo, Boqun Feng, Matthew Wilcox

Rust symbols can become quite long due to namespacing introduced
by modules, types, traits, generics, etc.

Increasing to 255 is not enough in some cases, therefore
introduce longer lengths to the symbol table.

In order to avoid increasing all lengths to 2 bytes (since most
of them are small, including many Rust ones), use ULEB128 to
keep smaller symbols in 1 byte, with the rest in 2 bytes.

Reviewed-by: Kees Cook <keescook@chromium.org>
Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Co-developed-by: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 kernel/kallsyms.c  | 26 ++++++++++++++++++++++----
 scripts/kallsyms.c | 29 ++++++++++++++++++++++++++---
 2 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index fbdf8d3279ac..87e2b1638115 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -70,12 +70,20 @@ static unsigned int kallsyms_expand_symbol(unsigned int off,
 	data = &kallsyms_names[off];
 	len = *data;
 	data++;
+	off++;
+
+	/* If MSB is 1, it is a "big" symbol, so needs an additional byte. */
+	if ((len & 0x80) != 0) {
+		len = (len & 0x7F) | (*data << 7);
+		data++;
+		off++;
+	}
 
 	/*
 	 * Update the offset to return the offset for the next symbol on
 	 * the compressed stream.
 	 */
-	off += len + 1;
+	off += len;
 
 	/*
 	 * For every byte on the compressed symbol data, copy the table
@@ -128,7 +136,7 @@ static char kallsyms_get_symbol_type(unsigned int off)
 static unsigned int get_symbol_offset(unsigned long pos)
 {
 	const u8 *name;
-	int i;
+	int i, len;
 
 	/*
 	 * Use the closest marker we have. We have markers every 256 positions,
@@ -142,8 +150,18 @@ static unsigned int get_symbol_offset(unsigned long pos)
 	 * so we just need to add the len to the current pointer for every
 	 * symbol we wish to skip.
 	 */
-	for (i = 0; i < (pos & 0xFF); i++)
-		name = name + (*name) + 1;
+	for (i = 0; i < (pos & 0xFF); i++) {
+		len = *name;
+
+		/*
+		 * If MSB is 1, it is a "big" symbol, so we need to look into
+		 * the next byte (and skip it, too).
+		 */
+		if ((len & 0x80) != 0)
+			len = ((len & 0x7F) | (name[1] << 7)) + 1;
+
+		name = name + len + 1;
+	}
 
 	return name - kallsyms_names;
 }
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index f543b1c4f99f..9da3b7767e9d 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -481,12 +481,35 @@ static void write_src(void)
 		if ((i & 0xFF) == 0)
 			markers[i >> 8] = off;
 
-		printf("\t.byte 0x%02x", table[i]->len);
+		/* There cannot be any symbol of length zero. */
+		if (table[i]->len == 0) {
+			fprintf(stderr, "kallsyms failure: "
+				"unexpected zero symbol length\n");
+			exit(EXIT_FAILURE);
+		}
+
+		/* Only lengths that fit in up-to-two-byte ULEB128 are supported. */
+		if (table[i]->len > 0x3FFF) {
+			fprintf(stderr, "kallsyms failure: "
+				"unexpected huge symbol length\n");
+			exit(EXIT_FAILURE);
+		}
+
+		/* Encode length with ULEB128. */
+		if (table[i]->len <= 0x7F) {
+			/* Most symbols use a single byte for the length. */
+			printf("\t.byte 0x%02x", table[i]->len);
+			off += table[i]->len + 1;
+		} else {
+			/* "Big" symbols use two bytes. */
+			printf("\t.byte 0x%02x, 0x%02x",
+				(table[i]->len & 0x7F) | 0x80,
+				(table[i]->len >> 7) & 0x7F);
+			off += table[i]->len + 2;
+		}
 		for (k = 0; k < table[i]->len; k++)
 			printf(", 0x%02x", table[i]->sym[k]);
 		printf("\n");
-
-		off += table[i]->len + 1;
 	}
 	printf("\n");
 
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 05/27] kallsyms: increase maximum kernel symbol length to 512
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (3 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 04/27] kallsyms: support "big" kernel symbols Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-05 15:41 ` [PATCH v9 06/27] rust: add C helpers Miguel Ojeda
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Kees Cook, Petr Mladek,
	Alex Gaynor, Wedson Almeida Filho, Gary Guo, Boqun Feng,
	Josh Poimboeuf, Jiri Kosina, Miroslav Benes, Joe Lawrence,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	live-patching, linux-perf-users

Rust symbols can become quite long due to namespacing introduced
by modules, types, traits, generics, etc. For instance,
the following code:

    pub mod my_module {
        pub struct MyType;
        pub struct MyGenericType<T>(T);

        pub trait MyTrait {
            fn my_method() -> u32;
        }

        impl MyTrait for MyGenericType<MyType> {
            fn my_method() -> u32 {
                42
            }
        }
    }

generates a symbol of length 96 when using the upcoming v0 mangling scheme:

    _RNvXNtCshGpAVYOtgW1_7example9my_moduleINtB2_13MyGenericTypeNtB2_6MyTypeENtB2_7MyTrait9my_method

At the moment, Rust symbols may reach up to 300 in length.
Setting 512 as the maximum seems like a reasonable choice to
keep some headroom.

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 include/linux/kallsyms.h            | 2 +-
 kernel/livepatch/core.c             | 4 ++--
 scripts/kallsyms.c                  | 4 ++--
 tools/include/linux/kallsyms.h      | 2 +-
 tools/lib/perf/include/perf/event.h | 2 +-
 tools/lib/symbol/kallsyms.h         | 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index ad39636e0c3f..649faac31ddb 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -15,7 +15,7 @@
 
 #include <asm/sections.h>
 
-#define KSYM_NAME_LEN 128
+#define KSYM_NAME_LEN 512
 #define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s %s]") + \
 			(KSYM_NAME_LEN - 1) + \
 			2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + \
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index bc475e62279d..ec06ce59d728 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -213,7 +213,7 @@ static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab,
 	 * we use the smallest/strictest upper bound possible (56, based on
 	 * the current definition of MODULE_NAME_LEN) to prevent overflows.
 	 */
-	BUILD_BUG_ON(MODULE_NAME_LEN < 56 || KSYM_NAME_LEN != 128);
+	BUILD_BUG_ON(MODULE_NAME_LEN < 56 || KSYM_NAME_LEN != 512);
 
 	relas = (Elf_Rela *) relasec->sh_addr;
 	/* For each rela in this klp relocation section */
@@ -227,7 +227,7 @@ static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab,
 
 		/* Format: .klp.sym.sym_objname.sym_name,sympos */
 		cnt = sscanf(strtab + sym->st_name,
-			     ".klp.sym.%55[^.].%127[^,],%lu",
+			     ".klp.sym.%55[^.].%511[^,],%lu",
 			     sym_objname, sym_name, &sympos);
 		if (cnt != 3) {
 			pr_err("symbol %s has an incorrectly formatted name\n",
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 9da3b7767e9d..3b64dda7e4cc 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -30,10 +30,10 @@
 #define _stringify_1(x)	#x
 #define _stringify(x)	_stringify_1(x)
 
-#define KSYM_NAME_LEN		128
+#define KSYM_NAME_LEN		512
 
 /* A substantially bigger size than the current maximum. */
-#define KSYM_NAME_LEN_BUFFER	512
+#define KSYM_NAME_LEN_BUFFER	2048
 _Static_assert(
 	KSYM_NAME_LEN_BUFFER == KSYM_NAME_LEN * 4,
 	"Please keep KSYM_NAME_LEN_BUFFER in sync with KSYM_NAME_LEN"
diff --git a/tools/include/linux/kallsyms.h b/tools/include/linux/kallsyms.h
index efb6c3f5f2a9..5a37ccbec54f 100644
--- a/tools/include/linux/kallsyms.h
+++ b/tools/include/linux/kallsyms.h
@@ -6,7 +6,7 @@
 #include <stdio.h>
 #include <unistd.h>
 
-#define KSYM_NAME_LEN 128
+#define KSYM_NAME_LEN 512
 
 struct module;
 
diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/perf/event.h
index e7758707cadd..116a80c31675 100644
--- a/tools/lib/perf/include/perf/event.h
+++ b/tools/lib/perf/include/perf/event.h
@@ -95,7 +95,7 @@ struct perf_record_throttle {
 };
 
 #ifndef KSYM_NAME_LEN
-#define KSYM_NAME_LEN 256
+#define KSYM_NAME_LEN 512
 #endif
 
 struct perf_record_ksymbol {
diff --git a/tools/lib/symbol/kallsyms.h b/tools/lib/symbol/kallsyms.h
index 72ab9870454b..542f9b059c3b 100644
--- a/tools/lib/symbol/kallsyms.h
+++ b/tools/lib/symbol/kallsyms.h
@@ -7,7 +7,7 @@
 #include <linux/types.h>
 
 #ifndef KSYM_NAME_LEN
-#define KSYM_NAME_LEN 256
+#define KSYM_NAME_LEN 512
 #endif
 
 static inline u8 kallsyms2elf_binding(char type)
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 06/27] rust: add C helpers
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (4 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 05/27] kallsyms: increase maximum kernel symbol length to 512 Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-17 19:44   ` Kees Cook
  2022-08-05 15:41 ` [PATCH v9 08/27] rust: adapt `alloc` crate to the kernel Miguel Ojeda
                   ` (20 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Geoffrey Thomas,
	Wedson Almeida Filho, Sven Van Asbroeck, Gary Guo, Boqun Feng,
	Maciej Falkowski, Wei Liu, Björn Roy Baron

This source file contains forwarders to C macros and inlined
functions.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Geoffrey Thomas <geofft@ldpreload.com>
Signed-off-by: Geoffrey Thomas <geofft@ldpreload.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Co-developed-by: Maciej Falkowski <m.falkowski@samsung.com>
Signed-off-by: Maciej Falkowski <m.falkowski@samsung.com>
Co-developed-by: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 rust/helpers.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 rust/helpers.c

diff --git a/rust/helpers.c b/rust/helpers.c
new file mode 100644
index 000000000000..b4f15eee2ffd
--- /dev/null
+++ b/rust/helpers.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Non-trivial C macros cannot be used in Rust. Similarly, inlined C functions
+ * cannot be called either. This file explicitly creates functions ("helpers")
+ * that wrap those so that they can be called from Rust.
+ *
+ * Even though Rust kernel modules should never use directly the bindings, some
+ * of these helpers need to be exported because Rust generics and inlined
+ * functions may not get their code generated in the crate where they are
+ * defined. Other helpers, called from non-inline functions, may not be
+ * exported, in principle. However, in general, the Rust compiler does not
+ * guarantee codegen will be performed for a non-inline function either.
+ * Therefore, this file exports all the helpers. In the future, this may be
+ * revisited to reduce the number of exports after the compiler is informed
+ * about the places codegen is required.
+ *
+ * All symbols are exported as GPL-only to guarantee no GPL-only feature is
+ * accidentally exposed.
+ */
+
+#include <linux/bug.h>
+#include <linux/build_bug.h>
+
+__noreturn void rust_helper_BUG(void)
+{
+	BUG();
+}
+EXPORT_SYMBOL_GPL(rust_helper_BUG);
+
+/*
+ * We use `bindgen`'s `--size_t-is-usize` option to bind the C `size_t` type
+ * as the Rust `usize` type, so we can use it in contexts where Rust
+ * expects a `usize` like slice (array) indices. `usize` is defined to be
+ * the same as C's `uintptr_t` type (can hold any pointer) but not
+ * necessarily the same as `size_t` (can hold the size of any single
+ * object). Most modern platforms use the same concrete integer type for
+ * both of them, but in case we find ourselves on a platform where
+ * that's not true, fail early instead of risking ABI or
+ * integer-overflow issues.
+ *
+ * If your platform fails this assertion, it means that you are in
+ * danger of integer-overflow bugs (even if you attempt to remove
+ * `--size_t-is-usize`). It may be easiest to change the kernel ABI on
+ * your platform such that `size_t` matches `uintptr_t` (i.e., to increase
+ * `size_t`, because `uintptr_t` has to be at least as big as `size_t`).
+ */
+static_assert(
+	sizeof(size_t) == sizeof(uintptr_t) &&
+	__alignof__(size_t) == __alignof__(uintptr_t),
+	"Rust code expects C `size_t` to match Rust `usize`"
+);
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 08/27] rust: adapt `alloc` crate to the kernel
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (5 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 06/27] rust: add C helpers Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-05 15:41 ` [PATCH v9 09/27] rust: add `compiler_builtins` crate Miguel Ojeda
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho,
	Gary Guo, Matthew Bakhtiari, Boqun Feng, Björn Roy Baron

This customizes the subset of the Rust standard library `alloc` that
was just imported as-is, mainly by:

  - Adding SPDX license identifiers.

  - Skipping modules (e.g. `rc` and `sync`) via new `cfg`s.

  - Adding fallible (`try_*`) versions of existing infallible methods
    (i.e. returning a `Result` instead of panicking).

    Since the standard library requires stable/unstable attributes,
    these additions are annotated with:

        #[stable(feature = "kernel", since = "1.0.0")]

    Using "kernel" as the feature allows to have the additions
    clearly marked. The "1.0.0" version is just a placeholder.

    (At the moment, only one is needed, but in the future more
    fallible methods will be added).

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Matthew Bakhtiari <dev@mtbk.me>
Signed-off-by: Matthew Bakhtiari <dev@mtbk.me>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 rust/alloc/README.md           | 33 +++++++++++++++++++++++++++++++++
 rust/alloc/alloc.rs            |  2 ++
 rust/alloc/borrow.rs           |  4 +++-
 rust/alloc/boxed.rs            |  4 ++++
 rust/alloc/collections/mod.rs  |  2 ++
 rust/alloc/lib.rs              |  8 ++++++++
 rust/alloc/raw_vec.rs          |  9 +++++++++
 rust/alloc/slice.rs            |  2 ++
 rust/alloc/vec/drain.rs        |  2 ++
 rust/alloc/vec/drain_filter.rs |  2 ++
 rust/alloc/vec/into_iter.rs    |  4 ++++
 rust/alloc/vec/is_zero.rs      |  2 ++
 rust/alloc/vec/mod.rs          | 25 +++++++++++++++++++++++++
 rust/alloc/vec/partial_eq.rs   |  2 ++
 14 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 rust/alloc/README.md

diff --git a/rust/alloc/README.md b/rust/alloc/README.md
new file mode 100644
index 000000000000..c89c753720b5
--- /dev/null
+++ b/rust/alloc/README.md
@@ -0,0 +1,33 @@
+# `alloc`
+
+These source files 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,
+see <https://github.com/rust-lang/rust/blob/master/COPYRIGHT>.
+
+Please note that these files should be kept as close as possible to
+upstream. In general, only additions should be performed (e.g. new
+methods). Eventually, changes should make it into upstream so that,
+at some point, this fork can be dropped from the kernel tree.
+
+
+## Rationale
+
+On one hand, kernel folks wanted to keep `alloc` in-tree to have more
+freedom in both workflow and actual features if actually needed
+(e.g. receiver types if we ended up using them), which is reasonable.
+
+On the other hand, Rust folks wanted to keep `alloc` as close as
+upstream as possible and avoid as much divergence as possible, which
+is also reasonable.
+
+We agreed on a middle-ground: we would keep a subset of `alloc`
+in-tree that would be as small and as close as possible to upstream.
+Then, upstream can start adding the functions that we add to `alloc`
+etc., until we reach a point where the kernel already knows exactly
+what it needs in `alloc` and all the new methods are merged into
+upstream, so that we can drop `alloc` from the kernel tree and go back
+to using the upstream one.
+
+By doing this, the kernel can go a bit faster now, and Rust can
+slowly incorporate and discuss the changes as needed.
diff --git a/rust/alloc/alloc.rs b/rust/alloc/alloc.rs
index 6162b5c6d4c9..ca224a541770 100644
--- a/rust/alloc/alloc.rs
+++ b/rust/alloc/alloc.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 //! Memory allocation APIs
 
 #![stable(feature = "alloc_module", since = "1.28.0")]
diff --git a/rust/alloc/borrow.rs b/rust/alloc/borrow.rs
index cb4e438f8bea..dde4957200d4 100644
--- a/rust/alloc/borrow.rs
+++ b/rust/alloc/borrow.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 //! A module for working with borrowed data.
 
 #![stable(feature = "rust1", since = "1.0.0")]
@@ -11,7 +13,7 @@ use core::ops::{Add, AddAssign};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::borrow::{Borrow, BorrowMut};
 
-use crate::fmt;
+use core::fmt;
 #[cfg(not(no_global_oom_handling))]
 use crate::string::String;
 
diff --git a/rust/alloc/boxed.rs b/rust/alloc/boxed.rs
index c07536f0d0ce..dcfe87b14f3a 100644
--- a/rust/alloc/boxed.rs
+++ b/rust/alloc/boxed.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 //! A pointer type for heap allocation.
 //!
 //! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
@@ -163,9 +165,11 @@ use crate::str::from_boxed_utf8_unchecked;
 #[cfg(not(no_global_oom_handling))]
 use crate::vec::Vec;
 
+#[cfg(not(no_thin))]
 #[unstable(feature = "thin_box", issue = "92791")]
 pub use thin::ThinBox;
 
+#[cfg(not(no_thin))]
 mod thin;
 
 /// A pointer type for heap allocation.
diff --git a/rust/alloc/collections/mod.rs b/rust/alloc/collections/mod.rs
index 628a5b155673..1eec265b28f8 100644
--- a/rust/alloc/collections/mod.rs
+++ b/rust/alloc/collections/mod.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 //! Collection types.
 
 #![stable(feature = "rust1", since = "1.0.0")]
diff --git a/rust/alloc/lib.rs b/rust/alloc/lib.rs
index fd21b3671182..233bcd5e4654 100644
--- a/rust/alloc/lib.rs
+++ b/rust/alloc/lib.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 //! # The Rust core allocation and collections library
 //!
 //! This library provides smart pointers and collections for managing
@@ -192,6 +194,7 @@ extern crate std;
 extern crate test;
 
 // Module with internal macros used by other modules (needs to be included before other modules).
+#[cfg(not(no_macros))]
 #[macro_use]
 mod macros;
 
@@ -216,11 +219,16 @@ pub mod borrow;
 pub mod collections;
 #[cfg(not(no_global_oom_handling))]
 pub mod ffi;
+#[cfg(not(no_fmt))]
 pub mod fmt;
+#[cfg(not(no_rc))]
 pub mod rc;
 pub mod slice;
+#[cfg(not(no_str))]
 pub mod str;
+#[cfg(not(no_string))]
 pub mod string;
+#[cfg(not(no_sync))]
 #[cfg(target_has_atomic = "ptr")]
 pub mod sync;
 #[cfg(all(not(no_global_oom_handling), target_has_atomic = "ptr"))]
diff --git a/rust/alloc/raw_vec.rs b/rust/alloc/raw_vec.rs
index 4be5f6cf9ca5..daf5f2da7168 100644
--- a/rust/alloc/raw_vec.rs
+++ b/rust/alloc/raw_vec.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 #![unstable(feature = "raw_vec_internals", reason = "unstable const warnings", issue = "none")]
 
 use core::alloc::LayoutError;
@@ -307,6 +309,12 @@ impl<T, A: Allocator> RawVec<T, A> {
         }
     }
 
+    /// The same as `reserve_for_push`, but returns on errors instead of panicking or aborting.
+    #[inline(never)]
+    pub fn try_reserve_for_push(&mut self, len: usize) -> Result<(), TryReserveError> {
+        self.grow_amortized(len, 1)
+    }
+
     /// Ensures that the buffer contains at least enough space to hold `len +
     /// additional` elements. If it doesn't already, will reallocate the
     /// minimum possible amount of memory necessary. Generally this will be
@@ -421,6 +429,7 @@ impl<T, A: Allocator> RawVec<T, A> {
         Ok(())
     }
 
+    #[allow(dead_code)]
     fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> {
         assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity");
 
diff --git a/rust/alloc/slice.rs b/rust/alloc/slice.rs
index 199b3c9d0290..e444e97fa145 100644
--- a/rust/alloc/slice.rs
+++ b/rust/alloc/slice.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 //! A dynamically-sized view into a contiguous sequence, `[T]`.
 //!
 //! *[See also the slice primitive type](slice).*
diff --git a/rust/alloc/vec/drain.rs b/rust/alloc/vec/drain.rs
index 5cdee0bd4da4..b6a5f98e4fcd 100644
--- a/rust/alloc/vec/drain.rs
+++ b/rust/alloc/vec/drain.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 use crate::alloc::{Allocator, Global};
 use core::fmt;
 use core::iter::{FusedIterator, TrustedLen};
diff --git a/rust/alloc/vec/drain_filter.rs b/rust/alloc/vec/drain_filter.rs
index 3c37c92ae44b..b04fce041622 100644
--- a/rust/alloc/vec/drain_filter.rs
+++ b/rust/alloc/vec/drain_filter.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 use crate::alloc::{Allocator, Global};
 use core::ptr::{self};
 use core::slice::{self};
diff --git a/rust/alloc/vec/into_iter.rs b/rust/alloc/vec/into_iter.rs
index 9b84a1d9b4b6..f7a50e76691e 100644
--- a/rust/alloc/vec/into_iter.rs
+++ b/rust/alloc/vec/into_iter.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 #[cfg(not(no_global_oom_handling))]
 use super::AsVecIntoIter;
 use crate::alloc::{Allocator, Global};
@@ -9,6 +11,7 @@ use core::iter::{
 };
 use core::marker::PhantomData;
 use core::mem::{self, ManuallyDrop};
+#[cfg(not(no_global_oom_handling))]
 use core::ops::Deref;
 use core::ptr::{self, NonNull};
 use core::slice::{self};
@@ -123,6 +126,7 @@ impl<T, A: Allocator> IntoIter<T, A> {
     }
 
     /// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed.
+    #[allow(dead_code)]
     pub(crate) fn forget_remaining_elements(&mut self) {
         self.ptr = self.end;
     }
diff --git a/rust/alloc/vec/is_zero.rs b/rust/alloc/vec/is_zero.rs
index edf270db81d4..377f3d172777 100644
--- a/rust/alloc/vec/is_zero.rs
+++ b/rust/alloc/vec/is_zero.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 use crate::boxed::Box;
 
 #[rustc_specialization_trait]
diff --git a/rust/alloc/vec/mod.rs b/rust/alloc/vec/mod.rs
index 3dc8a4fbba86..540787804cc2 100644
--- a/rust/alloc/vec/mod.rs
+++ b/rust/alloc/vec/mod.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 //! A contiguous growable array type with heap-allocated contents, written
 //! `Vec<T>`.
 //!
@@ -1739,6 +1741,29 @@ impl<T, A: Allocator> Vec<T, A> {
         }
     }
 
+    /// Tries to append an element to the back of a collection.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut vec = vec![1, 2];
+    /// vec.try_push(3).unwrap();
+    /// assert_eq!(vec, [1, 2, 3]);
+    /// ```
+    #[inline]
+    #[stable(feature = "kernel", since = "1.0.0")]
+    pub fn try_push(&mut self, value: T) -> Result<(), TryReserveError> {
+        if self.len == self.buf.capacity() {
+            self.buf.try_reserve_for_push(self.len)?;
+        }
+        unsafe {
+            let end = self.as_mut_ptr().add(self.len);
+            ptr::write(end, value);
+            self.len += 1;
+        }
+        Ok(())
+    }
+
     /// Removes the last element from a vector and returns it, or [`None`] if it
     /// is empty.
     ///
diff --git a/rust/alloc/vec/partial_eq.rs b/rust/alloc/vec/partial_eq.rs
index b0cf72577a1b..10ad4e492287 100644
--- a/rust/alloc/vec/partial_eq.rs
+++ b/rust/alloc/vec/partial_eq.rs
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
 use crate::alloc::Allocator;
 #[cfg(not(no_global_oom_handling))]
 use crate::borrow::Cow;
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 09/27] rust: add `compiler_builtins` crate
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (6 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 08/27] rust: adapt `alloc` crate to the kernel Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-17 20:08   ` Kees Cook
  2022-08-22 23:55   ` Nick Desaulniers
  2022-08-05 15:41 ` [PATCH v9 10/27] rust: add `macros` crate Miguel Ojeda
                   ` (18 subsequent siblings)
  26 siblings, 2 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho,
	Sven Van Asbroeck, Gary Guo, Boqun Feng, Björn Roy Baron

Rust provides `compiler_builtins` as a port of LLVM's `compiler-rt`.
Since we do not need the vast majority of them, we avoid the
dependency by providing our own crate.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 rust/compiler_builtins.rs | 63 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 rust/compiler_builtins.rs

diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs
new file mode 100644
index 000000000000..f8f39a3e6855
--- /dev/null
+++ b/rust/compiler_builtins.rs
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Our own `compiler_builtins`.
+//!
+//! Rust provides [`compiler_builtins`] as a port of LLVM's [`compiler-rt`].
+//! Since we do not need the vast majority of them, we avoid the dependency
+//! by providing this file.
+//!
+//! At the moment, some builtins are required that should not be. For instance,
+//! [`core`] has 128-bit integers functionality which we should not be compiling
+//! in. We will work with upstream [`core`] to provide feature flags to disable
+//! the parts we do not need. For the moment, we define them to [`panic!`] at
+//! runtime for simplicity to catch mistakes, instead of performing surgery
+//! on `core.o`.
+//!
+//! In any case, all these symbols are weakened to ensure we do not override
+//! those that may be provided by the rest of the kernel.
+//!
+//! [`compiler_builtins`]: https://github.com/rust-lang/compiler-builtins
+//! [`compiler-rt`]: https://compiler-rt.llvm.org/
+
+#![feature(compiler_builtins)]
+#![compiler_builtins]
+#![no_builtins]
+#![no_std]
+
+macro_rules! define_panicking_intrinsics(
+    ($reason: tt, { $($ident: ident, )* }) => {
+        $(
+            #[doc(hidden)]
+            #[no_mangle]
+            pub extern "C" fn $ident() {
+                panic!($reason);
+            }
+        )*
+    }
+);
+
+define_panicking_intrinsics!("`f32` should not be used", {
+    __eqsf2,
+    __gesf2,
+    __lesf2,
+    __nesf2,
+    __unordsf2,
+});
+
+define_panicking_intrinsics!("`f64` should not be used", {
+    __unorddf2,
+});
+
+define_panicking_intrinsics!("`i128` should not be used", {
+    __ashrti3,
+    __muloti4,
+    __multi3,
+});
+
+define_panicking_intrinsics!("`u128` should not be used", {
+    __ashlti3,
+    __lshrti3,
+    __udivmodti4,
+    __udivti3,
+    __umodti3,
+});
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 10/27] rust: add `macros` crate
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (7 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 09/27] rust: add `compiler_builtins` crate Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-05 15:41 ` [PATCH v9 11/27] rust: add `bindings` crate Miguel Ojeda
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Finn Behrens,
	Adam Bratschi-Kaye, Wedson Almeida Filho, Sumera Priyadarsini,
	Gary Guo, Matthew Bakhtiari, Björn Roy Baron, Boqun Feng

This crate contains all the procedural macros ("proc macros")
shared by all the kernel.

Procedural macros allow to create syntax extensions. They run at
compile-time and can consume as well as produce Rust syntax.

For instance, the `module!` macro that is used by Rust modules
is implemented here. It allows to easily declare the equivalent
information to the `MODULE_*` macros in C modules, e.g.:

    module! {
        type: RustMinimal,
        name: b"rust_minimal",
        author: b"Rust for Linux Contributors",
        description: b"Rust minimal sample",
        license: b"GPL",
    }

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Sumera Priyadarsini <sylphrenadin@gmail.com>
Signed-off-by: Sumera Priyadarsini <sylphrenadin@gmail.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Matthew Bakhtiari <dev@mtbk.me>
Signed-off-by: Matthew Bakhtiari <dev@mtbk.me>
Co-developed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 rust/macros/helpers.rs |  51 ++++++++
 rust/macros/lib.rs     |  72 +++++++++++
 rust/macros/module.rs  | 282 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 405 insertions(+)
 create mode 100644 rust/macros/helpers.rs
 create mode 100644 rust/macros/lib.rs
 create mode 100644 rust/macros/module.rs

diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs
new file mode 100644
index 000000000000..cdc7dc6135d2
--- /dev/null
+++ b/rust/macros/helpers.rs
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use proc_macro::{token_stream, TokenTree};
+
+pub(crate) fn try_ident(it: &mut token_stream::IntoIter) -> Option<String> {
+    if let Some(TokenTree::Ident(ident)) = it.next() {
+        Some(ident.to_string())
+    } else {
+        None
+    }
+}
+
+pub(crate) fn try_literal(it: &mut token_stream::IntoIter) -> Option<String> {
+    if let Some(TokenTree::Literal(literal)) = it.next() {
+        Some(literal.to_string())
+    } else {
+        None
+    }
+}
+
+pub(crate) fn try_byte_string(it: &mut token_stream::IntoIter) -> Option<String> {
+    try_literal(it).and_then(|byte_string| {
+        if byte_string.starts_with("b\"") && byte_string.ends_with('\"') {
+            Some(byte_string[2..byte_string.len() - 1].to_string())
+        } else {
+            None
+        }
+    })
+}
+
+pub(crate) fn expect_ident(it: &mut token_stream::IntoIter) -> String {
+    try_ident(it).expect("Expected Ident")
+}
+
+pub(crate) fn expect_punct(it: &mut token_stream::IntoIter) -> char {
+    if let TokenTree::Punct(punct) = it.next().expect("Reached end of token stream for Punct") {
+        punct.as_char()
+    } else {
+        panic!("Expected Punct");
+    }
+}
+
+pub(crate) fn expect_byte_string(it: &mut token_stream::IntoIter) -> String {
+    try_byte_string(it).expect("Expected byte string")
+}
+
+pub(crate) fn expect_end(it: &mut token_stream::IntoIter) {
+    if it.next().is_some() {
+        panic!("Expected end");
+    }
+}
diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
new file mode 100644
index 000000000000..91764bfb1f89
--- /dev/null
+++ b/rust/macros/lib.rs
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Crate for all kernel procedural macros.
+
+mod helpers;
+mod module;
+
+use proc_macro::TokenStream;
+
+/// Declares a kernel module.
+///
+/// The `type` argument should be a type which implements the [`Module`]
+/// trait. Also accepts various forms of kernel metadata.
+///
+/// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h)
+///
+/// [`Module`]: ../kernel/trait.Module.html
+///
+/// # Examples
+///
+/// ```ignore
+/// use kernel::prelude::*;
+///
+/// module!{
+///     type: MyModule,
+///     name: b"my_kernel_module",
+///     author: b"Rust for Linux Contributors",
+///     description: b"My very own kernel module!",
+///     license: b"GPL",
+///     params: {
+///        my_i32: i32 {
+///            default: 42,
+///            permissions: 0o000,
+///            description: b"Example of i32",
+///        },
+///        writeable_i32: i32 {
+///            default: 42,
+///            permissions: 0o644,
+///            description: b"Example of i32",
+///        },
+///    },
+/// }
+///
+/// struct MyModule;
+///
+/// impl kernel::Module for MyModule {
+///     fn init() -> Result<Self> {
+///         // If the parameter is writeable, then the kparam lock must be
+///         // taken to read the parameter:
+///         {
+///             let lock = THIS_MODULE.kernel_param_lock();
+///             pr_info!("i32 param is:  {}\n", writeable_i32.read(&lock));
+///         }
+///         // If the parameter is read only, it can be read without locking
+///         // the kernel parameters:
+///         pr_info!("i32 param is:  {}\n", my_i32.read());
+///         Ok(Self)
+///     }
+/// }
+/// ```
+///
+/// # Supported argument types
+///   - `type`: type which implements the [`Module`] trait (required).
+///   - `name`: byte array of the name of the kernel module (required).
+///   - `author`: byte array of the author of the kernel module.
+///   - `description`: byte array of the description of the kernel module.
+///   - `license`: byte array of the license of the kernel module (required).
+///   - `alias`: byte array of alias name of the kernel module.
+#[proc_macro]
+pub fn module(ts: TokenStream) -> TokenStream {
+    module::module(ts)
+}
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
new file mode 100644
index 000000000000..186a5b8be23c
--- /dev/null
+++ b/rust/macros/module.rs
@@ -0,0 +1,282 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use crate::helpers::*;
+use proc_macro::{token_stream, Literal, TokenStream, TokenTree};
+use std::fmt::Write;
+
+struct ModInfoBuilder<'a> {
+    module: &'a str,
+    counter: usize,
+    buffer: String,
+}
+
+impl<'a> ModInfoBuilder<'a> {
+    fn new(module: &'a str) -> Self {
+        ModInfoBuilder {
+            module,
+            counter: 0,
+            buffer: String::new(),
+        }
+    }
+
+    fn emit_base(&mut self, field: &str, content: &str, builtin: bool) {
+        let string = if builtin {
+            // Built-in modules prefix their modinfo strings by `module.`.
+            format!(
+                "{module}.{field}={content}\0",
+                module = self.module,
+                field = field,
+                content = content
+            )
+        } else {
+            // Loadable modules' modinfo strings go as-is.
+            format!("{field}={content}\0", field = field, content = content)
+        };
+
+        write!(
+            &mut self.buffer,
+            "
+                {cfg}
+                #[doc(hidden)]
+                #[link_section = \".modinfo\"]
+                #[used]
+                pub static __{module}_{counter}: [u8; {length}] = *{string};
+            ",
+            cfg = if builtin {
+                "#[cfg(not(MODULE))]"
+            } else {
+                "#[cfg(MODULE)]"
+            },
+            module = self.module.to_uppercase(),
+            counter = self.counter,
+            length = string.len(),
+            string = Literal::byte_string(string.as_bytes()),
+        )
+        .unwrap();
+
+        self.counter += 1;
+    }
+
+    fn emit_only_builtin(&mut self, field: &str, content: &str) {
+        self.emit_base(field, content, true)
+    }
+
+    fn emit_only_loadable(&mut self, field: &str, content: &str) {
+        self.emit_base(field, content, false)
+    }
+
+    fn emit(&mut self, field: &str, content: &str) {
+        self.emit_only_builtin(field, content);
+        self.emit_only_loadable(field, content);
+    }
+}
+
+#[derive(Debug, Default)]
+struct ModuleInfo {
+    type_: String,
+    license: String,
+    name: String,
+    author: Option<String>,
+    description: Option<String>,
+    alias: Option<String>,
+}
+
+impl ModuleInfo {
+    fn parse(it: &mut token_stream::IntoIter) -> Self {
+        let mut info = ModuleInfo::default();
+
+        const EXPECTED_KEYS: &[&str] =
+            &["type", "name", "author", "description", "license", "alias"];
+        const REQUIRED_KEYS: &[&str] = &["type", "name", "license"];
+        let mut seen_keys = Vec::new();
+
+        loop {
+            let key = match it.next() {
+                Some(TokenTree::Ident(ident)) => ident.to_string(),
+                Some(_) => panic!("Expected Ident or end"),
+                None => break,
+            };
+
+            if seen_keys.contains(&key) {
+                panic!(
+                    "Duplicated key \"{}\". Keys can only be specified once.",
+                    key
+                );
+            }
+
+            assert_eq!(expect_punct(it), ':');
+
+            match key.as_str() {
+                "type" => info.type_ = expect_ident(it),
+                "name" => info.name = expect_byte_string(it),
+                "author" => info.author = Some(expect_byte_string(it)),
+                "description" => info.description = Some(expect_byte_string(it)),
+                "license" => info.license = expect_byte_string(it),
+                "alias" => info.alias = Some(expect_byte_string(it)),
+                _ => panic!(
+                    "Unknown key \"{}\". Valid keys are: {:?}.",
+                    key, EXPECTED_KEYS
+                ),
+            }
+
+            assert_eq!(expect_punct(it), ',');
+
+            seen_keys.push(key);
+        }
+
+        expect_end(it);
+
+        for key in REQUIRED_KEYS {
+            if !seen_keys.iter().any(|e| e == key) {
+                panic!("Missing required key \"{}\".", key);
+            }
+        }
+
+        let mut ordered_keys: Vec<&str> = Vec::new();
+        for key in EXPECTED_KEYS {
+            if seen_keys.iter().any(|e| e == key) {
+                ordered_keys.push(key);
+            }
+        }
+
+        if seen_keys != ordered_keys {
+            panic!(
+                "Keys are not ordered as expected. Order them like: {:?}.",
+                ordered_keys
+            );
+        }
+
+        info
+    }
+}
+
+pub(crate) fn module(ts: TokenStream) -> TokenStream {
+    let mut it = ts.into_iter();
+
+    let info = ModuleInfo::parse(&mut it);
+
+    let mut modinfo = ModInfoBuilder::new(info.name.as_ref());
+    if let Some(author) = info.author {
+        modinfo.emit("author", &author);
+    }
+    if let Some(description) = info.description {
+        modinfo.emit("description", &description);
+    }
+    modinfo.emit("license", &info.license);
+    if let Some(alias) = info.alias {
+        modinfo.emit("alias", &alias);
+    }
+
+    // Built-in modules also export the `file` modinfo string.
+    let file =
+        std::env::var("RUST_MODFILE").expect("Unable to fetch RUST_MODFILE environmental variable");
+    modinfo.emit_only_builtin("file", &file);
+
+    format!(
+        "
+            /// The module name.
+            ///
+            /// Used by the printing macros, e.g. [`info!`].
+            const __LOG_PREFIX: &[u8] = b\"{name}\\0\";
+
+            /// The \"Rust loadable module\" mark, for `scripts/is_rust_module.sh`.
+            //
+            // This may be best done another way later on, e.g. as a new modinfo
+            // key or a new section. For the moment, keep it simple.
+            #[cfg(MODULE)]
+            #[doc(hidden)]
+            #[used]
+            static __IS_RUST_MODULE: () = ();
+
+            static mut __MOD: Option<{type_}> = None;
+
+            // SAFETY: `__this_module` is constructed by the kernel at load time and will not be
+            // freed until the module is unloaded.
+            #[cfg(MODULE)]
+            static THIS_MODULE: kernel::ThisModule = unsafe {{
+                kernel::ThisModule::from_ptr(&kernel::bindings::__this_module as *const _ as *mut _)
+            }};
+            #[cfg(not(MODULE))]
+            static THIS_MODULE: kernel::ThisModule = unsafe {{
+                kernel::ThisModule::from_ptr(core::ptr::null_mut())
+            }};
+
+            // Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
+            #[cfg(MODULE)]
+            #[doc(hidden)]
+            #[no_mangle]
+            pub extern \"C\" fn init_module() -> core::ffi::c_int {{
+                __init()
+            }}
+
+            #[cfg(MODULE)]
+            #[doc(hidden)]
+            #[no_mangle]
+            pub extern \"C\" fn cleanup_module() {{
+                __exit()
+            }}
+
+            // Built-in modules are initialized through an initcall pointer
+            // and the identifiers need to be unique.
+            #[cfg(not(MODULE))]
+            #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
+            #[doc(hidden)]
+            #[link_section = \"{initcall_section}\"]
+            #[used]
+            pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init;
+
+            #[cfg(not(MODULE))]
+            #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
+            core::arch::global_asm!(
+                r#\".section \"{initcall_section}\", \"a\"
+                __{name}_initcall:
+                    .long   __{name}_init - .
+                    .previous
+                \"#
+            );
+
+            #[cfg(not(MODULE))]
+            #[doc(hidden)]
+            #[no_mangle]
+            pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{
+                __init()
+            }}
+
+            #[cfg(not(MODULE))]
+            #[doc(hidden)]
+            #[no_mangle]
+            pub extern \"C\" fn __{name}_exit() {{
+                __exit()
+            }}
+
+            fn __init() -> core::ffi::c_int {{
+                match <{type_} as kernel::Module>::init(&THIS_MODULE) {{
+                    Ok(m) => {{
+                        unsafe {{
+                            __MOD = Some(m);
+                        }}
+                        return 0;
+                    }}
+                    Err(e) => {{
+                        return e.to_kernel_errno();
+                    }}
+                }}
+            }}
+
+            fn __exit() {{
+                unsafe {{
+                    // Invokes `drop()` on `__MOD`, which should be used for cleanup.
+                    __MOD = None;
+                }}
+            }}
+
+            {modinfo}
+        ",
+        type_ = info.type_,
+        name = info.name,
+        modinfo = modinfo.buffer,
+        initcall_section = ".initcall6.init"
+    )
+    .parse()
+    .expect("Error parsing formatted string into token stream.")
+}
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 11/27] rust: add `bindings` crate
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (8 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 10/27] rust: add `macros` crate Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-05 15:41 ` [PATCH v9 12/27] rust: add `kernel` crate Miguel Ojeda
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Finn Behrens,
	Wedson Almeida Filho, Sven Van Asbroeck, Gary Guo,
	Maciej Falkowski, Jiapeng Chong, Björn Roy Baron,
	Boqun Feng

This crate contains the bindings to the C side of the kernel.

Calling C (in general, FFI) is assumed to be unsafe in Rust
and, in many cases, this is accurate. For instance, virtually
all C functions that take a pointer are unsafe since, typically,
it will be dereferenced at some point (and in most cases there
is no way for the callee to check its validity beforehand).

Since one of the goals of using Rust in the kernel is precisely
to avoid unsafe code in "leaf" kernel modules (e.g. drivers),
these bindings should not be used directly by them.

Instead, these bindings need to be wrapped into safe abstractions.
These abstractions provide a safe API that kernel modules can use.
In this way, unsafe code in kernel modules is minimized.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Maciej Falkowski <m.falkowski@samsung.com>
Signed-off-by: Maciej Falkowski <m.falkowski@samsung.com>
Co-developed-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
Co-developed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 rust/bindings/bindings_helper.h | 13 ++++++++
 rust/bindings/lib.rs            | 53 +++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)
 create mode 100644 rust/bindings/bindings_helper.h
 create mode 100644 rust/bindings/lib.rs

diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
new file mode 100644
index 000000000000..c48bc284214a
--- /dev/null
+++ b/rust/bindings/bindings_helper.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header that contains the code (mostly headers) for which Rust bindings
+ * will be automatically generated by `bindgen`.
+ *
+ * Sorted alphabetically.
+ */
+
+#include <linux/slab.h>
+
+/* `bindgen` gets confused at certain things. */
+const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;
+const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;
diff --git a/rust/bindings/lib.rs b/rust/bindings/lib.rs
new file mode 100644
index 000000000000..6c50ee62c56b
--- /dev/null
+++ b/rust/bindings/lib.rs
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Bindings.
+//!
+//! Imports the generated bindings by `bindgen`.
+//!
+//! This crate may not be directly used. If you need a kernel C API that is
+//! not ported or wrapped in the `kernel` crate, then do so first instead of
+//! using this crate.
+
+#![no_std]
+#![feature(core_ffi_c)]
+// See <https://github.com/rust-lang/rust-bindgen/issues/1651>.
+#![cfg_attr(test, allow(deref_nullptr))]
+#![cfg_attr(test, allow(unaligned_references))]
+#![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))]
+#![allow(
+    clippy::all,
+    missing_docs,
+    non_camel_case_types,
+    non_upper_case_globals,
+    non_snake_case,
+    improper_ctypes,
+    unreachable_pub,
+    unsafe_op_in_unsafe_fn
+)]
+
+mod bindings_raw {
+    // 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::*;
+    include!(concat!(
+        env!("OBJTREE"),
+        "/rust/bindings/bindings_generated.rs"
+    ));
+}
+
+// When both a directly exposed symbol and a helper exists for the same function,
+// the directly exposed symbol is preferred and the helper becomes dead code, so
+// ignore the warning here.
+#[allow(dead_code)]
+mod bindings_helper {
+    // Import the generated bindings for types.
+    include!(concat!(
+        env!("OBJTREE"),
+        "/rust/bindings/bindings_helpers_generated.rs"
+    ));
+}
+
+pub use bindings_raw::*;
+
+pub const GFP_KERNEL: gfp_t = BINDINGS_GFP_KERNEL;
+pub const __GFP_ZERO: gfp_t = BINDINGS___GFP_ZERO;
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 12/27] rust: add `kernel` crate
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (9 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 11/27] rust: add `bindings` crate Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-06 10:24   ` Konstantin Shelekhin
  2022-08-05 15:41 ` [PATCH v9 13/27] rust: export generated symbols Miguel Ojeda
                   ` (15 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Wedson Almeida Filho, Alex Gaynor,
	Geoffrey Thomas, Finn Behrens, Adam Bratschi-Kaye,
	Sven Van Asbroeck, Gary Guo, Boris-Chengbiao Zhou, Boqun Feng,
	Fox Chen, Viktor Garske, Dariusz Sosnowski,
	Léo Lanteri Thauvin, Niklas Mohrin, Milan Landaverde,
	Morgan Bartlett, Maciej Falkowski,
	Nándor István Krácser, David Gow, John Baublitz,
	Björn Roy Baron

From: Wedson Almeida Filho <wedsonaf@google.com>

The `kernel` crate currently includes all the abstractions that wrap
kernel features written in C.

These abstractions call the C side of the kernel via the generated
bindings with the `bindgen` tool. Modules developed in Rust should
never call the bindings themselves.

In the future, as the abstractions grow in number, we may need
to split this crate into several, possibly following a similar
subdivision in subsystems as the kernel itself and/or moving
the code to the actual subsystems.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Geoffrey Thomas <geofft@ldpreload.com>
Signed-off-by: Geoffrey Thomas <geofft@ldpreload.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Boris-Chengbiao Zhou <bobo1239@web.de>
Signed-off-by: Boris-Chengbiao Zhou <bobo1239@web.de>
Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Co-developed-by: Fox Chen <foxhlchen@gmail.com>
Signed-off-by: Fox Chen <foxhlchen@gmail.com>
Co-developed-by: Viktor Garske <viktor@v-gar.de>
Signed-off-by: Viktor Garske <viktor@v-gar.de>
Co-developed-by: Dariusz Sosnowski <dsosnowski@dsosnowski.pl>
Signed-off-by: Dariusz Sosnowski <dsosnowski@dsosnowski.pl>
Co-developed-by: Léo Lanteri Thauvin <leseulartichaut@gmail.com>
Signed-off-by: Léo Lanteri Thauvin <leseulartichaut@gmail.com>
Co-developed-by: Niklas Mohrin <dev@niklasmohrin.de>
Signed-off-by: Niklas Mohrin <dev@niklasmohrin.de>
Co-developed-by: Milan Landaverde <milan@mdaverde.com>
Signed-off-by: Milan Landaverde <milan@mdaverde.com>
Co-developed-by: Morgan Bartlett <mjmouse9999@gmail.com>
Signed-off-by: Morgan Bartlett <mjmouse9999@gmail.com>
Co-developed-by: Maciej Falkowski <m.falkowski@samsung.com>
Signed-off-by: Maciej Falkowski <m.falkowski@samsung.com>
Co-developed-by: Nándor István Krácser <bonifaido@gmail.com>
Signed-off-by: Nándor István Krácser <bonifaido@gmail.com>
Co-developed-by: David Gow <davidgow@google.com>
Signed-off-by: David Gow <davidgow@google.com>
Co-developed-by: John Baublitz <john.m.baublitz@gmail.com>
Signed-off-by: John Baublitz <john.m.baublitz@gmail.com>
Co-developed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 rust/kernel/allocator.rs |  64 +++++++++++++
 rust/kernel/error.rs     |  59 ++++++++++++
 rust/kernel/lib.rs       |  78 +++++++++++++++
 rust/kernel/prelude.rs   |  20 ++++
 rust/kernel/print.rs     | 198 +++++++++++++++++++++++++++++++++++++++
 rust/kernel/str.rs       |  72 ++++++++++++++
 6 files changed, 491 insertions(+)
 create mode 100644 rust/kernel/allocator.rs
 create mode 100644 rust/kernel/error.rs
 create mode 100644 rust/kernel/lib.rs
 create mode 100644 rust/kernel/prelude.rs
 create mode 100644 rust/kernel/print.rs
 create mode 100644 rust/kernel/str.rs

diff --git a/rust/kernel/allocator.rs b/rust/kernel/allocator.rs
new file mode 100644
index 000000000000..397a3dd57a9b
--- /dev/null
+++ b/rust/kernel/allocator.rs
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Allocator support.
+
+use core::alloc::{GlobalAlloc, Layout};
+use core::ptr;
+
+use crate::bindings;
+
+struct KernelAllocator;
+
+unsafe impl GlobalAlloc for KernelAllocator {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        // `krealloc()` is used instead of `kmalloc()` because the latter is
+        // an inline function and cannot be bound to as a result.
+        unsafe { bindings::krealloc(ptr::null(), layout.size(), bindings::GFP_KERNEL) as *mut u8 }
+    }
+
+    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
+        unsafe {
+            bindings::kfree(ptr as *const core::ffi::c_void);
+        }
+    }
+}
+
+#[global_allocator]
+static ALLOCATOR: KernelAllocator = KernelAllocator;
+
+// `rustc` only generates these for some crate types. Even then, we would need
+// to extract the object file that has them from the archive. For the moment,
+// let's generate them ourselves instead.
+//
+// Note that `#[no_mangle]` implies exported too, nowadays.
+#[no_mangle]
+fn __rust_alloc(size: usize, _align: usize) -> *mut u8 {
+    unsafe { bindings::krealloc(core::ptr::null(), size, bindings::GFP_KERNEL) as *mut u8 }
+}
+
+#[no_mangle]
+fn __rust_dealloc(ptr: *mut u8, _size: usize, _align: usize) {
+    unsafe { bindings::kfree(ptr as *const core::ffi::c_void) };
+}
+
+#[no_mangle]
+fn __rust_realloc(ptr: *mut u8, _old_size: usize, _align: usize, new_size: usize) -> *mut u8 {
+    unsafe {
+        bindings::krealloc(
+            ptr as *const core::ffi::c_void,
+            new_size,
+            bindings::GFP_KERNEL,
+        ) as *mut u8
+    }
+}
+
+#[no_mangle]
+fn __rust_alloc_zeroed(size: usize, _align: usize) -> *mut u8 {
+    unsafe {
+        bindings::krealloc(
+            core::ptr::null(),
+            size,
+            bindings::GFP_KERNEL | bindings::__GFP_ZERO,
+        ) as *mut u8
+    }
+}
diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs
new file mode 100644
index 000000000000..466b2a8fe569
--- /dev/null
+++ b/rust/kernel/error.rs
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Kernel errors.
+//!
+//! C header: [`include/uapi/asm-generic/errno-base.h`](../../../include/uapi/asm-generic/errno-base.h)
+
+use alloc::collections::TryReserveError;
+
+/// Contains the C-compatible error codes.
+pub mod code {
+    /// Out of memory.
+    pub const ENOMEM: super::Error = super::Error(-(crate::bindings::ENOMEM as i32));
+}
+
+/// Generic integer kernel error.
+///
+/// The kernel defines a set of integer generic error codes based on C and
+/// POSIX ones. These codes may have a more specific meaning in some contexts.
+///
+/// # Invariants
+///
+/// The value is a valid `errno` (i.e. `>= -MAX_ERRNO && < 0`).
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub struct Error(core::ffi::c_int);
+
+impl Error {
+    /// Returns the kernel error code.
+    pub fn to_kernel_errno(self) -> core::ffi::c_int {
+        self.0
+    }
+}
+
+impl From<TryReserveError> for Error {
+    fn from(_: TryReserveError) -> Error {
+        code::ENOMEM
+    }
+}
+
+/// A [`Result`] with an [`Error`] error type.
+///
+/// To be used as the return type for functions that may fail.
+///
+/// # Error codes in C and Rust
+///
+/// In C, it is common that functions indicate success or failure through
+/// their return value; modifying or returning extra data through non-`const`
+/// pointer parameters. In particular, in the kernel, functions that may fail
+/// typically return an `int` that represents a generic error code. We model
+/// those as [`Error`].
+///
+/// In Rust, it is idiomatic to model functions that may fail as returning
+/// a [`Result`]. Since in the kernel many functions return an error code,
+/// [`Result`] is a type alias for a [`core::result::Result`] that uses
+/// [`Error`] as its error type.
+///
+/// Note that even if a function does not return anything when it succeeds,
+/// it should still be modeled as returning a `Result` rather than
+/// just an [`Error`].
+pub type Result<T = ()> = core::result::Result<T, Error>;
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
new file mode 100644
index 000000000000..abd46261d385
--- /dev/null
+++ b/rust/kernel/lib.rs
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! The `kernel` crate.
+//!
+//! This crate contains the kernel APIs that have been ported or wrapped for
+//! usage by Rust code in the kernel and is shared by all of them.
+//!
+//! In other words, all the rest of the Rust code in the kernel (e.g. kernel
+//! modules written in Rust) depends on [`core`], [`alloc`] and this crate.
+//!
+//! If you need a kernel C API that is not ported or wrapped yet here, then
+//! do so first instead of bypassing this crate.
+
+#![no_std]
+#![feature(core_ffi_c)]
+
+// Ensure conditional compilation based on the kernel configuration works;
+// otherwise we may silently break things like initcall handling.
+#[cfg(not(CONFIG_RUST))]
+compile_error!("Missing kernel configuration for conditional compilation");
+
+#[cfg(not(test))]
+#[cfg(not(testlib))]
+mod allocator;
+pub mod error;
+pub mod prelude;
+pub mod print;
+pub mod str;
+
+#[doc(hidden)]
+pub use bindings;
+pub use macros;
+
+/// Prefix to appear before log messages printed from within the `kernel` crate.
+const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
+
+/// The top level entrypoint to implementing a kernel module.
+///
+/// For any teardown or cleanup operations, your type may implement [`Drop`].
+pub trait Module: Sized + Sync {
+    /// Called at module initialization time.
+    ///
+    /// Use this method to perform whatever setup or registration your module
+    /// should do.
+    ///
+    /// Equivalent to the `module_init` macro in the C API.
+    fn init(module: &'static ThisModule) -> error::Result<Self>;
+}
+
+/// Equivalent to `THIS_MODULE` in the C API.
+///
+/// C header: `include/linux/export.h`
+pub struct ThisModule(*mut bindings::module);
+
+// SAFETY: `THIS_MODULE` may be used from all threads within a module.
+unsafe impl Sync for ThisModule {}
+
+impl ThisModule {
+    /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer.
+    ///
+    /// # Safety
+    ///
+    /// The pointer must be equal to the right `THIS_MODULE`.
+    pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> ThisModule {
+        ThisModule(ptr)
+    }
+}
+
+#[cfg(not(any(testlib, test)))]
+#[panic_handler]
+fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
+    pr_emerg!("{}\n", info);
+    // SAFETY: FFI call.
+    unsafe { bindings::BUG() };
+    // Bindgen currently does not recognize `__noreturn` so `BUG` returns `()`
+    // instead of `!`. See <https://github.com/rust-lang/rust-bindgen/issues/2094>.
+    loop {}
+}
diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs
new file mode 100644
index 000000000000..495e22250726
--- /dev/null
+++ b/rust/kernel/prelude.rs
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! The `kernel` prelude.
+//!
+//! These are the most common items used by Rust code in the kernel,
+//! intended to be imported by all Rust code, for convenience.
+//!
+//! # Examples
+//!
+//! ```
+//! use kernel::prelude::*;
+//! ```
+
+pub use super::{
+    error::{Error, Result},
+    pr_emerg, pr_info, ThisModule,
+};
+pub use alloc::{boxed::Box, vec::Vec};
+pub use core::pin::Pin;
+pub use macros::module;
diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs
new file mode 100644
index 000000000000..55db5a1ba752
--- /dev/null
+++ b/rust/kernel/print.rs
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Printing facilities.
+//!
+//! C header: [`include/linux/printk.h`](../../../../include/linux/printk.h)
+//!
+//! Reference: <https://www.kernel.org/doc/html/latest/core-api/printk-basics.html>
+
+use core::{
+    ffi::{c_char, c_void},
+    fmt,
+};
+
+use crate::str::RawFormatter;
+
+#[cfg(CONFIG_PRINTK)]
+use crate::bindings;
+
+// Called from `vsprintf` with format specifier `%pA`.
+#[no_mangle]
+unsafe fn rust_fmt_argument(buf: *mut c_char, end: *mut c_char, ptr: *const c_void) -> *mut c_char {
+    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()) };
+    let _ = w.write_fmt(unsafe { *(ptr as *const fmt::Arguments<'_>) });
+    w.pos().cast()
+}
+
+/// Format strings.
+///
+/// Public but hidden since it should only be used from public macros.
+#[doc(hidden)]
+pub mod format_strings {
+    use crate::bindings;
+
+    /// The length we copy from the `KERN_*` kernel prefixes.
+    const LENGTH_PREFIX: usize = 2;
+
+    /// The length of the fixed format strings.
+    pub const LENGTH: usize = 10;
+
+    /// Generates a fixed format string for the kernel's [`_printk`].
+    ///
+    /// The format string is always the same for a given level, i.e. for a
+    /// given `prefix`, which are the kernel's `KERN_*` constants.
+    ///
+    /// [`_printk`]: ../../../../include/linux/printk.h
+    const fn generate(is_cont: bool, prefix: &[u8; 3]) -> [u8; LENGTH] {
+        // Ensure the `KERN_*` macros are what we expect.
+        assert!(prefix[0] == b'\x01');
+        if is_cont {
+            assert!(prefix[1] == b'c');
+        } else {
+            assert!(prefix[1] >= b'0' && prefix[1] <= b'7');
+        }
+        assert!(prefix[2] == b'\x00');
+
+        let suffix: &[u8; LENGTH - LENGTH_PREFIX] = if is_cont {
+            b"%pA\0\0\0\0\0"
+        } else {
+            b"%s: %pA\0"
+        };
+
+        [
+            prefix[0], prefix[1], suffix[0], suffix[1], suffix[2], suffix[3], suffix[4], suffix[5],
+            suffix[6], suffix[7],
+        ]
+    }
+
+    // Generate the format strings at compile-time.
+    //
+    // This avoids the compiler generating the contents on the fly in the stack.
+    //
+    // Furthermore, `static` instead of `const` is used to share the strings
+    // for all the kernel.
+    pub static EMERG: [u8; LENGTH] = generate(false, bindings::KERN_EMERG);
+    pub static INFO: [u8; LENGTH] = generate(false, bindings::KERN_INFO);
+}
+
+/// Prints a message via the kernel's [`_printk`].
+///
+/// Public but hidden since it should only be used from public macros.
+///
+/// # Safety
+///
+/// The format string must be one of the ones in [`format_strings`], and
+/// the module name must be null-terminated.
+///
+/// [`_printk`]: ../../../../include/linux/_printk.h
+#[doc(hidden)]
+#[cfg_attr(not(CONFIG_PRINTK), allow(unused_variables))]
+pub unsafe fn call_printk(
+    format_string: &[u8; format_strings::LENGTH],
+    module_name: &[u8],
+    args: fmt::Arguments<'_>,
+) {
+    // `_printk` does not seem to fail in any path.
+    #[cfg(CONFIG_PRINTK)]
+    unsafe {
+        bindings::_printk(
+            format_string.as_ptr() as _,
+            module_name.as_ptr(),
+            &args as *const _ as *const c_void,
+        );
+    }
+}
+
+/// Performs formatting and forwards the string to [`call_printk`].
+///
+/// Public but hidden since it should only be used from public macros.
+#[doc(hidden)]
+#[cfg(not(testlib))]
+#[macro_export]
+#[allow(clippy::crate_in_macro_def)]
+macro_rules! print_macro (
+    // The non-continuation cases (most of them, e.g. `INFO`).
+    ($format_string:path, $($arg:tt)+) => (
+        // SAFETY: This hidden macro should only be called by the documented
+        // printing macros which ensure the format string is one of the fixed
+        // ones. All `__LOG_PREFIX`s are null-terminated as they are generated
+        // by the `module!` proc macro or fixed values defined in a kernel
+        // crate.
+        unsafe {
+            $crate::print::call_printk(
+                &$format_string,
+                crate::__LOG_PREFIX,
+                format_args!($($arg)+),
+            );
+        }
+    );
+);
+
+/// Stub for doctests
+#[cfg(testlib)]
+#[macro_export]
+macro_rules! print_macro (
+    ($format_string:path, $e:expr, $($arg:tt)+) => (
+        ()
+    );
+);
+
+// We could use a macro to generate these macros. However, doing so ends
+// up being a bit ugly: it requires the dollar token trick to escape `$` as
+// well as playing with the `doc` attribute. Furthermore, they cannot be easily
+// imported in the prelude due to [1]. So, for the moment, we just write them
+// manually, like in the C side; while keeping most of the logic in another
+// macro, i.e. [`print_macro`].
+//
+// [1]: https://github.com/rust-lang/rust/issues/52234
+
+/// Prints an emergency-level message (level 0).
+///
+/// Use this level if the system is unusable.
+///
+/// Equivalent to the kernel's [`pr_emerg`] macro.
+///
+/// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
+/// `alloc::format!` for information about the formatting syntax.
+///
+/// [`pr_emerg`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_emerg
+/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
+///
+/// # Examples
+///
+/// ```
+/// pr_emerg!("hello {}\n", "there");
+/// ```
+#[macro_export]
+macro_rules! pr_emerg (
+    ($($arg:tt)*) => (
+        $crate::print_macro!($crate::print::format_strings::EMERG, $($arg)*)
+    )
+);
+
+/// Prints an info-level message (level 6).
+///
+/// Use this level for informational messages.
+///
+/// Equivalent to the kernel's [`pr_info`] macro.
+///
+/// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
+/// `alloc::format!` for information about the formatting syntax.
+///
+/// [`pr_info`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_info
+/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
+///
+/// # Examples
+///
+/// ```
+/// pr_info!("hello {}\n", "there");
+/// ```
+#[macro_export]
+#[doc(alias = "print")]
+macro_rules! pr_info (
+    ($($arg:tt)*) => (
+        $crate::print_macro!($crate::print::format_strings::INFO, $($arg)*)
+    )
+);
diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
new file mode 100644
index 000000000000..e45ff220ae50
--- /dev/null
+++ b/rust/kernel/str.rs
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! String representations.
+
+use core::fmt;
+
+/// Allows formatting of [`fmt::Arguments`] into a raw buffer.
+///
+/// It does not fail if callers write past the end of the buffer so that they can calculate the
+/// size required to fit everything.
+///
+/// # Invariants
+///
+/// The memory region between `pos` (inclusive) and `end` (exclusive) is valid for writes if `pos`
+/// is less than `end`.
+pub(crate) struct RawFormatter {
+    // Use `usize` to use `saturating_*` functions.
+    #[allow(dead_code)]
+    beg: usize,
+    pos: usize,
+    end: usize,
+}
+
+impl RawFormatter {
+    /// Creates a new instance of [`RawFormatter`] with the given buffer pointers.
+    ///
+    /// # Safety
+    ///
+    /// If `pos` is less than `end`, then the region between `pos` (inclusive) and `end`
+    /// (exclusive) must be valid for writes for the lifetime of the returned [`RawFormatter`].
+    pub(crate) unsafe fn from_ptrs(pos: *mut u8, end: *mut u8) -> Self {
+        // INVARIANT: The safety requierments guarantee the type invariants.
+        Self {
+            beg: pos as _,
+            pos: pos as _,
+            end: end as _,
+        }
+    }
+
+    /// Returns the current insert position.
+    ///
+    /// N.B. It may point to invalid memory.
+    pub(crate) fn pos(&self) -> *mut u8 {
+        self.pos as _
+    }
+}
+
+impl fmt::Write for RawFormatter {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        // `pos` value after writing `len` bytes. This does not have to be bounded by `end`, but we
+        // don't want it to wrap around to 0.
+        let pos_new = self.pos.saturating_add(s.len());
+
+        // Amount that we can copy. `saturating_sub` ensures we get 0 if `pos` goes past `end`.
+        let len_to_copy = core::cmp::min(pos_new, self.end).saturating_sub(self.pos);
+
+        if len_to_copy > 0 {
+            // SAFETY: If `len_to_copy` is non-zero, then we know `pos` has not gone past `end`
+            // yet, so it is valid for write per the type invariants.
+            unsafe {
+                core::ptr::copy_nonoverlapping(
+                    s.as_bytes().as_ptr(),
+                    self.pos as *mut u8,
+                    len_to_copy,
+                )
+            };
+        }
+
+        self.pos = pos_new;
+        Ok(())
+    }
+}
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 13/27] rust: export generated symbols
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (10 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 12/27] rust: add `kernel` crate Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-17 20:11   ` Kees Cook
  2022-08-05 15:41 ` [PATCH v9 14/27] vsprintf: add new `%pA` format specifier Miguel Ojeda
                   ` (14 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho,
	Björn Roy Baron, Boqun Feng, Gary Guo

All symbols are reexported reusing the `EXPORT_SYMBOL_GPL` macro
from C. The lists of symbols are generated on the fly.

There are three main sets of symbols to distinguish:

  - The ones from the `core` and `alloc` crates (from the Rust
    standard library). The code is licensed as Apache/MIT.

  - The ones from our abstractions in the `kernel` crate.

  - The helpers (already exported since they are not generated).

We export everything as GPL. This ensures we do not mistakenly
expose GPL kernel symbols/features as non-GPL, even indirectly.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 rust/exports.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 rust/exports.c

diff --git a/rust/exports.c b/rust/exports.c
new file mode 100644
index 000000000000..bb7cc64cecd0
--- /dev/null
+++ b/rust/exports.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * A hack to export Rust symbols for loadable modules without having to redo
+ * the entire `include/linux/export.h` logic in Rust.
+ *
+ * This requires the Rust's new/future `v0` mangling scheme because the default
+ * one ("legacy") uses invalid characters for C identifiers (thus we cannot use
+ * the `EXPORT_SYMBOL_*` macros).
+ *
+ * All symbols are exported as GPL-only to guarantee no GPL-only feature is
+ * accidentally exposed.
+ */
+
+#include <linux/module.h>
+
+#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_bindings_generated.h"
+#include "exports_kernel_generated.h"
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 14/27] vsprintf: add new `%pA` format specifier
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (11 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 13/27] rust: export generated symbols Miguel Ojeda
@ 2022-08-05 15:41 ` Miguel Ojeda
  2022-08-05 15:42 ` [PATCH v9 15/27] scripts: checkpatch: diagnose uses of `%pA` in the C side as errors Miguel Ojeda
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:41 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Gary Guo, Kees Cook, Petr Mladek,
	Alex Gaynor, Wedson Almeida Filho, Steven Rostedt,
	Sergey Senozhatsky, Andy Shevchenko, Rasmus Villemoes,
	Jonathan Corbet, linux-doc

From: Gary Guo <gary@garyguo.net>

This patch adds a format specifier `%pA` to `vsprintf` which formats
a pointer as `core::fmt::Arguments`. Doing so allows us to directly
format to the internal buffer of `printf`, so we do not have to use
a temporary buffer on the stack to pre-assemble the message on
the Rust side.

This specifier is intended only to be used from Rust and not for C, so
`checkpatch.pl` is intentionally unchanged to catch any misuse.

Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Petr Mladek <pmladek@suse.com>
Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 Documentation/core-api/printk-formats.rst | 10 ++++++++++
 lib/vsprintf.c                            | 13 +++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
index 5e89497ba314..dbe1aacc79d0 100644
--- a/Documentation/core-api/printk-formats.rst
+++ b/Documentation/core-api/printk-formats.rst
@@ -625,6 +625,16 @@ Examples::
 	%p4cc	Y10  little-endian (0x20303159)
 	%p4cc	NV12 big-endian (0xb231564e)
 
+Rust
+----
+
+::
+
+	%pA
+
+Only intended to be used from Rust code to format ``core::fmt::Arguments``.
+Do *not* use it from C.
+
 Thanks
 ======
 
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 3c1853a9d1c0..c414a8d9f1ea 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -2246,6 +2246,9 @@ int __init no_hash_pointers_enable(char *str)
 }
 early_param("no_hash_pointers", no_hash_pointers_enable);
 
+/* Used for Rust formatting ('%pA'). */
+char *rust_fmt_argument(char *buf, char *end, void *ptr);
+
 /*
  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
  * by an extra set of alphanumeric characters that are extended format
@@ -2372,6 +2375,10 @@ early_param("no_hash_pointers", no_hash_pointers_enable);
  *
  * Note: The default behaviour (unadorned %p) is to hash the address,
  * rendering it useful as a unique identifier.
+ *
+ * There is also a '%pA' format specifier, but it is only intended to be used
+ * from Rust code to format core::fmt::Arguments. Do *not* use it from C.
+ * See rust/kernel/print.rs for details.
  */
 static noinline_for_stack
 char *pointer(const char *fmt, char *buf, char *end, void *ptr,
@@ -2444,6 +2451,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
 		return device_node_string(buf, end, ptr, spec, fmt + 1);
 	case 'f':
 		return fwnode_string(buf, end, ptr, spec, fmt + 1);
+	case 'A':
+		if (!IS_ENABLED(CONFIG_RUST)) {
+			WARN_ONCE(1, "Please remove %%pA from non-Rust code\n");
+			return error_string(buf, end, "(%pA?)", spec);
+		}
+		return rust_fmt_argument(buf, end, ptr);
 	case 'x':
 		return pointer_string(buf, end, ptr, spec);
 	case 'e':
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 15/27] scripts: checkpatch: diagnose uses of `%pA` in the C side as errors
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (12 preceding siblings ...)
  2022-08-05 15:41 ` [PATCH v9 14/27] vsprintf: add new `%pA` format specifier Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-05 15:42 ` [PATCH v9 16/27] scripts: checkpatch: enable language-independent checks for Rust Miguel Ojeda
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Kees Cook, Alex Gaynor,
	Wedson Almeida Filho, Joe Perches, Andy Whitcroft, Dwaipayan Ray,
	Lukas Bulwahn

The `%pA` format specifier is only intended to be used from Rust.

`checkpatch.pl` already gives a warning for invalid specificers:

    WARNING: Invalid vsprintf pointer extension '%pA'

This makes it an error and introduces an explanatory message:

    ERROR: Invalid vsprintf pointer extension '%pA' - '%pA' is only intended to be used from Rust code

Suggested-by: Kees Cook <keescook@chromium.org>
Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Joe Perches <joe@perches.com>
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 scripts/checkpatch.pl | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 503e8abbb2c1..23799e8013b3 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -6782,15 +6782,19 @@ sub process {
 				}
 				if ($bad_specifier ne "") {
 					my $stat_real = get_stat_real($linenr, $lc);
+					my $msg_level = \&WARN;
 					my $ext_type = "Invalid";
 					my $use = "";
 					if ($bad_specifier =~ /p[Ff]/) {
 						$use = " - use %pS instead";
 						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
+					} elsif ($bad_specifier =~ /pA/) {
+						$use =  " - '%pA' is only intended to be used from Rust code";
+						$msg_level = \&ERROR;
 					}
 
-					WARN("VSPRINTF_POINTER_EXTENSION",
-					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
+					&{$msg_level}("VSPRINTF_POINTER_EXTENSION",
+						      "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
 				}
 			}
 		}
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 16/27] scripts: checkpatch: enable language-independent checks for Rust
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (13 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 15/27] scripts: checkpatch: diagnose uses of `%pA` in the C side as errors Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-17 20:12   ` Kees Cook
  2022-08-05 15:42 ` [PATCH v9 17/27] scripts: decode_stacktrace: demangle Rust symbols Miguel Ojeda
                   ` (11 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho,
	Andy Whitcroft, Joe Perches, Dwaipayan Ray, Lukas Bulwahn

Include Rust in the "source code files" category, so that
the language-independent tests are checked for Rust too,
and teach `checkpatch` about the comment style for Rust files.

This enables the malformed SPDX check, the misplaced SPDX license
tag check, the long line checks, the lines without a newline check
and the embedded filename check.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 scripts/checkpatch.pl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 23799e8013b3..bd0025d77bcf 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -3615,7 +3615,7 @@ sub process {
 				my $comment = "";
 				if ($realfile =~ /\.(h|s|S)$/) {
 					$comment = '/*';
-				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
+				} elsif ($realfile =~ /\.(c|rs|dts|dtsi)$/) {
 					$comment = '//';
 				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
 					$comment = '#';
@@ -3663,7 +3663,7 @@ sub process {
 		}
 
 # check we are in a valid source file if not then ignore this hunk
-		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
+		next if ($realfile !~ /\.(h|c|rs|s|S|sh|dtsi|dts)$/);
 
 # check for using SPDX-License-Identifier on the wrong line number
 		if ($realline != $checklicenseline &&
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 17/27] scripts: decode_stacktrace: demangle Rust symbols
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (14 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 16/27] scripts: checkpatch: enable language-independent checks for Rust Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-05 15:42 ` [PATCH v9 18/27] scripts: add `generate_rust_analyzer.py` Miguel Ojeda
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Kees Cook, Alex Gaynor,
	Wedson Almeida Filho

Recent versions of both Binutils (`c++filt`) and LLVM (`llvm-cxxfilt`)
provide Rust v0 mangling support.

Reviewed-by: Kees Cook <keescook@chromium.org>
Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 scripts/decode_stacktrace.sh | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh
index 7075e26ab2c4..564c5632e1a2 100755
--- a/scripts/decode_stacktrace.sh
+++ b/scripts/decode_stacktrace.sh
@@ -8,6 +8,14 @@ usage() {
 	echo "	$0 -r <release> | <vmlinux> [<base path>|auto] [<modules path>]"
 }
 
+# Try to find a Rust demangler
+if type llvm-cxxfilt >/dev/null 2>&1 ; then
+	cppfilt=llvm-cxxfilt
+elif type c++filt >/dev/null 2>&1 ; then
+	cppfilt=c++filt
+	cppfilt_opts=-i
+fi
+
 if [[ $1 == "-r" ]] ; then
 	vmlinux=""
 	basepath="auto"
@@ -180,6 +188,12 @@ parse_symbol() {
 	# In the case of inlines, move everything to same line
 	code=${code//$'\n'/' '}
 
+	# Demangle if the name looks like a Rust symbol and if
+	# we got a Rust demangler
+	if [[ $name =~ ^_R && $cppfilt != "" ]] ; then
+		name=$("$cppfilt" "$cppfilt_opts" "$name")
+	fi
+
 	# Replace old address with pretty line numbers
 	symbol="$segment$name ($code)"
 }
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 18/27] scripts: add `generate_rust_analyzer.py`
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (15 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 17/27] scripts: decode_stacktrace: demangle Rust symbols Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-17 20:13   ` Kees Cook
  2022-08-05 15:42 ` [PATCH v9 19/27] scripts: add `generate_rust_target.rs` Miguel Ojeda
                   ` (9 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Finn Behrens,
	Wedson Almeida Filho, Gary Guo, Boris-Chengbiao Zhou,
	Björn Roy Baron, Boqun Feng

The `generate_rust_analyzer.py` script generates the configuration
file (`rust-project.json`) for rust-analyzer.

rust-analyzer is a modular compiler frontend for the Rust language.
It provides an LSP server which can be used in editors such as
VS Code, Emacs or Vim.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Boris-Chengbiao Zhou <bobo1239@web.de>
Signed-off-by: Boris-Chengbiao Zhou <bobo1239@web.de>
Co-developed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 .gitignore                        |   3 +
 scripts/generate_rust_analyzer.py | 135 ++++++++++++++++++++++++++++++
 2 files changed, 138 insertions(+)
 create mode 100755 scripts/generate_rust_analyzer.py

diff --git a/.gitignore b/.gitignore
index 265959544978..80989914c97d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -162,3 +162,6 @@ x509.genkey
 
 # Documentation toolchain
 sphinx_*/
+
+# Rust analyzer configuration
+/rust-project.json
diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
new file mode 100755
index 000000000000..75bb611bd751
--- /dev/null
+++ b/scripts/generate_rust_analyzer.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+"""generate_rust_analyzer - Generates the `rust-project.json` file for `rust-analyzer`.
+"""
+
+import argparse
+import json
+import logging
+import pathlib
+import sys
+
+def generate_crates(srctree, objtree, sysroot_src):
+    # Generate the configuration list.
+    cfg = []
+    with open(objtree / "include" / "generated" / "rustc_cfg") as fd:
+        for line in fd:
+            line = line.replace("--cfg=", "")
+            line = line.replace("\n", "")
+            cfg.append(line)
+
+    # Now fill the crates list -- dependencies need to come first.
+    #
+    # Avoid O(n^2) iterations by keeping a map of indexes.
+    crates = []
+    crates_indexes = {}
+
+    def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False):
+        crates_indexes[display_name] = len(crates)
+        crates.append({
+            "display_name": display_name,
+            "root_module": str(root_module),
+            "is_workspace_member": is_workspace_member,
+            "is_proc_macro": is_proc_macro,
+            "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps],
+            "cfg": cfg,
+            "edition": "2021",
+            "env": {
+                "RUST_MODFILE": "This is only for rust-analyzer"
+            }
+        })
+
+    # First, the ones in `rust/` since they are a bit special.
+    append_crate(
+        "core",
+        sysroot_src / "core" / "src" / "lib.rs",
+        [],
+        is_workspace_member=False,
+    )
+
+    append_crate(
+        "compiler_builtins",
+        srctree / "rust" / "compiler_builtins.rs",
+        [],
+    )
+
+    append_crate(
+        "alloc",
+        srctree / "rust" / "alloc" / "lib.rs",
+        ["core", "compiler_builtins"],
+    )
+
+    append_crate(
+        "macros",
+        srctree / "rust" / "macros" / "lib.rs",
+        [],
+        is_proc_macro=True,
+    )
+    crates[-1]["proc_macro_dylib_path"] = "rust/libmacros.so"
+
+    append_crate(
+        "bindings",
+        srctree / "rust"/ "bindings" / "lib.rs",
+        ["core"],
+        cfg=cfg,
+    )
+    crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
+
+    append_crate(
+        "kernel",
+        srctree / "rust" / "kernel" / "lib.rs",
+        ["core", "alloc", "macros", "bindings"],
+        cfg=cfg,
+    )
+    crates[-1]["source"] = {
+        "include_dirs": [
+            str(srctree / "rust" / "kernel"),
+            str(objtree / "rust")
+        ],
+        "exclude_dirs": [],
+    }
+
+    # Then, the rest outside of `rust/`.
+    #
+    # We explicitly mention the top-level folders we want to cover.
+    for folder in ("samples", "drivers"):
+        for path in (srctree / folder).rglob("*.rs"):
+            logging.info("Checking %s", path)
+            name = path.name.replace(".rs", "")
+
+            # Skip those that are not crate roots.
+            if f"{name}.o" not in open(path.parent / "Makefile").read():
+                continue
+
+            logging.info("Adding %s", name)
+            append_crate(
+                name,
+                path,
+                ["core", "alloc", "kernel"],
+                cfg=cfg,
+            )
+
+    return crates
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--verbose', '-v', action='store_true')
+    parser.add_argument("srctree", type=pathlib.Path)
+    parser.add_argument("objtree", type=pathlib.Path)
+    parser.add_argument("sysroot_src", type=pathlib.Path)
+    args = parser.parse_args()
+
+    logging.basicConfig(
+        format="[%(asctime)s] [%(levelname)s] %(message)s",
+        level=logging.INFO if args.verbose else logging.WARNING
+    )
+
+    rust_project = {
+        "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src),
+        "sysroot_src": str(args.sysroot_src),
+    }
+
+    json.dump(rust_project, sys.stdout, sort_keys=True, indent=4)
+
+if __name__ == "__main__":
+    main()
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 19/27] scripts: add `generate_rust_target.rs`
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (16 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 18/27] scripts: add `generate_rust_analyzer.py` Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-17 20:14   ` Kees Cook
  2022-08-05 15:42 ` [PATCH v9 20/27] scripts: add `rust_is_available.sh` Miguel Ojeda
                   ` (8 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho,
	David Gow, Boqun Feng, Gary Guo, Björn Roy Baron

This script takes care of generating the custom target specification
file for `rustc`, based on the kernel configuration.

It also serves as an example of a Rust host program.

A dummy architecture is kept in this patch so that a later patch
adds x86 support on top with as few changes as possible.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: David Gow <davidgow@google.com>
Signed-off-by: David Gow <davidgow@google.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 scripts/.gitignore              |   1 +
 scripts/generate_rust_target.rs | 171 ++++++++++++++++++++++++++++++++
 2 files changed, 172 insertions(+)
 create mode 100644 scripts/generate_rust_target.rs

diff --git a/scripts/.gitignore b/scripts/.gitignore
index eed308bef604..b7aec8eb1bd4 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 /asn1_compiler
 /bin2c
+/generate_rust_target
 /insert-sys-cert
 /kallsyms
 /module.lds
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
new file mode 100644
index 000000000000..7256c9606cf0
--- /dev/null
+++ b/scripts/generate_rust_target.rs
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! The custom target specification file generator for `rustc`.
+//!
+//! To configure a target from scratch, a JSON-encoded file has to be passed
+//! to `rustc` (introduced in [RFC 131]). These options and the file itself are
+//! unstable. Eventually, `rustc` should provide a way to do this in a stable
+//! manner. For instance, via command-line arguments. Therefore, this file
+//! should avoid using keys which can be set via `-C` or `-Z` options.
+//!
+//! [RFC 131]: https://rust-lang.github.io/rfcs/0131-target-specification.html
+
+use std::{
+    collections::HashMap,
+    fmt::{Display, Formatter, Result},
+    io::BufRead,
+};
+
+enum Value {
+    Boolean(bool),
+    Number(i32),
+    String(String),
+    Object(Object),
+}
+
+type Object = Vec<(String, Value)>;
+
+/// Minimal "almost JSON" generator (e.g. no `null`s, no arrays, no escaping),
+/// enough for this purpose.
+impl Display for Value {
+    fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
+        match self {
+            Value::Boolean(boolean) => write!(formatter, "{}", boolean),
+            Value::Number(number) => write!(formatter, "{}", number),
+            Value::String(string) => write!(formatter, "\"{}\"", string),
+            Value::Object(object) => {
+                formatter.write_str("{")?;
+                if let [ref rest @ .., ref last] = object[..] {
+                    for (key, value) in rest {
+                        write!(formatter, "\"{}\": {},", key, value)?;
+                    }
+                    write!(formatter, "\"{}\": {}", last.0, last.1)?;
+                }
+                formatter.write_str("}")
+            }
+        }
+    }
+}
+
+struct TargetSpec(Object);
+
+impl TargetSpec {
+    fn new() -> TargetSpec {
+        TargetSpec(Vec::new())
+    }
+}
+
+trait Push<T> {
+    fn push(&mut self, key: &str, value: T);
+}
+
+impl Push<bool> for TargetSpec {
+    fn push(&mut self, key: &str, value: bool) {
+        self.0.push((key.to_string(), Value::Boolean(value)));
+    }
+}
+
+impl Push<i32> for TargetSpec {
+    fn push(&mut self, key: &str, value: i32) {
+        self.0.push((key.to_string(), Value::Number(value)));
+    }
+}
+
+impl Push<String> for TargetSpec {
+    fn push(&mut self, key: &str, value: String) {
+        self.0.push((key.to_string(), Value::String(value)));
+    }
+}
+
+impl Push<&str> for TargetSpec {
+    fn push(&mut self, key: &str, value: &str) {
+        self.push(key, value.to_string());
+    }
+}
+
+impl Push<Object> for TargetSpec {
+    fn push(&mut self, key: &str, value: Object) {
+        self.0.push((key.to_string(), Value::Object(value)));
+    }
+}
+
+impl Display for TargetSpec {
+    fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
+        // We add some newlines for clarity.
+        formatter.write_str("{\n")?;
+        if let [ref rest @ .., ref last] = self.0[..] {
+            for (key, value) in rest {
+                write!(formatter, "    \"{}\": {},\n", key, value)?;
+            }
+            write!(formatter, "    \"{}\": {}\n", last.0, last.1)?;
+        }
+        formatter.write_str("}")
+    }
+}
+
+struct KernelConfig(HashMap<String, String>);
+
+impl KernelConfig {
+    /// Parses `include/config/auto.conf` from `stdin`.
+    fn from_stdin() -> KernelConfig {
+        let mut result = HashMap::new();
+
+        let stdin = std::io::stdin();
+        let mut handle = stdin.lock();
+        let mut line = String::new();
+
+        loop {
+            line.clear();
+
+            if handle.read_line(&mut line).unwrap() == 0 {
+                break;
+            }
+
+            if line.starts_with('#') {
+                continue;
+            }
+
+            let (key, value) = line.split_once('=').expect("Missing `=` in line.");
+            result.insert(key.to_string(), value.trim_end_matches('\n').to_string());
+        }
+
+        KernelConfig(result)
+    }
+
+    /// Does the option exist in the configuration (any value)?
+    ///
+    /// The argument must be passed without the `CONFIG_` prefix.
+    /// This avoids repetition and it also avoids `fixdep` making us
+    /// depend on it.
+    fn has(&self, option: &str) -> bool {
+        let option = "CONFIG_".to_owned() + option;
+        self.0.contains_key(&option)
+    }
+}
+
+fn main() {
+    let cfg = KernelConfig::from_stdin();
+    let mut ts = TargetSpec::new();
+
+    // `llvm-target`s are taken from `scripts/Makefile.clang`.
+    if cfg.has("DUMMY_ARCH") {
+        ts.push("arch", "dummy_arch");
+    } else {
+        panic!("Unsupported architecture");
+    }
+
+    ts.push("emit-debug-gdb-scripts", false);
+    ts.push("frame-pointer", "may-omit");
+    ts.push(
+        "stack-probes",
+        vec![("kind".to_string(), Value::String("none".to_string()))],
+    );
+
+    // Everything else is LE, whether `CPU_LITTLE_ENDIAN` is declared or not
+    // (e.g. x86). It is also `rustc`'s default.
+    if cfg.has("CPU_BIG_ENDIAN") {
+        ts.push("target-endian", "big");
+    }
+
+    println!("{}", ts);
+}
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 20/27] scripts: add `rust_is_available.sh`
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (17 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 19/27] scripts: add `generate_rust_target.rs` Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-17 20:18   ` Kees Cook
  2022-08-22 20:09   ` Nick Desaulniers
  2022-08-05 15:42 ` [PATCH v9 21/27] scripts: add `is_rust_module.sh` Miguel Ojeda
                   ` (7 subsequent siblings)
  26 siblings, 2 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho,
	Finn Behrens, Miguel Cano, Tiago Lam, Boqun Feng, Gary Guo,
	Björn Roy Baron

This script tests whether the Rust toolchain requirements are in place
to enable Rust support.

The build system will call it to set `CONFIG_RUST_IS_AVAILABLE` in
a later patch.

It also has an option (`-v`) to explain what is missing, which is
useful to set up the development environment. This is used via
the `make rustavailable` target added in a later patch.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Miguel Cano <macanroj@gmail.com>
Signed-off-by: Miguel Cano <macanroj@gmail.com>
Co-developed-by: Tiago Lam <tiagolam@gmail.com>
Signed-off-by: Tiago Lam <tiagolam@gmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 scripts/rust_is_available.sh                 | 160 +++++++++++++++++++
 scripts/rust_is_available_bindgen_libclang.h |   2 +
 2 files changed, 162 insertions(+)
 create mode 100755 scripts/rust_is_available.sh
 create mode 100644 scripts/rust_is_available_bindgen_libclang.h

diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh
new file mode 100755
index 000000000000..aebbf1913970
--- /dev/null
+++ b/scripts/rust_is_available.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Tests whether a suitable Rust toolchain is available.
+#
+# Pass `-v` for human output and more checks (as warnings).
+
+set -e
+
+min_tool_version=$(dirname $0)/min-tool-version.sh
+
+# Convert the version string x.y.z to a canonical up-to-7-digits form.
+#
+# Note that this function uses one more digit (compared to other
+# instances in other version scripts) to give a bit more space to
+# `rustc` since it will reach 1.100.0 in late 2026.
+get_canonical_version()
+{
+	IFS=.
+	set -- $1
+	echo $((100000 * $1 + 100 * $2 + $3))
+}
+
+# Check that the Rust compiler exists.
+if ! command -v "$RUSTC" >/dev/null; then
+	if [ "$1" = -v ]; then
+		echo >&2 "***"
+		echo >&2 "*** Rust compiler '$RUSTC' could not be found."
+		echo >&2 "***"
+	fi
+	exit 1
+fi
+
+# Check that the Rust bindings generator exists.
+if ! command -v "$BINDGEN" >/dev/null; then
+	if [ "$1" = -v ]; then
+		echo >&2 "***"
+		echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found."
+		echo >&2 "***"
+	fi
+	exit 1
+fi
+
+# Check that the Rust compiler version is suitable.
+#
+# Non-stable and distributions' versions may have a version suffix, e.g. `-dev`.
+rust_compiler_version=$( \
+	LC_ALL=C "$RUSTC" --version 2>/dev/null \
+		| head -n 1 \
+		| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
+)
+rust_compiler_min_version=$($min_tool_version rustc)
+rust_compiler_cversion=$(get_canonical_version $rust_compiler_version)
+rust_compiler_min_cversion=$(get_canonical_version $rust_compiler_min_version)
+if [ "$rust_compiler_cversion" -lt "$rust_compiler_min_cversion" ]; then
+	if [ "$1" = -v ]; then
+		echo >&2 "***"
+		echo >&2 "*** Rust compiler '$RUSTC' is too old."
+		echo >&2 "***   Your version:    $rust_compiler_version"
+		echo >&2 "***   Minimum version: $rust_compiler_min_version"
+		echo >&2 "***"
+	fi
+	exit 1
+fi
+if [ "$1" = -v ] && [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then
+	echo >&2 "***"
+	echo >&2 "*** Rust compiler '$RUSTC' is too new. This may or may not work."
+	echo >&2 "***   Your version:     $rust_compiler_version"
+	echo >&2 "***   Expected version: $rust_compiler_min_version"
+	echo >&2 "***"
+fi
+
+# Check that the Rust bindings generator is suitable.
+#
+# Non-stable and distributions' versions may have a version suffix, e.g. `-dev`.
+rust_bindings_generator_version=$( \
+	LC_ALL=C "$BINDGEN" --version 2>/dev/null \
+		| head -n 1 \
+		| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
+)
+rust_bindings_generator_min_version=$($min_tool_version bindgen)
+rust_bindings_generator_cversion=$(get_canonical_version $rust_bindings_generator_version)
+rust_bindings_generator_min_cversion=$(get_canonical_version $rust_bindings_generator_min_version)
+if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cversion" ]; then
+	if [ "$1" = -v ]; then
+		echo >&2 "***"
+		echo >&2 "*** Rust bindings generator '$BINDGEN' is too old."
+		echo >&2 "***   Your version:    $rust_bindings_generator_version"
+		echo >&2 "***   Minimum version: $rust_bindings_generator_min_version"
+		echo >&2 "***"
+	fi
+	exit 1
+fi
+if [ "$1" = -v ] && [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then
+	echo >&2 "***"
+	echo >&2 "*** Rust bindings generator '$BINDGEN' is too new. This may or may not work."
+	echo >&2 "***   Your version:     $rust_bindings_generator_version"
+	echo >&2 "***   Expected version: $rust_bindings_generator_min_version"
+	echo >&2 "***"
+fi
+
+# Check that the `libclang` used by the Rust bindings generator is suitable.
+bindgen_libclang_version=$( \
+	LC_ALL=C "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang.h 2>&1 >/dev/null \
+		| grep -F 'clang version ' \
+		| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
+		| head -n 1 \
+)
+bindgen_libclang_min_version=$($min_tool_version llvm)
+bindgen_libclang_cversion=$(get_canonical_version $bindgen_libclang_version)
+bindgen_libclang_min_cversion=$(get_canonical_version $bindgen_libclang_min_version)
+if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then
+	if [ "$1" = -v ]; then
+		echo >&2 "***"
+		echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old."
+		echo >&2 "***   Your version:    $bindgen_libclang_version"
+		echo >&2 "***   Minimum version: $bindgen_libclang_min_version"
+		echo >&2 "***"
+	fi
+	exit 1
+fi
+
+# If the C compiler is Clang, then we can also check whether its version
+# matches the `libclang` version used by the Rust bindings generator.
+#
+# In the future, we might be able to perform a full version check, see
+# https://github.com/rust-lang/rust-bindgen/issues/2138.
+if [ "$1" = -v ]; then
+	cc_name=$($(dirname $0)/cc-version.sh "$CC" | cut -f1 -d' ')
+	if [ "$cc_name" = Clang ]; then
+		clang_version=$( \
+			LC_ALL=C "$CC" --version 2>/dev/null \
+				| sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p'
+		)
+		if [ "$clang_version" != "$bindgen_libclang_version" ]; then
+			echo >&2 "***"
+			echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN')"
+			echo >&2 "*** version does not match Clang's. This may be a problem."
+			echo >&2 "***   libclang version: $bindgen_libclang_version"
+			echo >&2 "***   Clang version:    $clang_version"
+			echo >&2 "***"
+		fi
+	fi
+fi
+
+# Check that the source code for the `core` standard library exists.
+#
+# `$KRUSTFLAGS` is passed in case the user added `--sysroot`.
+rustc_sysroot=$("$RUSTC" $KRUSTFLAGS --print sysroot)
+rustc_src=${RUST_LIB_SRC:-"$rustc_sysroot/lib/rustlib/src/rust/library"}
+rustc_src_core="$rustc_src/core/src/lib.rs"
+if [ ! -e "$rustc_src_core" ]; then
+	if [ "$1" = -v ]; then
+		echo >&2 "***"
+		echo >&2 "*** Source code for the 'core' standard library could not be found"
+		echo >&2 "*** at '$rustc_src_core'."
+		echo >&2 "***"
+	fi
+	exit 1
+fi
diff --git a/scripts/rust_is_available_bindgen_libclang.h b/scripts/rust_is_available_bindgen_libclang.h
new file mode 100644
index 000000000000..0ef6db10d674
--- /dev/null
+++ b/scripts/rust_is_available_bindgen_libclang.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#pragma message("clang version " __clang_version__)
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 21/27] scripts: add `is_rust_module.sh`
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (18 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 20/27] scripts: add `rust_is_available.sh` Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-17 20:19   ` Kees Cook
  2022-08-05 15:42 ` [PATCH v9 22/27] rust: add `.rustfmt.toml` Miguel Ojeda
                   ` (6 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Daniel Xu, Alex Gaynor,
	Wedson Almeida Filho, Boqun Feng, Gary Guo, Björn Roy Baron

From: Daniel Xu <dxu@dxuuu.xyz>

This script is used to detect whether a kernel module is written
in Rust.

It will later be used to disable BTF generation on Rust modules as
BTF does not yet support Rust.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
Co-developed-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 scripts/is_rust_module.sh | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100755 scripts/is_rust_module.sh

diff --git a/scripts/is_rust_module.sh b/scripts/is_rust_module.sh
new file mode 100755
index 000000000000..28b3831a7593
--- /dev/null
+++ b/scripts/is_rust_module.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# is_rust_module.sh module.ko
+#
+# Returns `0` if `module.ko` is a Rust module, `1` otherwise.
+
+set -e
+
+# Using the `16_` prefix ensures other symbols with the same substring
+# are not picked up (even if it would be unlikely). The last part is
+# used just in case LLVM decides to use the `.` suffix.
+#
+# In the future, checking for the `.comment` section may be another
+# option, see https://github.com/rust-lang/rust/pull/97550.
+${NM} "$*" | grep -qE '^[0-9a-fA-F]+ r _R[^[:space:]]+16___IS_RUST_MODULE[^[:space:]]*$'
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 22/27] rust: add `.rustfmt.toml`
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (19 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 21/27] scripts: add `is_rust_module.sh` Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-17 20:19   ` Kees Cook
  2022-08-05 15:42 ` [PATCH v9 23/27] Kbuild: add Rust support Miguel Ojeda
                   ` (5 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho

This is the configuration file for the `rustfmt` tool.

`rustfmt` is a tool for formatting Rust code according to style guidelines.
It is very commonly used across Rust projects.

The default configuration options are used.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 .gitignore    |  1 +
 .rustfmt.toml | 12 ++++++++++++
 2 files changed, 13 insertions(+)
 create mode 100644 .rustfmt.toml

diff --git a/.gitignore b/.gitignore
index 80989914c97d..97e085d613a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -97,6 +97,7 @@ modules.order
 !.gitattributes
 !.gitignore
 !.mailmap
+!.rustfmt.toml
 
 #
 # Generated include files
diff --git a/.rustfmt.toml b/.rustfmt.toml
new file mode 100644
index 000000000000..3de5cc497465
--- /dev/null
+++ b/.rustfmt.toml
@@ -0,0 +1,12 @@
+edition = "2021"
+newline_style = "Unix"
+
+# Unstable options that help catching some mistakes in formatting and that we may want to enable
+# when they become stable.
+#
+# They are kept here since they are useful to run from time to time.
+#format_code_in_doc_comments = true
+#reorder_impl_items = true
+#comment_width = 100
+#wrap_comments = true
+#normalize_comments = true
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 23/27] Kbuild: add Rust support
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (20 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 22/27] rust: add `.rustfmt.toml` Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-17 20:26   ` Kees Cook
                     ` (2 more replies)
  2022-08-05 15:42 ` [PATCH v9 24/27] docs: add Rust documentation Miguel Ojeda
                   ` (4 subsequent siblings)
  26 siblings, 3 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Finn Behrens,
	Adam Bratschi-Kaye, Wedson Almeida Filho, Michael Ellerman,
	Sven Van Asbroeck, Gary Guo, Boris-Chengbiao Zhou, Boqun Feng,
	Douglas Su, Dariusz Sosnowski, Antonio Terceiro, Daniel Xu,
	Björn Roy Baron, Martin Rodriguez Reboredo, Masahiro Yamada,
	Michal Marek, Nick Desaulniers, linux-kbuild

Having most of the new files in place, we now enable Rust support
in the build system, including `Kconfig` entries related to Rust,
the Rust configuration printer and a few other bits.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Boris-Chengbiao Zhou <bobo1239@web.de>
Signed-off-by: Boris-Chengbiao Zhou <bobo1239@web.de>
Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Co-developed-by: Douglas Su <d0u9.su@outlook.com>
Signed-off-by: Douglas Su <d0u9.su@outlook.com>
Co-developed-by: Dariusz Sosnowski <dsosnowski@dsosnowski.pl>
Signed-off-by: Dariusz Sosnowski <dsosnowski@dsosnowski.pl>
Co-developed-by: Antonio Terceiro <antonio.terceiro@linaro.org>
Signed-off-by: Antonio Terceiro <antonio.terceiro@linaro.org>
Co-developed-by: Daniel Xu <dxu@dxuuu.xyz>
Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
Co-developed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Co-developed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 .gitignore                     |   2 +
 Makefile                       | 172 ++++++++++++++-
 arch/Kconfig                   |   6 +
 include/linux/compiler_types.h |   6 +-
 init/Kconfig                   |  46 +++-
 kernel/configs/rust.config     |   1 +
 lib/Kconfig.debug              |  34 +++
 rust/.gitignore                |   8 +
 rust/Makefile                  | 381 +++++++++++++++++++++++++++++++++
 rust/bindgen_parameters        |  21 ++
 scripts/Kconfig.include        |   6 +-
 scripts/Makefile               |   3 +
 scripts/Makefile.build         |  60 ++++++
 scripts/Makefile.debug         |  10 +
 scripts/Makefile.host          |  34 ++-
 scripts/Makefile.lib           |  12 ++
 scripts/Makefile.modfinal      |   8 +-
 scripts/cc-version.sh          |  12 +-
 scripts/kconfig/confdata.c     |  75 +++++++
 scripts/min-tool-version.sh    |   6 +
 20 files changed, 877 insertions(+), 26 deletions(-)
 create mode 100644 kernel/configs/rust.config
 create mode 100644 rust/.gitignore
 create mode 100644 rust/Makefile
 create mode 100644 rust/bindgen_parameters

diff --git a/.gitignore b/.gitignore
index 97e085d613a2..5da004814678 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,8 @@
 *.o
 *.o.*
 *.patch
+*.rmeta
+*.rsi
 *.s
 *.so
 *.so.dbg
diff --git a/Makefile b/Makefile
index df92892325ae..a105cb893b4c 100644
--- a/Makefile
+++ b/Makefile
@@ -120,6 +120,15 @@ endif
 
 export KBUILD_CHECKSRC
 
+# Enable "clippy" (a linter) as part of the Rust compilation.
+#
+# Use 'make CLIPPY=1' to enable it.
+ifeq ("$(origin CLIPPY)", "command line")
+  KBUILD_CLIPPY := $(CLIPPY)
+endif
+
+export KBUILD_CLIPPY
+
 # Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the
 # directory of external module to build. Setting M= takes precedence.
 ifeq ("$(origin M)", "command line")
@@ -267,14 +276,14 @@ no-dot-config-targets := $(clean-targets) \
 			 cscope gtags TAGS tags help% %docs check% coccicheck \
 			 $(version_h) headers headers_% archheaders archscripts \
 			 %asm-generic kernelversion %src-pkg dt_binding_check \
-			 outputmakefile
+			 outputmakefile rustavailable rustfmt rustfmtcheck
 # Installation targets should not require compiler. Unfortunately, vdso_install
 # is an exception where build artifacts may be updated. This must be fixed.
 no-compiler-targets := $(no-dot-config-targets) install dtbs_install \
 			headers_install modules_install kernelrelease image_name
 no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease \
 			  image_name
-single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/
+single-targets := %.a %.i %.rsi %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/
 
 config-build	:=
 mixed-build	:=
@@ -436,6 +445,7 @@ else
 HOSTCC	= gcc
 HOSTCXX	= g++
 endif
+HOSTRUSTC = rustc
 HOSTPKG_CONFIG	= pkg-config
 
 KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \
@@ -444,8 +454,26 @@ KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \
 KBUILD_USERCFLAGS  := $(KBUILD_USERHOSTCFLAGS) $(USERCFLAGS)
 KBUILD_USERLDFLAGS := $(USERLDFLAGS)
 
+# These flags apply to all Rust code in the tree, including the kernel and
+# host programs.
+export rust_common_flags := --edition=2021 \
+			    -Zbinary_dep_depinfo=y \
+			    -Dunsafe_op_in_unsafe_fn -Drust_2018_idioms \
+			    -Dunreachable_pub -Dnon_ascii_idents \
+			    -Wmissing_docs \
+			    -Drustdoc::missing_crate_level_docs \
+			    -Dclippy::correctness -Dclippy::style \
+			    -Dclippy::suspicious -Dclippy::complexity \
+			    -Dclippy::perf \
+			    -Dclippy::let_unit_value -Dclippy::mut_mut \
+			    -Dclippy::needless_bitwise_bool \
+			    -Dclippy::needless_continue \
+			    -Wclippy::dbg_macro
+
 KBUILD_HOSTCFLAGS   := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS)
 KBUILD_HOSTCXXFLAGS := -Wall -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS)
+KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \
+			-Zallow-features= $(HOSTRUSTFLAGS)
 KBUILD_HOSTLDFLAGS  := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS)
 KBUILD_HOSTLDLIBS   := $(HOST_LFS_LIBS) $(HOSTLDLIBS)
 
@@ -470,6 +498,12 @@ OBJDUMP		= $(CROSS_COMPILE)objdump
 READELF		= $(CROSS_COMPILE)readelf
 STRIP		= $(CROSS_COMPILE)strip
 endif
+RUSTC		= rustc
+RUSTDOC		= rustdoc
+RUSTFMT		= rustfmt
+CLIPPY_DRIVER	= clippy-driver
+BINDGEN		= bindgen
+CARGO		= cargo
 PAHOLE		= pahole
 RESOLVE_BTFIDS	= $(objtree)/tools/bpf/resolve_btfids/resolve_btfids
 LEX		= flex
@@ -495,9 +529,11 @@ CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
 		  -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF)
 NOSTDINC_FLAGS :=
 CFLAGS_MODULE   =
+RUSTFLAGS_MODULE =
 AFLAGS_MODULE   =
 LDFLAGS_MODULE  =
 CFLAGS_KERNEL	=
+RUSTFLAGS_KERNEL =
 AFLAGS_KERNEL	=
 LDFLAGS_vmlinux =
 
@@ -526,15 +562,42 @@ KBUILD_CFLAGS   := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \
 		   -Werror=return-type -Wno-format-security \
 		   -std=gnu11
 KBUILD_CPPFLAGS := -D__KERNEL__
+KBUILD_RUSTFLAGS := $(rust_common_flags) \
+		    --target=$(objtree)/rust/target.json \
+		    -Cpanic=abort -Cembed-bitcode=n -Clto=n \
+		    -Cforce-unwind-tables=n -Ccodegen-units=1 \
+		    -Csymbol-mangling-version=v0 \
+		    -Crelocation-model=static \
+		    -Zfunction-sections=n \
+		    -Dclippy::float_arithmetic
+
 KBUILD_AFLAGS_KERNEL :=
 KBUILD_CFLAGS_KERNEL :=
+KBUILD_RUSTFLAGS_KERNEL :=
 KBUILD_AFLAGS_MODULE  := -DMODULE
 KBUILD_CFLAGS_MODULE  := -DMODULE
+KBUILD_RUSTFLAGS_MODULE := --cfg MODULE
 KBUILD_LDFLAGS_MODULE :=
 KBUILD_LDFLAGS :=
 CLANG_FLAGS :=
 
+ifeq ($(KBUILD_CLIPPY),1)
+	RUSTC_OR_CLIPPY_QUIET := CLIPPY
+	RUSTC_OR_CLIPPY = $(CLIPPY_DRIVER)
+else
+	RUSTC_OR_CLIPPY_QUIET := RUSTC
+	RUSTC_OR_CLIPPY = $(RUSTC)
+endif
+
+ifdef RUST_LIB_SRC
+	export RUST_LIB_SRC
+endif
+
+export RUSTC_BOOTSTRAP := 1
+
 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 CARGO
+export HOSTRUSTC KBUILD_HOSTRUSTFLAGS
 export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
 export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
 export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD
@@ -543,9 +606,10 @@ export KBUILD_USERCFLAGS KBUILD_USERLDFLAGS
 
 export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
 export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+export KBUILD_RUSTFLAGS RUSTFLAGS_KERNEL RUSTFLAGS_MODULE
 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
-export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
-export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
+export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_RUSTFLAGS_MODULE KBUILD_LDFLAGS_MODULE
+export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL KBUILD_RUSTFLAGS_KERNEL
 export PAHOLE_FLAGS
 
 # Files to ignore in find ... statements
@@ -726,7 +790,7 @@ $(KCONFIG_CONFIG):
 #
 # Do not use $(call cmd,...) here. That would suppress prompts from syncconfig,
 # so you cannot notice that Kconfig is waiting for the user input.
-%/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h: $(KCONFIG_CONFIG)
+%/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h %/generated/rustc_cfg: $(KCONFIG_CONFIG)
 	$(Q)$(kecho) "  SYNC    $@"
 	$(Q)$(MAKE) -f $(srctree)/Makefile syncconfig
 else # !may-sync-config
@@ -755,12 +819,20 @@ KBUILD_CFLAGS	+= $(call cc-disable-warning, address-of-packed-member)
 
 ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
 KBUILD_CFLAGS += -O2
+KBUILD_RUSTFLAGS += -Copt-level=2
 else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3
 KBUILD_CFLAGS += -O3
+KBUILD_RUSTFLAGS += -Copt-level=3
 else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
 KBUILD_CFLAGS += -Os
+KBUILD_RUSTFLAGS += -Copt-level=s
 endif
 
+# Always set `debug-assertions` and `overflow-checks` because their default
+# depends on `opt-level` and `debug-assertions`, respectively.
+KBUILD_RUSTFLAGS += -Cdebug-assertions=$(if $(CONFIG_RUST_DEBUG_ASSERTIONS),y,n)
+KBUILD_RUSTFLAGS += -Coverflow-checks=$(if $(CONFIG_RUST_OVERFLOW_CHECKS),y,n)
+
 # Tell gcc to never replace conditional load with a non-conditional one
 ifdef CONFIG_CC_IS_GCC
 # gcc-10 renamed --param=allow-store-data-races=0 to
@@ -791,6 +863,9 @@ KBUILD_CFLAGS-$(CONFIG_WERROR) += -Werror
 KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds
 KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH)
 
+KBUILD_RUSTFLAGS-$(CONFIG_WERROR) += -Dwarnings
+KBUILD_RUSTFLAGS += $(KBUILD_RUSTFLAGS-y)
+
 ifdef CONFIG_CC_IS_CLANG
 KBUILD_CPPFLAGS += -Qunused-arguments
 # The kernel builds with '-std=gnu11' so use of GNU extensions is acceptable.
@@ -811,12 +886,15 @@ KBUILD_CFLAGS += $(call cc-disable-warning, dangling-pointer)
 
 ifdef CONFIG_FRAME_POINTER
 KBUILD_CFLAGS	+= -fno-omit-frame-pointer -fno-optimize-sibling-calls
+KBUILD_RUSTFLAGS += -Cforce-frame-pointers=y
 else
 # Some targets (ARM with Thumb2, for example), can't be built with frame
 # pointers.  For those, we don't have FUNCTION_TRACER automatically
 # select FRAME_POINTER.  However, FUNCTION_TRACER adds -pg, and this is
 # incompatible with -fomit-frame-pointer with current GCC, so we don't use
 # -fomit-frame-pointer with FUNCTION_TRACER.
+# In the Rust target specification, "frame-pointer" is set explicitly
+# to "may-omit".
 ifndef CONFIG_FUNCTION_TRACER
 KBUILD_CFLAGS	+= -fomit-frame-pointer
 endif
@@ -881,8 +959,10 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH
 KBUILD_CFLAGS += -fno-inline-functions-called-once
 endif
 
+# `rustc`'s `-Zfunction-sections` applies to data too (as of 1.59.0).
 ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
 KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
+KBUILD_RUSTFLAGS_KERNEL += -Zfunction-sections=y
 LDFLAGS_vmlinux += --gc-sections
 endif
 
@@ -1025,10 +1105,11 @@ include $(addprefix $(srctree)/, $(include-y))
 # Do not add $(call cc-option,...) below this line. When you build the kernel
 # from the clean source tree, the GCC plugins do not exist at this point.
 
-# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
+# Add user supplied CPPFLAGS, AFLAGS, CFLAGS and RUSTFLAGS as the last assignments
 KBUILD_CPPFLAGS += $(KCPPFLAGS)
 KBUILD_AFLAGS   += $(KAFLAGS)
 KBUILD_CFLAGS   += $(KCFLAGS)
+KBUILD_RUSTFLAGS += $(KRUSTFLAGS)
 
 KBUILD_LDFLAGS_MODULE += --build-id=sha1
 LDFLAGS_vmlinux += --build-id=sha1
@@ -1097,6 +1178,7 @@ export MODULES_NSDEPS := $(extmod_prefix)modules.nsdeps
 ifeq ($(KBUILD_EXTMOD),)
 core-y			+= kernel/ certs/ mm/ fs/ ipc/ security/ crypto/
 core-$(CONFIG_BLOCK)	+= block/
+core-$(CONFIG_RUST)	+= rust/
 
 vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, \
 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
@@ -1201,6 +1283,10 @@ prepare0: archprepare
 
 # All the preparing..
 prepare: prepare0
+ifdef CONFIG_RUST
+	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v
+	$(Q)$(MAKE) $(build)=rust
+endif
 
 PHONY += remove-stale-files
 remove-stale-files:
@@ -1490,7 +1576,7 @@ endif # CONFIG_MODULES
 # Directories & files removed with 'make clean'
 CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \
 	       modules.builtin modules.builtin.modinfo modules.nsdeps \
-	       compile_commands.json .thinlto-cache
+	       compile_commands.json .thinlto-cache rust/test rust/doc
 
 # Directories & files removed with 'make mrproper'
 MRPROPER_FILES += include/config include/generated          \
@@ -1501,7 +1587,8 @@ MRPROPER_FILES += include/config include/generated          \
 		  certs/signing_key.pem \
 		  certs/x509.genkey \
 		  vmlinux-gdb.py \
-		  *.spec
+		  *.spec \
+		  rust/target.json rust/libmacros.so
 
 # clean - Delete most, but leave enough to build external modules
 #
@@ -1526,6 +1613,9 @@ $(mrproper-dirs):
 
 mrproper: clean $(mrproper-dirs)
 	$(call cmd,rmfiles)
+	@find . $(RCS_FIND_IGNORE) \
+		\( -name '*.rmeta' \) \
+		-type f -print | xargs rm -f
 
 # distclean
 #
@@ -1613,6 +1703,24 @@ help:
 	@echo  '  kselftest-merge   - Merge all the config dependencies of'
 	@echo  '		      kselftest to existing .config.'
 	@echo  ''
+	@echo  'Rust targets:'
+	@echo  '  rustavailable   - Checks whether the Rust toolchain is'
+	@echo  '		    available and, if not, explains why.'
+	@echo  '  rustfmt	  - Reformat all the Rust code in the kernel'
+	@echo  '  rustfmtcheck	  - Checks if all the Rust code in the kernel'
+	@echo  '		    is formatted, printing a diff otherwise.'
+	@echo  '  rustdoc	  - Generate Rust documentation'
+	@echo  '		    (requires kernel .config)'
+	@echo  '  rusttest        - Runs the Rust tests'
+	@echo  '                    (requires kernel .config; downloads external repos)'
+	@echo  '  rust-analyzer	  - Generate rust-project.json rust-analyzer support file'
+	@echo  '		    (requires kernel .config)'
+	@echo  '  dir/file.[os]   - Build specified target only'
+	@echo  '  dir/file.rsi    - Build macro expanded source, similar to C preprocessing.'
+	@echo  '                    Run with RUSTFMT=n to skip reformatting if needed.'
+	@echo  '                    The output is not intended to be compilable.'
+	@echo  '  dir/file.ll     - Build the LLVM assembly file'
+	@echo  ''
 	@$(if $(dtstree), \
 		echo 'Devicetree:'; \
 		echo '* dtbs             - Build device tree blobs for enabled boards'; \
@@ -1685,6 +1793,52 @@ PHONY += $(DOC_TARGETS)
 $(DOC_TARGETS):
 	$(Q)$(MAKE) $(build)=Documentation $@
 
+
+# Rust targets
+# ---------------------------------------------------------------------------
+
+# "Is Rust available?" target
+PHONY += rustavailable
+rustavailable:
+	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v && echo "Rust is available!"
+
+# Documentation target
+#
+# Using the singular to avoid running afoul of `no-dot-config-targets`.
+PHONY += rustdoc
+rustdoc: prepare
+	$(Q)$(MAKE) $(build)=rust $@
+
+# Testing target
+PHONY += rusttest
+rusttest: prepare
+	$(Q)$(MAKE) $(build)=rust $@
+
+# Formatting targets
+PHONY += rustfmt rustfmtcheck
+
+# We skip `rust/alloc` since we want to minimize the diff w.r.t. upstream.
+#
+# We match using absolute paths since `find` does not resolve them
+# when matching, which is a problem when e.g. `srctree` is `..`.
+# We `grep` afterwards in order to remove the directory entry itself.
+rustfmt:
+	$(Q)find $(abs_srctree) -type f -name '*.rs' \
+		-o -path $(abs_srctree)/rust/alloc -prune \
+		-o -path $(abs_objtree)/rust/test -prune \
+		| grep -Fv $(abs_srctree)/rust/alloc \
+		| grep -Fv $(abs_objtree)/rust/test \
+		| grep -Fv generated \
+		| xargs $(RUSTFMT) $(rustfmt_flags)
+
+rustfmtcheck: rustfmt_flags = --check
+rustfmtcheck: rustfmt
+
+# IDE support targets
+PHONY += rust-analyzer
+rust-analyzer:
+	$(Q)$(MAKE) $(build)=rust $@
+
 # Misc
 # ---------------------------------------------------------------------------
 
@@ -1852,7 +2006,7 @@ $(clean-dirs):
 clean: $(clean-dirs)
 	$(call cmd,rmfiles)
 	@find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
-		\( -name '*.[aios]' -o -name '*.ko' -o -name '.*.cmd' \
+		\( -name '*.[aios]' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \
 		-o -name '*.ko.*' \
 		-o -name '*.dtb' -o -name '*.dtbo' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
 		-o -name '*.dwo' -o -name '*.lst' \
diff --git a/arch/Kconfig b/arch/Kconfig
index 71b9272acb28..d5038cf8dd49 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -353,6 +353,12 @@ config HAVE_RSEQ
 	  This symbol should be selected by an architecture if it
 	  supports an implementation of restartable sequences.
 
+config HAVE_RUST
+	bool
+	help
+	  This symbol should be selected by an architecture if it
+	  supports Rust.
+
 config HAVE_FUNCTION_ARG_ACCESS_API
 	bool
 	help
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 4f2a819fd60a..50b3f6b9502e 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -4,8 +4,12 @@
 
 #ifndef __ASSEMBLY__
 
+/*
+ * Skipped when running bindgen due to a libclang issue;
+ * see https://github.com/rust-lang/rust-bindgen/issues/2244.
+ */
 #if defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \
-	__has_attribute(btf_type_tag)
+	__has_attribute(btf_type_tag) && !defined(__BINDGEN__)
 # define BTF_TYPE_TAG(value) __attribute__((btf_type_tag(#value)))
 #else
 # define BTF_TYPE_TAG(value) /* nothing */
diff --git a/init/Kconfig b/init/Kconfig
index c7900e8975f1..ff0636891bc1 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -60,6 +60,17 @@ config LLD_VERSION
 	default $(ld-version) if LD_IS_LLD
 	default 0
 
+config RUST_IS_AVAILABLE
+	def_bool $(success,$(srctree)/scripts/rust_is_available.sh)
+	help
+	  This shows whether a suitable Rust toolchain is available (found).
+
+	  Please see Documentation/rust/quick-start.rst for instructions on how
+	  to satify the build requirements of Rust support.
+
+	  In particular, the Makefile target 'rustavailable' is useful to check
+	  why the Rust toolchain is not being detected.
+
 config CC_CAN_LINK
 	bool
 	default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m64-flag)) if 64BIT
@@ -151,7 +162,8 @@ config WERROR
 	default COMPILE_TEST
 	help
 	  A kernel build should not cause any compiler warnings, and this
-	  enables the '-Werror' flag to enforce that rule by default.
+	  enables the '-Werror' (for C) and '-Dwarnings' (for Rust) flags
+	  to enforce that rule by default.
 
 	  However, if you have a new (or very old) compiler with odd and
 	  unusual warnings, or you have some architecture with problems,
@@ -1898,6 +1910,38 @@ config PROFILING
 	  Say Y here to enable the extended profiling support mechanisms used
 	  by profilers.
 
+config RUST
+	bool "Rust support"
+	depends on HAVE_RUST
+	depends on RUST_IS_AVAILABLE
+	depends on !MODVERSIONS
+	depends on !GCC_PLUGINS
+	depends on !RANDSTRUCT
+	depends on !DEBUG_INFO_BTF
+	select CONSTRUCTORS
+	help
+	  Enables Rust support in the kernel.
+
+	  This allows other Rust-related options, like drivers written in Rust,
+	  to be selected.
+
+	  It is also required to be able to load external kernel modules
+	  written in Rust.
+
+	  See Documentation/rust/ for more information.
+
+	  If unsure, say N.
+
+config RUSTC_VERSION_TEXT
+	string
+	depends on RUST
+	default $(shell,command -v $(RUSTC) >/dev/null 2>&1 && $(RUSTC) --version || echo n)
+
+config BINDGEN_VERSION_TEXT
+	string
+	depends on RUST
+	default $(shell,command -v $(BINDGEN) >/dev/null 2>&1 && $(BINDGEN) --version || echo n)
+
 #
 # Place an empty function call at each tracepoint site. Can be
 # dynamically changed for a probe function.
diff --git a/kernel/configs/rust.config b/kernel/configs/rust.config
new file mode 100644
index 000000000000..38a7c5362c9c
--- /dev/null
+++ b/kernel/configs/rust.config
@@ -0,0 +1 @@
+CONFIG_RUST=y
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 2e24db4bff19..06af1cd68e95 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2688,6 +2688,40 @@ config HYPERV_TESTING
 
 endmenu # "Kernel Testing and Coverage"
 
+menu "Rust hacking"
+
+config RUST_DEBUG_ASSERTIONS
+	bool "Debug assertions"
+	depends on RUST
+	help
+	  Enables rustc's `-Cdebug-assertions` codegen option.
+
+	  This flag lets you turn `cfg(debug_assertions)` conditional
+	  compilation on or off. This can be used to enable extra debugging
+	  code in development but not in production. For example, it controls
+	  the behavior of the standard library's `debug_assert!` macro.
+
+	  Note that this will apply to all Rust code, including `core`.
+
+	  If unsure, say N.
+
+config RUST_OVERFLOW_CHECKS
+	bool "Overflow checks"
+	default y
+	depends on RUST
+	help
+	  Enables rustc's `-Coverflow-checks` codegen option.
+
+	  This flag allows you to control the behavior of runtime integer
+	  overflow. When overflow-checks are enabled, a Rust panic will occur
+	  on overflow.
+
+	  Note that this will apply to all Rust code, including `core`.
+
+	  If unsure, say Y.
+
+endmenu # "Rust"
+
 source "Documentation/Kconfig"
 
 endmenu # Kernel hacking
diff --git a/rust/.gitignore b/rust/.gitignore
new file mode 100644
index 000000000000..9bd1af8e05a1
--- /dev/null
+++ b/rust/.gitignore
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+
+target.json
+bindings_generated.rs
+bindings_helpers_generated.rs
+exports_*_generated.h
+doc/
+test/
diff --git a/rust/Makefile b/rust/Makefile
new file mode 100644
index 000000000000..7700d3853404
--- /dev/null
+++ b/rust/Makefile
@@ -0,0 +1,381 @@
+# SPDX-License-Identifier: GPL-2.0
+
+always-$(CONFIG_RUST) += target.json
+no-clean-files += target.json
+
+obj-$(CONFIG_RUST) += core.o compiler_builtins.o
+always-$(CONFIG_RUST) += exports_core_generated.h
+
+# Missing prototypes are expected in the helpers since these are exported
+# for Rust only, thus there is no header nor prototypes.
+obj-$(CONFIG_RUST) += helpers.o
+CFLAGS_REMOVE_helpers.o = -Wmissing-prototypes -Wmissing-declarations
+
+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_bindings_generated.h \
+    exports_kernel_generated.h
+
+obj-$(CONFIG_RUST) += exports.o
+
+# Avoids running `$(RUSTC)` for the sysroot when it may not be available.
+ifdef CONFIG_RUST
+
+# `$(rust_flags)` is passed in case the user added `--sysroot`.
+rustc_sysroot := $(shell $(RUSTC) $(rust_flags) --print sysroot)
+rustc_host_target := $(shell $(RUSTC) --version --verbose | grep -F 'host: ' | cut -d' ' -f2)
+RUST_LIB_SRC ?= $(rustc_sysroot)/lib/rustlib/src/rust/library
+
+ifeq ($(quiet),silent_)
+cargo_quiet=-q
+rust_test_quiet=-q
+rustdoc_test_quiet=--test-args -q
+else ifeq ($(quiet),quiet_)
+rust_test_quiet=-q
+rustdoc_test_quiet=--test-args -q
+else
+cargo_quiet=--verbose
+endif
+
+core-cfgs = \
+    --cfg no_fp_fmt_parse
+
+alloc-cfgs = \
+    --cfg no_fmt \
+    --cfg no_global_oom_handling \
+    --cfg no_macros \
+    --cfg no_rc \
+    --cfg no_str \
+    --cfg no_string \
+    --cfg no_sync \
+    --cfg no_thin
+
+quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $<
+      cmd_rustdoc = \
+	OBJTREE=$(abspath $(objtree)) \
+	$(RUSTDOC) $(if $(rustdoc_host),$(rust_common_flags),$(rust_flags)) \
+		$(rustc_target_flags) -L$(objtree)/$(obj) \
+		--output $(objtree)/$(obj)/doc \
+		--crate-name $(subst rustdoc-,,$@) \
+		@$(objtree)/include/generated/rustc_cfg $<
+
+# The `html_logo_url` and `html_favicon_url` forms of the `doc` attribute
+# can be used to specify a custom logo. However:
+#   - The given value is used as-is, thus it cannot be relative or a local file
+#     (unlike the non-custom case) since the generated docs have subfolders.
+#   - It requires adding it to every crate.
+#   - It requires changing `core` which comes from the sysroot.
+#
+# Using `-Zcrate-attr` would solve the last two points, but not the first.
+# The https://github.com/rust-lang/rfcs/pull/3226 RFC suggests two new
+# 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
+	$(Q)cp $(srctree)/Documentation/images/logo.svg $(objtree)/$(obj)/doc
+	$(Q)cp $(srctree)/Documentation/images/COPYING-logo $(objtree)/$(obj)/doc
+	$(Q)find $(objtree)/$(obj)/doc -name '*.html' -type f -print0 | xargs -0 sed -Ei \
+		-e 's:rust-logo\.svg:logo.svg:g' \
+		-e 's:rust-logo\.png:logo.svg:g' \
+		-e 's:favicon\.svg:logo.svg:g' \
+		-e 's:<link rel="alternate icon" type="image/png" href="[./]*favicon-(16x16|32x32)\.png">::g'
+	$(Q)echo '.logo-container > img { object-fit: contain; }' \
+		>> $(objtree)/$(obj)/doc/rustdoc.css
+
+rustdoc-macros: private rustdoc_host = yes
+rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \
+    --extern proc_macro
+rustdoc-macros: $(src)/macros/lib.rs FORCE
+	$(call if_changed,rustdoc)
+
+rustdoc-core: private rustc_target_flags = $(core-cfgs)
+rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE
+	$(call if_changed,rustdoc)
+
+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: $(src)/alloc/lib.rs rustdoc-core rustdoc-compiler_builtins FORCE
+	$(call if_changed,rustdoc)
+
+rustdoc-kernel: private rustc_target_flags = --extern alloc \
+    --extern macros=$(objtree)/$(obj)/libmacros.so \
+    --extern bindings
+rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \
+    rustdoc-compiler_builtins rustdoc-alloc $(obj)/libmacros.so \
+    $(obj)/bindings.o FORCE
+	$(call if_changed,rustdoc)
+
+quiet_cmd_rustc_test_library = RUSTC TL $<
+      cmd_rustc_test_library = \
+	OBJTREE=$(abspath $(objtree)) \
+	$(RUSTC) $(rust_common_flags) \
+		@$(objtree)/include/generated/rustc_cfg $(rustc_target_flags) \
+		--crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \
+		--out-dir $(objtree)/$(obj)/test --cfg testlib \
+		--sysroot $(objtree)/$(obj)/test/sysroot \
+		-L$(objtree)/$(obj)/test \
+		--crate-name $(subst rusttest-,,$(subst rusttestlib-,,$@)) $<
+
+rusttestlib-macros: private rustc_target_flags = --extern proc_macro
+rusttestlib-macros: private rustc_test_library_proc = yes
+rusttestlib-macros: $(src)/macros/lib.rs rusttest-prepare FORCE
+	$(call if_changed,rustc_test_library)
+
+rusttestlib-bindings: $(src)/bindings/lib.rs rusttest-prepare FORCE
+	$(call if_changed,rustc_test_library)
+
+quiet_cmd_rustdoc_test = RUSTDOC T $<
+      cmd_rustdoc_test = \
+	OBJTREE=$(abspath $(objtree)) \
+	$(RUSTDOC) --test $(rust_common_flags) \
+		@$(objtree)/include/generated/rustc_cfg \
+		$(rustc_target_flags) $(rustdoc_test_target_flags) \
+		--sysroot $(objtree)/$(obj)/test/sysroot $(rustdoc_test_quiet) \
+		-L$(objtree)/$(obj)/test --output $(objtree)/$(obj)/doc \
+		--crate-name $(subst rusttest-,,$@) $<
+
+# We cannot use `-Zpanic-abort-tests` because some tests are dynamic,
+# so for the moment we skip `-Cpanic=abort`.
+quiet_cmd_rustc_test = RUSTC T  $<
+      cmd_rustc_test = \
+	OBJTREE=$(abspath $(objtree)) \
+	$(RUSTC) --test $(rust_common_flags) \
+		@$(objtree)/include/generated/rustc_cfg \
+		$(rustc_target_flags) --out-dir $(objtree)/$(obj)/test \
+		--sysroot $(objtree)/$(obj)/test/sysroot \
+		-L$(objtree)/$(obj)/test \
+		--crate-name $(subst rusttest-,,$@) $<; \
+	$(objtree)/$(obj)/test/$(subst rusttest-,,$@) $(rust_test_quiet) \
+		$(rustc_test_run_flags)
+
+rusttest: rusttest-macros rusttest-kernel
+
+# This prepares a custom sysroot with our custom `alloc` instead of
+# the standard one.
+#
+# This requires several hacks:
+#   - Unlike `core` and `alloc`, `std` depends on more than a dozen crates,
+#     including third-party crates that need to be downloaded, plus custom
+#     `build.rs` steps. Thus hardcoding things here is not maintainable.
+#   - `cargo` knows how to build the standard library, but it is an unstable
+#     feature so far (`-Zbuild-std`).
+#   - `cargo` only considers the use case of building the standard library
+#     to use it in a given package. Thus we need to create a dummy package
+#     and pick the generated libraries from there.
+#   - Since we only keep a subset of upstream `alloc` in-tree, we need
+#     to recreate it on the fly by putting our sources on top.
+#   - The usual ways of modifying the dependency graph in `cargo` do not seem
+#     to apply for the `-Zbuild-std` steps, thus we have to mislead it
+#     by modifying the sources in the sysroot.
+#   - To avoid messing with the user's Rust installation, we create a clone
+#     of the sysroot. However, `cargo` ignores `RUSTFLAGS` in the `-Zbuild-std`
+#     steps, thus we use a wrapper binary passed via `RUSTC` to pass the flag.
+#
+# In the future, we hope to avoid the whole ordeal by either:
+#   - Making the `test` crate not depend on `std` (either improving upstream
+#     or having our own custom crate).
+#   - Making the tests run in kernel space (requires the previous point).
+#   - Making `std` and friends be more like a "normal" crate, so that
+#     `-Zbuild-std` and related hacks are not needed.
+quiet_cmd_rustsysroot = RUSTSYSROOT
+      cmd_rustsysroot = \
+	rm -rf $(objtree)/$(obj)/test; \
+	mkdir -p $(objtree)/$(obj)/test; \
+	cp -a $(rustc_sysroot) $(objtree)/$(obj)/test/sysroot; \
+	cp -r $(srctree)/$(src)/alloc/* \
+		$(objtree)/$(obj)/test/sysroot/lib/rustlib/src/rust/library/alloc/src; \
+	echo '\#!/bin/sh' > $(objtree)/$(obj)/test/rustc_sysroot; \
+	echo "$(RUSTC) --sysroot=$(abspath $(objtree)/$(obj)/test/sysroot) \"\$$@\"" \
+		>> $(objtree)/$(obj)/test/rustc_sysroot; \
+	chmod u+x $(objtree)/$(obj)/test/rustc_sysroot; \
+	$(CARGO) -q new $(objtree)/$(obj)/test/dummy; \
+	RUSTC=$(objtree)/$(obj)/test/rustc_sysroot $(CARGO) $(cargo_quiet) \
+		test -Zbuild-std --target $(rustc_host_target) \
+		--manifest-path $(objtree)/$(obj)/test/dummy/Cargo.toml; \
+	rm $(objtree)/$(obj)/test/sysroot/lib/rustlib/$(rustc_host_target)/lib/*; \
+	cp $(objtree)/$(obj)/test/dummy/target/$(rustc_host_target)/debug/deps/* \
+		$(objtree)/$(obj)/test/sysroot/lib/rustlib/$(rustc_host_target)/lib
+
+rusttest-prepare: FORCE
+	$(call if_changed,rustsysroot)
+
+rusttest-macros: private rustc_target_flags = --extern proc_macro
+rusttest-macros: private rustdoc_test_target_flags = --crate-type proc-macro
+rusttest-macros: $(src)/macros/lib.rs rusttest-prepare FORCE
+	$(call if_changed,rustc_test)
+	$(call if_changed,rustdoc_test)
+
+rusttest-kernel: private rustc_target_flags = --extern alloc \
+    --extern macros --extern bindings
+rusttest-kernel: $(src)/kernel/lib.rs rusttest-prepare \
+    rusttestlib-macros rusttestlib-bindings FORCE
+	$(call if_changed,rustc_test)
+	$(call if_changed,rustc_test_library)
+
+filechk_rust_target = $(objtree)/scripts/generate_rust_target < $<
+
+$(obj)/target.json: $(objtree)/include/config/auto.conf FORCE
+	$(call filechk,rust_target)
+
+ifdef CONFIG_CC_IS_CLANG
+bindgen_c_flags = $(c_flags)
+else
+# bindgen relies on libclang to parse C. Ideally, bindgen would support a GCC
+# plugin backend and/or the Clang driver would be perfectly compatible with GCC.
+#
+# For the moment, here we are tweaking the flags on the fly. This is a hack,
+# and some kernel configurations may not work (e.g. `GCC_PLUGIN_RANDSTRUCT`
+# if we end up using one of those structs).
+bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \
+	-mskip-rax-setup -mgeneral-regs-only -msign-return-address=% \
+	-mindirect-branch=thunk-extern -mindirect-branch-register \
+	-mfunction-return=thunk-extern -mrecord-mcount -mabi=lp64 \
+	-mindirect-branch-cs-prefix -mstack-protector-guard% -mtraceback=no \
+	-mno-pointers-to-nested-functions -mno-string \
+	-mno-strict-align -mstrict-align \
+	-fconserve-stack -falign-jumps=% -falign-loops=% \
+	-femit-struct-debug-baseonly -fno-ipa-cp-clone -fno-ipa-sra \
+	-fno-partial-inlining -fplugin-arg-arm_ssp_per_task_plugin-% \
+	-fno-reorder-blocks -fno-allow-store-data-races -fasan-shadow-offset=% \
+	-fzero-call-used-regs=% -fno-stack-clash-protection \
+	-fno-inline-functions-called-once \
+	--param=% --param asan-%
+
+# Derived from `scripts/Makefile.clang`.
+BINDGEN_TARGET_x86	:= x86_64-linux-gnu
+BINDGEN_TARGET		:= $(BINDGEN_TARGET_$(SRCARCH))
+
+# All warnings are inhibited since GCC builds are very experimental,
+# many GCC warnings are not supported by Clang, they may only appear in
+# some configurations, with new GCC versions, etc.
+bindgen_extra_c_flags = -w --target=$(BINDGEN_TARGET)
+
+bindgen_c_flags = $(filter-out $(bindgen_skip_c_flags), $(c_flags)) \
+	$(bindgen_extra_c_flags)
+endif
+
+ifdef CONFIG_LTO
+bindgen_c_flags_lto = $(filter-out $(CC_FLAGS_LTO), $(bindgen_c_flags))
+else
+bindgen_c_flags_lto = $(bindgen_c_flags)
+endif
+
+bindgen_c_flags_final = $(bindgen_c_flags_lto) -D__BINDGEN__
+
+quiet_cmd_bindgen = BINDGEN $@
+      cmd_bindgen = \
+	$(BINDGEN) $< $(bindgen_target_flags) \
+		--use-core --with-derive-default --ctypes-prefix core::ffi --no-layout-tests \
+		--no-debug '.*' \
+		--size_t-is-usize -o $@ -- $(bindgen_c_flags_final) -DMODULE \
+		$(bindgen_target_cflags) $(bindgen_target_extra)
+
+$(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \
+    $(shell grep -v '^\#\|^$$' $(srctree)/$(src)/bindgen_parameters)
+$(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \
+    $(src)/bindgen_parameters FORCE
+	$(call if_changed_dep,bindgen)
+
+# See `CFLAGS_REMOVE_helpers.o` above. In addition, Clang on C does not warn
+# with `-Wmissing-declarations` (unlike GCC), so it is not strictly needed here
+# given it is `libclang`; but for consistency, future Clang changes and/or
+# a potential future GCC backend for `bindgen`, we disable it too.
+$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_flags = \
+    --blacklist-type '.*' --whitelist-var '' \
+    --whitelist-function 'rust_helper_.*'
+$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_cflags = \
+    -I$(objtree)/$(obj) -Wno-missing-prototypes -Wno-missing-declarations
+$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_extra = ; \
+    sed -Ei 's/pub fn rust_helper_([a-zA-Z0-9_]*)/#[link_name="rust_helper_\1"]\n    pub fn \1/g' $@
+$(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers.c FORCE
+	$(call if_changed_dep,bindgen)
+
+quiet_cmd_exports = EXPORTS $@
+      cmd_exports = \
+	$(NM) -p --defined-only $< \
+		| grep -E ' (T|R|D) ' | cut -d ' ' -f 3 \
+		| xargs -Isymbol \
+		echo 'EXPORT_SYMBOL_RUST_GPL(symbol);' > $@
+
+$(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)
+
+$(obj)/exports_bindings_generated.h: $(obj)/bindings.o FORCE
+	$(call if_changed,exports)
+
+$(obj)/exports_kernel_generated.h: $(obj)/kernel.o FORCE
+	$(call if_changed,exports)
+
+quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@
+      cmd_rustc_procmacro = \
+	$(RUSTC_OR_CLIPPY) $(rust_common_flags) \
+		--emit=dep-info,link --extern proc_macro \
+		--crate-type proc-macro --out-dir $(objtree)/$(obj) \
+		--crate-name $(patsubst lib%.so,%,$(notdir $@)) $<; \
+	mv $(objtree)/$(obj)/$(patsubst lib%.so,%,$(notdir $@)).d $(depfile); \
+	sed -i '/^\#/d' $(depfile)
+
+# Procedural macros can only be used with the `rustc` that compiled it.
+# Therefore, to get `libmacros.so` automatically recompiled when the compiler
+# version changes, we add `core.o` as a dependency (even if it is not needed).
+$(obj)/libmacros.so: $(src)/macros/lib.rs $(obj)/core.o FORCE
+	$(call if_changed_dep,rustc_procmacro)
+
+quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@
+      cmd_rustc_library = \
+	OBJTREE=$(abspath $(objtree)) \
+	$(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \
+		$(filter-out $(skip_flags),$(rust_flags) $(rustc_target_flags)) \
+		--emit=dep-info,obj,metadata --crate-type rlib \
+		--out-dir $(objtree)/$(obj) -L$(objtree)/$(obj) \
+		--crate-name $(patsubst %.o,%,$(notdir $@)) $<; \
+	mv $(objtree)/$(obj)/$(patsubst %.o,%,$(notdir $@)).d $(depfile); \
+	sed -i '/^\#/d' $(depfile) \
+	$(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@)
+
+rust-analyzer:
+	$(Q)$(srctree)/scripts/generate_rust_analyzer.py $(srctree) $(objtree) \
+		$(RUST_LIB_SRC) > $(objtree)/rust-project.json
+
+$(obj)/core.o: private skip_clippy = 1
+$(obj)/core.o: private skip_flags = -Dunreachable_pub
+$(obj)/core.o: private rustc_target_flags = $(core-cfgs)
+$(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs $(obj)/target.json FORCE
+	$(call if_changed_dep,rustc_library)
+
+$(obj)/compiler_builtins.o: private rustc_objcopy = -w -W '__*'
+$(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE
+	$(call if_changed_dep,rustc_library)
+
+$(obj)/alloc.o: private skip_clippy = 1
+$(obj)/alloc.o: private skip_flags = -Dunreachable_pub
+$(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs)
+$(obj)/alloc.o: $(src)/alloc/lib.rs $(obj)/compiler_builtins.o FORCE
+	$(call if_changed_dep,rustc_library)
+
+$(obj)/bindings.o: $(src)/bindings/lib.rs \
+    $(obj)/compiler_builtins.o \
+    $(obj)/bindings/bindings_generated.rs \
+    $(obj)/bindings/bindings_helpers_generated.rs FORCE
+	$(call if_changed_dep,rustc_library)
+
+$(obj)/kernel.o: private rustc_target_flags = --extern alloc \
+    --extern macros --extern bindings
+$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o \
+    $(obj)/libmacros.so $(obj)/bindings.o FORCE
+	$(call if_changed_dep,rustc_library)
+
+endif # CONFIG_RUST
diff --git a/rust/bindgen_parameters b/rust/bindgen_parameters
new file mode 100644
index 000000000000..be4963bf7203
--- /dev/null
+++ b/rust/bindgen_parameters
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0
+
+--opaque-type xregs_state
+--opaque-type desc_struct
+--opaque-type arch_lbr_state
+--opaque-type local_apic
+
+# Packed type cannot transitively contain a `#[repr(align)]` type.
+--opaque-type x86_msi_data
+--opaque-type x86_msi_addr_lo
+
+# `try` is a reserved keyword since Rust 2018; solved in `bindgen` v0.59.2,
+# commit 2aed6b021680 ("context: Escape the try keyword properly").
+--opaque-type kunit_try_catch
+
+# If SMP is disabled, `arch_spinlock_t` is defined as a ZST which triggers a Rust
+# warning. We don't need to peek into it anyway.
+--opaque-type spinlock
+
+# `seccomp`'s comment gets understood as a doctest
+--no-doc-comments
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include
index 0496efd6e117..83e850321eb6 100644
--- a/scripts/Kconfig.include
+++ b/scripts/Kconfig.include
@@ -36,12 +36,12 @@ ld-option = $(success,$(LD) -v $(1))
 as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o /dev/null -)
 
 # check if $(CC) and $(LD) exist
-$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found)
+$(error-if,$(failure,command -v $(CC)),C compiler '$(CC)' not found)
 $(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found)
 
-# Get the compiler name, version, and error out if it is not supported.
+# Get the C compiler name, version, and error out if it is not supported.
 cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC))
-$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is not supported.)
+$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this C compiler is not supported.)
 cc-name := $(shell,set -- $(cc-info) && echo $1)
 cc-version := $(shell,set -- $(cc-info) && echo $2)
 
diff --git a/scripts/Makefile b/scripts/Makefile
index f084f08ed176..1575af84d557 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -10,6 +10,9 @@ hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT)		+= sorttable
 hostprogs-always-$(CONFIG_ASN1)				+= asn1_compiler
 hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT)		+= sign-file
 hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE)	+= insert-sys-cert
+hostprogs-always-$(CONFIG_RUST)				+= generate_rust_target
+
+generate_rust_target-rust := y
 
 HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
 HOSTLDLIBS_sorttable = -lpthread
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index cac070aee791..ffbbeae0989b 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -26,6 +26,7 @@ EXTRA_CPPFLAGS :=
 EXTRA_LDFLAGS  :=
 asflags-y  :=
 ccflags-y  :=
+rustflags-y :=
 cppflags-y :=
 ldflags-y  :=
 
@@ -271,6 +272,65 @@ quiet_cmd_cc_lst_c = MKLST   $@
 $(obj)/%.lst: $(src)/%.c FORCE
 	$(call if_changed_dep,cc_lst_c)
 
+# Compile Rust sources (.rs)
+# ---------------------------------------------------------------------------
+
+rust_allowed_features := core_ffi_c
+
+rust_common_cmd = \
+	RUST_MODFILE=$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \
+	-Zallow-features=$(rust_allowed_features) \
+	-Zcrate-attr=no_std \
+	-Zcrate-attr='feature($(rust_allowed_features))' \
+	--extern alloc --extern kernel \
+	--crate-type rlib --out-dir $(obj) -L $(objtree)/rust/ \
+	--crate-name $(basename $(notdir $@))
+
+rust_handle_depfile = \
+	mv $(obj)/$(basename $(notdir $@)).d $(depfile); \
+	sed -i '/^\#/d' $(depfile)
+
+# `--emit=obj`, `--emit=asm` and `--emit=llvm-ir` imply a single codegen unit
+# will be used. We explicitly request `-Ccodegen-units=1` in any case, and
+# the compiler shows a warning if it is not 1. However, if we ever stop
+# requesting it explicitly and we start using some other `--emit` that does not
+# imply it (and for which codegen is performed), then we would be out of sync,
+# i.e. the outputs we would get for the different single targets (e.g. `.ll`)
+# would not match each other.
+
+quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
+      cmd_rustc_o_rs = \
+	$(rust_common_cmd) --emit=dep-info,obj $<; \
+	$(rust_handle_depfile)
+
+$(obj)/%.o: $(src)/%.rs FORCE
+	$(call if_changed_dep,rustc_o_rs)
+
+quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
+      cmd_rustc_rsi_rs = \
+	$(rust_common_cmd) --emit=dep-info -Zunpretty=expanded $< >$@; \
+	command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@; \
+	$(rust_handle_depfile)
+
+$(obj)/%.rsi: $(src)/%.rs FORCE
+	$(call if_changed_dep,rustc_rsi_rs)
+
+quiet_cmd_rustc_s_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
+      cmd_rustc_s_rs = \
+	$(rust_common_cmd) --emit=dep-info,asm $<; \
+	$(rust_handle_depfile)
+
+$(obj)/%.s: $(src)/%.rs FORCE
+	$(call if_changed_dep,rustc_s_rs)
+
+quiet_cmd_rustc_ll_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
+      cmd_rustc_ll_rs = \
+	$(rust_common_cmd) --emit=dep-info,llvm-ir $<; \
+	$(rust_handle_depfile)
+
+$(obj)/%.ll: $(src)/%.rs FORCE
+	$(call if_changed_dep,rustc_ll_rs)
+
 # Compile assembler sources (.S)
 # ---------------------------------------------------------------------------
 
diff --git a/scripts/Makefile.debug b/scripts/Makefile.debug
index 9f39b0130551..fe87389d52c0 100644
--- a/scripts/Makefile.debug
+++ b/scripts/Makefile.debug
@@ -1,4 +1,5 @@
 DEBUG_CFLAGS	:=
+DEBUG_RUSTFLAGS	:=
 
 ifdef CONFIG_DEBUG_INFO_SPLIT
 DEBUG_CFLAGS	+= -gsplit-dwarf
@@ -10,6 +11,12 @@ ifndef CONFIG_AS_IS_LLVM
 KBUILD_AFLAGS	+= -Wa,-gdwarf-2
 endif
 
+ifdef CONFIG_DEBUG_INFO_REDUCED
+DEBUG_RUSTFLAGS += -Cdebuginfo=1
+else
+DEBUG_RUSTFLAGS += -Cdebuginfo=2
+endif
+
 ifndef CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
 dwarf-version-$(CONFIG_DEBUG_INFO_DWARF4) := 4
 dwarf-version-$(CONFIG_DEBUG_INFO_DWARF5) := 5
@@ -31,3 +38,6 @@ endif
 
 KBUILD_CFLAGS += $(DEBUG_CFLAGS)
 export DEBUG_CFLAGS
+
+KBUILD_RUSTFLAGS += $(DEBUG_RUSTFLAGS)
+export DEBUG_RUSTFLAGS
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 278b4d6ac945..da133780b751 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -22,6 +22,8 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
 # to preprocess a data file.
 #
 # Both C and C++ are supported, but preferred language is C for such utilities.
+# Rust is also supported, but it may only be used in scenarios where a Rust
+# toolchain is required to be available (e.g. when  `CONFIG_RUST` is enabled).
 #
 # Sample syntax (see Documentation/kbuild/makefiles.rst for reference)
 # hostprogs := bin2hex
@@ -37,15 +39,20 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
 # qconf-objs      := menu.o
 # Will compile qconf as a C++ program, and menu as a C program.
 # They are linked as C++ code to the executable qconf
+#
+# hostprogs   := target
+# target-rust := y
+# Will compile `target` as a Rust program, using `target.rs` as the crate root.
+# The crate may consist of several source files.
 
 # C code
 # Executables compiled from a single .c file
 host-csingle	:= $(foreach m,$(hostprogs), \
-			$(if $($(m)-objs)$($(m)-cxxobjs),,$(m)))
+			$(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-rust),,$(m)))
 
 # C executables linked based on several .o files
 host-cmulti	:= $(foreach m,$(hostprogs),\
-		   $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
+		   $(if $($(m)-cxxobjs)$($(m)-rust),,$(if $($(m)-objs),$(m))))
 
 # Object (.o) files compiled from .c files
 host-cobjs	:= $(sort $(foreach m,$(hostprogs),$($(m)-objs)))
@@ -58,11 +65,17 @@ host-cxxmulti	:= $(foreach m,$(hostprogs),$(if $($(m)-cxxobjs),$(m)))
 # C++ Object (.o) files compiled from .cc files
 host-cxxobjs	:= $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
 
+# Rust code
+# Executables compiled from a single Rust crate (which may consist of
+# one or more .rs files)
+host-rust	:= $(foreach m,$(hostprogs),$(if $($(m)-rust),$(m)))
+
 host-csingle	:= $(addprefix $(obj)/,$(host-csingle))
 host-cmulti	:= $(addprefix $(obj)/,$(host-cmulti))
 host-cobjs	:= $(addprefix $(obj)/,$(host-cobjs))
 host-cxxmulti	:= $(addprefix $(obj)/,$(host-cxxmulti))
 host-cxxobjs	:= $(addprefix $(obj)/,$(host-cxxobjs))
+host-rust	:= $(addprefix $(obj)/,$(host-rust))
 
 #####
 # Handle options to gcc. Support building with separate output directory
@@ -71,6 +84,8 @@ _hostc_flags   = $(KBUILD_HOSTCFLAGS)   $(HOST_EXTRACFLAGS)   \
                  $(HOSTCFLAGS_$(target-stem).o)
 _hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
                  $(HOSTCXXFLAGS_$(target-stem).o)
+_hostrust_flags = $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \
+                  $(HOSTRUSTFLAGS_$(target-stem))
 
 # $(objtree)/$(obj) for including generated headers from checkin source files
 ifeq ($(KBUILD_EXTMOD),)
@@ -82,6 +97,7 @@ endif
 
 hostc_flags    = -Wp,-MMD,$(depfile) $(_hostc_flags)
 hostcxx_flags  = -Wp,-MMD,$(depfile) $(_hostcxx_flags)
+hostrust_flags = $(_hostrust_flags)
 
 #####
 # Compile programs on the host
@@ -128,5 +144,17 @@ quiet_cmd_host-cxxobjs	= HOSTCXX $@
 $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
 	$(call if_changed_dep,host-cxxobjs)
 
+# Create executable from a single Rust crate (which may consist of
+# one or more `.rs` files)
+# host-rust -> Executable
+quiet_cmd_host-rust	= HOSTRUSTC $@
+      cmd_host-rust	= \
+	$(HOSTRUSTC) $(hostrust_flags) --emit=dep-info,link \
+		--out-dir=$(obj)/ $<; \
+	mv $(obj)/$(target-stem).d $(depfile); \
+	sed -i '/^\#/d' $(depfile)
+$(host-rust): $(obj)/%: $(src)/%.rs FORCE
+	$(call if_changed_dep,host-rust)
+
 targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \
-	   $(host-cxxmulti) $(host-cxxobjs)
+	   $(host-cxxmulti) $(host-cxxobjs) $(host-rust)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 3fb6a99e78c4..c88b98b5dc44 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -8,6 +8,7 @@ ldflags-y  += $(EXTRA_LDFLAGS)
 # flags that take effect in current and sub directories
 KBUILD_AFLAGS += $(subdir-asflags-y)
 KBUILD_CFLAGS += $(subdir-ccflags-y)
+KBUILD_RUSTFLAGS += $(subdir-rustflags-y)
 
 # Figure out what we need to build from the various variables
 # ===========================================================================
@@ -128,6 +129,10 @@ _c_flags       = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \
                      $(filter-out $(ccflags-remove-y), \
                          $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \
                      $(CFLAGS_$(target-stem).o))
+_rust_flags    = $(filter-out $(RUSTFLAGS_REMOVE_$(target-stem).o), \
+                     $(filter-out $(rustflags-remove-y), \
+                         $(KBUILD_RUSTFLAGS) $(rustflags-y)) \
+                     $(RUSTFLAGS_$(target-stem).o))
 _a_flags       = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \
                      $(filter-out $(asflags-remove-y), \
                          $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \
@@ -202,6 +207,11 @@ modkern_cflags =                                          \
 		$(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
 		$(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags))
 
+modkern_rustflags =                                              \
+	$(if $(part-of-module),                                   \
+		$(KBUILD_RUSTFLAGS_MODULE) $(RUSTFLAGS_MODULE), \
+		$(KBUILD_RUSTFLAGS_KERNEL) $(RUSTFLAGS_KERNEL))
+
 modkern_aflags = $(if $(part-of-module),				\
 			$(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE),	\
 			$(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL))
@@ -211,6 +221,8 @@ c_flags        = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
 		 $(_c_flags) $(modkern_cflags)                           \
 		 $(basename_flags) $(modname_flags)
 
+rust_flags     = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg
+
 a_flags        = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
 		 $(_a_flags) $(modkern_aflags)
 
diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
index 35100e981f4a..9a1fa6aa30fe 100644
--- a/scripts/Makefile.modfinal
+++ b/scripts/Makefile.modfinal
@@ -39,11 +39,13 @@ quiet_cmd_ld_ko_o = LD [M]  $@
 
 quiet_cmd_btf_ko = BTF [M] $@
       cmd_btf_ko = 							\
-	if [ -f vmlinux ]; then						\
+	if [ ! -f vmlinux ]; then					\
+		printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
+	elif [ -n "$(CONFIG_RUST)" ] && $(srctree)/scripts/is_rust_module.sh $@; then 		\
+		printf "Skipping BTF generation for %s because it's a Rust module\n" $@ 1>&2; \
+	else								\
 		LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \
 		$(RESOLVE_BTFIDS) -b vmlinux $@; 			\
-	else								\
-		printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
 	fi;
 
 # Same as newer-prereqs, but allows to exclude specified extra dependencies
diff --git a/scripts/cc-version.sh b/scripts/cc-version.sh
index f1952c522466..2401c86fcf53 100755
--- a/scripts/cc-version.sh
+++ b/scripts/cc-version.sh
@@ -1,13 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 #
-# Print the compiler name and its version in a 5 or 6-digit form.
+# Print the C compiler name and its version in a 5 or 6-digit form.
 # Also, perform the minimum version check.
 
 set -e
 
-# Print the compiler name and some version components.
-get_compiler_info()
+# Print the C compiler name and some version components.
+get_c_compiler_info()
 {
 	cat <<- EOF | "$@" -E -P -x c - 2>/dev/null
 	#if defined(__clang__)
@@ -32,7 +32,7 @@ get_canonical_version()
 
 # $@ instead of $1 because multiple words might be given, e.g. CC="ccache gcc".
 orig_args="$@"
-set -- $(get_compiler_info "$@")
+set -- $(get_c_compiler_info "$@")
 
 name=$1
 
@@ -52,7 +52,7 @@ ICC)
 	min_version=$($min_tool_version icc)
 	;;
 *)
-	echo "$orig_args: unknown compiler" >&2
+	echo "$orig_args: unknown C compiler" >&2
 	exit 1
 	;;
 esac
@@ -62,7 +62,7 @@ min_cversion=$(get_canonical_version $min_version)
 
 if [ "$cversion" -lt "$min_cversion" ]; then
 	echo >&2 "***"
-	echo >&2 "*** Compiler is too old."
+	echo >&2 "*** C compiler is too old."
 	echo >&2 "***   Your $name version:    $version"
 	echo >&2 "***   Minimum $name version: $min_version"
 	echo >&2 "***"
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index c4340c90e172..b7c9f1dd5e42 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -216,6 +216,13 @@ static const char *conf_get_autoheader_name(void)
 	return name ? name : "include/generated/autoconf.h";
 }
 
+static const char *conf_get_rustccfg_name(void)
+{
+	char *name = getenv("KCONFIG_RUSTCCFG");
+
+	return name ? name : "include/generated/rustc_cfg";
+}
+
 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
 {
 	char *p2;
@@ -605,6 +612,9 @@ static const struct comment_style comment_style_c = {
 
 static void conf_write_heading(FILE *fp, const struct comment_style *cs)
 {
+	if (!cs)
+		return;
+
 	fprintf(fp, "%s\n", cs->prefix);
 
 	fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n",
@@ -745,6 +755,65 @@ static void print_symbol_for_c(FILE *fp, struct symbol *sym)
 	free(escaped);
 }
 
+static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym)
+{
+	const char *val;
+	const char *val_prefix = "";
+	char *val_prefixed = NULL;
+	size_t val_prefixed_len;
+	char *escaped = NULL;
+
+	if (sym->type == S_UNKNOWN)
+		return;
+
+	val = sym_get_string_value(sym);
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		/*
+		 * We do not care about disabled ones, i.e. no need for
+		 * what otherwise are "comments" in other printers.
+		 */
+		if (*val == 'n')
+			return;
+
+		/*
+		 * To have similar functionality to the C macro `IS_ENABLED()`
+		 * we provide an empty `--cfg CONFIG_X` here in both `y`
+		 * and `m` cases.
+		 *
+		 * Then, the common `fprintf()` below will also give us
+		 * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can
+		 * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`.
+		 */
+		fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name);
+		break;
+	case S_HEX:
+		if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
+			val_prefix = "0x";
+		break;
+	default:
+		break;
+	}
+
+	if (strlen(val_prefix) > 0) {
+		val_prefixed_len = strlen(val) + strlen(val_prefix) + 1;
+		val_prefixed = xmalloc(val_prefixed_len);
+		snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val);
+		val = val_prefixed;
+	}
+
+	/* All values get escaped: the `--cfg` option only takes strings */
+	escaped = escape_string_value(val);
+	val = escaped;
+
+	fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val);
+
+	free(escaped);
+	free(val_prefixed);
+}
+
 /*
  * Write out a minimal config.
  * All values that has default values are skipped as this is redundant.
@@ -1132,6 +1201,12 @@ int conf_write_autoconf(int overwrite)
 	if (ret)
 		return ret;
 
+	ret = __conf_write_autoconf(conf_get_rustccfg_name(),
+				    print_symbol_for_rustccfg,
+				    NULL);
+	if (ret)
+		return ret;
+
 	/*
 	 * Create include/config/auto.conf. This must be the last step because
 	 * Kbuild has a dependency on auto.conf and this marks the successful
diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh
index 250925aab101..b6593eac5003 100755
--- a/scripts/min-tool-version.sh
+++ b/scripts/min-tool-version.sh
@@ -30,6 +30,12 @@ llvm)
 		echo 11.0.0
 	fi
 	;;
+rustc)
+	echo 1.62.0
+	;;
+bindgen)
+	echo 0.56.0
+	;;
 *)
 	echo "$1: unknown tool" >&2
 	exit 1
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 24/27] docs: add Rust documentation
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (21 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 23/27] Kbuild: add Rust support Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-05 15:42 ` [PATCH v9 25/27] x86: enable initial Rust support Miguel Ojeda
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Kees Cook, Alex Gaynor,
	Finn Behrens, Adam Bratschi-Kaye, Wedson Almeida Filho,
	Michael Ellerman, Sven Van Asbroeck, Wu XiangCheng, Gary Guo,
	Boris-Chengbiao Zhou, Yuki Okushi, Wei Liu, Daniel Xu,
	Julian Merkle, Jonathan Corbet, Masahiro Yamada, Michal Marek,
	Nick Desaulniers, Boqun Feng, Björn Roy Baron, linux-doc,
	linux-kbuild

Most of the documentation for Rust is written within the source code
itself, as it is idiomatic for Rust projects. This applies to both
the shared infrastructure at `rust/` as well as any other Rust module
(e.g. drivers) written across the kernel.

However, these documents contain general information that does not
fit particularly well in the source code, like the Quick Start guide.

It also contains a few other small changes elsewhere in the
documentation folder.

Reviewed-by: Kees Cook <keescook@chromium.org>
Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
Co-developed-by: Wu XiangCheng <bobwxc@email.cn>
Signed-off-by: Wu XiangCheng <bobwxc@email.cn>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Boris-Chengbiao Zhou <bobo1239@web.de>
Signed-off-by: Boris-Chengbiao Zhou <bobo1239@web.de>
Co-developed-by: Yuki Okushi <jtitor@2k36.org>
Signed-off-by: Yuki Okushi <jtitor@2k36.org>
Co-developed-by: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Co-developed-by: Daniel Xu <dxu@dxuuu.xyz>
Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
Co-developed-by: Julian Merkle <me@jvmerkle.de>
Signed-off-by: Julian Merkle <me@jvmerkle.de>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 Documentation/doc-guide/kernel-doc.rst     |   3 +
 Documentation/index.rst                    |   1 +
 Documentation/kbuild/kbuild.rst            |  17 ++
 Documentation/kbuild/makefiles.rst         |  50 ++++-
 Documentation/process/changes.rst          |  41 ++++
 Documentation/rust/arch-support.rst        |  18 ++
 Documentation/rust/coding-guidelines.rst   | 216 +++++++++++++++++++
 Documentation/rust/general-information.rst |  79 +++++++
 Documentation/rust/index.rst               |  22 ++
 Documentation/rust/quick-start.rst         | 232 +++++++++++++++++++++
 10 files changed, 675 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/rust/arch-support.rst
 create mode 100644 Documentation/rust/coding-guidelines.rst
 create mode 100644 Documentation/rust/general-information.rst
 create mode 100644 Documentation/rust/index.rst
 create mode 100644 Documentation/rust/quick-start.rst

diff --git a/Documentation/doc-guide/kernel-doc.rst b/Documentation/doc-guide/kernel-doc.rst
index a7cb2afd7990..9b868d9eb20f 100644
--- a/Documentation/doc-guide/kernel-doc.rst
+++ b/Documentation/doc-guide/kernel-doc.rst
@@ -12,6 +12,9 @@ when it is embedded in source files.
    reasons. The kernel source contains tens of thousands of kernel-doc
    comments. Please stick to the style described here.
 
+.. note:: kernel-doc does not cover Rust code: please see
+   Documentation/rust/general-information.rst instead.
+
 The kernel-doc structure is extracted from the comments, and proper
 `Sphinx C Domain`_ function and type descriptions with anchors are
 generated from them. The descriptions are filtered for special kernel-doc
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 67036a05b771..35d90903242a 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -82,6 +82,7 @@ merged much easier.
    maintainer/index
    fault-injection/index
    livepatch/index
+   rust/index
 
 
 Kernel API documentation
diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst
index ef19b9c13523..08f575e6236c 100644
--- a/Documentation/kbuild/kbuild.rst
+++ b/Documentation/kbuild/kbuild.rst
@@ -48,6 +48,10 @@ KCFLAGS
 -------
 Additional options to the C compiler (for built-in and modules).
 
+KRUSTFLAGS
+----------
+Additional options to the Rust compiler (for built-in and modules).
+
 CFLAGS_KERNEL
 -------------
 Additional options for $(CC) when used to compile
@@ -57,6 +61,15 @@ CFLAGS_MODULE
 -------------
 Additional module specific options to use for $(CC).
 
+RUSTFLAGS_KERNEL
+----------------
+Additional options for $(RUSTC) when used to compile
+code that is compiled as built-in.
+
+RUSTFLAGS_MODULE
+----------------
+Additional module specific options to use for $(RUSTC).
+
 LDFLAGS_MODULE
 --------------
 Additional options used for $(LD) when linking modules.
@@ -69,6 +82,10 @@ HOSTCXXFLAGS
 ------------
 Additional flags to be passed to $(HOSTCXX) when building host programs.
 
+HOSTRUSTFLAGS
+-------------
+Additional flags to be passed to $(HOSTRUSTC) when building host programs.
+
 HOSTLDFLAGS
 -----------
 Additional flags to be passed when linking host programs.
diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst
index 11a296e52d68..5ea1e72d89c8 100644
--- a/Documentation/kbuild/makefiles.rst
+++ b/Documentation/kbuild/makefiles.rst
@@ -29,8 +29,9 @@ This document describes the Linux kernel Makefiles.
 	   --- 4.1 Simple Host Program
 	   --- 4.2 Composite Host Programs
 	   --- 4.3 Using C++ for host programs
-	   --- 4.4 Controlling compiler options for host programs
-	   --- 4.5 When host programs are actually built
+	   --- 4.4 Using Rust for host programs
+	   --- 4.5 Controlling compiler options for host programs
+	   --- 4.6 When host programs are actually built
 
 	=== 5 Userspace Program support
 	   --- 5.1 Simple Userspace Program
@@ -835,7 +836,24 @@ Both possibilities are described in the following.
 		qconf-cxxobjs := qconf.o
 		qconf-objs    := check.o
 
-4.4 Controlling compiler options for host programs
+4.4 Using Rust for host programs
+--------------------------------
+
+	Kbuild offers support for host programs written in Rust. However,
+	since a Rust toolchain is not mandatory for kernel compilation,
+	it may only be used in scenarios where Rust is required to be
+	available (e.g. when  ``CONFIG_RUST`` is enabled).
+
+	Example::
+
+		hostprogs     := target
+		target-rust   := y
+
+	Kbuild will compile ``target`` using ``target.rs`` as the crate root,
+	located in the same directory as the ``Makefile``. The crate may
+	consist of several source files (see ``samples/rust/hostprogs``).
+
+4.5 Controlling compiler options for host programs
 --------------------------------------------------
 
 	When compiling host programs, it is possible to set specific flags.
@@ -867,7 +885,7 @@ Both possibilities are described in the following.
 	When linking qconf, it will be passed the extra option
 	"-L$(QTDIR)/lib".
 
-4.5 When host programs are actually built
+4.6 When host programs are actually built
 -----------------------------------------
 
 	Kbuild will only build host-programs when they are referenced
@@ -1181,6 +1199,17 @@ When kbuild executes, the following steps are followed (roughly):
 	The first example utilises the trick that a config option expands
 	to 'y' when selected.
 
+    KBUILD_RUSTFLAGS
+	$(RUSTC) compiler flags
+
+	Default value - see top level Makefile
+	Append or modify as required per architecture.
+
+	Often, the KBUILD_RUSTFLAGS variable depends on the configuration.
+
+	Note that target specification file generation (for ``--target``)
+	is handled in ``scripts/generate_rust_target.rs``.
+
     KBUILD_AFLAGS_KERNEL
 	Assembler options specific for built-in
 
@@ -1208,6 +1237,19 @@ When kbuild executes, the following steps are followed (roughly):
 	are used for $(CC).
 	From commandline CFLAGS_MODULE shall be used (see kbuild.rst).
 
+    KBUILD_RUSTFLAGS_KERNEL
+	$(RUSTC) options specific for built-in
+
+	$(KBUILD_RUSTFLAGS_KERNEL) contains extra Rust compiler flags used to
+	compile resident kernel code.
+
+    KBUILD_RUSTFLAGS_MODULE
+	Options for $(RUSTC) when building modules
+
+	$(KBUILD_RUSTFLAGS_MODULE) is used to add arch-specific options that
+	are used for $(RUSTC).
+	From commandline RUSTFLAGS_MODULE shall be used (see kbuild.rst).
+
     KBUILD_LDFLAGS_MODULE
 	Options for $(LD) when linking modules
 
diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
index 19c286c23786..9a90197989dd 100644
--- a/Documentation/process/changes.rst
+++ b/Documentation/process/changes.rst
@@ -31,6 +31,8 @@ you probably needn't concern yourself with pcmciautils.
 ====================== ===============  ========================================
 GNU C                  5.1              gcc --version
 Clang/LLVM (optional)  11.0.0           clang --version
+Rust (optional)        1.62.0           rustc --version
+bindgen (optional)     0.56.0           bindgen --version
 GNU make               3.81             make --version
 bash                   4.2              bash --version
 binutils               2.23             ld -v
@@ -80,6 +82,29 @@ kernels. Older releases aren't guaranteed to work, and we may drop workarounds
 from the kernel that were used to support older versions. Please see additional
 docs on :ref:`Building Linux with Clang/LLVM <kbuild_llvm>`.
 
+Rust (optional)
+---------------
+
+A particular version of the Rust toolchain is required. Newer versions may or
+may not work because the kernel depends on some unstable Rust features, for
+the moment.
+
+Each Rust toolchain comes with several "components", some of which are required
+(like ``rustc``) and some that are optional. The ``rust-src`` component (which
+is optional) needs to be installed to build the kernel. Other components are
+useful for developing.
+
+Please see Documentation/rust/quick-start.rst for instructions on how to
+satisfy the build requirements of Rust support. In particular, the ``Makefile``
+target ``rustavailable`` is useful to check why the Rust toolchain may not
+be detected.
+
+bindgen (optional)
+------------------
+
+``bindgen`` is used to generate the Rust bindings to the C side of the kernel.
+It depends on ``libclang``.
+
 Make
 ----
 
@@ -348,6 +373,12 @@ Sphinx
 Please see :ref:`sphinx_install` in :ref:`Documentation/doc-guide/sphinx.rst <sphinxdoc>`
 for details about Sphinx requirements.
 
+rustdoc
+-------
+
+``rustdoc`` is used to generate the documentation for Rust code. Please see
+Documentation/rust/general-information.rst for more information.
+
 Getting updated software
 ========================
 
@@ -364,6 +395,16 @@ Clang/LLVM
 
 - :ref:`Getting LLVM <getting_llvm>`.
 
+Rust
+----
+
+- Documentation/rust/quick-start.rst.
+
+bindgen
+-------
+
+- Documentation/rust/quick-start.rst.
+
 Make
 ----
 
diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
new file mode 100644
index 000000000000..1152e0fbdad0
--- /dev/null
+++ b/Documentation/rust/arch-support.rst
@@ -0,0 +1,18 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Arch Support
+============
+
+Currently, the Rust compiler (``rustc``) uses LLVM for code generation,
+which limits the supported architectures that can be targeted. In addition,
+support for building the kernel with LLVM/Clang varies (please see
+Documentation/kbuild/llvm.rst). This support is needed for ``bindgen``
+which uses ``libclang``.
+
+Below is a general summary of architectures that currently work. Level of
+support corresponds to ``S`` values in the ``MAINTAINERS`` file.
+
+============  ================  ==============================================
+Architecture  Level of support  Constraints
+============  ================  ==============================================
+============  ================  ==============================================
diff --git a/Documentation/rust/coding-guidelines.rst b/Documentation/rust/coding-guidelines.rst
new file mode 100644
index 000000000000..aa8ed082613e
--- /dev/null
+++ b/Documentation/rust/coding-guidelines.rst
@@ -0,0 +1,216 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Coding Guidelines
+=================
+
+This document describes how to write Rust code in the kernel.
+
+
+Style & formatting
+------------------
+
+The code should be formatted using ``rustfmt``. In this way, a person
+contributing from time to time to the kernel does not need to learn and
+remember one more style guide. More importantly, reviewers and maintainers
+do not need to spend time pointing out style issues anymore, and thus
+less patch roundtrips may be needed to land a change.
+
+.. note:: Conventions on comments and documentation are not checked by
+  ``rustfmt``. Thus those are still needed to be taken care of.
+
+The default settings of ``rustfmt`` are used. This means the idiomatic Rust
+style is followed. For instance, 4 spaces are used for indentation rather
+than tabs.
+
+It is convenient to instruct editors/IDEs to format while typing,
+when saving or at commit time. However, if for some reason reformatting
+the entire kernel Rust sources is needed at some point, the following can be
+run::
+
+	make LLVM=1 rustfmt
+
+It is also possible to check if everything is formatted (printing a diff
+otherwise), for instance for a CI, with::
+
+	make LLVM=1 rustfmtcheck
+
+Like ``clang-format`` for the rest of the kernel, ``rustfmt`` works on
+individual files, and does not require a kernel configuration. Sometimes it may
+even work with broken code.
+
+
+Comments
+--------
+
+"Normal" comments (i.e. ``//``, rather than code documentation which starts
+with ``///`` or ``//!``) are written in Markdown the same way as documentation
+comments are, even though they will not be rendered. This improves consistency,
+simplifies the rules and allows to move content between the two kinds of
+comments more easily. For instance:
+
+.. code-block:: rust
+
+	// `object` is ready to be handled now.
+	f(object);
+
+Furthermore, just like documentation, comments are capitalized at the beginning
+of a sentence and ended with a period (even if it is a single sentence). This
+includes ``// SAFETY:``, ``// TODO:`` and other "tagged" comments, e.g.:
+
+.. code-block:: rust
+
+	// FIXME: The error should be handled properly.
+
+Comments should not be used for documentation purposes: comments are intended
+for implementation details, not users. This distinction is useful even if the
+reader of the source file is both an implementor and a user of an API. In fact,
+sometimes it is useful to use both comments and documentation at the same time.
+For instance, for a ``TODO`` list or to comment on the documentation itself.
+For the latter case, comments can be inserted in the middle; that is, closer to
+the line of documentation to be commented. For any other case, comments are
+written after the documentation, e.g.:
+
+.. code-block:: rust
+
+	/// Returns a new [`Foo`].
+	///
+	/// # Examples
+	///
+	// TODO: Find a better example.
+	/// ```
+	/// let foo = f(42);
+	/// ```
+	// FIXME: Use fallible approach.
+	pub fn f(x: i32) -> Foo {
+	    // ...
+	}
+
+One special kind of comments are the ``// SAFETY:`` comments. These must appear
+before every ``unsafe`` block, and they explain why the code inside the block is
+correct/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.:
+
+.. code-block:: rust
+
+	// SAFETY: `p` is valid by the safety requirements.
+	unsafe { *p = 0; }
+
+``// SAFETY:`` comments are not to be confused with the ``# Safety`` sections
+in code documentation. ``# Safety`` sections specify the contract that callers
+(for functions) or implementors (for traits) need to abide by. ``// SAFETY:``
+comments show why a call (for functions) or implementation (for traits) actually
+respects the preconditions stated in a ``# Safety`` section or the language
+reference.
+
+
+Code documentation
+------------------
+
+Rust kernel code is not documented like C kernel code (i.e. via kernel-doc).
+Instead, the usual system for documenting Rust code is used: the ``rustdoc``
+tool, which uses Markdown (a lightweight markup language).
+
+To learn Markdown, there are many guides available out there. For instance,
+the one at:
+
+	https://commonmark.org/help/
+
+This is how a well-documented Rust function may look like:
+
+.. code-block:: rust
+
+	/// Returns the contained [`Some`] value, consuming the `self` value,
+	/// without checking that the value is not [`None`].
+	///
+	/// # Safety
+	///
+	/// Calling this method on [`None`] is *[undefined behavior]*.
+	///
+	/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+	///
+	/// # Examples
+	///
+	/// ```
+	/// let x = Some("air");
+	/// assert_eq!(unsafe { x.unwrap_unchecked() }, "air");
+	/// ```
+	pub unsafe fn unwrap_unchecked(self) -> T {
+	    match self {
+	        Some(val) => val,
+
+	        // SAFETY: The safety contract must be upheld by the caller.
+	        None => unsafe { hint::unreachable_unchecked() },
+	    }
+	}
+
+This example showcases a few ``rustdoc`` features and some conventions followed
+in the kernel:
+
+  - The first paragraph must be a single sentence briefly describing what
+    the documented item does. Further explanations must go in extra paragraphs.
+
+  - Unsafe functions must document their safety preconditions under
+    a ``# Safety`` section.
+
+  - While not shown here, if a function may panic, the conditions under which
+    that happens must be described under a ``# Panics`` section.
+
+    Please note that panicking should be very rare and used only with a good
+    reason. In almost all cases, a fallible approach should be used, typically
+    returning a ``Result``.
+
+  - If providing examples of usage would help readers, they must be written in
+    a section called ``# Examples``.
+
+  - Rust items (functions, types, constants...) must be linked appropriately
+    (``rustdoc`` will create a link automatically).
+
+  - Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment
+    describing why the code inside is sound.
+
+    While sometimes the reason might look trivial and therefore unneeded,
+    writing these comments is not just a good way of documenting what has been
+    taken into account, but most importantly, it provides a way to know that
+    there are no *extra* implicit constraints.
+
+To learn more about how to write documentation for Rust and extra features,
+please take a look at the ``rustdoc`` book at:
+
+	https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html
+
+
+Naming
+------
+
+Rust kernel code follows the usual Rust naming conventions:
+
+	https://rust-lang.github.io/api-guidelines/naming.html
+
+When existing C concepts (e.g. macros, functions, objects...) are wrapped into
+a Rust abstraction, a name as close as reasonably possible to the C side should
+be used in order to avoid confusion and to improve readability when switching
+back and forth between the C and Rust sides. For instance, macros such as
+``pr_info`` from C are named the same in the Rust side.
+
+Having said that, casing should be adjusted to follow the Rust naming
+conventions, and namespacing introduced by modules and types should not be
+repeated in the item names. For instance, when wrapping constants like:
+
+.. code-block:: c
+
+	#define GPIO_LINE_DIRECTION_IN	0
+	#define GPIO_LINE_DIRECTION_OUT	1
+
+The equivalent in Rust may look like (ignoring documentation):
+
+.. code-block:: rust
+
+	pub mod gpio {
+	    pub enum LineDirection {
+	        In = bindings::GPIO_LINE_DIRECTION_IN as _,
+	        Out = bindings::GPIO_LINE_DIRECTION_OUT as _,
+	    }
+	}
+
+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``.
diff --git a/Documentation/rust/general-information.rst b/Documentation/rust/general-information.rst
new file mode 100644
index 000000000000..49029ee82e55
--- /dev/null
+++ b/Documentation/rust/general-information.rst
@@ -0,0 +1,79 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+General Information
+===================
+
+This document contains useful information to know when working with
+the Rust support in the kernel.
+
+
+Code documentation
+------------------
+
+Rust kernel code is documented using ``rustdoc``, its built-in documentation
+generator.
+
+The generated HTML docs include integrated search, linked items (e.g. types,
+functions, constants), source code, etc. They may be read at (TODO: link when
+in mainline and generated alongside the rest of the documentation):
+
+	http://kernel.org/
+
+The docs can also be easily generated and read locally. This is quite fast
+(same order as compiling the code itself) and no special tools or environment
+are needed. This has the added advantage that they will be tailored to
+the particular kernel configuration used. To generate them, use the ``rustdoc``
+target with the same invocation used for compilation, e.g.::
+
+	make LLVM=1 rustdoc
+
+To read the docs locally in your web browser, run e.g.::
+
+	xdg-open rust/doc/kernel/index.html
+
+To learn about how to write the documentation, please see coding-guidelines.rst.
+
+
+Extra lints
+-----------
+
+While ``rustc`` is a very helpful compiler, some extra lints and analyses are
+available via ``clippy``, a Rust linter. To enable it, pass ``CLIPPY=1`` to
+the same invocation used for compilation, e.g.::
+
+	make LLVM=1 CLIPPY=1
+
+Please note that Clippy may change code generation, thus it should not be
+enabled while building a production kernel.
+
+
+Abstractions vs. bindings
+-------------------------
+
+Abstractions are Rust code wrapping kernel functionality from the C side.
+
+In order to use functions and types from the C side, bindings are created.
+Bindings are the declarations for Rust of those functions and types from
+the C side.
+
+For instance, one may write a ``Mutex`` abstraction in Rust which wraps
+a ``struct mutex`` from the C side and calls its functions through the bindings.
+
+Abstractions are not available for all the kernel internal APIs and concepts,
+but it is intended that coverage is expanded as time goes on. "Leaf" modules
+(e.g. drivers) should not use the C bindings directly. Instead, subsystems
+should provide as-safe-as-possible abstractions as needed.
+
+
+Conditional compilation
+-----------------------
+
+Rust code has access to conditional compilation based on the kernel
+configuration:
+
+.. code-block:: rust
+
+	#[cfg(CONFIG_X)]       // Enabled               (`y` or `m`)
+	#[cfg(CONFIG_X="y")]   // Enabled as a built-in (`y`)
+	#[cfg(CONFIG_X="m")]   // Enabled as a module   (`m`)
+	#[cfg(not(CONFIG_X))]  // Disabled
diff --git a/Documentation/rust/index.rst b/Documentation/rust/index.rst
new file mode 100644
index 000000000000..4ae8c66b94fa
--- /dev/null
+++ b/Documentation/rust/index.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Rust
+====
+
+Documentation related to Rust within the kernel. To start using Rust
+in the kernel, please read the quick-start.rst guide.
+
+.. toctree::
+    :maxdepth: 1
+
+    quick-start
+    general-information
+    coding-guidelines
+    arch-support
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst
new file mode 100644
index 000000000000..13b7744b1e27
--- /dev/null
+++ b/Documentation/rust/quick-start.rst
@@ -0,0 +1,232 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Quick Start
+===========
+
+This document describes how to get started with kernel development in Rust.
+
+
+Requirements: Building
+----------------------
+
+This section explains how to fetch the tools needed for building.
+
+Some of these requirements might be available from Linux distributions
+under names like ``rustc``, ``rust-src``, ``rust-bindgen``, etc. However,
+at the time of writing, they are likely not to be recent enough unless
+the distribution tracks the latest releases.
+
+To easily check whether the requirements are met, the following target
+can be used::
+
+	make LLVM=1 rustavailable
+
+This triggers the same logic used by Kconfig to determine whether
+``RUST_IS_AVAILABLE`` should be enabled; but it also explains why not
+if that is the case.
+
+
+rustc
+*****
+
+A particular version of the Rust compiler is required. Newer versions may or
+may not work because, for the moment, the kernel depends on some unstable
+Rust features.
+
+If ``rustup`` is being used, enter the checked out source code directory
+and run::
+
+	rustup override set $(scripts/min-tool-version.sh rustc)
+
+Otherwise, fetch a standalone installer or install ``rustup`` from:
+
+	https://www.rust-lang.org
+
+
+Rust standard library source
+****************************
+
+The Rust standard library source is required because the build system will
+cross-compile ``core`` and ``alloc``.
+
+If ``rustup`` is being used, run::
+
+	rustup component add rust-src
+
+The components are installed per toolchain, thus upgrading the Rust compiler
+version later on requires re-adding the component.
+
+Otherwise, if a standalone installer is used, the Rust repository may be cloned
+into the installation folder of the toolchain::
+
+	git clone --recurse-submodules \
+		--branch $(scripts/min-tool-version.sh rustc) \
+		https://github.com/rust-lang/rust \
+		$(rustc --print sysroot)/lib/rustlib/src/rust
+
+In this case, upgrading the Rust compiler version later on requires manually
+updating this clone.
+
+
+libclang
+********
+
+``libclang`` (part of LLVM) is used by ``bindgen`` to understand the C code
+in the kernel, which means LLVM needs to be installed; like when the kernel
+is compiled with ``CC=clang`` or ``LLVM=1``.
+
+Linux distributions are likely to have a suitable one available, so it is
+best to check that first.
+
+There are also some binaries for several systems and architectures uploaded at:
+
+	https://releases.llvm.org/download.html
+
+Otherwise, building LLVM takes quite a while, but it is not a complex process:
+
+	https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm
+
+Please see Documentation/kbuild/llvm.rst for more information and further ways
+to fetch pre-built releases and distribution packages.
+
+
+bindgen
+*******
+
+The bindings to the C side of the kernel are generated at build time using
+the ``bindgen`` tool. A particular version is required.
+
+Install it via (note that this will download and build the tool from source)::
+
+	cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen
+
+
+Requirements: Developing
+------------------------
+
+This section explains how to fetch the tools needed for developing. That is,
+they are not needed when just building the kernel.
+
+
+rustfmt
+*******
+
+The ``rustfmt`` tool is used to automatically format all the Rust kernel code,
+including the generated C bindings (for details, please see
+coding-guidelines.rst).
+
+If ``rustup`` is being used, its ``default`` profile already installs the tool,
+thus nothing needs to be done. If another profile is being used, the component
+can be installed manually::
+
+	rustup component add rustfmt
+
+The standalone installers also come with ``rustfmt``.
+
+
+clippy
+******
+
+``clippy`` is a Rust linter. Running it provides extra warnings for Rust code.
+It can be run by passing ``CLIPPY=1`` to ``make`` (for details, please see
+general-information.rst).
+
+If ``rustup`` is being used, its ``default`` profile already installs the tool,
+thus nothing needs to be done. If another profile is being used, the component
+can be installed manually::
+
+	rustup component add clippy
+
+The standalone installers also come with ``clippy``.
+
+
+cargo
+*****
+
+``cargo`` is the Rust native build system. It is currently required to run
+the tests since it is used to build a custom standard library that contains
+the facilities provided by the custom ``alloc`` in the kernel. The tests can
+be run using the ``rusttest`` Make target.
+
+If ``rustup`` is being used, all the profiles already install the tool,
+thus nothing needs to be done.
+
+The standalone installers also come with ``cargo``.
+
+
+rustdoc
+*******
+
+``rustdoc`` is the documentation tool for Rust. It generates pretty HTML
+documentation for Rust code (for details, please see
+general-information.rst).
+
+``rustdoc`` is also used to test the examples provided in documented Rust code
+(called doctests or documentation tests). The ``rusttest`` Make target uses
+this feature.
+
+If ``rustup`` is being used, all the profiles already install the tool,
+thus nothing needs to be done.
+
+The standalone installers also come with ``rustdoc``.
+
+
+rust-analyzer
+*************
+
+The `rust-analyzer <https://rust-analyzer.github.io/>`_ language server can
+be used with many editors to enable syntax highlighting, completion, go to
+definition, and other features.
+
+``rust-analyzer`` needs a configuration file, ``rust-project.json``, which
+can be generated by the ``rust-analyzer`` Make target.
+
+
+Configuration
+-------------
+
+``Rust support`` (``CONFIG_RUST``) needs to be enabled in the ``General setup``
+menu. The option is only shown if a suitable Rust toolchain is found (see
+above), as long as the other requirements are met. In turn, this will make
+visible the rest of options that depend on Rust.
+
+Afterwards, go to::
+
+	Kernel hacking
+	    -> Sample kernel code
+	        -> Rust samples
+
+And enable some sample modules either as built-in or as loadable.
+
+
+Building
+--------
+
+Building a kernel with a complete LLVM toolchain is the best supported setup
+at the moment. That is::
+
+	make LLVM=1
+
+For architectures that do not support a full LLVM toolchain, use::
+
+	make CC=clang
+
+Using GCC also works for some configurations, but it is very experimental at
+the moment.
+
+
+Hacking
+-------
+
+To dive deeper, take a look at the source code of the samples
+at ``samples/rust/``, the Rust support code under ``rust/`` and
+the ``Rust hacking`` menu under ``Kernel hacking``.
+
+If GDB/Binutils is used and Rust symbols are not getting demangled, the reason
+is the toolchain does not support Rust's new v0 mangling scheme yet.
+There are a few ways out:
+
+  - Install a newer release (GDB >= 10.2, Binutils >= 2.36).
+
+  - Some versions of GDB (e.g. vanilla GDB 10.1) are able to use
+    the pre-demangled names embedded in the debug info (``CONFIG_DEBUG_INFO``).
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 25/27] x86: enable initial Rust support
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (22 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 24/27] docs: add Rust documentation Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-17 20:27   ` Kees Cook
  2022-08-05 15:42 ` [PATCH v9 26/27] samples: add first Rust examples Miguel Ojeda
                   ` (2 subsequent siblings)
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho,
	David Gow, Boqun Feng, Gary Guo, Björn Roy Baron,
	Jonathan Corbet, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, H. Peter Anvin, linux-doc

Note that only x86_64 is covered and not all features nor mitigations
are handled, but it is enough as a starting point and showcases
the basics needed to add Rust support for a new architecture.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: David Gow <davidgow@google.com>
Signed-off-by: David Gow <davidgow@google.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 Documentation/rust/arch-support.rst |  1 +
 arch/x86/Kconfig                    |  1 +
 arch/x86/Makefile                   | 10 ++++++++++
 scripts/generate_rust_target.rs     | 15 +++++++++++++--
 4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index 1152e0fbdad0..6982b63775da 100644
--- a/Documentation/rust/arch-support.rst
+++ b/Documentation/rust/arch-support.rst
@@ -15,4 +15,5 @@ support corresponds to ``S`` values in the ``MAINTAINERS`` file.
 ============  ================  ==============================================
 Architecture  Level of support  Constraints
 ============  ================  ==============================================
+``x86``       Maintained        ``x86_64`` only.
 ============  ================  ==============================================
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 52a7f91527fe..4d5a3f256cbc 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -258,6 +258,7 @@ config X86
 	select HAVE_STATIC_CALL_INLINE		if HAVE_OBJTOOL
 	select HAVE_PREEMPT_DYNAMIC_CALL
 	select HAVE_RSEQ
+	select HAVE_RUST			if X86_64
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UACCESS_VALIDATION		if HAVE_OBJTOOL
 	select HAVE_UNSTABLE_SCHED_CLOCK
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 7854685c5f25..bab595003f07 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -68,6 +68,7 @@ export BITS
 #    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383
 #
 KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx
+KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2
 
 ifeq ($(CONFIG_X86_KERNEL_IBT),y)
 #
@@ -155,8 +156,17 @@ else
         cflags-$(CONFIG_GENERIC_CPU)	+= -mtune=generic
         KBUILD_CFLAGS += $(cflags-y)
 
+        rustflags-$(CONFIG_MK8)		+= -Ctarget-cpu=k8
+        rustflags-$(CONFIG_MPSC)	+= -Ctarget-cpu=nocona
+        rustflags-$(CONFIG_MCORE2)	+= -Ctarget-cpu=core2
+        rustflags-$(CONFIG_MATOM)	+= -Ctarget-cpu=atom
+        rustflags-$(CONFIG_GENERIC_CPU)	+= -Ztune-cpu=generic
+        KBUILD_RUSTFLAGS += $(rustflags-y)
+
         KBUILD_CFLAGS += -mno-red-zone
         KBUILD_CFLAGS += -mcmodel=kernel
+        KBUILD_RUSTFLAGS += -Cno-redzone=y
+        KBUILD_RUSTFLAGS += -Ccode-model=kernel
 endif
 
 #
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
index 7256c9606cf0..3c6cbe2b278d 100644
--- a/scripts/generate_rust_target.rs
+++ b/scripts/generate_rust_target.rs
@@ -148,8 +148,19 @@ fn main() {
     let mut ts = TargetSpec::new();
 
     // `llvm-target`s are taken from `scripts/Makefile.clang`.
-    if cfg.has("DUMMY_ARCH") {
-        ts.push("arch", "dummy_arch");
+    if cfg.has("X86_64") {
+        ts.push("arch", "x86_64");
+        ts.push(
+            "data-layout",
+            "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
+        );
+        let mut features = "-3dnow,-3dnowa,-mmx,+soft-float".to_string();
+        if cfg.has("RETPOLINE") {
+            features += ",+retpoline-external-thunk";
+        }
+        ts.push("features", features);
+        ts.push("llvm-target", "x86_64-linux-gnu");
+        ts.push("target-pointer-width", "64");
     } else {
         panic!("Unsupported architecture");
     }
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 26/27] samples: add first Rust examples
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (23 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 25/27] x86: enable initial Rust support Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-06 13:14   ` Konstantin Shelekhin
  2022-08-17 20:28   ` Kees Cook
  2022-08-05 15:42 ` [PATCH v9 27/27] MAINTAINERS: Rust Miguel Ojeda
       [not found] ` <20220805154231.31257-8-ojeda@kernel.org>
  26 siblings, 2 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Finn Behrens,
	Wedson Almeida Filho, Milan Landaverde, Boqun Feng, Gary Guo,
	Björn Roy Baron

The beginning of a set of Rust modules that showcase how Rust
modules look like and how to use the abstracted kernel features.

It also includes an example of a Rust host program with
several modules.

These samples also double as tests in the CI.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Milan Landaverde <milan@mdaverde.com>
Signed-off-by: Milan Landaverde <milan@mdaverde.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 samples/Kconfig                   |  2 ++
 samples/Makefile                  |  1 +
 samples/rust/Kconfig              | 30 ++++++++++++++++++++++++
 samples/rust/Makefile             |  5 ++++
 samples/rust/hostprogs/.gitignore |  3 +++
 samples/rust/hostprogs/Makefile   |  5 ++++
 samples/rust/hostprogs/a.rs       |  7 ++++++
 samples/rust/hostprogs/b.rs       |  5 ++++
 samples/rust/hostprogs/single.rs  | 12 ++++++++++
 samples/rust/rust_minimal.rs      | 38 +++++++++++++++++++++++++++++++
 10 files changed, 108 insertions(+)
 create mode 100644 samples/rust/Kconfig
 create mode 100644 samples/rust/Makefile
 create mode 100644 samples/rust/hostprogs/.gitignore
 create mode 100644 samples/rust/hostprogs/Makefile
 create mode 100644 samples/rust/hostprogs/a.rs
 create mode 100644 samples/rust/hostprogs/b.rs
 create mode 100644 samples/rust/hostprogs/single.rs
 create mode 100644 samples/rust/rust_minimal.rs

diff --git a/samples/Kconfig b/samples/Kconfig
index 470ee3baf2e1..0d81c00289ee 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -263,6 +263,8 @@ config SAMPLE_CORESIGHT_SYSCFG
 	  This demonstrates how a user may create their own CoreSight
 	  configurations and easily load them into the system at runtime.
 
+source "samples/rust/Kconfig"
+
 endif # SAMPLES
 
 config HAVE_SAMPLE_FTRACE_DIRECT
diff --git a/samples/Makefile b/samples/Makefile
index 701e912ab5af..9832ef3f8fcb 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -35,3 +35,4 @@ subdir-$(CONFIG_SAMPLE_WATCH_QUEUE)	+= watch_queue
 obj-$(CONFIG_DEBUG_KMEMLEAK_TEST)	+= kmemleak/
 obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG)	+= coresight/
 obj-$(CONFIG_SAMPLE_FPROBE)		+= fprobe/
+obj-$(CONFIG_SAMPLES_RUST)		+= rust/
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig
new file mode 100644
index 000000000000..841e0906e943
--- /dev/null
+++ b/samples/rust/Kconfig
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0
+
+menuconfig SAMPLES_RUST
+	bool "Rust samples"
+	depends on RUST
+	help
+	  You can build sample Rust kernel code here.
+
+	  If unsure, say N.
+
+if SAMPLES_RUST
+
+config SAMPLE_RUST_MINIMAL
+	tristate "Minimal"
+	help
+	  This option builds the Rust minimal module sample.
+
+	  To compile this as a module, choose M here:
+	  the module will be called rust_minimal.
+
+	  If unsure, say N.
+
+config SAMPLE_RUST_HOSTPROGS
+	bool "Host programs"
+	help
+	  This option builds the Rust host program samples.
+
+	  If unsure, say N.
+
+endif # SAMPLES_RUST
diff --git a/samples/rust/Makefile b/samples/rust/Makefile
new file mode 100644
index 000000000000..1daba5f8658a
--- /dev/null
+++ b/samples/rust/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SAMPLE_RUST_MINIMAL)		+= rust_minimal.o
+
+subdir-$(CONFIG_SAMPLE_RUST_HOSTPROGS)		+= hostprogs
diff --git a/samples/rust/hostprogs/.gitignore b/samples/rust/hostprogs/.gitignore
new file mode 100644
index 000000000000..a6c173da5048
--- /dev/null
+++ b/samples/rust/hostprogs/.gitignore
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+single
diff --git a/samples/rust/hostprogs/Makefile b/samples/rust/hostprogs/Makefile
new file mode 100644
index 000000000000..8ddcbd7416db
--- /dev/null
+++ b/samples/rust/hostprogs/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+hostprogs-always-y := single
+
+single-rust := y
diff --git a/samples/rust/hostprogs/a.rs b/samples/rust/hostprogs/a.rs
new file mode 100644
index 000000000000..f7a4a3d0f4e0
--- /dev/null
+++ b/samples/rust/hostprogs/a.rs
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust single host program sample: module `a`.
+
+pub(crate) fn f(x: i32) {
+    println!("The number is {}.", x);
+}
diff --git a/samples/rust/hostprogs/b.rs b/samples/rust/hostprogs/b.rs
new file mode 100644
index 000000000000..c1675890648f
--- /dev/null
+++ b/samples/rust/hostprogs/b.rs
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust single host program sample: module `b`.
+
+pub(crate) const CONSTANT: i32 = 42;
diff --git a/samples/rust/hostprogs/single.rs b/samples/rust/hostprogs/single.rs
new file mode 100644
index 000000000000..8c48a119339a
--- /dev/null
+++ b/samples/rust/hostprogs/single.rs
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust single host program sample.
+
+mod a;
+mod b;
+
+fn main() {
+    println!("Hello world!");
+
+    a::f(b::CONSTANT);
+}
diff --git a/samples/rust/rust_minimal.rs b/samples/rust/rust_minimal.rs
new file mode 100644
index 000000000000..54ad17685742
--- /dev/null
+++ b/samples/rust/rust_minimal.rs
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust minimal sample.
+
+use kernel::prelude::*;
+
+module! {
+    type: RustMinimal,
+    name: b"rust_minimal",
+    author: b"Rust for Linux Contributors",
+    description: b"Rust minimal sample",
+    license: b"GPL",
+}
+
+struct RustMinimal {
+    numbers: Vec<i32>,
+}
+
+impl kernel::Module for RustMinimal {
+    fn init(_module: &'static ThisModule) -> Result<Self> {
+        pr_info!("Rust minimal sample (init)\n");
+        pr_info!("Am I built-in? {}\n", !cfg!(MODULE));
+
+        let mut numbers = Vec::new();
+        numbers.try_push(72)?;
+        numbers.try_push(108)?;
+        numbers.try_push(200)?;
+
+        Ok(RustMinimal { numbers })
+    }
+}
+
+impl Drop for RustMinimal {
+    fn drop(&mut self) {
+        pr_info!("My numbers are {:?}\n", self.numbers);
+        pr_info!("Rust minimal sample (exit)\n");
+    }
+}
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* [PATCH v9 27/27] MAINTAINERS: Rust
  2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
                   ` (24 preceding siblings ...)
  2022-08-05 15:42 ` [PATCH v9 26/27] samples: add first Rust examples Miguel Ojeda
@ 2022-08-05 15:42 ` Miguel Ojeda
  2022-08-17 20:28   ` Kees Cook
       [not found] ` <20220805154231.31257-8-ojeda@kernel.org>
  26 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 15:42 UTC (permalink / raw)
  To: Linus Torvalds, Greg Kroah-Hartman
  Cc: rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho

Miguel, Alex and Wedson will be maintaining the Rust support.

Boqun, Gary and Björn will be reviewers.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 MAINTAINERS | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 64379c699903..263ff9abca0b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17477,6 +17477,24 @@ L:	linux-rdma@vger.kernel.org
 S:	Maintained
 F:	drivers/infiniband/ulp/rtrs/
 
+RUST
+M:	Miguel Ojeda <ojeda@kernel.org>
+M:	Alex Gaynor <alex.gaynor@gmail.com>
+M:	Wedson Almeida Filho <wedsonaf@google.com>
+R:	Boqun Feng <boqun.feng@gmail.com>
+R:	Gary Guo <gary@garyguo.net>
+R:	Björn Roy Baron <bjorn3_gh@protonmail.com>
+L:	rust-for-linux@vger.kernel.org
+S:	Supported
+W:	https://github.com/Rust-for-Linux/linux
+B:	https://github.com/Rust-for-Linux/linux/issues
+T:	git https://github.com/Rust-for-Linux/linux.git rust-next
+F:	Documentation/rust/
+F:	rust/
+F:	samples/rust/
+F:	scripts/*rust*
+K:	\b(?i:rust)\b
+
 RXRPC SOCKETS (AF_RXRPC)
 M:	David Howells <dhowells@redhat.com>
 M:	Marc Dionne <marc.dionne@auristor.com>
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size
  2022-08-05 15:41 ` [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size Miguel Ojeda
@ 2022-08-05 16:48   ` Geert Stappers
  2022-08-05 18:46     ` Miguel Ojeda
  2022-08-05 22:40   ` Konstantin Shelekhin
  1 sibling, 1 reply; 102+ messages in thread
From: Geert Stappers @ 2022-08-05 16:48 UTC (permalink / raw)
  To: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Boqun Feng

[-- Attachment #1: Type: text/plain, Size: 1208 bytes --]

On Fri, Aug 05, 2022 at 05:41:46PM +0200, Miguel Ojeda wrote:
> From: Boqun Feng <boqun.feng@gmail.com>
> 
> This removes one place where the `500` constant is hardcoded.
> 
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> Co-developed-by: Miguel Ojeda <ojeda@kernel.org>
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> ---
>  scripts/kallsyms.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> index f18e6dfc68c5..52f5488c61bc 100644
> --- a/scripts/kallsyms.c
> +++ b/scripts/kallsyms.c
> @@ -206,7 +206,7 @@ static struct sym_entry *read_symbol(FILE *in)
>  
>  	rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
>  	if (rc != 3) {
> -		if (rc != EOF && fgets(name, 500, in) == NULL)
> +		if (rc != EOF && fgets(name, sizeof(name), in) == NULL)
>  			fprintf(stderr, "Read error or end of file.\n");
>  		return NULL;
>  	}
> -- 
> 2.37.1
> 


Signed-off-by: Geert Stappers <stappers@stappers.nl>


And I think that this patch and all other "rust" kallsyms patches
allready should have been accepted in the v3 or v5 series.





Regards
Geert Stappers
-- 
Silence is hard to parse

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size
  2022-08-05 16:48   ` Geert Stappers
@ 2022-08-05 18:46     ` Miguel Ojeda
  0 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-05 18:46 UTC (permalink / raw)
  To: Geert Stappers
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Boqun Feng

On Fri, Aug 5, 2022 at 6:48 PM Geert Stappers <stappers@stappers.nl> wrote:
>
> Signed-off-by: Geert Stappers <stappers@stappers.nl>

Thanks for the message and the support, but please note that since you
are not in the path of the patch, you cannot use this tag; instead
look into Reviewed-by etc. See
https://www.kernel.org/doc/html/v5.19/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
and the following section for details.

> And I think that this patch and all other "rust" kallsyms patches
> allready should have been accepted in the v3 or v5 series.

Yeah, it could be a good idea to get the prerequisites in first. Let's
see if the patches get some Reviewed-bys (e.g. I had to remove Kees'
one because I had to split the patch).

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size
  2022-08-05 15:41 ` [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size Miguel Ojeda
  2022-08-05 16:48   ` Geert Stappers
@ 2022-08-05 22:40   ` Konstantin Shelekhin
  2022-08-17 19:36     ` Kees Cook
  1 sibling, 1 reply; 102+ messages in thread
From: Konstantin Shelekhin @ 2022-08-05 22:40 UTC (permalink / raw)
  To: ojeda
  Cc: boqun.feng, gregkh, jarkko, linux-fsdevel, linux-kernel, patches,
	rust-for-linux, torvalds

> diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> index f18e6dfc68c5..52f5488c61bc 100644
> --- a/scripts/kallsyms.c
> +++ b/scripts/kallsyms.c
> @@ -206,7 +206,7 @@ static struct sym_entry *read_symbol(FILE *in)
>  
>  	rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
>  	if (rc != 3) {
> -		if (rc != EOF && fgets(name, 500, in) == NULL)
> +		if (rc != EOF && fgets(name, sizeof(name), in) == NULL)
>  			fprintf(stderr, "Read error or end of file.\n");
>  		return NULL;
>  	}

Might be another nit, but IMO it's better to use ARRAY_SIZE() here.

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-08-05 15:41 ` [PATCH v9 12/27] rust: add `kernel` crate Miguel Ojeda
@ 2022-08-06 10:24   ` Konstantin Shelekhin
  2022-08-06 11:22     ` Miguel Ojeda
  0 siblings, 1 reply; 102+ messages in thread
From: Konstantin Shelekhin @ 2022-08-06 10:24 UTC (permalink / raw)
  To: ojeda
  Cc: alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, torvalds, viktor, wedsonaf

> +unsafe impl GlobalAlloc for KernelAllocator {
> +    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
> +        // `krealloc()` is used instead of `kmalloc()` because the latter is
> +        // an inline function and cannot be bound to as a result.
> +        unsafe { bindings::krealloc(ptr::null(), layout.size(), bindings::GFP_KERNEL) as *mut u8 }
> +    }
> +
> +    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
> +        unsafe {
> +            bindings::kfree(ptr as *const core::ffi::c_void);
> +        }
> +    }
> +}

I sense possible problems here. It's common for a kernel code to pass
flags during memory allocations.

For example:

  struct bio *bio;

  for (...) {
        bio = bio_alloc_bioset(bdev, nr_vecs, opf, GFP_NOIO, bs);
        if (!bio)
        	return -ENOMEM;
  }

Without GFP_NOIO we can run into a deadlock, because the kernel will try
give us free memory by flushing the dirty pages and we need the memory
to actually do it and boom, deadlock.

Or we can be allocating some structs under spinlock (yeah, that happens too):

  struct efc_vport *vport;

  spin_lock_irqsave(...);
  vport = kzalloc(sizeof(*vport), GFP_ATOMIC);
  if (!vport) {
  	spin_unlock_irqrestore(...);
  	return NULL;
  }
  spin_unlock(...);

Same can (and probably will) happen to e.g. Vec elements. So some form
of flags passing should be supported in try_* variants:

  let mut vec = Vec::try_new(GFP_ATOMIC)?;

  vec.try_push(GFP_ATOMIC, 1)?;
  vec.try_push(GFP_ATOMIC, 2)?;
  vec.try_push(GFP_ATOMIC, 3)?;

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-08-06 10:24   ` Konstantin Shelekhin
@ 2022-08-06 11:22     ` Miguel Ojeda
  2022-08-06 12:15       ` Konstantin Shelekhin
                         ` (2 more replies)
  0 siblings, 3 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-06 11:22 UTC (permalink / raw)
  To: Konstantin Shelekhin
  Cc: ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, torvalds, viktor, wedsonaf,
	Andreas Hindborg

On Sat, Aug 6, 2022 at 12:25 PM Konstantin Shelekhin
<k.shelekhin@yadro.com> wrote:
>
> I sense possible problems here. It's common for a kernel code to pass
> flags during memory allocations.

Yes, of course. We will support this, but how exactly it will look
like, to what extent upstream Rust's `alloc` could support our use
cases, etc. has been on discussion for a long time.

For instance, see https://github.com/Rust-for-Linux/linux/pull/815 for
a potential extension trait approach with no allocator carried on the
type that Andreas wrote after a discussion in the last informal call:

    let a = Box::try_new_atomic(101)?;

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-08-06 11:22     ` Miguel Ojeda
@ 2022-08-06 12:15       ` Konstantin Shelekhin
  2022-08-06 14:57       ` Matthew Wilcox
  2022-09-21 11:23       ` Konstantin Shelekhin
  2 siblings, 0 replies; 102+ messages in thread
From: Konstantin Shelekhin @ 2022-08-06 12:15 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, torvalds, viktor, wedsonaf,
	Andreas Hindborg

On Sat, Aug 06, 2022 at 01:22:52PM +0200, Miguel Ojeda wrote:
> > I sense possible problems here. It's common for a kernel code to pass
> > flags during memory allocations.
> 
> Yes, of course. We will support this, but how exactly it will look
> like, to what extent upstream Rust's `alloc` could support our use
> cases, etc. has been on discussion for a long time.
> 
> For instance, see https://github.com/Rust-for-Linux/linux/pull/815 for
> a potential extension trait approach with no allocator carried on the
> type that Andreas wrote after a discussion in the last informal call:
> 
>     let a = Box::try_new_atomic(101)?;

IMO it's just easier to always pass flags like this:

  let a = Box::try_new(GFP_KERNEL | GFP_DMA, 101)?;

But if allocate_with_flags() will be somehow present in the API that's
just what we need.

P.S. Thanks for a quick reply!

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 26/27] samples: add first Rust examples
  2022-08-05 15:42 ` [PATCH v9 26/27] samples: add first Rust examples Miguel Ojeda
@ 2022-08-06 13:14   ` Konstantin Shelekhin
  2022-08-17 21:02     ` Miguel Ojeda
  2022-08-17 20:28   ` Kees Cook
  1 sibling, 1 reply; 102+ messages in thread
From: Konstantin Shelekhin @ 2022-08-06 13:14 UTC (permalink / raw)
  To: ojeda
  Cc: alex.gaynor, bjorn3_gh, boqun.feng, gary, gregkh, jarkko,
	linux-fsdevel, linux-kernel, me, milan, patches, rust-for-linux,
	torvalds, wedsonaf

> +impl Drop for RustMinimal {
> +    fn drop(&mut self) {
> +        pr_info!("My numbers are {:?}\n", self.numbers);
> +        pr_info!("Rust minimal sample (exit)\n");
> +    }
> +}

I wonder if it would make more sense to implement exit() in
kernel::Module, just for the sake of uniformity.

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-08-06 11:22     ` Miguel Ojeda
  2022-08-06 12:15       ` Konstantin Shelekhin
@ 2022-08-06 14:57       ` Matthew Wilcox
  2022-09-19 14:07         ` Wedson Almeida Filho
  2022-09-21 11:23       ` Konstantin Shelekhin
  2 siblings, 1 reply; 102+ messages in thread
From: Matthew Wilcox @ 2022-08-06 14:57 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Konstantin Shelekhin, ojeda, alex.gaynor, ark.email, bjorn3_gh,
	bobo1239, bonifaido, boqun.feng, davidgow, dev, dsosnowski,
	foxhlchen, gary, geofft, gregkh, jarkko, john.m.baublitz,
	leseulartichaut, linux-fsdevel, linux-kernel, m.falkowski, me,
	milan, mjmouse9999, patches, rust-for-linux, thesven73, torvalds,
	viktor, wedsonaf, Andreas Hindborg

On Sat, Aug 06, 2022 at 01:22:52PM +0200, Miguel Ojeda wrote:
> On Sat, Aug 6, 2022 at 12:25 PM Konstantin Shelekhin
> <k.shelekhin@yadro.com> wrote:
> >
> > I sense possible problems here. It's common for a kernel code to pass
> > flags during memory allocations.
> 
> Yes, of course. We will support this, but how exactly it will look
> like, to what extent upstream Rust's `alloc` could support our use
> cases, etc. has been on discussion for a long time.
> 
> For instance, see https://github.com/Rust-for-Linux/linux/pull/815 for
> a potential extension trait approach with no allocator carried on the
> type that Andreas wrote after a discussion in the last informal call:
> 
>     let a = Box::try_new_atomic(101)?;

Something I've been wondering about for a while is ...

struct task_struct {
...
+	gfp_t gfp_flags;
...
};

We've already done some work towards this with the scoped allocation
API for NOIO and NOFS, but having spin_lock() turn current->gfp_flags
into GFP_ATOMIC might not be the worst idea in the world.

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size
  2022-08-05 22:40   ` Konstantin Shelekhin
@ 2022-08-17 19:36     ` Kees Cook
  2022-08-18  9:03       ` Konstantin Shelekhin
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 19:36 UTC (permalink / raw)
  To: Konstantin Shelekhin
  Cc: ojeda, boqun.feng, gregkh, jarkko, linux-fsdevel, linux-kernel,
	patches, rust-for-linux, torvalds

On Sat, Aug 06, 2022 at 01:40:33AM +0300, Konstantin Shelekhin wrote:
> > diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> > index f18e6dfc68c5..52f5488c61bc 100644
> > --- a/scripts/kallsyms.c
> > +++ b/scripts/kallsyms.c
> > @@ -206,7 +206,7 @@ static struct sym_entry *read_symbol(FILE *in)
> >  
> >  	rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
> >  	if (rc != 3) {
> > -		if (rc != EOF && fgets(name, 500, in) == NULL)
> > +		if (rc != EOF && fgets(name, sizeof(name), in) == NULL)
> >  			fprintf(stderr, "Read error or end of file.\n");
> >  		return NULL;
> >  	}
> 
> Might be another nit, but IMO it's better to use ARRAY_SIZE() here.

I'm not sure I see a benefit for char arrays. It'll produce the same
result, and the tradition for string functions is to use sizeof().
*shrug*

Either way:

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 02/27] kallsyms: avoid hardcoding buffer size
  2022-08-05 15:41 ` [PATCH v9 02/27] kallsyms: avoid hardcoding buffer size Miguel Ojeda
@ 2022-08-17 19:37   ` Kees Cook
  2022-08-18 16:50     ` Geert Stappers
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 19:37 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Boqun Feng

On Fri, Aug 05, 2022 at 05:41:47PM +0200, Miguel Ojeda wrote:
> From: Boqun Feng <boqun.feng@gmail.com>
> 
> This introduces `KSYM_NAME_LEN_BUFFER` in place of the previously
> hardcoded size of the input buffer.
> 
> It will also make it easier to update the size in a single place
> in a later patch.
> 
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> Co-developed-by: Miguel Ojeda <ojeda@kernel.org>
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

Reviewed-by: Kees Cook <keescook@chromium.org>

Does someone want to commit to taking these "prereq" patches? These
clean-ups are nice even without adding Rust.

-Kees

> ---
>  scripts/kallsyms.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> index 52f5488c61bc..f3c5a2623f71 100644
> --- a/scripts/kallsyms.c
> +++ b/scripts/kallsyms.c
> @@ -27,8 +27,14 @@
>  
>  #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
>  
> +#define _stringify_1(x)	#x
> +#define _stringify(x)	_stringify_1(x)
> +
>  #define KSYM_NAME_LEN		128
>  
> +/* A substantially bigger size than the current maximum. */
> +#define KSYM_NAME_LEN_BUFFER	499
> +
>  struct sym_entry {
>  	unsigned long long addr;
>  	unsigned int len;
> @@ -198,13 +204,13 @@ static void check_symbol_range(const char *sym, unsigned long long addr,
>  
>  static struct sym_entry *read_symbol(FILE *in)
>  {
> -	char name[500], type;
> +	char name[KSYM_NAME_LEN_BUFFER+1], type;
>  	unsigned long long addr;
>  	unsigned int len;
>  	struct sym_entry *sym;
>  	int rc;
>  
> -	rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
> +	rc = fscanf(in, "%llx %c %" _stringify(KSYM_NAME_LEN_BUFFER) "s\n", &addr, &type, name);
>  	if (rc != 3) {
>  		if (rc != EOF && fgets(name, sizeof(name), in) == NULL)
>  			fprintf(stderr, "Read error or end of file.\n");
> -- 
> 2.37.1
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 03/27] kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}`
  2022-08-05 15:41 ` [PATCH v9 03/27] kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}` Miguel Ojeda
@ 2022-08-17 19:39   ` Kees Cook
  2022-08-17 19:50     ` Boqun Feng
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 19:39 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Boqun Feng

On Fri, Aug 05, 2022 at 05:41:48PM +0200, Miguel Ojeda wrote:
> This adds a static assert to ensure `KSYM_NAME_LEN_BUFFER`
> gets updated when `KSYM_NAME_LEN` changes.
> 
> The relationship used is one that keeps the new size (512+1)
> close to the original buffer size (500).
> 
> Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> ---
>  scripts/kallsyms.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> index f3c5a2623f71..f543b1c4f99f 100644
> --- a/scripts/kallsyms.c
> +++ b/scripts/kallsyms.c
> @@ -33,7 +33,11 @@
>  #define KSYM_NAME_LEN		128
>  
>  /* A substantially bigger size than the current maximum. */
> -#define KSYM_NAME_LEN_BUFFER	499
> +#define KSYM_NAME_LEN_BUFFER	512
> +_Static_assert(
> +	KSYM_NAME_LEN_BUFFER == KSYM_NAME_LEN * 4,
> +	"Please keep KSYM_NAME_LEN_BUFFER in sync with KSYM_NAME_LEN"
> +);

Why not just make this define:

#define KSYM_NAME_LEN_BUFFER (KSYM_NAME_LEN * 4)

? If there's a good reason not it, please put it in the commit log.

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 06/27] rust: add C helpers
  2022-08-05 15:41 ` [PATCH v9 06/27] rust: add C helpers Miguel Ojeda
@ 2022-08-17 19:44   ` Kees Cook
  2022-08-17 20:22     ` Miguel Ojeda
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 19:44 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Geoffrey Thomas, Wedson Almeida Filho, Sven Van Asbroeck,
	Gary Guo, Boqun Feng, Maciej Falkowski, Wei Liu,
	Björn Roy Baron

On Fri, Aug 05, 2022 at 05:41:51PM +0200, Miguel Ojeda wrote:
> This source file contains forwarders to C macros and inlined
> functions.

Perhaps:

"Introduce the source file that will contain forwarders to common C
macros as inlined Rust functions. Initially this only contains type
size asserts, but will gain more helpers in subsequent patches."

> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
> Co-developed-by: Geoffrey Thomas <geofft@ldpreload.com>
> Signed-off-by: Geoffrey Thomas <geofft@ldpreload.com>
> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
> Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
> Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
> Co-developed-by: Gary Guo <gary@garyguo.net>
> Signed-off-by: Gary Guo <gary@garyguo.net>
> Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> Co-developed-by: Maciej Falkowski <m.falkowski@samsung.com>
> Signed-off-by: Maciej Falkowski <m.falkowski@samsung.com>
> Co-developed-by: Wei Liu <wei.liu@kernel.org>
> Signed-off-by: Wei Liu <wei.liu@kernel.org>
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> ---
>  rust/helpers.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 51 insertions(+)
>  create mode 100644 rust/helpers.c
> 
> diff --git a/rust/helpers.c b/rust/helpers.c
> new file mode 100644
> index 000000000000..b4f15eee2ffd
> --- /dev/null
> +++ b/rust/helpers.c
> @@ -0,0 +1,51 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Non-trivial C macros cannot be used in Rust. Similarly, inlined C functions
> + * cannot be called either. This file explicitly creates functions ("helpers")
> + * that wrap those so that they can be called from Rust.
> + *
> + * Even though Rust kernel modules should never use directly the bindings, some
> + * of these helpers need to be exported because Rust generics and inlined
> + * functions may not get their code generated in the crate where they are
> + * defined. Other helpers, called from non-inline functions, may not be
> + * exported, in principle. However, in general, the Rust compiler does not
> + * guarantee codegen will be performed for a non-inline function either.
> + * Therefore, this file exports all the helpers. In the future, this may be
> + * revisited to reduce the number of exports after the compiler is informed
> + * about the places codegen is required.
> + *
> + * All symbols are exported as GPL-only to guarantee no GPL-only feature is
> + * accidentally exposed.
> + */
> +
> +#include <linux/bug.h>
> +#include <linux/build_bug.h>
> +
> +__noreturn void rust_helper_BUG(void)
> +{
> +	BUG();
> +}
> +EXPORT_SYMBOL_GPL(rust_helper_BUG);

Given the distaste for ever using BUG()[1], why does this helper exist?

> +
> +/*
> + * We use `bindgen`'s `--size_t-is-usize` option to bind the C `size_t` type
> + * as the Rust `usize` type, so we can use it in contexts where Rust
> + * expects a `usize` like slice (array) indices. `usize` is defined to be
> + * the same as C's `uintptr_t` type (can hold any pointer) but not
> + * necessarily the same as `size_t` (can hold the size of any single
> + * object). Most modern platforms use the same concrete integer type for
> + * both of them, but in case we find ourselves on a platform where
> + * that's not true, fail early instead of risking ABI or
> + * integer-overflow issues.
> + *
> + * If your platform fails this assertion, it means that you are in
> + * danger of integer-overflow bugs (even if you attempt to remove
> + * `--size_t-is-usize`). It may be easiest to change the kernel ABI on
> + * your platform such that `size_t` matches `uintptr_t` (i.e., to increase
> + * `size_t`, because `uintptr_t` has to be at least as big as `size_t`).
> + */
> +static_assert(
> +	sizeof(size_t) == sizeof(uintptr_t) &&
> +	__alignof__(size_t) == __alignof__(uintptr_t),
> +	"Rust code expects C `size_t` to match Rust `usize`"
> +);

-Kees

[1] https://docs.kernel.org/process/deprecated.html#bug-and-bug-on

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 03/27] kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}`
  2022-08-17 19:39   ` Kees Cook
@ 2022-08-17 19:50     ` Boqun Feng
  2022-08-17 20:31       ` Kees Cook
  0 siblings, 1 reply; 102+ messages in thread
From: Boqun Feng @ 2022-08-17 19:50 UTC (permalink / raw)
  To: Kees Cook
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen

On Wed, Aug 17, 2022 at 12:39:48PM -0700, Kees Cook wrote:
> On Fri, Aug 05, 2022 at 05:41:48PM +0200, Miguel Ojeda wrote:
> > This adds a static assert to ensure `KSYM_NAME_LEN_BUFFER`
> > gets updated when `KSYM_NAME_LEN` changes.
> > 
> > The relationship used is one that keeps the new size (512+1)
> > close to the original buffer size (500).
> > 
> > Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
> > Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> > Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> > ---
> >  scripts/kallsyms.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> > index f3c5a2623f71..f543b1c4f99f 100644
> > --- a/scripts/kallsyms.c
> > +++ b/scripts/kallsyms.c
> > @@ -33,7 +33,11 @@
> >  #define KSYM_NAME_LEN		128
> >  
> >  /* A substantially bigger size than the current maximum. */
> > -#define KSYM_NAME_LEN_BUFFER	499
> > +#define KSYM_NAME_LEN_BUFFER	512
> > +_Static_assert(
> > +	KSYM_NAME_LEN_BUFFER == KSYM_NAME_LEN * 4,
> > +	"Please keep KSYM_NAME_LEN_BUFFER in sync with KSYM_NAME_LEN"
> > +);
> 
> Why not just make this define:
> 
> #define KSYM_NAME_LEN_BUFFER (KSYM_NAME_LEN * 4)
> 
> ? If there's a good reason not it, please put it in the commit log.
> 

Because KSYM_NAME_LEN_BUFFER is used as a string by stringify() in
fscanf(), defining it as (KSYM_NAME_LEN * 4) will produce a string

	"128 * 4"

after stringify() and that doesn't work with fscanf().

Miguel, maybe we can add something below in the commit log?

`KSYM_NAME_LEN_BUFFER` cannot be defined as an expression, because it
gets stringified in the fscanf() format. Therefore a _Static_assert() is
needed.

Thoughts?

Regards,
Boqun

> -Kees
> 
> -- 
> Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 07/27] rust: import upstream `alloc` crate
       [not found] ` <20220805154231.31257-8-ojeda@kernel.org>
@ 2022-08-17 20:07   ` Kees Cook
  2022-08-17 21:00     ` Miguel Ojeda
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:07 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho, Boqun Feng, Gary Guo, Björn Roy Baron

On Fri, Aug 05, 2022 at 05:41:52PM +0200, Miguel Ojeda wrote:
> This is a subset of the Rust standard library `alloc` crate,
> version 1.62.0, licensed under "Apache-2.0 OR MIT", from:
> 
>     https://github.com/rust-lang/rust/tree/1.62.0/library/alloc/src
> 
> The files are copied as-is, with no modifications whatsoever
> (not even adding the SPDX identifiers).
> 
> For copyright details, please see:
> 
>     https://github.com/rust-lang/rust/blob/1.62.0/COPYRIGHT
> 
> The next patch modifies these files as needed for use within
> the kernel. This patch split allows reviewers to double-check
> the import and to clearly see the differences introduced.

Can you include an easy script (in the commit log) for this kind of
verification?

For this, I have done:

$ git am 0001-rust-import-upstream-alloc-crate.patch
$ for i in $(diffstat -lp3 0001-rust-import-upstream-alloc-crate.patch); do
	wget --quiet -O check.rs \
	 https://github.com/rust-lang/rust/raw/1.62.0/library/alloc/src/$i
	diff -up rust/alloc/$i check.rs && echo $i: ok
	rm -f check.rs
done

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 09/27] rust: add `compiler_builtins` crate
  2022-08-05 15:41 ` [PATCH v9 09/27] rust: add `compiler_builtins` crate Miguel Ojeda
@ 2022-08-17 20:08   ` Kees Cook
  2022-08-22 23:55   ` Nick Desaulniers
  1 sibling, 0 replies; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:08 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho, Sven Van Asbroeck, Gary Guo, Boqun Feng,
	Björn Roy Baron

On Fri, Aug 05, 2022 at 05:41:54PM +0200, Miguel Ojeda wrote:
> Rust provides `compiler_builtins` as a port of LLVM's `compiler-rt`.
> Since we do not need the vast majority of them, we avoid the
> dependency by providing our own crate.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 13/27] rust: export generated symbols
  2022-08-05 15:41 ` [PATCH v9 13/27] rust: export generated symbols Miguel Ojeda
@ 2022-08-17 20:11   ` Kees Cook
  0 siblings, 0 replies; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:11 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho, Björn Roy Baron, Boqun Feng, Gary Guo

On Fri, Aug 05, 2022 at 05:41:58PM +0200, Miguel Ojeda wrote:
> All symbols are reexported reusing the `EXPORT_SYMBOL_GPL` macro
> from C. The lists of symbols are generated on the fly.
> 
> There are three main sets of symbols to distinguish:
> 
>   - The ones from the `core` and `alloc` crates (from the Rust
>     standard library). The code is licensed as Apache/MIT.
> 
>   - The ones from our abstractions in the `kernel` crate.
> 
>   - The helpers (already exported since they are not generated).
> 
> We export everything as GPL. This ensures we do not mistakenly
> expose GPL kernel symbols/features as non-GPL, even indirectly.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 16/27] scripts: checkpatch: enable language-independent checks for Rust
  2022-08-05 15:42 ` [PATCH v9 16/27] scripts: checkpatch: enable language-independent checks for Rust Miguel Ojeda
@ 2022-08-17 20:12   ` Kees Cook
  0 siblings, 0 replies; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:12 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho, Andy Whitcroft, Joe Perches, Dwaipayan Ray,
	Lukas Bulwahn

On Fri, Aug 05, 2022 at 05:42:01PM +0200, Miguel Ojeda wrote:
> Include Rust in the "source code files" category, so that
> the language-independent tests are checked for Rust too,
> and teach `checkpatch` about the comment style for Rust files.
> 
> This enables the malformed SPDX check, the misplaced SPDX license
> tag check, the long line checks, the lines without a newline check
> and the embedded filename check.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 18/27] scripts: add `generate_rust_analyzer.py`
  2022-08-05 15:42 ` [PATCH v9 18/27] scripts: add `generate_rust_analyzer.py` Miguel Ojeda
@ 2022-08-17 20:13   ` Kees Cook
  0 siblings, 0 replies; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:13 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Finn Behrens, Wedson Almeida Filho, Gary Guo,
	Boris-Chengbiao Zhou, Björn Roy Baron, Boqun Feng

On Fri, Aug 05, 2022 at 05:42:03PM +0200, Miguel Ojeda wrote:
> The `generate_rust_analyzer.py` script generates the configuration
> file (`rust-project.json`) for rust-analyzer.
> 
> rust-analyzer is a modular compiler frontend for the Rust language.
> It provides an LSP server which can be used in editors such as
> VS Code, Emacs or Vim.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 19/27] scripts: add `generate_rust_target.rs`
  2022-08-05 15:42 ` [PATCH v9 19/27] scripts: add `generate_rust_target.rs` Miguel Ojeda
@ 2022-08-17 20:14   ` Kees Cook
  0 siblings, 0 replies; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:14 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho, David Gow, Boqun Feng, Gary Guo,
	Björn Roy Baron

On Fri, Aug 05, 2022 at 05:42:04PM +0200, Miguel Ojeda wrote:
> This script takes care of generating the custom target specification
> file for `rustc`, based on the kernel configuration.
> 
> It also serves as an example of a Rust host program.
> 
> A dummy architecture is kept in this patch so that a later patch
> adds x86 support on top with as few changes as possible.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 20/27] scripts: add `rust_is_available.sh`
  2022-08-05 15:42 ` [PATCH v9 20/27] scripts: add `rust_is_available.sh` Miguel Ojeda
@ 2022-08-17 20:18   ` Kees Cook
  2022-08-17 20:40     ` Miguel Ojeda
  2022-08-22 20:09   ` Nick Desaulniers
  1 sibling, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:18 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho, Finn Behrens, Miguel Cano, Tiago Lam,
	Boqun Feng, Gary Guo, Björn Roy Baron

On Fri, Aug 05, 2022 at 05:42:05PM +0200, Miguel Ojeda wrote:
> This script tests whether the Rust toolchain requirements are in place
> to enable Rust support.
> 
> The build system will call it to set `CONFIG_RUST_IS_AVAILABLE` in
> a later patch.
> 
> It also has an option (`-v`) to explain what is missing, which is
> useful to set up the development environment. This is used via
> the `make rustavailable` target added in a later patch.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
> Co-developed-by: Finn Behrens <me@kloenk.de>
> Signed-off-by: Finn Behrens <me@kloenk.de>
> Co-developed-by: Miguel Cano <macanroj@gmail.com>
> Signed-off-by: Miguel Cano <macanroj@gmail.com>
> Co-developed-by: Tiago Lam <tiagolam@gmail.com>
> Signed-off-by: Tiago Lam <tiagolam@gmail.com>
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> ---
>  scripts/rust_is_available.sh                 | 160 +++++++++++++++++++
>  scripts/rust_is_available_bindgen_libclang.h |   2 +
>  2 files changed, 162 insertions(+)
>  create mode 100755 scripts/rust_is_available.sh
>  create mode 100644 scripts/rust_is_available_bindgen_libclang.h
> 
> diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh
> new file mode 100755
> index 000000000000..aebbf1913970
> --- /dev/null
> +++ b/scripts/rust_is_available.sh
> @@ -0,0 +1,160 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Tests whether a suitable Rust toolchain is available.
> +#
> +# Pass `-v` for human output and more checks (as warnings).
> +
> +set -e
> +
> +min_tool_version=$(dirname $0)/min-tool-version.sh
> +
> +# Convert the version string x.y.z to a canonical up-to-7-digits form.
> +#
> +# Note that this function uses one more digit (compared to other
> +# instances in other version scripts) to give a bit more space to
> +# `rustc` since it will reach 1.100.0 in late 2026.
> +get_canonical_version()
> +{
> +	IFS=.
> +	set -- $1
> +	echo $((100000 * $1 + 100 * $2 + $3))
> +}
> +
> +# Check that the Rust compiler exists.
> +if ! command -v "$RUSTC" >/dev/null; then
> +	if [ "$1" = -v ]; then
> +		echo >&2 "***"
> +		echo >&2 "*** Rust compiler '$RUSTC' could not be found."
> +		echo >&2 "***"
> +	fi
> +	exit 1
> +fi
> +
> +# Check that the Rust bindings generator exists.
> +if ! command -v "$BINDGEN" >/dev/null; then
> +	if [ "$1" = -v ]; then
> +		echo >&2 "***"
> +		echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found."
> +		echo >&2 "***"
> +	fi
> +	exit 1
> +fi
> +
> +# Check that the Rust compiler version is suitable.
> +#
> +# Non-stable and distributions' versions may have a version suffix, e.g. `-dev`.
> +rust_compiler_version=$( \
> +	LC_ALL=C "$RUSTC" --version 2>/dev/null \
> +		| head -n 1 \
> +		| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
> +)
> +rust_compiler_min_version=$($min_tool_version rustc)

I think the min-tool-version.sh changes from patch 23 should be moved
into this patch.

With that:

Reviewed-by: Kees Cook <keescook@chromium.org>

-Kees

> +rust_compiler_cversion=$(get_canonical_version $rust_compiler_version)
> +rust_compiler_min_cversion=$(get_canonical_version $rust_compiler_min_version)
> +if [ "$rust_compiler_cversion" -lt "$rust_compiler_min_cversion" ]; then
> +	if [ "$1" = -v ]; then
> +		echo >&2 "***"
> +		echo >&2 "*** Rust compiler '$RUSTC' is too old."
> +		echo >&2 "***   Your version:    $rust_compiler_version"
> +		echo >&2 "***   Minimum version: $rust_compiler_min_version"
> +		echo >&2 "***"
> +	fi
> +	exit 1
> +fi
> +if [ "$1" = -v ] && [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then
> +	echo >&2 "***"
> +	echo >&2 "*** Rust compiler '$RUSTC' is too new. This may or may not work."
> +	echo >&2 "***   Your version:     $rust_compiler_version"
> +	echo >&2 "***   Expected version: $rust_compiler_min_version"
> +	echo >&2 "***"
> +fi
> +
> +# Check that the Rust bindings generator is suitable.
> +#
> +# Non-stable and distributions' versions may have a version suffix, e.g. `-dev`.
> +rust_bindings_generator_version=$( \
> +	LC_ALL=C "$BINDGEN" --version 2>/dev/null \
> +		| head -n 1 \
> +		| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
> +)
> +rust_bindings_generator_min_version=$($min_tool_version bindgen)
> +rust_bindings_generator_cversion=$(get_canonical_version $rust_bindings_generator_version)
> +rust_bindings_generator_min_cversion=$(get_canonical_version $rust_bindings_generator_min_version)
> +if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cversion" ]; then
> +	if [ "$1" = -v ]; then
> +		echo >&2 "***"
> +		echo >&2 "*** Rust bindings generator '$BINDGEN' is too old."
> +		echo >&2 "***   Your version:    $rust_bindings_generator_version"
> +		echo >&2 "***   Minimum version: $rust_bindings_generator_min_version"
> +		echo >&2 "***"
> +	fi
> +	exit 1
> +fi
> +if [ "$1" = -v ] && [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then
> +	echo >&2 "***"
> +	echo >&2 "*** Rust bindings generator '$BINDGEN' is too new. This may or may not work."
> +	echo >&2 "***   Your version:     $rust_bindings_generator_version"
> +	echo >&2 "***   Expected version: $rust_bindings_generator_min_version"
> +	echo >&2 "***"
> +fi
> +
> +# Check that the `libclang` used by the Rust bindings generator is suitable.
> +bindgen_libclang_version=$( \
> +	LC_ALL=C "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang.h 2>&1 >/dev/null \
> +		| grep -F 'clang version ' \
> +		| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
> +		| head -n 1 \
> +)
> +bindgen_libclang_min_version=$($min_tool_version llvm)
> +bindgen_libclang_cversion=$(get_canonical_version $bindgen_libclang_version)
> +bindgen_libclang_min_cversion=$(get_canonical_version $bindgen_libclang_min_version)
> +if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then
> +	if [ "$1" = -v ]; then
> +		echo >&2 "***"
> +		echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old."
> +		echo >&2 "***   Your version:    $bindgen_libclang_version"
> +		echo >&2 "***   Minimum version: $bindgen_libclang_min_version"
> +		echo >&2 "***"
> +	fi
> +	exit 1
> +fi
> +
> +# If the C compiler is Clang, then we can also check whether its version
> +# matches the `libclang` version used by the Rust bindings generator.
> +#
> +# In the future, we might be able to perform a full version check, see
> +# https://github.com/rust-lang/rust-bindgen/issues/2138.
> +if [ "$1" = -v ]; then
> +	cc_name=$($(dirname $0)/cc-version.sh "$CC" | cut -f1 -d' ')
> +	if [ "$cc_name" = Clang ]; then
> +		clang_version=$( \
> +			LC_ALL=C "$CC" --version 2>/dev/null \
> +				| sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p'
> +		)
> +		if [ "$clang_version" != "$bindgen_libclang_version" ]; then
> +			echo >&2 "***"
> +			echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN')"
> +			echo >&2 "*** version does not match Clang's. This may be a problem."
> +			echo >&2 "***   libclang version: $bindgen_libclang_version"
> +			echo >&2 "***   Clang version:    $clang_version"
> +			echo >&2 "***"
> +		fi
> +	fi
> +fi
> +
> +# Check that the source code for the `core` standard library exists.
> +#
> +# `$KRUSTFLAGS` is passed in case the user added `--sysroot`.
> +rustc_sysroot=$("$RUSTC" $KRUSTFLAGS --print sysroot)
> +rustc_src=${RUST_LIB_SRC:-"$rustc_sysroot/lib/rustlib/src/rust/library"}
> +rustc_src_core="$rustc_src/core/src/lib.rs"
> +if [ ! -e "$rustc_src_core" ]; then
> +	if [ "$1" = -v ]; then
> +		echo >&2 "***"
> +		echo >&2 "*** Source code for the 'core' standard library could not be found"
> +		echo >&2 "*** at '$rustc_src_core'."
> +		echo >&2 "***"
> +	fi
> +	exit 1
> +fi
> diff --git a/scripts/rust_is_available_bindgen_libclang.h b/scripts/rust_is_available_bindgen_libclang.h
> new file mode 100644
> index 000000000000..0ef6db10d674
> --- /dev/null
> +++ b/scripts/rust_is_available_bindgen_libclang.h
> @@ -0,0 +1,2 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#pragma message("clang version " __clang_version__)
> -- 
> 2.37.1
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 21/27] scripts: add `is_rust_module.sh`
  2022-08-05 15:42 ` [PATCH v9 21/27] scripts: add `is_rust_module.sh` Miguel Ojeda
@ 2022-08-17 20:19   ` Kees Cook
  0 siblings, 0 replies; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:19 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Daniel Xu, Alex Gaynor,
	Wedson Almeida Filho, Boqun Feng, Gary Guo, Björn Roy Baron

On Fri, Aug 05, 2022 at 05:42:06PM +0200, Miguel Ojeda wrote:
> From: Daniel Xu <dxu@dxuuu.xyz>
> 
> This script is used to detect whether a kernel module is written
> in Rust.
> 
> It will later be used to disable BTF generation on Rust modules as
> BTF does not yet support Rust.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 22/27] rust: add `.rustfmt.toml`
  2022-08-05 15:42 ` [PATCH v9 22/27] rust: add `.rustfmt.toml` Miguel Ojeda
@ 2022-08-17 20:19   ` Kees Cook
  0 siblings, 0 replies; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:19 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho

On Fri, Aug 05, 2022 at 05:42:07PM +0200, Miguel Ojeda wrote:
> This is the configuration file for the `rustfmt` tool.
> 
> `rustfmt` is a tool for formatting Rust code according to style guidelines.
> It is very commonly used across Rust projects.
> 
> The default configuration options are used.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 06/27] rust: add C helpers
  2022-08-17 19:44   ` Kees Cook
@ 2022-08-17 20:22     ` Miguel Ojeda
  2022-08-17 20:34       ` Kees Cook
  0 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-17 20:22 UTC (permalink / raw)
  To: Kees Cook
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Geoffrey Thomas, Wedson Almeida Filho,
	Sven Van Asbroeck, Gary Guo, Boqun Feng, Maciej Falkowski,
	Wei Liu, Björn Roy Baron

On Wed, Aug 17, 2022 at 9:44 PM Kees Cook <keescook@chromium.org> wrote:
>
> "Introduce the source file that will contain forwarders to common C
> macros as inlined Rust functions. Initially this only contains type
> size asserts, but will gain more helpers in subsequent patches."

Yeah, I will reword it, it doesn't make as much sense now that it is trimmed.

> Given the distaste for ever using BUG()[1], why does this helper exist?

We use it exclusively for the Rust panic handler, which does not
return (we use fallible operations as much as possible, of course, but
we need to provide a panic handler nevertheless).

Killing the entire machine is definitely too aggressive for some
setups/situations, so at some point last year we discussed potential
alternatives (e.g. `make_task_dead()` or similar) with, if I recall
correctly, Greg. Maybe we want to make it configurable too. We are
open to suggestions!

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 23/27] Kbuild: add Rust support
  2022-08-05 15:42 ` [PATCH v9 23/27] Kbuild: add Rust support Miguel Ojeda
@ 2022-08-17 20:26   ` Kees Cook
  2022-08-17 20:56     ` Miguel Ojeda
  2022-08-22 22:35   ` Nick Desaulniers
  2022-09-12 16:07   ` Masahiro Yamada
  2 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:26 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Finn Behrens, Adam Bratschi-Kaye, Wedson Almeida Filho,
	Michael Ellerman, Sven Van Asbroeck, Gary Guo,
	Boris-Chengbiao Zhou, Boqun Feng, Douglas Su, Dariusz Sosnowski,
	Antonio Terceiro, Daniel Xu, Björn Roy Baron,
	Martin Rodriguez Reboredo, Masahiro Yamada, Michal Marek,
	Nick Desaulniers, linux-kbuild

On Fri, Aug 05, 2022 at 05:42:08PM +0200, Miguel Ojeda wrote:
> Having most of the new files in place, we now enable Rust support
> in the build system, including `Kconfig` entries related to Rust,
> the Rust configuration printer and a few other bits.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
> Co-developed-by: Finn Behrens <me@kloenk.de>
> Signed-off-by: Finn Behrens <me@kloenk.de>
> Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com>
> Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com>
> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
> Co-developed-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
> Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
> Co-developed-by: Gary Guo <gary@garyguo.net>
> Signed-off-by: Gary Guo <gary@garyguo.net>
> Co-developed-by: Boris-Chengbiao Zhou <bobo1239@web.de>
> Signed-off-by: Boris-Chengbiao Zhou <bobo1239@web.de>
> Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> Co-developed-by: Douglas Su <d0u9.su@outlook.com>
> Signed-off-by: Douglas Su <d0u9.su@outlook.com>
> Co-developed-by: Dariusz Sosnowski <dsosnowski@dsosnowski.pl>
> Signed-off-by: Dariusz Sosnowski <dsosnowski@dsosnowski.pl>
> Co-developed-by: Antonio Terceiro <antonio.terceiro@linaro.org>
> Signed-off-by: Antonio Terceiro <antonio.terceiro@linaro.org>
> Co-developed-by: Daniel Xu <dxu@dxuuu.xyz>
> Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
> Co-developed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
> Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
> Co-developed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
> Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

It'd be nice to split this up into maybe per-target patches, but given
how long this has been getting developed, I'd prefer to avoid blocking
on that, and just get this series landed so we can move to incremental
fixes/additions.

Reviewed-by: Kees Cook <keescook@chromium.org>

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 25/27] x86: enable initial Rust support
  2022-08-05 15:42 ` [PATCH v9 25/27] x86: enable initial Rust support Miguel Ojeda
@ 2022-08-17 20:27   ` Kees Cook
  0 siblings, 0 replies; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:27 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho, David Gow, Boqun Feng, Gary Guo,
	Björn Roy Baron, Jonathan Corbet, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
	linux-doc

On Fri, Aug 05, 2022 at 05:42:10PM +0200, Miguel Ojeda wrote:
> Note that only x86_64 is covered and not all features nor mitigations
> are handled, but it is enough as a starting point and showcases
> the basics needed to add Rust support for a new architecture.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 26/27] samples: add first Rust examples
  2022-08-05 15:42 ` [PATCH v9 26/27] samples: add first Rust examples Miguel Ojeda
  2022-08-06 13:14   ` Konstantin Shelekhin
@ 2022-08-17 20:28   ` Kees Cook
  1 sibling, 0 replies; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:28 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Finn Behrens, Wedson Almeida Filho, Milan Landaverde, Boqun Feng,
	Gary Guo, Björn Roy Baron

On Fri, Aug 05, 2022 at 05:42:11PM +0200, Miguel Ojeda wrote:
> The beginning of a set of Rust modules that showcase how Rust
> modules look like and how to use the abstracted kernel features.
> 
> It also includes an example of a Rust host program with
> several modules.
> 
> These samples also double as tests in the CI.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 27/27] MAINTAINERS: Rust
  2022-08-05 15:42 ` [PATCH v9 27/27] MAINTAINERS: Rust Miguel Ojeda
@ 2022-08-17 20:28   ` Kees Cook
  2022-08-17 20:43     ` Miguel Ojeda
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:28 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho

On Fri, Aug 05, 2022 at 05:42:12PM +0200, Miguel Ojeda wrote:
> Miguel, Alex and Wedson will be maintaining the Rust support.
> 
> Boqun, Gary and Björn will be reviewers.
> 
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 03/27] kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}`
  2022-08-17 19:50     ` Boqun Feng
@ 2022-08-17 20:31       ` Kees Cook
  2022-08-17 20:45         ` Miguel Ojeda
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:31 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen

On Wed, Aug 17, 2022 at 12:50:50PM -0700, Boqun Feng wrote:
> On Wed, Aug 17, 2022 at 12:39:48PM -0700, Kees Cook wrote:
> > On Fri, Aug 05, 2022 at 05:41:48PM +0200, Miguel Ojeda wrote:
> > > This adds a static assert to ensure `KSYM_NAME_LEN_BUFFER`
> > > gets updated when `KSYM_NAME_LEN` changes.
> > > 
> > > The relationship used is one that keeps the new size (512+1)
> > > close to the original buffer size (500).
> > > 
> > > Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
> > > Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> > > Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> > > ---
> > >  scripts/kallsyms.c | 6 +++++-
> > >  1 file changed, 5 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> > > index f3c5a2623f71..f543b1c4f99f 100644
> > > --- a/scripts/kallsyms.c
> > > +++ b/scripts/kallsyms.c
> > > @@ -33,7 +33,11 @@
> > >  #define KSYM_NAME_LEN		128
> > >  
> > >  /* A substantially bigger size than the current maximum. */
> > > -#define KSYM_NAME_LEN_BUFFER	499
> > > +#define KSYM_NAME_LEN_BUFFER	512
> > > +_Static_assert(
> > > +	KSYM_NAME_LEN_BUFFER == KSYM_NAME_LEN * 4,
> > > +	"Please keep KSYM_NAME_LEN_BUFFER in sync with KSYM_NAME_LEN"
> > > +);
> > 
> > Why not just make this define:
> > 
> > #define KSYM_NAME_LEN_BUFFER (KSYM_NAME_LEN * 4)
> > 
> > ? If there's a good reason not it, please put it in the commit log.
> > 
> 
> Because KSYM_NAME_LEN_BUFFER is used as a string by stringify() in
> fscanf(), defining it as (KSYM_NAME_LEN * 4) will produce a string
> 
> 	"128 * 4"
> 
> after stringify() and that doesn't work with fscanf().

Ah yeah. Thanks!

> Miguel, maybe we can add something below in the commit log?
> 
> `KSYM_NAME_LEN_BUFFER` cannot be defined as an expression, because it
> gets stringified in the fscanf() format. Therefore a _Static_assert() is
> needed.

Yeah, please add a source comment for that. :)

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 06/27] rust: add C helpers
  2022-08-17 20:22     ` Miguel Ojeda
@ 2022-08-17 20:34       ` Kees Cook
  2022-08-17 21:44         ` Miguel Ojeda
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 20:34 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Geoffrey Thomas, Wedson Almeida Filho,
	Sven Van Asbroeck, Gary Guo, Boqun Feng, Maciej Falkowski,
	Wei Liu, Björn Roy Baron

On Wed, Aug 17, 2022 at 10:22:37PM +0200, Miguel Ojeda wrote:
> On Wed, Aug 17, 2022 at 9:44 PM Kees Cook <keescook@chromium.org> wrote:
> > Given the distaste for ever using BUG()[1], why does this helper exist?
> 
> We use it exclusively for the Rust panic handler, which does not
> return (we use fallible operations as much as possible, of course, but
> we need to provide a panic handler nevertheless).

Gotcha -- it's for the implicit situations (e.g. -C overflow-checks=on),
nothing is expected to explicitly call the Rust panic handler?

> Killing the entire machine is definitely too aggressive for some
> setups/situations, so at some point last year we discussed potential
> alternatives (e.g. `make_task_dead()` or similar) with, if I recall
> correctly, Greg. Maybe we want to make it configurable too. We are
> open to suggestions!

I suffer the same problems trying to fix C and the old "can never fail"
interfaces. Mainly we've just been systematically replacing such APIs
with APIs that return error codes, allowing the error to bubble back up.
(Which I know is exactly what you've already done with the allocator,
etc. Yay!)

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 20/27] scripts: add `rust_is_available.sh`
  2022-08-17 20:18   ` Kees Cook
@ 2022-08-17 20:40     ` Miguel Ojeda
  0 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-17 20:40 UTC (permalink / raw)
  To: Kees Cook
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Wedson Almeida Filho, Finn Behrens, Miguel Cano,
	Tiago Lam, Boqun Feng, Gary Guo, Björn Roy Baron

On Wed, Aug 17, 2022 at 10:18 PM Kees Cook <keescook@chromium.org> wrote:
>
> I think the min-tool-version.sh changes from patch 23 should be moved
> into this patch.

Yeah, it calls into that script with a "rustc" argument, which doesn't
work if somebody happened to run it by hand, so this makes sense.

However, the intention was to move each "big" new file into their own
patch to make a smaller Kbuild one (and only do that "new file"
additions in each patch), and then finally do all the modifications
and enable the Rust support in the Kbuild patch (which has the callers
into this script). Also the script is not intended to be called
directly anyway (since you need the Make environment, but you
definitely can), there is a Make target to help with that.

Hopefully that explains the logic behind the arrangement of the
patches, which was to make the patches as simple as possible. I am
happy to rearrange if you think it is more understandable that way.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 27/27] MAINTAINERS: Rust
  2022-08-17 20:28   ` Kees Cook
@ 2022-08-17 20:43     ` Miguel Ojeda
  0 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-17 20:43 UTC (permalink / raw)
  To: Kees Cook
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Wedson Almeida Filho

On Wed, Aug 17, 2022 at 10:28 PM Kees Cook <keescook@chromium.org> wrote:
>
> Reviewed-by: Kees Cook <keescook@chromium.org>

Thanks a lot for all the reviews Kees!

In case you are wondering, I removed your previous Review of this one
too since we got some new `R` lines. I guessed you would have been OK
either way given new names are trivial, but it did change a fair % of
the patch, so I played it safe... :-)

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 03/27] kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}`
  2022-08-17 20:31       ` Kees Cook
@ 2022-08-17 20:45         ` Miguel Ojeda
  0 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-17 20:45 UTC (permalink / raw)
  To: Kees Cook
  Cc: Boqun Feng, Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman,
	rust-for-linux, linux-kernel, linux-fsdevel, patches,
	Jarkko Sakkinen

On Wed, Aug 17, 2022 at 10:31 PM Kees Cook <keescook@chromium.org> wrote:
>
> Yeah, please add a source comment for that. :)

I agree, I think this sort of explanation should be in the source vs.
the commit message, since it explains something about the code, not
the change itself.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 23/27] Kbuild: add Rust support
  2022-08-17 20:26   ` Kees Cook
@ 2022-08-17 20:56     ` Miguel Ojeda
  0 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-17 20:56 UTC (permalink / raw)
  To: Kees Cook
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Finn Behrens, Adam Bratschi-Kaye,
	Wedson Almeida Filho, Michael Ellerman, Sven Van Asbroeck,
	Gary Guo, Boris-Chengbiao Zhou, Boqun Feng, Douglas Su,
	Dariusz Sosnowski, Antonio Terceiro, Daniel Xu,
	Björn Roy Baron, Martin Rodriguez Reboredo, Masahiro Yamada,
	Michal Marek, Nick Desaulniers, linux-kbuild

On Wed, Aug 17, 2022 at 10:26 PM Kees Cook <keescook@chromium.org> wrote:
>
> It'd be nice to split this up into maybe per-target patches, but given
> how long this has been getting developed, I'd prefer to avoid blocking
> on that, and just get this series landed so we can move to incremental
> fixes/additions.

When I started the series, I considered several approaches, and in the
end opted for "setup as much as possible before the flag-patch that
enables the Kbuild support", which was simple, though indeed the
Kbuild patch remained fairly big.

Then some people commented on that patch over several versions, so I
kept the simple strategy :)

What I can look into is moving the optional targets out of this patch,
putting them after the "flag-patch", since they may be considered
"additional features" anyway. In fact, for the trimming down in v9, I
thought about removing them entirely. It will not change things too
much, since they are small, but it may help.

For v9 I nevertheless attempted to simplify this patch by doing the
"move all new, big files to their own patch" (see my reply at [1]), so
it is fairly smaller than in previous versions.

[1] https://lore.kernel.org/lkml/CANiq72nzOQSd2vsh2_=0YpGNpY=7agokbgi_vBc5_GF4-02rsA@mail.gmail.com/

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 07/27] rust: import upstream `alloc` crate
  2022-08-17 20:07   ` [PATCH v9 07/27] rust: import upstream `alloc` crate Kees Cook
@ 2022-08-17 21:00     ` Miguel Ojeda
  0 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-17 21:00 UTC (permalink / raw)
  To: Kees Cook
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Wedson Almeida Filho, Boqun Feng, Gary Guo,
	Björn Roy Baron

On Wed, Aug 17, 2022 at 10:07 PM Kees Cook <keescook@chromium.org> wrote:
>
> Can you include an easy script (in the commit log) for this kind of
> verification?

Of course, good idea!

> For this, I have done:
>
> $ git am 0001-rust-import-upstream-alloc-crate.patch
> $ for i in $(diffstat -lp3 0001-rust-import-upstream-alloc-crate.patch); do
>         wget --quiet -O check.rs \
>          https://github.com/rust-lang/rust/raw/1.62.0/library/alloc/src/$i
>         diff -up rust/alloc/$i check.rs && echo $i: ok
>         rm -f check.rs
> done

Thanks for providing the steps like in the other version. This one is
even fancier :)

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 26/27] samples: add first Rust examples
  2022-08-06 13:14   ` Konstantin Shelekhin
@ 2022-08-17 21:02     ` Miguel Ojeda
  2022-08-18  9:04       ` Konstantin Shelekhin
  0 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-17 21:02 UTC (permalink / raw)
  To: Konstantin Shelekhin
  Cc: ojeda, alex.gaynor, bjorn3_gh, boqun.feng, gary, gregkh, jarkko,
	linux-fsdevel, linux-kernel, me, milan, patches, rust-for-linux,
	torvalds, wedsonaf

On Sat, Aug 6, 2022 at 3:15 PM Konstantin Shelekhin
<k.shelekhin@yadro.com> wrote:
>
> I wonder if it would make more sense to implement exit() in
> kernel::Module, just for the sake of uniformity.

Do you mean uniformity with respect to the C side?

Thanks for taking a look!

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 06/27] rust: add C helpers
  2022-08-17 20:34       ` Kees Cook
@ 2022-08-17 21:44         ` Miguel Ojeda
  2022-08-17 23:56           ` Kees Cook
  0 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-17 21:44 UTC (permalink / raw)
  To: Kees Cook
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Geoffrey Thomas, Wedson Almeida Filho,
	Sven Van Asbroeck, Gary Guo, Boqun Feng, Maciej Falkowski,
	Wei Liu, Björn Roy Baron

On Wed, Aug 17, 2022 at 10:34 PM Kees Cook <keescook@chromium.org> wrote:
>
> Gotcha -- it's for the implicit situations (e.g. -C overflow-checks=on),

Yeah, exactly.

> nothing is expected to explicitly call the Rust panic handler?

If by explicitly you mean calling `panic!()`, then in the `kernel`
crate in the v9 patches there is none.

Though we may want to call it in the future (we have 4 instances in
the full code not submitted here, e.g. for mismatching an independent
lock guard with its owner). They can be avoided depending on how we
want the design to be and, I guess, what the "Rust panic" policy will
finally be (i.e. `BUG()` or something softer).

Outside the `kernel` crate, there are also instances in proc macros
and Rust hostprogs/scripts (compilation-time in the host), in the
`alloc` crate (compiled-out) and in the `compiler_builtins` crate (for
e.g. `u128` support that eventually we would like to not see
compiled-in).

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 06/27] rust: add C helpers
  2022-08-17 21:44         ` Miguel Ojeda
@ 2022-08-17 23:56           ` Kees Cook
  2022-08-18 16:03             ` Miguel Ojeda
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-17 23:56 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Geoffrey Thomas, Wedson Almeida Filho,
	Sven Van Asbroeck, Gary Guo, Boqun Feng, Maciej Falkowski,
	Wei Liu, Björn Roy Baron

On Wed, Aug 17, 2022 at 11:44:53PM +0200, Miguel Ojeda wrote:
> On Wed, Aug 17, 2022 at 10:34 PM Kees Cook <keescook@chromium.org> wrote:
> >
> > Gotcha -- it's for the implicit situations (e.g. -C overflow-checks=on),
> 
> Yeah, exactly.
> 
> > nothing is expected to explicitly call the Rust panic handler?
> 
> If by explicitly you mean calling `panic!()`, then in the `kernel`
> crate in the v9 patches there is none.

Perfect. It may be worth stating this explicitly with the helper. i.e.
"This is for handling any panic!() calls in core Rust, but should not
ever be used in the 'kernel' create; failures should be handled."

> Though we may want to call it in the future (we have 4 instances in
> the full code not submitted here, e.g. for mismatching an independent
> lock guard with its owner). They can be avoided depending on how we
> want the design to be and, I guess, what the "Rust panic" policy will
> finally be (i.e. `BUG()` or something softer).
> 
> Outside the `kernel` crate, there are also instances in proc macros
> and Rust hostprogs/scripts (compilation-time in the host), in the
> `alloc` crate (compiled-out) and in the `compiler_builtins` crate (for
> e.g. `u128` support that eventually we would like to not see
> compiled-in).

Sounds good!

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size
  2022-08-17 19:36     ` Kees Cook
@ 2022-08-18  9:03       ` Konstantin Shelekhin
  2022-08-18 16:03         ` Kees Cook
  0 siblings, 1 reply; 102+ messages in thread
From: Konstantin Shelekhin @ 2022-08-18  9:03 UTC (permalink / raw)
  To: Kees Cook
  Cc: ojeda, boqun.feng, gregkh, jarkko, linux-fsdevel, linux-kernel,
	patches, rust-for-linux, torvalds

On Wed, Aug 17, 2022 at 12:36:33PM -0700, Kees Cook wrote:
> On Sat, Aug 06, 2022 at 01:40:33AM +0300, Konstantin Shelekhin wrote:
> > > diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> > > index f18e6dfc68c5..52f5488c61bc 100644
> > > --- a/scripts/kallsyms.c
> > > +++ b/scripts/kallsyms.c
> > > @@ -206,7 +206,7 @@ static struct sym_entry *read_symbol(FILE *in)
> > >
> > >     rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
> > >     if (rc != 3) {
> > > -           if (rc != EOF && fgets(name, 500, in) == NULL)
> > > +           if (rc != EOF && fgets(name, sizeof(name), in) == NULL)
> > >                     fprintf(stderr, "Read error or end of file.\n");
> > >             return NULL;
> > >     }
> >
> > Might be another nit, but IMO it's better to use ARRAY_SIZE() here.
> 
> I'm not sure I see a benefit for char arrays. It'll produce the same
> result, and the tradition for string functions is to use sizeof().
> *shrug*

ARRAY_SIZE() (though not this one) can catch this:

  - char array[16];
  + char *array;

Saves me some.

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 26/27] samples: add first Rust examples
  2022-08-17 21:02     ` Miguel Ojeda
@ 2022-08-18  9:04       ` Konstantin Shelekhin
  0 siblings, 0 replies; 102+ messages in thread
From: Konstantin Shelekhin @ 2022-08-18  9:04 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: ojeda, alex.gaynor, bjorn3_gh, boqun.feng, gary, gregkh, jarkko,
	linux-fsdevel, linux-kernel, me, milan, patches, rust-for-linux,
	torvalds, wedsonaf

On Wed, Aug 17, 2022 at 11:02:01PM +0200, Miguel Ojeda wrote:
> On Sat, Aug 6, 2022 at 3:15 PM Konstantin Shelekhin
> <k.shelekhin@yadro.com> wrote:
> >
> > I wonder if it would make more sense to implement exit() in
> > kernel::Module, just for the sake of uniformity.
> 
> Do you mean uniformity with respect to the C side?

Yeah. It's weird that entry point is implemented in Module while exit
point in Drop.

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 06/27] rust: add C helpers
  2022-08-17 23:56           ` Kees Cook
@ 2022-08-18 16:03             ` Miguel Ojeda
  2022-08-18 16:08               ` Kees Cook
  0 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-18 16:03 UTC (permalink / raw)
  To: Kees Cook
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Geoffrey Thomas, Wedson Almeida Filho,
	Sven Van Asbroeck, Gary Guo, Boqun Feng, Maciej Falkowski,
	Wei Liu, Björn Roy Baron

On Thu, Aug 18, 2022 at 1:56 AM Kees Cook <keescook@chromium.org> wrote:
>
> Perfect. It may be worth stating this explicitly with the helper. i.e.
> "This is for handling any panic!() calls in core Rust, but should not
> ever be used in the 'kernel' create; failures should be handled."

I am not sure we should say "ever", because there are sometimes
situations where we statically know a situation is impossible. Of
course, "impossible" in practice is possible -- even if it is due to a
single-event upset.

For the "statically impossible" cases, we could simply trigger UB
instead of panicking. However, while developing and debugging one
would like to detect bugs as soon as possible. Moreover, in
production, people may have use cases where killing the world is
better as soon as anything "funny" is detected, no matter what.

So we could make it configurable, so that "Rust statically impossible
panics" can be defined as UB, `make_task_dead()` or a full `BUG()`.

By the way, I should have mentioned the `unwrap()s` too, since they
are pretty much explicit panics. We don't have any in v9 either, but
we do have a couple dozens in the full code (in the 97% not submitted)
in non-test or examples code. Many are of the "statically impossible"
kind, but any that is not merits some discussion, which we can do as
we upstream the different pieces.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size
  2022-08-18  9:03       ` Konstantin Shelekhin
@ 2022-08-18 16:03         ` Kees Cook
  2022-09-27 12:48           ` Miguel Ojeda
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-18 16:03 UTC (permalink / raw)
  To: Konstantin Shelekhin
  Cc: ojeda, boqun.feng, gregkh, jarkko, linux-fsdevel, linux-kernel,
	patches, rust-for-linux, torvalds

On Thu, Aug 18, 2022 at 12:03:37PM +0300, Konstantin Shelekhin wrote:
> On Wed, Aug 17, 2022 at 12:36:33PM -0700, Kees Cook wrote:
> > On Sat, Aug 06, 2022 at 01:40:33AM +0300, Konstantin Shelekhin wrote:
> > > > diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> > > > index f18e6dfc68c5..52f5488c61bc 100644
> > > > --- a/scripts/kallsyms.c
> > > > +++ b/scripts/kallsyms.c
> > > > @@ -206,7 +206,7 @@ static struct sym_entry *read_symbol(FILE *in)
> > > >
> > > >     rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
> > > >     if (rc != 3) {
> > > > -           if (rc != EOF && fgets(name, 500, in) == NULL)
> > > > +           if (rc != EOF && fgets(name, sizeof(name), in) == NULL)
> > > >                     fprintf(stderr, "Read error or end of file.\n");
> > > >             return NULL;
> > > >     }
> > >
> > > Might be another nit, but IMO it's better to use ARRAY_SIZE() here.
> > 
> > I'm not sure I see a benefit for char arrays. It'll produce the same
> > result, and the tradition for string functions is to use sizeof().
> > *shrug*
> 
> ARRAY_SIZE() (though not this one) can catch this:
> 
>   - char array[16];
>   + char *array;
> 
> Saves me some.

Oh, that's an excellent point; I forgot it'll actually compile-time
error if the var is a pointer. +1

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 06/27] rust: add C helpers
  2022-08-18 16:03             ` Miguel Ojeda
@ 2022-08-18 16:08               ` Kees Cook
  2022-08-18 17:01                 ` Miguel Ojeda
  0 siblings, 1 reply; 102+ messages in thread
From: Kees Cook @ 2022-08-18 16:08 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Geoffrey Thomas, Wedson Almeida Filho,
	Sven Van Asbroeck, Gary Guo, Boqun Feng, Maciej Falkowski,
	Wei Liu, Björn Roy Baron

On Thu, Aug 18, 2022 at 06:03:04PM +0200, Miguel Ojeda wrote:
> On Thu, Aug 18, 2022 at 1:56 AM Kees Cook <keescook@chromium.org> wrote:
> >
> > Perfect. It may be worth stating this explicitly with the helper. i.e.
> > "This is for handling any panic!() calls in core Rust, but should not
> > ever be used in the 'kernel' create; failures should be handled."
> 
> I am not sure we should say "ever", because there are sometimes
> situations where we statically know a situation is impossible. Of
> course, "impossible" in practice is possible -- even if it is due to a
> single-event upset.
> 
> For the "statically impossible" cases, we could simply trigger UB
> instead of panicking. However, while developing and debugging one
> would like to detect bugs as soon as possible. Moreover, in
> production, people may have use cases where killing the world is
> better as soon as anything "funny" is detected, no matter what.

Please, no UB. I will take a panic over UB any day. It'd be best to
handle things with some error path, but those are the rare exception.

> So we could make it configurable, so that "Rust statically impossible
> panics" can be defined as UB, `make_task_dead()` or a full `BUG()`.

C is riddled with UB and it's just terrible. Let's make sure we don't
continue that mistake. :)

> By the way, I should have mentioned the `unwrap()s` too, since they
> are pretty much explicit panics. We don't have any in v9 either, but
> we do have a couple dozens in the full code (in the 97% not submitted)
> in non-test or examples code. Many are of the "statically impossible"
> kind, but any that is not merits some discussion, which we can do as
> we upstream the different pieces.

The simple answer is that if an "impossible" situation can be recovered
from, it should error instead of panic. As long as that's the explicit
design goal, I think we're good. Yes there will be cases where it is
really and truly unrecoverable, but those will be rare and can be well
documented.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 02/27] kallsyms: avoid hardcoding buffer size
  2022-08-17 19:37   ` Kees Cook
@ 2022-08-18 16:50     ` Geert Stappers
  0 siblings, 0 replies; 102+ messages in thread
From: Geert Stappers @ 2022-08-18 16:50 UTC (permalink / raw)
  To: Kees Cook, Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Boqun Feng

On Wed, Aug 17, 2022 at 12:37:40PM -0700, Kees Cook wrote:
> On Fri, Aug 05, 2022 at 05:41:47PM +0200, Miguel Ojeda wrote:
> > From: Boqun Feng <boqun.feng@gmail.com>
> > 
> > This introduces `KSYM_NAME_LEN_BUFFER` in place of the previously
> > hardcoded size of the input buffer.
> > 
> > It will also make it easier to update the size in a single place
> > in a later patch.
> > 
> > Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> > Co-developed-by: Miguel Ojeda <ojeda@kernel.org>
> > Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> 
> Reviewed-by: Kees Cook <keescook@chromium.org>
> 
> Does someone want to commit to taking these "prereq" patches? These
> clean-ups are nice even without adding Rust.

Qouting Message-ID: <CANiq72mXDne_WkUCo2oRe+sip7nQWESnouOJrcCYzyJMkG8F6A@mail.gmail.com>
https://lore.kernel.org/lkml/CANiq72mXDne_WkUCo2oRe+sip7nQWESnouOJrcCYzyJMkG8F6A@mail.gmail.com/
Miguel Ojeda, 2022-08-05: 
| > And I think that this patch and all other "rust" kallsyms patches
| > allready should have been accepted in the v3 or v5 series.
| 
| Yeah, it could be a good idea to get the prerequisites in first.
| Let's see if the patches get some Reviewed-bys

Now that there is a 'Reviewed-by: Kees Cook <keescook@chromium.org>'


Regards
Geert Stappers
In an attempt to help making Rust for Linux happen.
-- 
Silence is hard to parse

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 06/27] rust: add C helpers
  2022-08-18 16:08               ` Kees Cook
@ 2022-08-18 17:01                 ` Miguel Ojeda
  0 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-18 17:01 UTC (permalink / raw)
  To: Kees Cook
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Geoffrey Thomas, Wedson Almeida Filho,
	Sven Van Asbroeck, Gary Guo, Boqun Feng, Maciej Falkowski,
	Wei Liu, Björn Roy Baron

On Thu, Aug 18, 2022 at 6:08 PM Kees Cook <keescook@chromium.org> wrote:
>
> Please, no UB. I will take a panic over UB any day. It'd be best to
> handle things with some error path, but those are the rare exception.
>
> C is riddled with UB and it's just terrible. Let's make sure we don't
> continue that mistake. :)

I definitely agree on avoiding UB :)

> The simple answer is that if an "impossible" situation can be recovered
> from, it should error instead of panic. As long as that's the explicit
> design goal, I think we're good. Yes there will be cases where it is
> really and truly unrecoverable, but those will be rare and can be well
> documented.

Yeah, that is the goal and we always take that into account, but there
are always tricky cases which is best to consider case-by-case.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 20/27] scripts: add `rust_is_available.sh`
  2022-08-05 15:42 ` [PATCH v9 20/27] scripts: add `rust_is_available.sh` Miguel Ojeda
  2022-08-17 20:18   ` Kees Cook
@ 2022-08-22 20:09   ` Nick Desaulniers
  2022-08-23 12:12     ` Miguel Ojeda
  1 sibling, 1 reply; 102+ messages in thread
From: Nick Desaulniers @ 2022-08-22 20:09 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho, Finn Behrens, Miguel Cano, Tiago Lam,
	Boqun Feng, Gary Guo, Björn Roy Baron

On Fri, Aug 5, 2022 at 8:46 AM Miguel Ojeda <ojeda@kernel.org> wrote:
>
> This script tests whether the Rust toolchain requirements are in place
> to enable Rust support.

With this, I get:

$ make LLVM=1 rustavailable
***
*** libclang (used by the Rust bindings generator 'bindgen')
*** version does not match Clang's. This may be a problem.
***   libclang version: 15.0.0
***   Clang version:    16.0.0
***
Rust is available!

because I'm using clang built from source from ToT.  Is this supposed
to mean that I can't use clang-16, clang-14, clang-13, clang-12, or
clang-11 (in the kernel we support clang-11+) in order to use rust?
I'm guessing that's going to hinder adoption.  Is there a way to
specify which libclang version bindgen should be using?

I have libclang built in my clang sources,
llvm-project/llvm/build/lib/libclang.so.  I also tried:

$ CLANG_PATH=/android0/llvm-project/llvm/build/lib/libclang.so.15 make
LLVM=1 -j72 rustavailable
$ CLANG_PATH=/android0/llvm-project/llvm/build/lib/libclang.so make
LLVM=1 -j72 rustavailable

-- 
Thanks,
~Nick Desaulniers

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 23/27] Kbuild: add Rust support
  2022-08-05 15:42 ` [PATCH v9 23/27] Kbuild: add Rust support Miguel Ojeda
  2022-08-17 20:26   ` Kees Cook
@ 2022-08-22 22:35   ` Nick Desaulniers
  2022-09-12 16:07   ` Masahiro Yamada
  2 siblings, 0 replies; 102+ messages in thread
From: Nick Desaulniers @ 2022-08-22 22:35 UTC (permalink / raw)
  To: Miguel Ojeda, Linus Torvalds, Masahiro Yamada
  Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-fsdevel,
	patches, Jarkko Sakkinen, Alex Gaynor, Finn Behrens,
	Adam Bratschi-Kaye, Wedson Almeida Filho, Michael Ellerman,
	Sven Van Asbroeck, Gary Guo, Boris-Chengbiao Zhou, Boqun Feng,
	Douglas Su, Dariusz Sosnowski, Antonio Terceiro, Daniel Xu,
	Björn Roy Baron, Martin Rodriguez Reboredo, Michal Marek,
	linux-kbuild

 On Fri, Aug 5, 2022 at 8:44 AM Miguel Ojeda <ojeda@kernel.org> wrote:
>
> Having most of the new files in place, we now enable Rust support
> in the build system, including `Kconfig` entries related to Rust,
> the Rust configuration printer and a few other bits.

Cool, I'm finally happy with this patch.

Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>

I built and boot tested with CONFIG_RUST enabled, played with
CLIPPY=1, and built all of the new make targets for rust.

Thanks for all of the work that went into these series from all of the
authors and Miguel for your determination. Keep it up!

I've left comments on other patches (and I will leave one on
rust/compiler_builtins.rs because I still don't like that approach)
and there may be small cleanups we can do here or there, but I think
we're in good shape to land something and start iterating on it
upstream.  I'll file bugs in your issue tracker for small nits I come
across, but so far, it's been more-so questions.

---

LWN recently demonstrated that most fixes are in relatively younger
code: https://lwn.net/Articles/902854/

An analysis of 0day exploits found in the wild in 2021 showed that for
Android, researchers are attacking drivers:
https://googleprojectzero.blogspot.com/2022/04/the-more-you-know-more-you-know-you.html

Multiple independent reports cite high numbers (70% or more) of memory
safety issues in native code:
https://www.memorysafety.org/docs/memory-safety/

I have colleagues that are developing a microkernel (they then use a
memory unsafe language for their kernel as well :^P ) to move as much
functionality as possible into lower levels of privilege.  It's
interesting and I wish them well, but I also prefer more incremental
approaches to existing solutions, and suspect the way of the monolith
to still give us the best performance.

I learned an interesting word the other day: Corten Steel
from the YouTube channel Practical Engineering (it's a great channel
on Civil Engineering):
https://www.youtube.com/watch?v=2RbiCOFffRs&t=523s
transcript:

>> I should also note that there are even steel alloys whose rust is protective! Weathering steel (sometimes known by its trade name of Corten Steel) is a group of alloys that are naturally resilient against rust because of passivation. A special blend of elements, including manganese, nickel, silicon, and chromium don’t keep the steel from rusting, but they allow the layer of rust to stay attached, forming a protective layer that significantly slows corrosion.

My hope is that Rust may provide a layer of Corten Steel to the Linux
kernel to help us protect newly written driver code from memory safety
related issues, so that Linux remains the best option for developing
products for the next 30 years. I also suspect it may bring in a whole
new generation of hackers to the kernel ecosystem.  That is my
blessing for Rust in the Linux kernel.
--
Thanks,
~Nick Desaulniers

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 09/27] rust: add `compiler_builtins` crate
  2022-08-05 15:41 ` [PATCH v9 09/27] rust: add `compiler_builtins` crate Miguel Ojeda
  2022-08-17 20:08   ` Kees Cook
@ 2022-08-22 23:55   ` Nick Desaulniers
  2022-08-24 18:38     ` Nick Desaulniers
  1 sibling, 1 reply; 102+ messages in thread
From: Nick Desaulniers @ 2022-08-22 23:55 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho, Sven Van Asbroeck, Gary Guo, Boqun Feng,
	Björn Roy Baron, Masahiro Yamada

On Fri, Aug 5, 2022 at 8:44 AM Miguel Ojeda <ojeda@kernel.org> wrote:
>
> Rust provides `compiler_builtins` as a port of LLVM's `compiler-rt`.
> Since we do not need the vast majority of them, we avoid the
> dependency by providing our own crate.
>
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
> Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
> Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
> Co-developed-by: Gary Guo <gary@garyguo.net>
> Signed-off-by: Gary Guo <gary@garyguo.net>
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

I still really really do not like this patch. Thoughts below.

> ---
>  rust/compiler_builtins.rs | 63 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 63 insertions(+)
>  create mode 100644 rust/compiler_builtins.rs
>
> diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs
> new file mode 100644
> index 000000000000..f8f39a3e6855
> --- /dev/null
> +++ b/rust/compiler_builtins.rs
> @@ -0,0 +1,63 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Our own `compiler_builtins`.
> +//!
> +//! Rust provides [`compiler_builtins`] as a port of LLVM's [`compiler-rt`].
> +//! Since we do not need the vast majority of them, we avoid the dependency
> +//! by providing this file.
> +//!
> +//! At the moment, some builtins are required that should not be. For instance,
> +//! [`core`] has 128-bit integers functionality which we should not be compiling

It's not just 128b, these are for double word sizes, so for 32b
targets (I recall an earlier version of series supporting armv6) these
symbols are for 64b types.

> +//! in. We will work with upstream [`core`] to provide feature flags to disable
> +//! the parts we do not need. For the moment, we define them to [`panic!`] at

Where is the bug filed upstream (or in your issue tracker)?

> +//! runtime for simplicity to catch mistakes, instead of performing surgery
> +//! on `core.o`.

Wait, so Kbuild performs surgery on alloc, but core is off limits? bah

Core is huge!
$ du -h rust/core.o
1.3M    rust/core.o

> +//!
> +//! In any case, all these symbols are weakened to ensure we do not override
> +//! those that may be provided by the rest of the kernel.
> +//!
> +//! [`compiler_builtins`]: https://github.com/rust-lang/compiler-builtins
> +//! [`compiler-rt`]: https://compiler-rt.llvm.org/
> +
> +#![feature(compiler_builtins)]
> +#![compiler_builtins]
> +#![no_builtins]
> +#![no_std]
> +
> +macro_rules! define_panicking_intrinsics(
> +    ($reason: tt, { $($ident: ident, )* }) => {
> +        $(
> +            #[doc(hidden)]
> +            #[no_mangle]
> +            pub extern "C" fn $ident() {
> +                panic!($reason);
> +            }
> +        )*
> +    }
> +);
> +
> +define_panicking_intrinsics!("`f32` should not be used", {
> +    __eqsf2,

I don't see ^ this symbol in core.

$ llvm-nm rust/core.o | grep "U __" | sort | tr -s " "
 U __gesf2
 U __lesf2
 U __udivti3
 U __umodti3
 U __unorddf2
 U __unordsf2
 U __x86_indirect_thunk_r11

so a few of these seem extraneous. Are you sure they're coming from
core? (or was it the different arch support that was removed from v8
to facilitate v9?)

__gesf2, __lesf2, and __unordsf2 all seem to be coming from
<<f32>::classify> and <<f32>::to_bits::ct_f32_to_u32>.  Surely we can
avoid more f32 support by relying on objcopy
-N/--strip-symbol=/--strip-symbols=filename to slice out/drop symbols
from core.o?

<core::fmt::num::exp_u128> uses __umodti3+__udivti3

__unorddf2 is referenced by <<f64>::classify> and
<<f64>::to_bits::ct_f64_to_u64>.

Can we slice those 5 symbols out from core, or are they further
referenced from within core?  If we can, we can drop this patch
outright, and avoid a false-negative when C code generates references
to these symbols from the compiler runtime, for architectures where
don't want to provide a full compiler runtime.  (--rtlib=none is a
pipe dream; first we need to get to the point where we're not
-ffreestanding for all targets...)

I suspect someone can iteratively whittle down core to avoid these symbols?

```
diff --git a/rust/Makefile b/rust/Makefile
index 7700d3853404..e64a82c21156 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -359,6 +359,7 @@ $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs
$(obj)/target.json FORCE
 $(obj)/compiler_builtins.o: private rustc_objcopy = -w -W '__*'
 $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE
        $(call if_changed_dep,rustc_library)
+       @$(OBJCOPY) --strip-symbols=$(obj)/strip-symbols.txt $(obj)/core.o

 $(obj)/alloc.o: private skip_clippy = 1
 $(obj)/alloc.o: private skip_flags = -Dunreachable_pub
```
then define symbols in rust/strip-symbols.txt?

I'm getting the sense that no, there are many functions like
<usize as core::fmt::UpperExp>::fmt
<i64 as core::fmt::UpperExp>::fmt
<u64 as core::fmt::UpperExp>::fmt

that call many of these functions...so if you call format! on an
i64/u64/usize you'll potentially panic the kernel? Seems kinda
dangerous.

I'm also seeing disassemblers having trouble completely disassembling
core.o ... the more I look to see who's calling what, the more
instances I find...

> +    __gesf2,
> +    __lesf2,
> +    __nesf2,
> +    __unordsf2,
> +});
> +
> +define_panicking_intrinsics!("`f64` should not be used", {
> +    __unorddf2,
> +});
> +
> +define_panicking_intrinsics!("`i128` should not be used", {
> +    __ashrti3,
> +    __muloti4,
> +    __multi3,
> +});
> +
> +define_panicking_intrinsics!("`u128` should not be used", {
> +    __ashlti3,
> +    __lshrti3,
> +    __udivmodti4,
> +    __udivti3,
> +    __umodti3,
> +});
> --
> 2.37.1
>


-- 
Thanks,
~Nick Desaulniers

^ permalink raw reply related	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 20/27] scripts: add `rust_is_available.sh`
  2022-08-22 20:09   ` Nick Desaulniers
@ 2022-08-23 12:12     ` Miguel Ojeda
  2022-08-23 12:16       ` Miguel Ojeda
  0 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-23 12:12 UTC (permalink / raw)
  To: Nick Desaulniers
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Wedson Almeida Filho, Finn Behrens, Miguel Cano,
	Tiago Lam, Boqun Feng, Gary Guo, Björn Roy Baron

On Mon, Aug 22, 2022 at 10:09 PM Nick Desaulniers
<ndesaulniers@google.com> wrote:
>
> because I'm using clang built from source from ToT.  Is this supposed
> to mean that I can't use clang-16, clang-14, clang-13, clang-12, or
> clang-11 (in the kernel we support clang-11+) in order to use rust?
> I'm guessing that's going to hinder adoption.  Is there a way to

No, it is only a warning, so you can proceed if you want to risk it.

However, is there a reason you would like to mix the versions?

If not, please point `bindgen` to your newer libclang (see below).

> specify which libclang version bindgen should be using?

Yes, see below.

> I have libclang built in my clang sources,
> llvm-project/llvm/build/lib/libclang.so.  I also tried:
>
> $ CLANG_PATH=/android0/llvm-project/llvm/build/lib/libclang.so.15 make
> LLVM=1 -j72 rustavailable

`CLANG_PATH` is for pointing to a `clang` executable, not `libclang`.

Instead, please try `LIBCLANG_PATH` (note the `LIB` there).

For instance, using the test header to print the libclang version,
this works for me:

    $ bindgen scripts/rust_is_available_bindgen_libclang.h
    ... clang version 14.0.6 (https://github.com/llvm/llvm-project.git ...

    $ LIBCLANG_PATH=.../libclang-6.0.so.1 \
      bindgen scripts/rust_is_available_bindgen_libclang.h
    ... clang version 6.0.0 (tags/RELEASE_600/final) ...

If the above does not work, for details on how the dependency is
resolved, please see:

    https://github.com/KyleMayes/clang-sys#linking
    https://github.com/KyleMayes/clang-sys#dependencies
    https://github.com/KyleMayes/clang-sys#environment-variables
    https://github.com/rust-lang/rust-bindgen#environment-variables

I will add a note about this to the docs.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 20/27] scripts: add `rust_is_available.sh`
  2022-08-23 12:12     ` Miguel Ojeda
@ 2022-08-23 12:16       ` Miguel Ojeda
  0 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-08-23 12:16 UTC (permalink / raw)
  To: Nick Desaulniers
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Wedson Almeida Filho, Finn Behrens, Miguel Cano,
	Tiago Lam, Boqun Feng, Gary Guo, Björn Roy Baron

On Tue, Aug 23, 2022 at 2:12 PM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> For instance, using the test header to print the libclang version,
> this works for me:
>
>     $ bindgen scripts/rust_is_available_bindgen_libclang.h
>     ... clang version 14.0.6 (https://github.com/llvm/llvm-project.git ...
>
>     $ LIBCLANG_PATH=.../libclang-6.0.so.1 \
>       bindgen scripts/rust_is_available_bindgen_libclang.h
>     ... clang version 6.0.0 (tags/RELEASE_600/final) ...

By the way, a while ago I requested an easier way to check the
libclang version directly from bindgen, and Emilio quickly added it
(thanks a lot!): since `bindgen` 0.60.0 you can do:

    $ bindgen --version --verbose
    bindgen 0.60.0
    Clang: clang version 14.0.6 (https://github.com/llvm/ ...

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 09/27] rust: add `compiler_builtins` crate
  2022-08-22 23:55   ` Nick Desaulniers
@ 2022-08-24 18:38     ` Nick Desaulniers
  2022-08-29 17:11       ` Gary Guo
  0 siblings, 1 reply; 102+ messages in thread
From: Nick Desaulniers @ 2022-08-24 18:38 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux, linux-kernel,
	linux-fsdevel, patches, Jarkko Sakkinen, Alex Gaynor,
	Wedson Almeida Filho, Sven Van Asbroeck, Gary Guo, Boqun Feng,
	Björn Roy Baron, Masahiro Yamada, Ard Biesheuvel

On Mon, Aug 22, 2022 at 4:55 PM Nick Desaulniers
<ndesaulniers@google.com> wrote:
>
> On Fri, Aug 5, 2022 at 8:44 AM Miguel Ojeda <ojeda@kernel.org> wrote:
> >
> > Rust provides `compiler_builtins` as a port of LLVM's `compiler-rt`.
> > Since we do not need the vast majority of them, we avoid the
> > dependency by providing our own crate.
> >
> > Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> > Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
> > Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
> > Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
> > Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
> > Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
> > Co-developed-by: Gary Guo <gary@garyguo.net>
> > Signed-off-by: Gary Guo <gary@garyguo.net>
> > Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
>
> I still really really do not like this patch. Thoughts below.
>
> > ---
> >  rust/compiler_builtins.rs | 63 +++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 63 insertions(+)
> >  create mode 100644 rust/compiler_builtins.rs
> >
> > diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs
> > new file mode 100644
> > index 000000000000..f8f39a3e6855
> > --- /dev/null
> > +++ b/rust/compiler_builtins.rs
> > @@ -0,0 +1,63 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +//! Our own `compiler_builtins`.
> > +//!
> > +//! Rust provides [`compiler_builtins`] as a port of LLVM's [`compiler-rt`].
> > +//! Since we do not need the vast majority of them, we avoid the dependency
> > +//! by providing this file.
> > +//!
> > +//! At the moment, some builtins are required that should not be. For instance,
> > +//! [`core`] has 128-bit integers functionality which we should not be compiling
>
> It's not just 128b, these are for double word sizes, so for 32b
> targets (I recall an earlier version of series supporting armv6) these
> symbols are for 64b types.
>
> > +//! in. We will work with upstream [`core`] to provide feature flags to disable
> > +//! the parts we do not need. For the moment, we define them to [`panic!`] at
> > +//! runtime for simplicity to catch mistakes, instead of performing surgery
> > +//! on `core.o`.
>
> Wait, so Kbuild performs surgery on alloc, but core is off limits? bah
>
> > +//!
> > +//! In any case, all these symbols are weakened to ensure we do not override
> > +//! those that may be provided by the rest of the kernel.
> > +//!
> > +//! [`compiler_builtins`]: https://github.com/rust-lang/compiler-builtins
> > +//! [`compiler-rt`]: https://compiler-rt.llvm.org/
> > +
> > +#![feature(compiler_builtins)]
> > +#![compiler_builtins]
> > +#![no_builtins]
> > +#![no_std]
> > +
> > +macro_rules! define_panicking_intrinsics(
> > +    ($reason: tt, { $($ident: ident, )* }) => {
> > +        $(
> > +            #[doc(hidden)]
> > +            #[no_mangle]
> > +            pub extern "C" fn $ident() {
> > +                panic!($reason);
> > +            }
> > +        )*
> > +    }
> > +);
> > +
> > +define_panicking_intrinsics!("`f32` should not be used", {
> > +    __eqsf2,
>
> I don't see ^ this symbol in core.
>
> $ llvm-nm rust/core.o | grep "U __" | sort | tr -s " "
>  U __gesf2
>  U __lesf2
>  U __udivti3
>  U __umodti3
>  U __unorddf2
>  U __unordsf2
>  U __x86_indirect_thunk_r11
>
> so a few of these seem extraneous. Are you sure they're coming from
> core? (or was it the different arch support that was removed from v8
> to facilitate v9?)
>
> __gesf2, __lesf2, and __unordsf2 all seem to be coming from
> <<f32>::classify> and <<f32>::to_bits::ct_f32_to_u32>.  Surely we can
> avoid more f32 support by relying on objcopy
> -N/--strip-symbol=/--strip-symbols=filename to slice out/drop symbols
> from core.o?
>
> <core::fmt::num::exp_u128> uses __umodti3+__udivti3
>
> __unorddf2 is referenced by <<f64>::classify> and
> <<f64>::to_bits::ct_f64_to_u64>.
>
> Can we slice those 5 symbols out from core, or are they further
> referenced from within core?  If we can, we can drop this patch
> outright, and avoid a false-negative when C code generates references
> to these symbols from the compiler runtime, for architectures where
> don't want to provide a full compiler runtime.  (--rtlib=none is a
> pipe dream; first we need to get to the point where we're not
> -ffreestanding for all targets...)
>
> I suspect someone can iteratively whittle down core to avoid these symbols?
>
> ```
> diff --git a/rust/Makefile b/rust/Makefile
> index 7700d3853404..e64a82c21156 100644
> --- a/rust/Makefile
> +++ b/rust/Makefile
> @@ -359,6 +359,7 @@ $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs
> $(obj)/target.json FORCE
>  $(obj)/compiler_builtins.o: private rustc_objcopy = -w -W '__*'
>  $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE
>         $(call if_changed_dep,rustc_library)
> +       @$(OBJCOPY) --strip-symbols=$(obj)/strip-symbols.txt $(obj)/core.o
>
>  $(obj)/alloc.o: private skip_clippy = 1
>  $(obj)/alloc.o: private skip_flags = -Dunreachable_pub
> ```
> then define symbols in rust/strip-symbols.txt?
>
> I'm getting the sense that no, there are many functions like
> <usize as core::fmt::UpperExp>::fmt
> <i64 as core::fmt::UpperExp>::fmt
> <u64 as core::fmt::UpperExp>::fmt

Another idea I had, and Ard mentioned to me this morning that efistub
does something similar:

I think objcopy can rename symbol references.  So instead of calling
foo, I think you can use objcopy to call bar instead.

To avoid the case of Rust core refering to symbols typically provided
by the --rtlib={libgcc|compiler-rt}, what if we:
1. build core.o (with reference to the unfavorable symbols)
2. use objcopy to rename references in core.o to the symbols listed in
this file; maybe prepend them with `rust_core_` or something.
3. provide this crate with panic'ing definitions, but for the renamed symbols.

That way, enabling CONFIG_RUST=y won't hide the case where C code is
triggering such libcalls from the C compiler?

To restate the concern, I don't want CONFIG_RUST=y to hide that fact
that someone wrote `float x, y; if (x != y) ...` in C code, where the
C compiler will likely lower that to a libcall to __nesf2 since with
the current approach in this patch, linkage would proceed. The current
behavior is to intentionally fail to link.  I think what I describe
above may work to keep this intended behavior of the kernel's build
system.

Ah, looks like there's objcopy flags:
       --redefine-sym old=new
           Change the name of a symbol old, to new.  This can be
useful when one is trying link
           two things together for which you have no source, and there
are name collisions.

       --redefine-syms=filename
           Apply --redefine-sym to each symbol pair "old new" listed
in the file filename.
           filename is simply a flat file, with one symbol pair per
line.  Line comments may be
           introduced by the hash character.  This option may be given
more than once.

So probably could start with my diff from above, but use
--redefine-syms=filename instead of --strip-symbols=.


>
> > +    __gesf2,
> > +    __lesf2,
> > +    __nesf2,
> > +    __unordsf2,
> > +});
> > +
> > +define_panicking_intrinsics!("`f64` should not be used", {
> > +    __unorddf2,
> > +});
> > +
> > +define_panicking_intrinsics!("`i128` should not be used", {
> > +    __ashrti3,
> > +    __muloti4,
> > +    __multi3,
> > +});
> > +
> > +define_panicking_intrinsics!("`u128` should not be used", {
> > +    __ashlti3,
> > +    __lshrti3,
> > +    __udivmodti4,
> > +    __udivti3,
> > +    __umodti3,
> > +});
> > --
> > 2.37.1
> >
>
>
> --
> Thanks,
> ~Nick Desaulniers



--
Thanks,
~Nick Desaulniers

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 09/27] rust: add `compiler_builtins` crate
  2022-08-24 18:38     ` Nick Desaulniers
@ 2022-08-29 17:11       ` Gary Guo
  0 siblings, 0 replies; 102+ messages in thread
From: Gary Guo @ 2022-08-29 17:11 UTC (permalink / raw)
  To: Nick Desaulniers
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	linux-kernel, linux-fsdevel, patches, Jarkko Sakkinen,
	Alex Gaynor, Wedson Almeida Filho, Sven Van Asbroeck, Boqun Feng,
	Björn Roy Baron, Masahiro Yamada, Ard Biesheuvel

On Wed, 24 Aug 2022 11:38:46 -0700
Nick Desaulniers <ndesaulniers@google.com> wrote:

> Another idea I had, and Ard mentioned to me this morning that efistub
> does something similar:
> 
> I think objcopy can rename symbol references.  So instead of calling
> foo, I think you can use objcopy to call bar instead.
> 
> To avoid the case of Rust core refering to symbols typically provided
> by the --rtlib={libgcc|compiler-rt}, what if we:
> 1. build core.o (with reference to the unfavorable symbols)
> 2. use objcopy to rename references in core.o to the symbols listed in
> this file; maybe prepend them with `rust_core_` or something.
> 3. provide this crate with panic'ing definitions, but for the renamed
> symbols.
> 
> That way, enabling CONFIG_RUST=y won't hide the case where C code is
> triggering such libcalls from the C compiler?
> 
> To restate the concern, I don't want CONFIG_RUST=y to hide that fact
> that someone wrote `float x, y; if (x != y) ...` in C code, where the
> C compiler will likely lower that to a libcall to __nesf2 since with
> the current approach in this patch, linkage would proceed. The current
> behavior is to intentionally fail to link.  I think what I describe
> above may work to keep this intended behavior of the kernel's build
> system.
> 
> Ah, looks like there's objcopy flags:
>        --redefine-sym old=new
>            Change the name of a symbol old, to new.  This can be
> useful when one is trying link
>            two things together for which you have no source, and there
> are name collisions.
> 
>        --redefine-syms=filename
>            Apply --redefine-sym to each symbol pair "old new" listed
> in the file filename.
>            filename is simply a flat file, with one symbol pair per
> line.  Line comments may be
>            introduced by the hash character.  This option may be given
> more than once.
> 
> So probably could start with my diff from above, but use
> --redefine-syms=filename instead of --strip-symbols=.
> 
> --
> Thanks,
> ~Nick Desaulniers

This is the approach we are about to take, see
https://github.com/Rust-for-Linux/linux/pull/779.

It's easy for just one symbol that is known to be not defined, but it
can be more complex as some of these symbols can be defined on a
platform but not another, so we would have to generate a dynamic list
of what symbols to "hijack" depending on the config. Currently we
avoid this issue by having all symbols in compiler_builtins
crate weak, but we couldn't weakly redefine a symbol.

It's certainly doable, though, but it require some effort. I am
not quite available recently so hadn't further extend and polish my
patch.

Best,
Gary

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 23/27] Kbuild: add Rust support
  2022-08-05 15:42 ` [PATCH v9 23/27] Kbuild: add Rust support Miguel Ojeda
  2022-08-17 20:26   ` Kees Cook
  2022-08-22 22:35   ` Nick Desaulniers
@ 2022-09-12 16:07   ` Masahiro Yamada
  2022-09-12 16:18     ` Miguel Ojeda
  2 siblings, 1 reply; 102+ messages in thread
From: Masahiro Yamada @ 2022-09-12 16:07 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	Linux Kernel Mailing List, Linux FS-devel Mailing List, patches,
	Jarkko Sakkinen, Alex Gaynor, Finn Behrens, Adam Bratschi-Kaye,
	Wedson Almeida Filho, Michael Ellerman, Sven Van Asbroeck,
	Gary Guo, Boris-Chengbiao Zhou, Boqun Feng, Douglas Su,
	Dariusz Sosnowski, Antonio Terceiro, Daniel Xu,
	Björn Roy Baron, Martin Rodriguez Reboredo, Michal Marek,
	Nick Desaulniers, Linux Kbuild mailing list

On Sat, Aug 6, 2022 at 12:44 AM Miguel Ojeda <ojeda@kernel.org> wrote:
>
> Having most of the new files in place, we now enable Rust support
> in the build system, including `Kconfig` entries related to Rust,
> the Rust configuration printer and a few other bits.
>
> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
> Co-developed-by: Finn Behrens <me@kloenk.de>
> Signed-off-by: Finn Behrens <me@kloenk.de>
> Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com>
> Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com>
> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
> Co-developed-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
> Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
> Co-developed-by: Gary Guo <gary@garyguo.net>
> Signed-off-by: Gary Guo <gary@garyguo.net>
> Co-developed-by: Boris-Chengbiao Zhou <bobo1239@web.de>
> Signed-off-by: Boris-Chengbiao Zhou <bobo1239@web.de>
> Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> Co-developed-by: Douglas Su <d0u9.su@outlook.com>
> Signed-off-by: Douglas Su <d0u9.su@outlook.com>
> Co-developed-by: Dariusz Sosnowski <dsosnowski@dsosnowski.pl>
> Signed-off-by: Dariusz Sosnowski <dsosnowski@dsosnowski.pl>
> Co-developed-by: Antonio Terceiro <antonio.terceiro@linaro.org>
> Signed-off-by: Antonio Terceiro <antonio.terceiro@linaro.org>
> Co-developed-by: Daniel Xu <dxu@dxuuu.xyz>
> Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
> Co-developed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
> Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
> Co-developed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
> Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> ---
>  .gitignore                     |   2 +
>  Makefile                       | 172 ++++++++++++++-
>  arch/Kconfig                   |   6 +
>  include/linux/compiler_types.h |   6 +-
>  init/Kconfig                   |  46 +++-
>  kernel/configs/rust.config     |   1 +
>  lib/Kconfig.debug              |  34 +++
>  rust/.gitignore                |   8 +
>  rust/Makefile                  | 381 +++++++++++++++++++++++++++++++++
>  rust/bindgen_parameters        |  21 ++
>  scripts/Kconfig.include        |   6 +-
>  scripts/Makefile               |   3 +
>  scripts/Makefile.build         |  60 ++++++
>  scripts/Makefile.debug         |  10 +
>  scripts/Makefile.host          |  34 ++-
>  scripts/Makefile.lib           |  12 ++
>  scripts/Makefile.modfinal      |   8 +-
>  scripts/cc-version.sh          |  12 +-
>  scripts/kconfig/confdata.c     |  75 +++++++
>  scripts/min-tool-version.sh    |   6 +
>  20 files changed, 877 insertions(+), 26 deletions(-)
>  create mode 100644 kernel/configs/rust.config
>  create mode 100644 rust/.gitignore
>  create mode 100644 rust/Makefile
>  create mode 100644 rust/bindgen_parameters
>
> diff --git a/.gitignore b/.gitignore
> index 97e085d613a2..5da004814678 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -37,6 +37,8 @@
>  *.o
>  *.o.*
>  *.patch
> +*.rmeta
> +*.rsi
>  *.s
>  *.so
>  *.so.dbg
> diff --git a/Makefile b/Makefile
> index df92892325ae..a105cb893b4c 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -120,6 +120,15 @@ endif
>
>  export KBUILD_CHECKSRC
>
> +# Enable "clippy" (a linter) as part of the Rust compilation.
> +#
> +# Use 'make CLIPPY=1' to enable it.
> +ifeq ("$(origin CLIPPY)", "command line")
> +  KBUILD_CLIPPY := $(CLIPPY)
> +endif
> +
> +export KBUILD_CLIPPY
> +
>  # Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the
>  # directory of external module to build. Setting M= takes precedence.
>  ifeq ("$(origin M)", "command line")
> @@ -267,14 +276,14 @@ no-dot-config-targets := $(clean-targets) \
>                          cscope gtags TAGS tags help% %docs check% coccicheck \
>                          $(version_h) headers headers_% archheaders archscripts \
>                          %asm-generic kernelversion %src-pkg dt_binding_check \
> -                        outputmakefile
> +                        outputmakefile rustavailable rustfmt rustfmtcheck
>  # Installation targets should not require compiler. Unfortunately, vdso_install
>  # is an exception where build artifacts may be updated. This must be fixed.
>  no-compiler-targets := $(no-dot-config-targets) install dtbs_install \
>                         headers_install modules_install kernelrelease image_name
>  no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease \
>                           image_name
> -single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/
> +single-targets := %.a %.i %.rsi %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/
>
>  config-build   :=
>  mixed-build    :=
> @@ -436,6 +445,7 @@ else
>  HOSTCC = gcc
>  HOSTCXX        = g++
>  endif
> +HOSTRUSTC = rustc
>  HOSTPKG_CONFIG = pkg-config
>
>  KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \
> @@ -444,8 +454,26 @@ KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \
>  KBUILD_USERCFLAGS  := $(KBUILD_USERHOSTCFLAGS) $(USERCFLAGS)
>  KBUILD_USERLDFLAGS := $(USERLDFLAGS)
>
> +# These flags apply to all Rust code in the tree, including the kernel and
> +# host programs.
> +export rust_common_flags := --edition=2021 \
> +                           -Zbinary_dep_depinfo=y \




Let me ask a question about the host_rust rule.



If I directly run the build command from the command line,
I get an error, like follows:


$ rustc --edition=2021 -Zbinary_dep_depinfo=y -Dunsafe_op_in_unsafe_fn
-Drust_2018_idioms -Dunreachable_pub -Dnon_ascii_idents -Wmissing_docs
-Drustdoc::missing_crate_level_docs -Dclippy::correctness
-Dclippy::style -Dclippy::suspicious -Dclippy::complexity
-Dclippy::perf -Dclippy::let_unit_value -Dclippy::mut_mut
-Dclippy::needless_bitwise_bool -Dclippy::needless_continue
-Wclippy::dbg_macro -O -Cstrip=debuginfo -Zallow-features=
--emit=dep-info,link --out-dir=scripts/
../scripts/generate_rust_target.rs
error: the option `Z` is only accepted on the nightly compiler



This is the same command recorded as in
scripts/.generate_rust_target.cmd



Why no error when it is invoked from Makefile?


I have not figured out where this difference comes from.








-- 
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 23/27] Kbuild: add Rust support
  2022-09-12 16:07   ` Masahiro Yamada
@ 2022-09-12 16:18     ` Miguel Ojeda
  2022-09-13  6:37       ` Masahiro Yamada
  0 siblings, 1 reply; 102+ messages in thread
From: Miguel Ojeda @ 2022-09-12 16:18 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	Linux Kernel Mailing List, Linux FS-devel Mailing List, patches,
	Jarkko Sakkinen, Alex Gaynor, Finn Behrens, Adam Bratschi-Kaye,
	Wedson Almeida Filho, Michael Ellerman, Sven Van Asbroeck,
	Gary Guo, Boris-Chengbiao Zhou, Boqun Feng, Douglas Su,
	Dariusz Sosnowski, Antonio Terceiro, Daniel Xu,
	Björn Roy Baron, Martin Rodriguez Reboredo, Michal Marek,
	Nick Desaulniers, Linux Kbuild mailing list

Hi Masahiro,

On Mon, Sep 12, 2022 at 5:08 PM Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> I have not figured out where this difference comes from.

It is the `RUSTC_BOOTSTRAP` environment variable: it allows to use
unstable featuers in the stable compiler.

We currently set it in the global `Makefile`, but we could be more
explicit and do it on each command if you think that would be better.

If you want that we keep using the global export, then we can add a
comment explaining this to clarify.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 23/27] Kbuild: add Rust support
  2022-09-12 16:18     ` Miguel Ojeda
@ 2022-09-13  6:37       ` Masahiro Yamada
  0 siblings, 0 replies; 102+ messages in thread
From: Masahiro Yamada @ 2022-09-13  6:37 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Miguel Ojeda, Linus Torvalds, Greg Kroah-Hartman, rust-for-linux,
	Linux Kernel Mailing List, Linux FS-devel Mailing List, patches,
	Jarkko Sakkinen, Alex Gaynor, Finn Behrens, Adam Bratschi-Kaye,
	Wedson Almeida Filho, Michael Ellerman, Sven Van Asbroeck,
	Gary Guo, Boris-Chengbiao Zhou, Boqun Feng, Douglas Su,
	Dariusz Sosnowski, Antonio Terceiro, Daniel Xu,
	Björn Roy Baron, Martin Rodriguez Reboredo, Michal Marek,
	Nick Desaulniers, Linux Kbuild mailing list

On Tue, Sep 13, 2022 at 1:18 AM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> Hi Masahiro,
>
> On Mon, Sep 12, 2022 at 5:08 PM Masahiro Yamada <masahiroy@kernel.org> wrote:
> >
> > I have not figured out where this difference comes from.
>
> It is the `RUSTC_BOOTSTRAP` environment variable: it allows to use
> unstable featuers in the stable compiler.


Thanks, I learned a new thing.


>
> We currently set it in the global `Makefile`, but we could be more
> explicit and do it on each command if you think that would be better.


I checked "make compile_commands.json", but it collects build commands
only for C.


I did not see any bad scenario with the current approach.








>
> If you want that we keep using the global export, then we can add a
> comment explaining this to clarify.
>
> Cheers,
> Miguel
--
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-08-06 14:57       ` Matthew Wilcox
@ 2022-09-19 14:07         ` Wedson Almeida Filho
  2022-09-19 16:09           ` Linus Torvalds
  0 siblings, 1 reply; 102+ messages in thread
From: Wedson Almeida Filho @ 2022-09-19 14:07 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Kees Cook, Miguel Ojeda, Konstantin Shelekhin, ojeda,
	alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, torvalds, viktor, Andreas Hindborg

On Sat, Aug 06, 2022 at 03:57:35PM +0100, Matthew Wilcox wrote:
> On Sat, Aug 06, 2022 at 01:22:52PM +0200, Miguel Ojeda wrote:
> > On Sat, Aug 6, 2022 at 12:25 PM Konstantin Shelekhin
> > <k.shelekhin@yadro.com> wrote:
> > >
> > > I sense possible problems here. It's common for a kernel code to pass
> > > flags during memory allocations.
> > 
> > Yes, of course. We will support this, but how exactly it will look
> > like, to what extent upstream Rust's `alloc` could support our use
> > cases, etc. has been on discussion for a long time.
> > 
> > For instance, see https://github.com/Rust-for-Linux/linux/pull/815 for
> > a potential extension trait approach with no allocator carried on the
> > type that Andreas wrote after a discussion in the last informal call:
> > 
> >     let a = Box::try_new_atomic(101)?;
> 
> Something I've been wondering about for a while is ...
> 
> struct task_struct {
> ...
> +	gfp_t gfp_flags;
> ...
> };

For GFP_ATOMIC, we could use preempt_count except that it isn't always
enabled. Conveniently, it is already separated out into its own config.
How do people feel about removing CONFIG_PREEMPT_COUNT and having the
count always enabled?

We would then have a way to reliably detect when we are in atomic
context and we could catch other scenarios beyond allocation. For
example, I recently noticed that the following code (as a minimal
reproduction) does _not_ lead to a deadlock when CONFIG_PREEMPT=n:

rcu_read_lock();
synchronize_rcu();

Boqun explained to me that the reason is that synchronize_rcu() is not
supposed to be called from an rcu read-side critical section and the
current implementation takes advantage of this fact plus there is no way
to detect if we're in atomic context. This is all well and good, but if
one makes this mistake, the result is a potential user-after-free.
Always having preempt_count would allow us to behave differently here --
this is another conversation but at least we'll have to option to choose
what to do. (And it seems to me that detecting this and deadlocking or
BUG'ing would be preferable over the alternative [CC'ing Kees].)

Anyway, objections to a patch series that would amount to the changes
below?

Thanks,
-Wedson

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 90fbe4a3f9c8..c88c932dba5b 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -224,7 +224,6 @@ THUMB(	fpreg	.req	r7	)
 /*
  * Increment/decrement the preempt count.
  */
-#ifdef CONFIG_PREEMPT_COUNT
 	.macro	inc_preempt_count, ti, tmp
 	ldr	\tmp, [\ti, #TI_PREEMPT]	@ get preempt count
 	add	\tmp, \tmp, #1			@ increment it
@@ -241,16 +240,6 @@ THUMB(	fpreg	.req	r7	)
 	get_thread_info \ti
 	dec_preempt_count \ti, \tmp
 	.endm
-#else
-	.macro	inc_preempt_count, ti, tmp
-	.endm
-
-	.macro	dec_preempt_count, ti, tmp
-	.endm
-
-	.macro	dec_preempt_count_ti, ti, tmp
-	.endm
-#endif
 
 #define USERL(l, x...)				\
 9999:	x;					\
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index d2b4ac06e4ed..ecdeaa4d5190 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -95,9 +95,7 @@ ENTRY(iwmmxt_task_enable)
 	mov	r2, r2				@ cpwait
 	bl	concan_save
 
-#ifdef CONFIG_PREEMPT_COUNT
 	get_thread_info r10
-#endif
 4:	dec_preempt_count r10, r3
 	ret	r9				@ normal exit from exception
 
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 272fff587907..8ad94e13d0f0 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -832,7 +832,7 @@ ENTRY(debug_exception)
 	 * preemption if we have HW breakpoints to preserve DEBUGCAUSE.DBNUM
 	 * meaning.
 	 */
-#if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_HAVE_HW_BREAKPOINT)
+#if defined(CONFIG_HAVE_HW_BREAKPOINT)
 	GET_THREAD_INFO(a2, a1)
 	l32i	a3, a2, TI_PRE_COUNT
 	addi	a3, a3, 1
diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug
index 47e845353ffa..811f34dbb80b 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -22,7 +22,6 @@ config DRM_I915_DEBUG
 	depends on EXPERT # only for developers
 	depends on !COMPILE_TEST # never built by robots
 	select DEBUG_FS
-	select PREEMPT_COUNT
 	select I2C_CHARDEV
 	select STACKDEPOT
 	select DRM_DP_AUX_CHARDEV
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index c10d68cdc3ca..93686bdb9707 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -293,8 +293,7 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
 						   (Wmax))
 #define wait_for(COND, MS)		_wait_for((COND), (MS) * 1000, 10, 1000)
 
-/* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */
-#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT)
+#if defined(CONFIG_DRM_I915_DEBUG)
 # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) WARN_ON_ONCE((ATOMIC) && !in_atomic())
 #else
 # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) do { } while (0)
diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h
index bbc4730a6505..1e03d54b0b6f 100644
--- a/include/linux/bit_spinlock.h
+++ b/include/linux/bit_spinlock.h
@@ -90,10 +90,8 @@ static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
 {
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
 	return test_bit(bitnum, addr);
-#elif defined CONFIG_PREEMPT_COUNT
-	return preempt_count();
 #else
-	return 1;
+	return preempt_count();
 #endif
 }
 
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 1f1099dac3f0..a05e40dccb0a 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -600,16 +600,14 @@ do {									\
 
 #define lockdep_assert_preemption_enabled()				\
 do {									\
-	WARN_ON_ONCE(IS_ENABLED(CONFIG_PREEMPT_COUNT)	&&		\
-		     __lockdep_enabled			&&		\
+	WARN_ON_ONCE(__lockdep_enabled			&&		\
 		     (preempt_count() != 0		||		\
 		      !this_cpu_read(hardirqs_enabled)));		\
 } while (0)
 
 #define lockdep_assert_preemption_disabled()				\
 do {									\
-	WARN_ON_ONCE(IS_ENABLED(CONFIG_PREEMPT_COUNT)	&&		\
-		     __lockdep_enabled			&&		\
+	WARN_ON_ONCE(__lockdep_enabled			&&		\
 		     (preempt_count() == 0		&&		\
 		      this_cpu_read(hardirqs_enabled)));		\
 } while (0)
diff --git a/include/linux/page_ref.h b/include/linux/page_ref.h
index 2e677e6ad09f..4cddcb17489a 100644
--- a/include/linux/page_ref.h
+++ b/include/linux/page_ref.h
@@ -271,9 +271,7 @@ static inline bool folio_ref_try_add_rcu(struct folio *folio, int count)
 	 * context, so (on !SMP) we only need preemption to be disabled
 	 * and TINY_RCU does that for us.
 	 */
-# ifdef CONFIG_PREEMPT_COUNT
 	VM_BUG_ON(!in_atomic() && !irqs_disabled());
-# endif
 	VM_BUG_ON_FOLIO(folio_ref_count(folio) == 0, folio);
 	folio_ref_add(folio, count);
 #else
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index b4381f255a5c..77da73007375 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -56,8 +56,7 @@
 #define PREEMPT_DISABLED	(PREEMPT_DISABLE_OFFSET + PREEMPT_ENABLED)
 
 /*
- * Disable preemption until the scheduler is running -- use an unconditional
- * value so that it also works on !PREEMPT_COUNT kernels.
+ * Disable preemption until the scheduler is running.
  *
  * Reset by start_kernel()->sched_init()->init_idle()->init_idle_preempt_count().
  */
@@ -69,7 +68,6 @@
  *
  *    preempt_count() == 2*PREEMPT_DISABLE_OFFSET
  *
- * Note: PREEMPT_DISABLE_OFFSET is 0 for !PREEMPT_COUNT kernels.
  * Note: See finish_task_switch().
  */
 #define FORK_PREEMPT_COUNT	(2*PREEMPT_DISABLE_OFFSET + PREEMPT_ENABLED)
@@ -133,11 +131,7 @@ static __always_inline unsigned char interrupt_context_level(void)
 /*
  * The preempt_count offset after preempt_disable();
  */
-#if defined(CONFIG_PREEMPT_COUNT)
-# define PREEMPT_DISABLE_OFFSET	PREEMPT_OFFSET
-#else
-# define PREEMPT_DISABLE_OFFSET	0
-#endif
+#define PREEMPT_DISABLE_OFFSET	PREEMPT_OFFSET
 
 /*
  * The preempt_count offset after spin_lock()
@@ -154,7 +148,7 @@ static __always_inline unsigned char interrupt_context_level(void)
  *
  *  spin_lock_bh()
  *
- * Which need to disable both preemption (CONFIG_PREEMPT_COUNT) and
+ * Which need to disable both preemption and
  * softirqs, such that unlock sequences of:
  *
  *  spin_unlock();
@@ -196,8 +190,6 @@ extern void preempt_count_sub(int val);
 #define preempt_count_inc() preempt_count_add(1)
 #define preempt_count_dec() preempt_count_sub(1)
 
-#ifdef CONFIG_PREEMPT_COUNT
-
 #define preempt_disable() \
 do { \
 	preempt_count_inc(); \
@@ -263,27 +255,6 @@ do { \
 	__preempt_count_dec(); \
 } while (0)
 
-#else /* !CONFIG_PREEMPT_COUNT */
-
-/*
- * Even if we don't have any preemption, we need preempt disable/enable
- * to be barriers, so that we don't have things like get_user/put_user
- * that can cause faults and scheduling migrate into our preempt-protected
- * region.
- */
-#define preempt_disable()			barrier()
-#define sched_preempt_enable_no_resched()	barrier()
-#define preempt_enable_no_resched()		barrier()
-#define preempt_enable()			barrier()
-#define preempt_check_resched()			do { } while (0)
-
-#define preempt_disable_notrace()		barrier()
-#define preempt_enable_no_resched_notrace()	barrier()
-#define preempt_enable_notrace()		barrier()
-#define preemptible()				0
-
-#endif /* CONFIG_PREEMPT_COUNT */
-
 #ifdef MODULE
 /*
  * Modules have no business playing preemption tricks.
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 47e5d374c7eb..8761b85c7874 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -225,9 +225,6 @@ static inline bool pagefault_disabled(void)
  *
  * This function should only be used by the fault handlers. Other users should
  * stick to pagefault_disabled().
- * Please NEVER use preempt_disable() to disable the fault handler. With
- * !CONFIG_PREEMPT_COUNT, this is like a NOP. So the handler won't be disabled.
- * in_atomic() will report different values based on !CONFIG_PREEMPT_COUNT.
  */
 #define faulthandler_disabled() (pagefault_disabled() || in_atomic())
 
diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index c2f1fd95a821..3d2f7ded0fee 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -86,12 +86,8 @@ config PREEMPT_RT
 
 endchoice
 
-config PREEMPT_COUNT
-       bool
-
 config PREEMPTION
        bool
-       select PREEMPT_COUNT
 
 config PREEMPT_DYNAMIC
 	bool "Preemption behaviour defined on boot"
diff --git a/kernel/rcu/Kconfig.debug b/kernel/rcu/Kconfig.debug
index 1b0c41d490f0..34d395f007a7 100644
--- a/kernel/rcu/Kconfig.debug
+++ b/kernel/rcu/Kconfig.debug
@@ -122,7 +122,6 @@ config RCU_STRICT_GRACE_PERIOD
 	bool "Provide debug RCU implementation with short grace periods"
 	depends on DEBUG_KERNEL && RCU_EXPERT && NR_CPUS <= 4 && !TINY_RCU
 	default n
-	select PREEMPT_COUNT if PREEMPT=n
 	help
 	  Select this option to build an RCU variant that is strict about
 	  grace periods, making them as short as it can.  This limits
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 79aea7df4345..c21a83e7b534 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -2478,7 +2478,7 @@ static __latent_entropy void rcu_core(void)
 	WARN_ON_ONCE(!rdp->beenonline);
 
 	/* Report any deferred quiescent states if preemption enabled. */
-	if (IS_ENABLED(CONFIG_PREEMPT_COUNT) && (!(preempt_count() & PREEMPT_MASK))) {
+	if (!(preempt_count() & PREEMPT_MASK)) {
 		rcu_preempt_deferred_qs(current);
 	} else if (rcu_preempt_need_deferred_qs(current)) {
 		set_tsk_need_resched(current);
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 438ecae6bd7e..432aa6e6cff7 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -29,7 +29,7 @@ static bool rcu_rdp_is_offloaded(struct rcu_data *rdp)
 		  (IS_ENABLED(CONFIG_HOTPLUG_CPU) && lockdep_is_cpus_held()) ||
 		  rcu_lockdep_is_held_nocb(rdp) ||
 		  (rdp == this_cpu_ptr(&rcu_data) &&
-		   !(IS_ENABLED(CONFIG_PREEMPT_COUNT) && preemptible())) ||
+		   !preemptible()) ||
 		  rcu_current_is_nocb_kthread(rdp)),
 		"Unsafe read of RCU_NOCB offloaded state"
 	);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index ee28253c9ac0..938f41569ae9 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5111,8 +5111,7 @@ asmlinkage __visible void schedule_tail(struct task_struct *prev)
 	 * finish_task_switch() for details.
 	 *
 	 * finish_task_switch() will drop rq->lock() and lower preempt_count
-	 * and the preempt_enable() will end up enabling preemption (on
-	 * PREEMPT_COUNT kernels).
+	 * and the preempt_enable() will end up enabling preemption.
 	 */
 
 	finish_task_switch(prev);
@@ -9901,9 +9900,6 @@ void __cant_sleep(const char *file, int line, int preempt_offset)
 	if (irqs_disabled())
 		return;
 
-	if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
-		return;
-
 	if (preempt_count() > preempt_offset)
 		return;
 
@@ -9933,9 +9929,6 @@ void __cant_migrate(const char *file, int line)
 	if (is_migration_disabled(current))
 		return;
 
-	if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
-		return;
-
 	if (preempt_count() > 0)
 		return;
 
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index bcbe60d6c80c..3dd4c8ccc7b2 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1230,7 +1230,6 @@ config PROVE_LOCKING
 	select DEBUG_RWSEMS
 	select DEBUG_WW_MUTEX_SLOWPATH
 	select DEBUG_LOCK_ALLOC
-	select PREEMPT_COUNT if !ARCH_NO_PREEMPT
 	select TRACE_IRQFLAGS
 	default n
 	help
@@ -1431,7 +1430,6 @@ config DEBUG_LOCKDEP
 
 config DEBUG_ATOMIC_SLEEP
 	bool "Sleep inside atomic section checking"
-	select PREEMPT_COUNT
 	depends on DEBUG_KERNEL
 	depends on !ARCH_NO_PREEMPT
 	help
diff --git a/mm/slub.c b/mm/slub.c
index 862dbd9af4f5..b01767226476 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3106,19 +3106,15 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
 {
 	void *p;
 
-#ifdef CONFIG_PREEMPT_COUNT
 	/*
 	 * We may have been preempted and rescheduled on a different
 	 * cpu before disabling preemption. Need to reload cpu area
 	 * pointer.
 	 */
 	c = slub_get_cpu_ptr(s->cpu_slab);
-#endif
-
 	p = ___slab_alloc(s, gfpflags, node, addr, c);
-#ifdef CONFIG_PREEMPT_COUNT
 	slub_put_cpu_ptr(s->cpu_slab);
-#endif
+
 	return p;
 }
 
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-T b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-T
index c70cf0405f24..e332b9b4d8c3 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-T
+++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-T
@@ -9,4 +9,3 @@ CONFIG_DEBUG_LOCK_ALLOC=y
 CONFIG_PROVE_LOCKING=y
 CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
 CONFIG_DEBUG_ATOMIC_SLEEP=y
-#CHECK#CONFIG_PREEMPT_COUNT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-U b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-U
index bc9eeabaa1b1..fac0047579c2 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-U
+++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-U
@@ -7,4 +7,3 @@ CONFIG_PREEMPT_DYNAMIC=n
 CONFIG_RCU_TRACE=n
 CONFIG_DEBUG_LOCK_ALLOC=n
 CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
-CONFIG_PREEMPT_COUNT=n
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TINY01 b/tools/testing/selftests/rcutorture/configs/rcu/TINY01
index 0953c52fcfd7..8363b0b546b7 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TINY01
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TINY01
@@ -11,4 +11,3 @@ CONFIG_RCU_TRACE=n
 #CHECK#CONFIG_RCU_STALL_COMMON=n
 CONFIG_DEBUG_LOCK_ALLOC=n
 CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
-CONFIG_PREEMPT_COUNT=n
diff --git a/tools/testing/selftests/rcutorture/doc/TINY_RCU.txt b/tools/testing/selftests/rcutorture/doc/TINY_RCU.txt
index a75b16991a92..4c596905b6b2 100644
--- a/tools/testing/selftests/rcutorture/doc/TINY_RCU.txt
+++ b/tools/testing/selftests/rcutorture/doc/TINY_RCU.txt
@@ -4,7 +4,6 @@ This document gives a brief rationale for the TINY_RCU test cases.
 Kconfig Parameters:
 
 CONFIG_DEBUG_LOCK_ALLOC -- Do all three and none of the three.
-CONFIG_PREEMPT_COUNT
 CONFIG_RCU_TRACE
 
 The theory here is that randconfig testing will hit the other six possible
diff --git a/tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt b/tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt
index 42acb1a64ce1..9e851c80c5eb 100644
--- a/tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt
+++ b/tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt
@@ -42,7 +42,6 @@ CONFIG_64BIT
 
 	Used only to check CONFIG_RCU_FANOUT value, inspection suffices.
 
-CONFIG_PREEMPT_COUNT
 CONFIG_PREEMPT_RCU
 
 	Redundant with CONFIG_PREEMPT, ignore.
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/config.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/config.h
index 283d7103334f..d0d485d48649 100644
--- a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/config.h
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/config.h
@@ -8,7 +8,6 @@
 #undef CONFIG_HOTPLUG_CPU
 #undef CONFIG_MODULES
 #undef CONFIG_NO_HZ_FULL_SYSIDLE
-#undef CONFIG_PREEMPT_COUNT
 #undef CONFIG_PREEMPT_RCU
 #undef CONFIG_PROVE_RCU
 #undef CONFIG_RCU_NOCB_CPU

^ permalink raw reply related	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 14:07         ` Wedson Almeida Filho
@ 2022-09-19 16:09           ` Linus Torvalds
  2022-09-19 17:20             ` Linus Torvalds
  0 siblings, 1 reply; 102+ messages in thread
From: Linus Torvalds @ 2022-09-19 16:09 UTC (permalink / raw)
  To: Wedson Almeida Filho
  Cc: Matthew Wilcox, Kees Cook, Miguel Ojeda, Konstantin Shelekhin,
	ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, viktor, Andreas Hindborg

On Mon, Sep 19, 2022 at 7:07 AM Wedson Almeida Filho <wedsonaf@gmail.com> wrote:
>
> For GFP_ATOMIC, we could use preempt_count except that it isn't always
> enabled. Conveniently, it is already separated out into its own config.
> How do people feel about removing CONFIG_PREEMPT_COUNT and having the
> count always enabled?
>
> We would then have a way to reliably detect when we are in atomic
> context [..]

No.

First off, it's not true. There are non-preempt atomic contexts too,
like interrupts disabled etc. Can you enumerate all those? Possibly.

But more importantly, doing "depending on context, I silently and
automatically do different things" is simply WRONG. Don't do it. It's
a disaster.

Doing that for *debugging* is fine. So having a

        WARN_ON_ONCE(in_atomic_context());

is a perfectly fine debug check to find people who do bad bad things,
and we have lots of variations of that theme (ie might_sleep(), but
also things like lockdep_assert_held() and friends that assert other
constraints entirely).

But having *behavior changes* depending on context is a total
disaster. And that's invariably why people want this disgusting thing.

They want to do broken things like "I want to allocate memory, and I
don't want to care where I am, so I want the memory allocator to just
do the whole GFP_ATOMIC for me".

And that is FUNDAMENTALLY BROKEN.

If you want to allocate memory, and you don't want to care about what
context you are in, or whether you are holding spinlocks etc, then you
damn well shouldn't be doing kernel programming. Not in C, and not in
Rust.

It really is that simple. Contexts like this ("I am in a critical
region, I must not do memory allocation or use sleeping locks") is
*fundamental* to kernel programming. It has nothing to do with the
language, and everything to do with the problem space.

So don't go down this "let's have the allocator just know if you're in
an atomic context automatically" path. It's wrong. It's complete
garbage. It may generate kernel code that superficially "works", but
one that is fundamentally broken, and will fail and becaome unreliable
under memory pressure.

The thing is, when you do kernel programming, and you're holding a
spinlock and need to allocate memory, you generally shouldn't allocate
memory at all, you should go "Oh, maybe I need to do the allocation
*before* getting the lock".

And it's not just locks. It's also "I'm in a hardware interrupt", but
now the solution is fundamentally different. Maybe you still want to
do pre-allocation, but now you're a driver interrupt and the
pre-allocation has to happen in another code sequence entirely,
because obviously the interrupt itself is asynchronous.

But more commonly, you just want to use GFP_ATOMIC, and go "ok, I know
the VM layer tries to keep a _limited_ set of pre-allocated buffers
around".

But it needs to be explicit, because that GFP_ATOMIC pool of
allocations really is very limited, and you as the allocator need to
make it *explicit* that yeah, now you're not just doing a random
allocation, you are doing one of these *special* allocations that will
eat into that very limited global pool of allocations.

So no, you cannot and MUST NOT have an allocator that silently just
dips into that special pool, without the user being aware or
requesting it.

That really is very very fundamental. Allocators that "just work" in
different contexts are broken garbage within the context of a kernel.

Please just accept this, and really *internalize* it.  Because this
isn't actually just about allocators. Allocators may be one very
common special case of this kind of issue, and they come up quite
often as a result, but this whole "your code needs to *understand* the
special restrictions that the kernel is under" is something that is
quite fundamental in general.

It shows up in various other situations too, like "Oh, this code can
run in an interrupt handler" (which is *different* from the atomicity
of just "while holding a lock", because it implies a level of random
nesting that is very relevant for locking).

Or sometimes it's subtler things than just correctness, ie "I'm
running under a critical lock, so I must be very careful because there
are scalability issues". The code may *work* just fine, but things
like tasklist_lock are very very special.

So embrace that kernel requirement. Kernels are special. We do things,
and we have constraints that pretty much no other environment has.

It is often what makes kernel programming interesting - because it's
challenging. We have a very limited stack. We have some very direct
and deep interactions with the CPU, with things like IO and
interrupts. Some constraints are always there, and others are
context-dependent.

The whole "really know what context this code is running within" is
really important. You may want to write very explicit comments about
it.

And you definitely should always write your code knowing about it.

              Linus

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 16:09           ` Linus Torvalds
@ 2022-09-19 17:20             ` Linus Torvalds
  2022-09-19 18:05               ` Wedson Almeida Filho
  0 siblings, 1 reply; 102+ messages in thread
From: Linus Torvalds @ 2022-09-19 17:20 UTC (permalink / raw)
  To: Wedson Almeida Filho
  Cc: Matthew Wilcox, Kees Cook, Miguel Ojeda, Konstantin Shelekhin,
	ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, viktor, Andreas Hindborg

On Mon, Sep 19, 2022 at 9:09 AM Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> The whole "really know what context this code is running within" is
> really important. You may want to write very explicit comments about
> it.

Side note: a corollary of this is that people should avoid "dynamic
context" things like the plague, because it makes for such pain when
the context isn't statically obvious.

So things like conditional locking should generally be avoided as much
as humanly possible. Either you take the lock or you don't - don't
write code where the lock context depends on some argument value or
flag, for example.

Code like this is fine:

        if (some_condition) {
                spin_lock(&mylock);
                xyz();
                spin_unlock(&mylock);
        }

because 'xyz()' is always run in the same context. But avoid patterns like

        if (some_condition)
                spin_lock(&mylock);
        xyz();
        if (same_condition)
                spin_unlock(&mylock);

where now 'xyz()' sometimes does something with the lock held, and
sometimes not. That way lies insanity.

Now, obviously, the context for helper functions (like the Rust kernel
crate is, pretty much by definition) obviously depends on the context
of the callers of said helpers, so in that sense the above kind of
"sometimes in locked context, sometimes not" will always be the case.

So those kinds of helper functions will generally need to be either
insensitive to context and usable in all contexts (best), or
documented - and verify with debug code like 'might_sleep()' - that
they only run in certain contexts.

And then in the worst case there's a gfp_flag that says "you can only
do these kinds of allocations" or whatever, but even then you should
strive to never have other dynamic behavior (ie please try to avoid
behavior like having a "already locked" argument and then taking a
lock depending on that).

Because if you follow those rules, at least you can statically see the
context from a call chain (so, for example, the stack trace of an oops
will make the context unambiguous, because there's hopefully no lock
or interrupt disabling or similar that has some dynamic behavior like
in that second example of "xyz()".

Do we have places in the kernel that do conditional locking? Yes we
do. Examples like that second case do exist. It's bad. Sometimes you
can't avoid it. But you can always *strive* to avoid it, and
minimizing those kinds of "context depends on other things"
situations.

And we should strive very hard to make those kinds of contexts very
clear and explicit and not dynamic exactly because it's so important
in the kernel, and it has subtle implications wrt other locking, and
memory allocations.

             Linus

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 17:20             ` Linus Torvalds
@ 2022-09-19 18:05               ` Wedson Almeida Filho
  2022-09-19 20:42                 ` Linus Torvalds
  0 siblings, 1 reply; 102+ messages in thread
From: Wedson Almeida Filho @ 2022-09-19 18:05 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Matthew Wilcox, Kees Cook, Miguel Ojeda, Konstantin Shelekhin,
	ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, viktor, Andreas Hindborg

On Mon, Sep 19, 2022 at 10:20:52AM -0700, Linus Torvalds wrote:
> On Mon, Sep 19, 2022 at 9:09 AM Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
> >
> > The whole "really know what context this code is running within" is
> > really important. You may want to write very explicit comments about
> > it.
> 
> Side note: a corollary of this is that people should avoid "dynamic
> context" things like the plague, because it makes for such pain when
> the context isn't statically obvious.

As you know, we're trying to guarantee the absence of undefined
behaviour for code written in Rust. And the context is _really_
important, so important that leaving it up to comments isn't enough.

I don't care as much about allocation flags as I do about sleeping in an
rcu read-side critical region. When CONFIG_PREEMPT=n, if some CPU makes
the mistake of sleeping between rcu_read_lock()/rcu_read_unlock(), RCU
will take that as a quiescent state, which may cause unsuspecting code
waiting for a grace period to wake up too early and potentially free
memory that is still in use, which is obviously undefined behaviour.

We generally have two routes to avoid undefined behaviour: detect at
compile time (and fail compilation) or at runtime (and stop things
before they go too far). The former, while feasible, would require some
static analysi or passing tokens as arguments to guarantee that we're in
sleepable context when sleeping (all ellided at compile time, so
zero-cost in terms of run-time performance), but likely painful to
program use.

Always having preempt_count would allow us to detect such issues in RCU
at runtime (for both C and Rust) and prevent user-after-frees.

Do you have an opinion on the above?

Cheers,
-Wedson

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 18:05               ` Wedson Almeida Filho
@ 2022-09-19 20:42                 ` Linus Torvalds
  2022-09-19 22:35                   ` Wedson Almeida Filho
  0 siblings, 1 reply; 102+ messages in thread
From: Linus Torvalds @ 2022-09-19 20:42 UTC (permalink / raw)
  To: Wedson Almeida Filho
  Cc: Matthew Wilcox, Kees Cook, Miguel Ojeda, Konstantin Shelekhin,
	ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, viktor, Andreas Hindborg

On Mon, Sep 19, 2022 at 11:05 AM Wedson Almeida Filho
<wedsonaf@gmail.com> wrote:
>
> As you know, we're trying to guarantee the absence of undefined
> behaviour for code written in Rust. And the context is _really_
> important, so important that leaving it up to comments isn't enough.

You need to realize that

 (a) reality trumps fantasy

 (b) kernel needs trump any Rust needs

And the *reality* is that there are no absolute guarantees.  Ever. The
"Rust is safe" is not some kind of absolute guarantee of code safety.
Never has been. Anybody who believes that should probably re-take
their kindergarten year, and stop believing in the Easter bunny and
Santa Claus.

Even "safe" rust code in user space will do things like panic when
things go wrong (overflows, allocation failures, etc). If you don't
realize that that is NOT some kind of true safely, I don't know what
to say.

Not completing the operation at all, is *not* really any better than
getting the wrong answer, it's only more debuggable.

In the kernel, "panic and stop" is not an option (it's actively worse
than even the wrong answer, since it's really not debugable), so the
kernel version of "panic" is "WARN_ON_ONCE()" and continue with the
wrong answer.

So this is something that I really *need* the Rust people to
understand. That whole reality of "safe" not being some absolute
thing, and the reality that the kernel side *requires* slightly
different rules than user space traditionally does.

> I don't care as much about allocation flags as I do about sleeping in an
> rcu read-side critical region. When CONFIG_PREEMPT=n, if some CPU makes
> the mistake of sleeping between rcu_read_lock()/rcu_read_unlock(), RCU
> will take that as a quiescent state, which may cause unsuspecting code
> waiting for a grace period to wake up too early and potentially free
> memory that is still in use, which is obviously undefined behaviour.

So?

You had a bug. Shit happens. We have a lot of debugging tools that
will give you a *HUGE* warning when said shit happens, including
sending automated reports to the distro maker. And then you fix the
bug.

Think of that "debugging tools give a huge warning" as being the
equivalent of std::panic in standard rust. Yes, the kernel will
continue (unless you have panic-on-warn set), because the kernel
*MUST* continue in order for that "report to upstream" to have a
chance of happening.

So it's technically a veryu different implementation from std:panic,
but you should basically see it as exactly that: a *technical*
difference, not a conceptual one. The rules for how the kernel deals
with bugs is just different, because we don't have core-files and
debuggers in the general case.

(And yes, you can have a kernel debugger, and you can just have the
WARN_ON_ONCE trigger the debugger, but think of all those billions of
devices that are in normal users hands).

And yes, in certain configurations, even those warnings will be turned
off because the state tracking isn't done. Again, that's just reality.
You don't need to use those configurations yourself if you don't like
them, but that does *NOT* mean that you get to say "nobody else gets
to use those configurations either".

Deal with it.

Or, you know, if you can't deal with the rules that the kernel
requires, then just don't do kernel programming.

Because in the end it really is that simple.  I really need you to
understand that Rust in the kernel is dependent on *kernel* rules. Not
some other random rules that exist elsewhere.

                Linus

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 20:42                 ` Linus Torvalds
@ 2022-09-19 22:35                   ` Wedson Almeida Filho
  2022-09-19 23:39                     ` Linus Torvalds
  0 siblings, 1 reply; 102+ messages in thread
From: Wedson Almeida Filho @ 2022-09-19 22:35 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Matthew Wilcox, Kees Cook, Miguel Ojeda, Konstantin Shelekhin,
	ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, viktor, Andreas Hindborg

On Mon, Sep 19, 2022 at 01:42:44PM -0700, Linus Torvalds wrote:
> On Mon, Sep 19, 2022 at 11:05 AM Wedson Almeida Filho
> <wedsonaf@gmail.com> wrote:
> >
> > As you know, we're trying to guarantee the absence of undefined
> > behaviour for code written in Rust. And the context is _really_
> > important, so important that leaving it up to comments isn't enough.
> 
> You need to realize that
> 
>  (a) reality trumps fantasy
> 
>  (b) kernel needs trump any Rust needs
> 
> And the *reality* is that there are no absolute guarantees.  Ever. The
> "Rust is safe" is not some kind of absolute guarantee of code safety.
> Never has been. Anybody who believes that should probably re-take
> their kindergarten year, and stop believing in the Easter bunny and
> Santa Claus.
> 
> Even "safe" rust code in user space will do things like panic when
> things go wrong (overflows, allocation failures, etc). If you don't
> realize that that is NOT some kind of true safely, I don't know what
> to say.

No one is talking about absolute safety guarantees. I am talking about
specific ones that Rust makes: these are well-documented and formally
defined.

> Not completing the operation at all, is *not* really any better than
> getting the wrong answer, it's only more debuggable.
>
> In the kernel, "panic and stop" is not an option (it's actively worse
> than even the wrong answer, since it's really not debugable), so the
> kernel version of "panic" is "WARN_ON_ONCE()" and continue with the
> wrong answer.
> 
> So this is something that I really *need* the Rust people to
> understand. That whole reality of "safe" not being some absolute
> thing, and the reality that the kernel side *requires* slightly
> different rules than user space traditionally does.
> 
> > I don't care as much about allocation flags as I do about sleeping in an
> > rcu read-side critical region. When CONFIG_PREEMPT=n, if some CPU makes
> > the mistake of sleeping between rcu_read_lock()/rcu_read_unlock(), RCU
> > will take that as a quiescent state, which may cause unsuspecting code
> > waiting for a grace period to wake up too early and potentially free
> > memory that is still in use, which is obviously undefined behaviour.
> 
> So?
> 
> You had a bug. Shit happens. We have a lot of debugging tools that
> will give you a *HUGE* warning when said shit happens, including
> sending automated reports to the distro maker. And then you fix the
> bug.
> 
> Think of that "debugging tools give a huge warning" as being the
> equivalent of std::panic in standard rust. Yes, the kernel will
> continue (unless you have panic-on-warn set), because the kernel
> *MUST* continue in order for that "report to upstream" to have a
> chance of happening.
> 
> So it's technically a veryu different implementation from std:panic,
> but you should basically see it as exactly that: a *technical*
> difference, not a conceptual one. The rules for how the kernel deals
> with bugs is just different, because we don't have core-files and
> debuggers in the general case.
> 
> (And yes, you can have a kernel debugger, and you can just have the
> WARN_ON_ONCE trigger the debugger, but think of all those billions of
> devices that are in normal users hands).
> 
> And yes, in certain configurations, even those warnings will be turned
> off because the state tracking isn't done. Again, that's just reality.
> You don't need to use those configurations yourself if you don't like
> them, but that does *NOT* mean that you get to say "nobody else gets
> to use those configurations either".
> 
> Deal with it.

While I disagree with some of what you write, the point is taken.

But I won't give up on Rust guarantees just yet, I'll try to find
ergonomic ways to enforce them at compile time.

Thanks,
-Wedson

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 22:35                   ` Wedson Almeida Filho
@ 2022-09-19 23:39                     ` Linus Torvalds
  2022-09-19 23:50                       ` Alex Gaynor
  2022-09-20  0:41                       ` Wedson Almeida Filho
  0 siblings, 2 replies; 102+ messages in thread
From: Linus Torvalds @ 2022-09-19 23:39 UTC (permalink / raw)
  To: Wedson Almeida Filho
  Cc: Matthew Wilcox, Kees Cook, Miguel Ojeda, Konstantin Shelekhin,
	ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, viktor, Andreas Hindborg

On Mon, Sep 19, 2022 at 3:35 PM Wedson Almeida Filho <wedsonaf@gmail.com> wrote:
>
> No one is talking about absolute safety guarantees. I am talking about
> specific ones that Rust makes: these are well-documented and formally
> defined.

If you cannot get over the fact that the kernel may have other
requirements that trump any language standards, we really can't work
together.

Those Rust rules may make sense in other environments. But the kernel
really does have hard requirements that you continue to limp along
even if some fundamental rule has been violated. Exactly because
there's often no separate environment outside the kernel that can deal
with it.

End result: a compiler - or language infrastructure - that says "my
rules are so ingrained that I cannot do that" is not one that is valid
for kernel work.

This is not really any different from the whole notion of "allocation
failures cannot panic" that Rust people seemed to readily understand
is a major kernel requirement, and that the kernel needed a graceful
failure return instead of a hard panic.

Also note that the kernel is perfectly willing to say "I will use
compiler flags that disable certain guarantees". We do it all the
time.

For example, the C standard has a lot of "the compiler is allowed to
make this assumption". And then we disagree with those, and so "kernel
C" is different.

For example, the standard says that dereferencing a NULL pointer is
undefined behavior, so a C compiler can see a dereference of a pointer
to be a guarantee that said pointer isn't NULL, and remove any
subsequent NULL pointer tests.

That turns out to be one of those "obviously true in a perfect world,
but problematic in a real world with bugs", and we tell the compiler
to not do that by passing it the '-fno-delete-null-pointer-checks'
flag, because the compiler _depending_ on undefined behavior and
changing code generation in the build ends up being a really bad idea
from a security standpoint.

Now, in C, most of these kinds of things come from the C standard
being very lax, and having much too many "this is undefined behavior"
rules. So in almost all cases we end up saying "we want the
well-defined implementation, not the 'strictly speaking, the language
specs allows the compiler to do Xyz".

Rust comes from a different direction than C, and it may well be that
we very much need some of the rules to be relaxed.

And hey, Rust people do know about "sometimes the rules have to be
relaxed". When it comes to integer overflows etc, there's a
"overflow-checks" flag, typically used for debug vs release builds.

The kernel has similar issues where sometimes you might want the
strict checking (lockdep etc), and sometimes you may end up being less
strict and miss a few rules (eg "we don't maintain a preempt count for
this config, so we can't check RCU mode violations").

> But I won't give up on Rust guarantees just yet, I'll try to find
> ergonomic ways to enforce them at compile time.

I think that compile-time static checking is wonderful, and as much as
possible should be done 100% statically so that people cannot write
incorrect programs.

But we all know that static checking is limited, and then the amount
of dynamic checking for violations is often something that will have
to depend on environment flags, because it may come with an exorbitant
price in the checking.

Exactly like integer overflow checking.

                 Linus

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 23:39                     ` Linus Torvalds
@ 2022-09-19 23:50                       ` Alex Gaynor
  2022-09-19 23:58                         ` Linus Torvalds
  2022-09-20  0:41                       ` Wedson Almeida Filho
  1 sibling, 1 reply; 102+ messages in thread
From: Alex Gaynor @ 2022-09-19 23:50 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Wedson Almeida Filho, Matthew Wilcox, Kees Cook, Miguel Ojeda,
	Konstantin Shelekhin, ojeda, ark.email, bjorn3_gh, bobo1239,
	bonifaido, boqun.feng, davidgow, dev, dsosnowski, foxhlchen,
	gary, geofft, gregkh, jarkko, john.m.baublitz, leseulartichaut,
	linux-fsdevel, linux-kernel, m.falkowski, me, milan, mjmouse9999,
	patches, rust-for-linux, thesven73, viktor, Andreas Hindborg

I think there is some amount of talking past each other here.

Rust's rules are that a function that's safe must not exhibit UB, no
matter what arguments they're called with. This can be done with
static checking or dynamic checking, with obvious trade offs between
the two.

We've had pretty good success, thus far, modeling various kernel
subsystems with APIs that follow this rule. But when there's not a
good way, consistent with the kernel's idioms, to expose a kernel API
in Rust that's safe, that doesn't mean it's impossible! In those cases
we expose an `unsafe fn` in Rust. This means that the caller (e.g.,
driver code) needs to ensure it meets the required pre-conditions for
calling that function.

This is how we square the circle of: How do we prioritize the kernel's
goals, while also staying consistent with Rust's notion of safety?

Wedson's point is that, when possible, finding ways to expose safe
functions is better, since it puts less of a burden on driver authors.
But, sadly, we all know we won't be able to find them in all
circumstances -- we just want to have it as a goal to find them
whenever possible.

Regards,
Alex

On Mon, Sep 19, 2022 at 7:40 PM Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> On Mon, Sep 19, 2022 at 3:35 PM Wedson Almeida Filho <wedsonaf@gmail.com> wrote:
> >
> > No one is talking about absolute safety guarantees. I am talking about
> > specific ones that Rust makes: these are well-documented and formally
> > defined.
>
> If you cannot get over the fact that the kernel may have other
> requirements that trump any language standards, we really can't work
> together.
>
> Those Rust rules may make sense in other environments. But the kernel
> really does have hard requirements that you continue to limp along
> even if some fundamental rule has been violated. Exactly because
> there's often no separate environment outside the kernel that can deal
> with it.
>
> End result: a compiler - or language infrastructure - that says "my
> rules are so ingrained that I cannot do that" is not one that is valid
> for kernel work.
>
> This is not really any different from the whole notion of "allocation
> failures cannot panic" that Rust people seemed to readily understand
> is a major kernel requirement, and that the kernel needed a graceful
> failure return instead of a hard panic.
>
> Also note that the kernel is perfectly willing to say "I will use
> compiler flags that disable certain guarantees". We do it all the
> time.
>
> For example, the C standard has a lot of "the compiler is allowed to
> make this assumption". And then we disagree with those, and so "kernel
> C" is different.
>
> For example, the standard says that dereferencing a NULL pointer is
> undefined behavior, so a C compiler can see a dereference of a pointer
> to be a guarantee that said pointer isn't NULL, and remove any
> subsequent NULL pointer tests.
>
> That turns out to be one of those "obviously true in a perfect world,
> but problematic in a real world with bugs", and we tell the compiler
> to not do that by passing it the '-fno-delete-null-pointer-checks'
> flag, because the compiler _depending_ on undefined behavior and
> changing code generation in the build ends up being a really bad idea
> from a security standpoint.
>
> Now, in C, most of these kinds of things come from the C standard
> being very lax, and having much too many "this is undefined behavior"
> rules. So in almost all cases we end up saying "we want the
> well-defined implementation, not the 'strictly speaking, the language
> specs allows the compiler to do Xyz".
>
> Rust comes from a different direction than C, and it may well be that
> we very much need some of the rules to be relaxed.
>
> And hey, Rust people do know about "sometimes the rules have to be
> relaxed". When it comes to integer overflows etc, there's a
> "overflow-checks" flag, typically used for debug vs release builds.
>
> The kernel has similar issues where sometimes you might want the
> strict checking (lockdep etc), and sometimes you may end up being less
> strict and miss a few rules (eg "we don't maintain a preempt count for
> this config, so we can't check RCU mode violations").
>
> > But I won't give up on Rust guarantees just yet, I'll try to find
> > ergonomic ways to enforce them at compile time.
>
> I think that compile-time static checking is wonderful, and as much as
> possible should be done 100% statically so that people cannot write
> incorrect programs.
>
> But we all know that static checking is limited, and then the amount
> of dynamic checking for violations is often something that will have
> to depend on environment flags, because it may come with an exorbitant
> price in the checking.
>
> Exactly like integer overflow checking.
>
>                  Linus



-- 
All that is necessary for evil to succeed is for good people to do nothing.

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 23:50                       ` Alex Gaynor
@ 2022-09-19 23:58                         ` Linus Torvalds
  2022-09-20  0:15                           ` Linus Torvalds
  2022-09-20  0:40                           ` Boqun Feng
  0 siblings, 2 replies; 102+ messages in thread
From: Linus Torvalds @ 2022-09-19 23:58 UTC (permalink / raw)
  To: Alex Gaynor
  Cc: Wedson Almeida Filho, Matthew Wilcox, Kees Cook, Miguel Ojeda,
	Konstantin Shelekhin, ojeda, ark.email, bjorn3_gh, bobo1239,
	bonifaido, boqun.feng, davidgow, dev, dsosnowski, foxhlchen,
	gary, geofft, gregkh, jarkko, john.m.baublitz, leseulartichaut,
	linux-fsdevel, linux-kernel, m.falkowski, me, milan, mjmouse9999,
	patches, rust-for-linux, thesven73, viktor, Andreas Hindborg

On Mon, Sep 19, 2022 at 4:50 PM Alex Gaynor <alex.gaynor@gmail.com> wrote:
>
> Rust's rules are that a function that's safe must not exhibit UB, no
> matter what arguments they're called with. This can be done with
> static checking or dynamic checking, with obvious trade offs between
> the two.

I think you are missing just how many things are "unsafe" in certain
contexts and *cannot* be validated.

This is not some kind of "a few special things".

This is things like absolutely _anything_ that allocates memory, or
takes a lock, or does a number of other things.

Those things are simply not "safe" if you hold a spinlock, or if you
are in a RCU read-locked region.

And there is literally no way to check for it in certain configurations. None.

So are you going to mark every single function that takes a mutex as
being "unsafe"?

Or are you just going to accept and understand that "hey, exactly like
with integer overflows, sometimes it will be checked, and sometimes it
just won't be".

Because that is literally the reality of the kernel. Sometimes you
WILL NOT have the checks, and you literally CANNOT have the checks.

This is just how reality is. You don't get to choose the universe you live in.

                  Linus

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 23:58                         ` Linus Torvalds
@ 2022-09-20  0:15                           ` Linus Torvalds
  2022-09-20 15:55                             ` Eric W. Biederman
  2022-09-20  0:40                           ` Boqun Feng
  1 sibling, 1 reply; 102+ messages in thread
From: Linus Torvalds @ 2022-09-20  0:15 UTC (permalink / raw)
  To: Alex Gaynor
  Cc: Wedson Almeida Filho, Matthew Wilcox, Kees Cook, Miguel Ojeda,
	Konstantin Shelekhin, ojeda, ark.email, bjorn3_gh, bobo1239,
	bonifaido, boqun.feng, davidgow, dev, dsosnowski, foxhlchen,
	gary, geofft, gregkh, jarkko, john.m.baublitz, leseulartichaut,
	linux-fsdevel, linux-kernel, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, viktor, Andreas Hindborg

On Mon, Sep 19, 2022 at 4:58 PM Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> This is not some kind of "a few special things".
>
> This is things like absolutely _anything_ that allocates memory, or
> takes a lock, or does a number of other things.

Examples of "number of other things" ends up being things like
"accessing user memory", which depending on what you are doing may be
very common too.

And btw, it's not only about the (multiple kinds of) atomic regions.

We have other context rules in the kernel too, like "does floating
point or vector unit calculations". Which you can actually do, but
only in a kernel_fpu_begin/kernel_fpu_end region.

Now, the floating point thing is rare enough that it's probably fine
to just say "no floating point at all in Rust code".  It tends to be
very special code, so you'd write it in C or inline assembly, because
you're doing special things like using the vector unit for crypto
hashes using special CPU instructions.

                  Linus

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 23:58                         ` Linus Torvalds
  2022-09-20  0:15                           ` Linus Torvalds
@ 2022-09-20  0:40                           ` Boqun Feng
  2022-10-03  4:17                             ` Kyle Strand
  1 sibling, 1 reply; 102+ messages in thread
From: Boqun Feng @ 2022-09-20  0:40 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Alex Gaynor, Wedson Almeida Filho, Matthew Wilcox, Kees Cook,
	Miguel Ojeda, Konstantin Shelekhin, ojeda, ark.email, bjorn3_gh,
	bobo1239, bonifaido, davidgow, dev, dsosnowski, foxhlchen, gary,
	geofft, gregkh, jarkko, john.m.baublitz, leseulartichaut,
	linux-fsdevel, linux-kernel, m.falkowski, me, milan, mjmouse9999,
	patches, rust-for-linux, thesven73, viktor, Andreas Hindborg

On Mon, Sep 19, 2022 at 04:58:06PM -0700, Linus Torvalds wrote:
> On Mon, Sep 19, 2022 at 4:50 PM Alex Gaynor <alex.gaynor@gmail.com> wrote:
> >
> > Rust's rules are that a function that's safe must not exhibit UB, no
> > matter what arguments they're called with. This can be done with
> > static checking or dynamic checking, with obvious trade offs between
> > the two.
> 
> I think you are missing just how many things are "unsafe" in certain
> contexts and *cannot* be validated.
> 
> This is not some kind of "a few special things".
> 
> This is things like absolutely _anything_ that allocates memory, or
> takes a lock, or does a number of other things.
> 
> Those things are simply not "safe" if you hold a spinlock, or if you
> are in a RCU read-locked region.
> 
> And there is literally no way to check for it in certain configurations. None.
> 
> So are you going to mark every single function that takes a mutex as
> being "unsafe"?
> 

In this early experiment stage, if something is unsafe per Rust safety
requirements, maybe we should mark it as "unsafe"? Not because Rust
safety needs trump kernel needs, but because we need showcases to the
Rust langauge people the things that are not working very well in Rust
today.

I definitely agree that we CANNOT change kernel behaviors to solely
fulfil Rust safety requirements, we (Rust-for-Linux people) should
either find a way to check in compiler time or just mark it as "unsafe".

Maybe I'm naive ;-) But keeping Rust safety requirements as they are
helps communication with the people on the other side (Rust
langauge/compiler): "Hey, I did everything per your safety requirements,
and it ends like this, I'm not happy about it, could you figure out
something helpful? After all, Rust is a *system programming" language,
it should be able to handle things like these".

Or we want to say "kernel is special, so please give me a option so that
I don't need to worry about these UBs and deal with my real problems"?
I don't have the first hand experience, but seems this is what we have
been doing with C for many years. Do we want to try a new strategy? ;-)
But perhaps it's not new, maybe it's done a few times already but didn't
end well..

Anyway, if I really want to teach Rust language/compiler people "I know
what I'm doing, the problem is that the language is not ready". What
should I do?

Regards,
Boqun

> Or are you just going to accept and understand that "hey, exactly like
> with integer overflows, sometimes it will be checked, and sometimes it
> just won't be".
> 
> Because that is literally the reality of the kernel. Sometimes you
> WILL NOT have the checks, and you literally CANNOT have the checks.
> 
> This is just how reality is. You don't get to choose the universe you live in.
> 
>                   Linus

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-19 23:39                     ` Linus Torvalds
  2022-09-19 23:50                       ` Alex Gaynor
@ 2022-09-20  0:41                       ` Wedson Almeida Filho
  1 sibling, 0 replies; 102+ messages in thread
From: Wedson Almeida Filho @ 2022-09-20  0:41 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Matthew Wilcox, Kees Cook, Miguel Ojeda, Konstantin Shelekhin,
	ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, viktor, Andreas Hindborg

On Mon, Sep 19, 2022 at 04:39:56PM -0700, Linus Torvalds wrote:
> On Mon, Sep 19, 2022 at 3:35 PM Wedson Almeida Filho <wedsonaf@gmail.com> wrote:
> >
> > No one is talking about absolute safety guarantees. I am talking about
> > specific ones that Rust makes: these are well-documented and formally
> > defined.
> 
> If you cannot get over the fact that the kernel may have other
> requirements that trump any language standards, we really can't work
> together.
> 
> Those Rust rules may make sense in other environments. But the kernel
> really does have hard requirements that you continue to limp along
> even if some fundamental rule has been violated. Exactly because
> there's often no separate environment outside the kernel that can deal
> with it.
> 
> End result: a compiler - or language infrastructure - that says "my
> rules are so ingrained that I cannot do that" is not one that is valid
> for kernel work.
> 
> This is not really any different from the whole notion of "allocation
> failures cannot panic" that Rust people seemed to readily understand
> is a major kernel requirement, and that the kernel needed a graceful
> failure return instead of a hard panic.

I am not a programming language/compiler person. My background is in
kernel programming (Linux is not the only kernel in existence) so I have
no difficulty whatsoever with kernel requirements; the graceful handling
of allocation failures that you brought up is in fact something I added
soon after I started started working on rust-for-linux and realised (in
admittedly a bit of a shock) that userland Rust didn't have this at the
time.

> 
> Also note that the kernel is perfectly willing to say "I will use
> compiler flags that disable certain guarantees". We do it all the
> time.
> 
> For example, the C standard has a lot of "the compiler is allowed to
> make this assumption". And then we disagree with those, and so "kernel
> C" is different.
> 
> For example, the standard says that dereferencing a NULL pointer is
> undefined behavior, so a C compiler can see a dereference of a pointer
> to be a guarantee that said pointer isn't NULL, and remove any
> subsequent NULL pointer tests.
> 
> That turns out to be one of those "obviously true in a perfect world,
> but problematic in a real world with bugs", and we tell the compiler
> to not do that by passing it the '-fno-delete-null-pointer-checks'
> flag, because the compiler _depending_ on undefined behavior and
> changing code generation in the build ends up being a really bad idea
> from a security standpoint.
> 
> Now, in C, most of these kinds of things come from the C standard
> being very lax, and having much too many "this is undefined behavior"
> rules. So in almost all cases we end up saying "we want the
> well-defined implementation, not the 'strictly speaking, the language
> specs allows the compiler to do Xyz".
> 
> Rust comes from a different direction than C, and it may well be that
> we very much need some of the rules to be relaxed.

Sure. In fact, we are likely to be able to influence the Rust language
more and more quickly than C. So if things don't make sense, we may be
able to change them.

There are also opportunities here, for example, a compatible memory
model and guaranteed honouring of dependency chains for more efficient
synchronisation primitives. I'm not claiming this is surely going to
happen or that it's easy, just that there's an opportunity to do better
than C here.

> And hey, Rust people do know about "sometimes the rules have to be
> relaxed". When it comes to integer overflows etc, there's a
> "overflow-checks" flag, typically used for debug vs release builds.
> 
> The kernel has similar issues where sometimes you might want the
> strict checking (lockdep etc), and sometimes you may end up being less
> strict and miss a few rules (eg "we don't maintain a preempt count for
> this config, so we can't check RCU mode violations").
> 
> > But I won't give up on Rust guarantees just yet, I'll try to find
> > ergonomic ways to enforce them at compile time.
> 
> I think that compile-time static checking is wonderful, and as much as
> possible should be done 100% statically so that people cannot write
> incorrect programs.
> 
> But we all know that static checking is limited, and then the amount
> of dynamic checking for violations is often something that will have
> to depend on environment flags, because it may come with an exorbitant
> price in the checking.

If we can't find an ergonomic way to enforce safety guarantees, we have
fallbacks like unsafe functions or runtime enforcement. And as you
point out, if the runtime cost is too high in certain scenarios, we
do allow users to give up safety with a config as in the integer
overflow case you mentioned. We do try to minimise those.

Cheers,
-Wedson

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-20  0:15                           ` Linus Torvalds
@ 2022-09-20 15:55                             ` Eric W. Biederman
  2022-09-20 22:39                               ` Gary Guo
  0 siblings, 1 reply; 102+ messages in thread
From: Eric W. Biederman @ 2022-09-20 15:55 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Alex Gaynor, Wedson Almeida Filho, Matthew Wilcox, Kees Cook,
	Miguel Ojeda, Konstantin Shelekhin, ojeda, ark.email, bjorn3_gh,
	bobo1239, bonifaido, boqun.feng, davidgow, dev, dsosnowski,
	foxhlchen, gary, geofft, gregkh, jarkko, john.m.baublitz,
	leseulartichaut, linux-fsdevel, linux-kernel, me, milan,
	mjmouse9999, patches, rust-for-linux, thesven73, viktor,
	Andreas Hindborg

Linus Torvalds <torvalds@linux-foundation.org> writes:

> On Mon, Sep 19, 2022 at 4:58 PM Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
>>
>> This is not some kind of "a few special things".
>>
>> This is things like absolutely _anything_ that allocates memory, or
>> takes a lock, or does a number of other things.
>
> Examples of "number of other things" ends up being things like
> "accessing user memory", which depending on what you are doing may be
> very common too.
>
> And btw, it's not only about the (multiple kinds of) atomic regions.
>
> We have other context rules in the kernel too, like "does floating
> point or vector unit calculations". Which you can actually do, but
> only in a kernel_fpu_begin/kernel_fpu_end region.
>
> Now, the floating point thing is rare enough that it's probably fine
> to just say "no floating point at all in Rust code".  It tends to be
> very special code, so you'd write it in C or inline assembly, because
> you're doing special things like using the vector unit for crypto
> hashes using special CPU instructions.

I just want to point out that there are ways of representing things like
the context you are running in during compile time.  I won't argue they
are necessarily practical, but there are ways and by exploring those
ways some practical solutions may result.

Instead of saying:
spin_lock(&lock);
do_something();
spin_unlock(&lock);

It is possible to say:
with_spin_lock(&lock, do_something());

This can be taken a step farther and with_spin_lock can pass a ``token''
say a structure with no members that disappears at compile time that
let's the code know it has the spinlock held.

In C I would do:
struct have_spin_lock_x {
	// nothing
};

do_something(struct have_spin_lock_x context_guarantee)
{
	...;
}

I think most of the special contexts in the kernel can be represented in
a similar manner.  A special parameter that can be passed and will
compile out.

I don't recall seeing anything like that tried in the kernel so I don't
know if it makes sense or if it would get too wordy to live, but it is
possible.  If passing a free context parameter is not too wordy it would
catch silly errors, and would hopefully leave more mental space for
developers to pay attention to the other details of the problems they
are solving.

*Shrug*  I don't know if rust allows for free parameters like that and
if it does I don't know if it would be cheap enough to live.

Eric

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-20 15:55                             ` Eric W. Biederman
@ 2022-09-20 22:39                               ` Gary Guo
  2022-09-21  6:42                                 ` comex
  0 siblings, 1 reply; 102+ messages in thread
From: Gary Guo @ 2022-09-20 22:39 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Linus Torvalds, Alex Gaynor, Wedson Almeida Filho,
	Matthew Wilcox, Kees Cook, Miguel Ojeda, Konstantin Shelekhin,
	ojeda, ark.email, bjorn3_gh, bobo1239, bonifaido, boqun.feng,
	davidgow, dev, dsosnowski, foxhlchen, geofft, gregkh, jarkko,
	john.m.baublitz, leseulartichaut, linux-fsdevel, linux-kernel,
	me, milan, mjmouse9999, patches, rust-for-linux, thesven73,
	viktor, Andreas Hindborg

On Tue, 20 Sep 2022 10:55:27 -0500
"Eric W. Biederman" <ebiederm@xmission.com> wrote:

> Linus Torvalds <torvalds@linux-foundation.org> writes:
> 
> > On Mon, Sep 19, 2022 at 4:58 PM Linus Torvalds
> > <torvalds@linux-foundation.org> wrote:  
> >>
> >> This is not some kind of "a few special things".
> >>
> >> This is things like absolutely _anything_ that allocates memory, or
> >> takes a lock, or does a number of other things.  
> >
> > Examples of "number of other things" ends up being things like
> > "accessing user memory", which depending on what you are doing may
> > be very common too.
> >
> > And btw, it's not only about the (multiple kinds of) atomic regions.
> >
> > We have other context rules in the kernel too, like "does floating
> > point or vector unit calculations". Which you can actually do, but
> > only in a kernel_fpu_begin/kernel_fpu_end region.
> >
> > Now, the floating point thing is rare enough that it's probably fine
> > to just say "no floating point at all in Rust code".  It tends to be
> > very special code, so you'd write it in C or inline assembly,
> > because you're doing special things like using the vector unit for
> > crypto hashes using special CPU instructions.  
> 
> I just want to point out that there are ways of representing things
> like the context you are running in during compile time.  I won't
> argue they are necessarily practical, but there are ways and by
> exploring those ways some practical solutions may result.
> 
> Instead of saying:
> spin_lock(&lock);
> do_something();
> spin_unlock(&lock);
> 
> It is possible to say:
> with_spin_lock(&lock, do_something());
> 
> This can be taken a step farther and with_spin_lock can pass a
> ``token'' say a structure with no members that disappears at compile
> time that let's the code know it has the spinlock held.
> 
> In C I would do:
> struct have_spin_lock_x {
> 	// nothing
> };
> 
> do_something(struct have_spin_lock_x context_guarantee)
> {
> 	...;
> }
> 
> I think most of the special contexts in the kernel can be represented
> in a similar manner.  A special parameter that can be passed and will
> compile out.
> 
> I don't recall seeing anything like that tried in the kernel so I
> don't know if it makes sense or if it would get too wordy to live,
> but it is possible.  If passing a free context parameter is not too
> wordy it would catch silly errors, and would hopefully leave more
> mental space for developers to pay attention to the other details of
> the problems they are solving.
> 
> *Shrug*  I don't know if rust allows for free parameters like that and
> if it does I don't know if it would be cheap enough to live.

I believe this was mentioned by Wedson in one of his previous emails.
This pattern is quite common in Rust code. It looks like this:

	#[derive(Clone, Copy)]
	pub struct Token<'a>(PhantomData<&'a ()>);
	
	pub fn with_token<T>(f: impl for<'a> FnOnce(Token<'a>) -> T) ->
	T { f(Token(PhantomData))
	}

Any function that requires something can just take token by value, e.g.
with `token: Token<'_>`. Since Token is a zero-sized type (ZST), this
parameter will be omitted during code generation, so it won't affect
the ABI and this has no runtime cost.

Example on godbolt: https://godbolt.org/z/9n954cG4d, showing that the
token is actually all optimised out.

It should be noted however, atomic context is not something that a
token can represent. You can only use tokens to restrict what you *can*
do, but not what you *can't* do. There is no negative reasoning with
tokens, you can't create a function that can only be called when you
don't have token.

You can use tokens to represent non-atomic contexts, but that'll be
really painful because this requires carrying a token in almost all
functions. This kind of API also works well for FPU contexts.

Best,
Gary

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-20 22:39                               ` Gary Guo
@ 2022-09-21  6:42                                 ` comex
  2022-09-21 14:19                                   ` Boqun Feng
  0 siblings, 1 reply; 102+ messages in thread
From: comex @ 2022-09-21  6:42 UTC (permalink / raw)
  To: Gary Guo
  Cc: Eric W. Biederman, Linus Torvalds, Alex Gaynor,
	Wedson Almeida Filho, Matthew Wilcox, Kees Cook, Miguel Ojeda,
	Konstantin Shelekhin, ojeda, ark.email, bjorn3_gh, bobo1239,
	bonifaido, Boqun Feng, davidgow, dev, dsosnowski, foxhlchen,
	geofft, gregkh, jarkko, john.m.baublitz, leseulartichaut,
	linux-fsdevel, linux-kernel, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, viktor, Andreas Hindborg



> On Sep 20, 2022, at 6:39 PM, Gary Guo <gary@garyguo.net> wrote:
> 
> It should be noted however, atomic context is not something that a
> token can represent. You can only use tokens to restrict what you *can*
> do, but not what you *can't* do. There is no negative reasoning with
> tokens, you can't create a function that can only be called when you
> don't have token.

On the other hand, it ought to be feasible to implement that kind of ’negative reasoning' as a custom lint.  It might not work as well as something built into the language, but it should work decently well, and could serve as a prototype for a future built-in feature.

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-08-06 11:22     ` Miguel Ojeda
  2022-08-06 12:15       ` Konstantin Shelekhin
  2022-08-06 14:57       ` Matthew Wilcox
@ 2022-09-21 11:23       ` Konstantin Shelekhin
  2022-09-21 11:46         ` Greg KH
  2 siblings, 1 reply; 102+ messages in thread
From: Konstantin Shelekhin @ 2022-09-21 11:23 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239, bonifaido,
	boqun.feng, davidgow, dev, dsosnowski, foxhlchen, gary, geofft,
	gregkh, jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, m.falkowski, me, milan, mjmouse9999, patches,
	rust-for-linux, thesven73, torvalds, viktor, wedsonaf,
	Andreas Hindborg

On Sat, Aug 06, 2022 at 01:22:52PM +0200, Miguel Ojeda wrote:
> On Sat, Aug 6, 2022 at 12:25 PM Konstantin Shelekhin
> <k.shelekhin@yadro.com> wrote:
> >
> > I sense possible problems here. It's common for a kernel code to pass
> > flags during memory allocations.
> 
> Yes, of course. We will support this, but how exactly it will look
> like, to what extent upstream Rust's `alloc` could support our use
> cases, etc. has been on discussion for a long time.
> 
> For instance, see https://github.com/Rust-for-Linux/linux/pull/815 for
> a potential extension trait approach with no allocator carried on the
> type that Andreas wrote after a discussion in the last informal call:
> 
>     let a = Box::try_new_atomic(101)?;

In my opinion, the rest of the thread clearly shows that the
conservative approach is currently the only solid option. I suggest the
following explicit API:

  let a = Box::try_new(size, flags)?;
  Vec::try_push(item, flags)?;

etc. Whadda you think?

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-21 11:23       ` Konstantin Shelekhin
@ 2022-09-21 11:46         ` Greg KH
  0 siblings, 0 replies; 102+ messages in thread
From: Greg KH @ 2022-09-21 11:46 UTC (permalink / raw)
  To: Konstantin Shelekhin
  Cc: Miguel Ojeda, ojeda, alex.gaynor, ark.email, bjorn3_gh, bobo1239,
	bonifaido, boqun.feng, davidgow, dev, dsosnowski, foxhlchen,
	gary, geofft, jarkko, john.m.baublitz, leseulartichaut,
	linux-fsdevel, linux-kernel, m.falkowski, me, milan, mjmouse9999,
	patches, rust-for-linux, thesven73, torvalds, viktor, wedsonaf,
	Andreas Hindborg

On Wed, Sep 21, 2022 at 02:23:42PM +0300, Konstantin Shelekhin wrote:
> On Sat, Aug 06, 2022 at 01:22:52PM +0200, Miguel Ojeda wrote:
> > On Sat, Aug 6, 2022 at 12:25 PM Konstantin Shelekhin
> > <k.shelekhin@yadro.com> wrote:
> > >
> > > I sense possible problems here. It's common for a kernel code to pass
> > > flags during memory allocations.
> > 
> > Yes, of course. We will support this, but how exactly it will look
> > like, to what extent upstream Rust's `alloc` could support our use
> > cases, etc. has been on discussion for a long time.
> > 
> > For instance, see https://github.com/Rust-for-Linux/linux/pull/815 for
> > a potential extension trait approach with no allocator carried on the
> > type that Andreas wrote after a discussion in the last informal call:
> > 
> >     let a = Box::try_new_atomic(101)?;
> 
> In my opinion, the rest of the thread clearly shows that the
> conservative approach is currently the only solid option. I suggest the
> following explicit API:
> 
>   let a = Box::try_new(size, flags)?;
>   Vec::try_push(item, flags)?;
> 
> etc. Whadda you think?

Please, yes.  This fits the current kernel memory allocation pattern and
allows for proper propagation of the allocation flags as needed through
the system.  This is going to be required in any non-trivial kernel code
anyway, might as well do it correct from the beginning.

It also allows for flags to change over time, which also happens.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-21  6:42                                 ` comex
@ 2022-09-21 14:19                                   ` Boqun Feng
  2022-10-03  2:03                                     ` comex
  0 siblings, 1 reply; 102+ messages in thread
From: Boqun Feng @ 2022-09-21 14:19 UTC (permalink / raw)
  To: comex
  Cc: Gary Guo, Eric W. Biederman, Linus Torvalds, Alex Gaynor,
	Wedson Almeida Filho, Matthew Wilcox, Kees Cook, Miguel Ojeda,
	Konstantin Shelekhin, ojeda, ark.email, bjorn3_gh, bobo1239,
	bonifaido, davidgow, dev, dsosnowski, foxhlchen, geofft, gregkh,
	jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, me, milan, mjmouse9999, patches, rust-for-linux,
	thesven73, viktor, Andreas Hindborg

On Wed, Sep 21, 2022 at 02:42:18AM -0400, comex wrote:
> 
> 
> > On Sep 20, 2022, at 6:39 PM, Gary Guo <gary@garyguo.net> wrote:
> > 
> > It should be noted however, atomic context is not something that a
> > token can represent. You can only use tokens to restrict what you *can*
> > do, but not what you *can't* do. There is no negative reasoning with
> > tokens, you can't create a function that can only be called when you
> > don't have token.
> 
> On the other hand, it ought to be feasible to implement that kind of
> ’negative reasoning' as a custom lint.  It might not work as well as
> something built into the language, but it should work decently well,
> and could serve as a prototype for a future built-in feature.

Interesting, do you have an example somewhere?

Regards,
Boqun

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size
  2022-08-18 16:03         ` Kees Cook
@ 2022-09-27 12:48           ` Miguel Ojeda
  0 siblings, 0 replies; 102+ messages in thread
From: Miguel Ojeda @ 2022-09-27 12:48 UTC (permalink / raw)
  To: Kees Cook
  Cc: Konstantin Shelekhin, ojeda, boqun.feng, gregkh, jarkko,
	linux-fsdevel, linux-kernel, patches, rust-for-linux, torvalds

On Thu, Aug 18, 2022 at 6:03 PM Kees Cook <keescook@chromium.org> wrote:
>
> Oh, that's an excellent point; I forgot it'll actually compile-time
> error if the var is a pointer. +1

In this case it doesn't, because `scripts/kallsyms.c` defines its own
`ARRAY_SIZE` that doesn't have the `__must_be_array`.

I have changed it for v10 anyway, since that way we may benefit in the
future if the `ARRAY_SIZE` here gains the check.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-21 14:19                                   ` Boqun Feng
@ 2022-10-03  2:03                                     ` comex
  0 siblings, 0 replies; 102+ messages in thread
From: comex @ 2022-10-03  2:03 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Gary Guo, Eric W. Biederman, Linus Torvalds, Alex Gaynor,
	Wedson Almeida Filho, Matthew Wilcox, Kees Cook, Miguel Ojeda,
	Konstantin Shelekhin, ojeda, ark.email, bjorn3_gh, bobo1239,
	bonifaido, davidgow, dev, dsosnowski, foxhlchen, geofft, gregkh,
	jarkko, john.m.baublitz, leseulartichaut, linux-fsdevel,
	linux-kernel, me, milan, mjmouse9999, patches, rust-for-linux,
	thesven73, viktor, Andreas Hindborg


>> On the other hand, it ought to be feasible to implement that kind of
>> ’negative reasoning' as a custom lint.  It might not work as well as
>> something built into the language, but it should work decently well,
>> and could serve as a prototype for a future built-in feature.
> 
> Interesting, do you have an example somewhere?
> 
> Regards,
> Boqun

After some searching, I found this, which someone wrote several years ago for a
very similar purpose:

https://github.com/thepowersgang/tag_safe/

> This is a linter designed originally for use with a kernel, where functions
> need to be marked as "IRQ safe" (meaning they are safe to call within an IRQ
> handler, and handle the case where they may interrupt themselves).

> If a function is annotated with #[req_safe(ident)] (where ident can be
> anything, and defines the type of safety) this linter will check that all
> functions called by that function are either annotated with the same
> annotation or #[is_safe(ident)], OR they do not call functions with the
> reverse #[is_unsafe(ident)] annotation.

Note that the code won't work as-is with recent rustc.  rustc's API for custom
lints is not stable, and in fact rustc has deprecated linter plugins entirely
[1], though there are alternative approaches to using custom lints [2].  Still,
it's a good example of the approach.

One fundamental caveat is that it doesn't seem to have the sophistication
needed to be sound with respect to indirect calls.

For example, suppose you have a function that fetches a callback from some
structure and calls it.  Whether this function is IRQ-safe depends on whether
the callback is expected to be IRQ-safe, so in order to safety-check this, you
would need an annotation on either the callback field or the function pointer
type.  This is more complex than just putting annotations on function
definitions.

Or suppose you have the following code:

    fn foo() {
        bar(|| do_something_not_irq_safe());
    }

If `foo` is expected to be IRQ-safe, this may or may not be sound, depending on
whether `bar` calls the callback immediately or saves it for later.  If `bar`
saves it for later, then it could be marked unconditionally IRQ-safe.  But if
`bar` calls it immediately, then it's neither IRQ-safe nor IRQ-unsafe, but
effectively generic over IRQ safety.  You could pessimistically mark it
IRQ-unsafe, but Rust has tons of basic helper methods that accept callbacks and
call them immediately; not being able to use any of them in an IRQ-safe context
would be quite limiting.

In short, a fully sound approach requires not just checking which functions
call which, but having some kind of integration with the type system.  This is
the kind of issue that I was thinking of when I said a custom lint may not work
as well as something built into the language.

However, I do think it's *possible* to handle it soundly from a lint,
especially if it focuses on typical use cases and relies on manual annotations
for the rest.  Alternately, even an unsound lint would be a good first step.
It wouldn't really comport with Rust's ethos of making safety guarantees
ironclad rather than heuristic, but it would serve as a good proof of concept
for a future language feature, while likely being helpful in practice in the
short term.

[1] https://github.com/rust-lang/rust/pull/64675/files
[2] https://www.trailofbits.com/post/write-rust-lints-without-forking-clippy

^ permalink raw reply	[flat|nested] 102+ messages in thread

* Re: [PATCH v9 12/27] rust: add `kernel` crate
  2022-09-20  0:40                           ` Boqun Feng
@ 2022-10-03  4:17                             ` Kyle Strand
  0 siblings, 0 replies; 102+ messages in thread
From: Kyle Strand @ 2022-10-03  4:17 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Linus Torvalds, Alex Gaynor, Wedson Almeida Filho,
	Matthew Wilcox, Kees Cook, Miguel Ojeda, Konstantin Shelekhin,
	ojeda, ark.email, bjorn3_gh, bobo1239, bonifaido, davidgow, dev,
	dsosnowski, foxhlchen, gary, geofft, gregkh, jarkko,
	john.m.baublitz, leseulartichaut, linux-fsdevel, linux-kernel,
	m.falkowski, me, milan, mjmouse9999, patches, rust-for-linux,
	thesven73, viktor, Andreas Hindborg

I don't know if there was ever a direct answer to this question; I was
hoping someone with more involvement in the project would jump in.

> In this early experiment stage, if something is unsafe per Rust safety
> requirements, maybe we should mark it as "unsafe"? Not because Rust
> safety needs trump kernel needs, but because we need showcases to the
> Rust langauge people the things that are not working very well in Rust
> today.
>
> I definitely agree that we CANNOT change kernel behaviors to solely
> fulfil Rust safety requirements, we (Rust-for-Linux people) should
> either find a way to check in compiler time or just mark it as "unsafe".

From the perspective of a Linux outsider, marking huge swaths of Rust
code "unsafe" doesn't actually sound incorrect to me. If a function
may exhibit undefined behavior, it's unsafe; thus, it should be marked
as such. True, you lose some of Rust's guarantees within the code
marked "unsafe", but this is what permits Rust to enforce those
guarantees elsewhere. Having lots of uses of "unsafe" in kernel code
is probably to be expected, and (in my opinion) not actually a sign
that things "are not working very well in Rust." It's not even
particularly verbose, if the callers of unsafe functions are generally
also marked "unsafe"; in these cases, only the signatures are
affected.

The last sentence of Boqun's quote above captures the intent of
"unsafe" perfectly: it simply indicates that code cannot be proven at
compile time not to exhibit undefined behavior. It's important for
systems languages to enable such code to be written, which is
precisely why Rust has the "unsafe" keyword.


On Mon, Sep 19, 2022 at 6:45 PM Boqun Feng <boqun.feng@gmail.com> wrote:
>
> On Mon, Sep 19, 2022 at 04:58:06PM -0700, Linus Torvalds wrote:
> > On Mon, Sep 19, 2022 at 4:50 PM Alex Gaynor <alex.gaynor@gmail.com> wrote:
> > >
> > > Rust's rules are that a function that's safe must not exhibit UB, no
> > > matter what arguments they're called with. This can be done with
> > > static checking or dynamic checking, with obvious trade offs between
> > > the two.
> >
> > I think you are missing just how many things are "unsafe" in certain
> > contexts and *cannot* be validated.
> >
> > This is not some kind of "a few special things".
> >
> > This is things like absolutely _anything_ that allocates memory, or
> > takes a lock, or does a number of other things.
> >
> > Those things are simply not "safe" if you hold a spinlock, or if you
> > are in a RCU read-locked region.
> >
> > And there is literally no way to check for it in certain configurations. None.
> >
> > So are you going to mark every single function that takes a mutex as
> > being "unsafe"?
> >
>
> In this early experiment stage, if something is unsafe per Rust safety
> requirements, maybe we should mark it as "unsafe"? Not because Rust
> safety needs trump kernel needs, but because we need showcases to the
> Rust langauge people the things that are not working very well in Rust
> today.
>
> I definitely agree that we CANNOT change kernel behaviors to solely
> fulfil Rust safety requirements, we (Rust-for-Linux people) should
> either find a way to check in compiler time or just mark it as "unsafe".
>
> Maybe I'm naive ;-) But keeping Rust safety requirements as they are
> helps communication with the people on the other side (Rust
> langauge/compiler): "Hey, I did everything per your safety requirements,
> and it ends like this, I'm not happy about it, could you figure out
> something helpful? After all, Rust is a *system programming" language,
> it should be able to handle things like these".
>
> Or we want to say "kernel is special, so please give me a option so that
> I don't need to worry about these UBs and deal with my real problems"?
> I don't have the first hand experience, but seems this is what we have
> been doing with C for many years. Do we want to try a new strategy? ;-)
> But perhaps it's not new, maybe it's done a few times already but didn't
> end well..
>
> Anyway, if I really want to teach Rust language/compiler people "I know
> what I'm doing, the problem is that the language is not ready". What
> should I do?
>
> Regards,
> Boqun
>
> > Or are you just going to accept and understand that "hey, exactly like
> > with integer overflows, sometimes it will be checked, and sometimes it
> > just won't be".
> >
> > Because that is literally the reality of the kernel. Sometimes you
> > WILL NOT have the checks, and you literally CANNOT have the checks.
> >
> > This is just how reality is. You don't get to choose the universe you live in.
> >
> >                   Linus

^ permalink raw reply	[flat|nested] 102+ messages in thread

end of thread, other threads:[~2022-10-03  4:17 UTC | newest]

Thread overview: 102+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-05 15:41 [PATCH v9 00/27] Rust support Miguel Ojeda
2022-08-05 15:41 ` [PATCH v9 01/27] kallsyms: use `sizeof` instead of hardcoded size Miguel Ojeda
2022-08-05 16:48   ` Geert Stappers
2022-08-05 18:46     ` Miguel Ojeda
2022-08-05 22:40   ` Konstantin Shelekhin
2022-08-17 19:36     ` Kees Cook
2022-08-18  9:03       ` Konstantin Shelekhin
2022-08-18 16:03         ` Kees Cook
2022-09-27 12:48           ` Miguel Ojeda
2022-08-05 15:41 ` [PATCH v9 02/27] kallsyms: avoid hardcoding buffer size Miguel Ojeda
2022-08-17 19:37   ` Kees Cook
2022-08-18 16:50     ` Geert Stappers
2022-08-05 15:41 ` [PATCH v9 03/27] kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}` Miguel Ojeda
2022-08-17 19:39   ` Kees Cook
2022-08-17 19:50     ` Boqun Feng
2022-08-17 20:31       ` Kees Cook
2022-08-17 20:45         ` Miguel Ojeda
2022-08-05 15:41 ` [PATCH v9 04/27] kallsyms: support "big" kernel symbols Miguel Ojeda
2022-08-05 15:41 ` [PATCH v9 05/27] kallsyms: increase maximum kernel symbol length to 512 Miguel Ojeda
2022-08-05 15:41 ` [PATCH v9 06/27] rust: add C helpers Miguel Ojeda
2022-08-17 19:44   ` Kees Cook
2022-08-17 20:22     ` Miguel Ojeda
2022-08-17 20:34       ` Kees Cook
2022-08-17 21:44         ` Miguel Ojeda
2022-08-17 23:56           ` Kees Cook
2022-08-18 16:03             ` Miguel Ojeda
2022-08-18 16:08               ` Kees Cook
2022-08-18 17:01                 ` Miguel Ojeda
2022-08-05 15:41 ` [PATCH v9 08/27] rust: adapt `alloc` crate to the kernel Miguel Ojeda
2022-08-05 15:41 ` [PATCH v9 09/27] rust: add `compiler_builtins` crate Miguel Ojeda
2022-08-17 20:08   ` Kees Cook
2022-08-22 23:55   ` Nick Desaulniers
2022-08-24 18:38     ` Nick Desaulniers
2022-08-29 17:11       ` Gary Guo
2022-08-05 15:41 ` [PATCH v9 10/27] rust: add `macros` crate Miguel Ojeda
2022-08-05 15:41 ` [PATCH v9 11/27] rust: add `bindings` crate Miguel Ojeda
2022-08-05 15:41 ` [PATCH v9 12/27] rust: add `kernel` crate Miguel Ojeda
2022-08-06 10:24   ` Konstantin Shelekhin
2022-08-06 11:22     ` Miguel Ojeda
2022-08-06 12:15       ` Konstantin Shelekhin
2022-08-06 14:57       ` Matthew Wilcox
2022-09-19 14:07         ` Wedson Almeida Filho
2022-09-19 16:09           ` Linus Torvalds
2022-09-19 17:20             ` Linus Torvalds
2022-09-19 18:05               ` Wedson Almeida Filho
2022-09-19 20:42                 ` Linus Torvalds
2022-09-19 22:35                   ` Wedson Almeida Filho
2022-09-19 23:39                     ` Linus Torvalds
2022-09-19 23:50                       ` Alex Gaynor
2022-09-19 23:58                         ` Linus Torvalds
2022-09-20  0:15                           ` Linus Torvalds
2022-09-20 15:55                             ` Eric W. Biederman
2022-09-20 22:39                               ` Gary Guo
2022-09-21  6:42                                 ` comex
2022-09-21 14:19                                   ` Boqun Feng
2022-10-03  2:03                                     ` comex
2022-09-20  0:40                           ` Boqun Feng
2022-10-03  4:17                             ` Kyle Strand
2022-09-20  0:41                       ` Wedson Almeida Filho
2022-09-21 11:23       ` Konstantin Shelekhin
2022-09-21 11:46         ` Greg KH
2022-08-05 15:41 ` [PATCH v9 13/27] rust: export generated symbols Miguel Ojeda
2022-08-17 20:11   ` Kees Cook
2022-08-05 15:41 ` [PATCH v9 14/27] vsprintf: add new `%pA` format specifier Miguel Ojeda
2022-08-05 15:42 ` [PATCH v9 15/27] scripts: checkpatch: diagnose uses of `%pA` in the C side as errors Miguel Ojeda
2022-08-05 15:42 ` [PATCH v9 16/27] scripts: checkpatch: enable language-independent checks for Rust Miguel Ojeda
2022-08-17 20:12   ` Kees Cook
2022-08-05 15:42 ` [PATCH v9 17/27] scripts: decode_stacktrace: demangle Rust symbols Miguel Ojeda
2022-08-05 15:42 ` [PATCH v9 18/27] scripts: add `generate_rust_analyzer.py` Miguel Ojeda
2022-08-17 20:13   ` Kees Cook
2022-08-05 15:42 ` [PATCH v9 19/27] scripts: add `generate_rust_target.rs` Miguel Ojeda
2022-08-17 20:14   ` Kees Cook
2022-08-05 15:42 ` [PATCH v9 20/27] scripts: add `rust_is_available.sh` Miguel Ojeda
2022-08-17 20:18   ` Kees Cook
2022-08-17 20:40     ` Miguel Ojeda
2022-08-22 20:09   ` Nick Desaulniers
2022-08-23 12:12     ` Miguel Ojeda
2022-08-23 12:16       ` Miguel Ojeda
2022-08-05 15:42 ` [PATCH v9 21/27] scripts: add `is_rust_module.sh` Miguel Ojeda
2022-08-17 20:19   ` Kees Cook
2022-08-05 15:42 ` [PATCH v9 22/27] rust: add `.rustfmt.toml` Miguel Ojeda
2022-08-17 20:19   ` Kees Cook
2022-08-05 15:42 ` [PATCH v9 23/27] Kbuild: add Rust support Miguel Ojeda
2022-08-17 20:26   ` Kees Cook
2022-08-17 20:56     ` Miguel Ojeda
2022-08-22 22:35   ` Nick Desaulniers
2022-09-12 16:07   ` Masahiro Yamada
2022-09-12 16:18     ` Miguel Ojeda
2022-09-13  6:37       ` Masahiro Yamada
2022-08-05 15:42 ` [PATCH v9 24/27] docs: add Rust documentation Miguel Ojeda
2022-08-05 15:42 ` [PATCH v9 25/27] x86: enable initial Rust support Miguel Ojeda
2022-08-17 20:27   ` Kees Cook
2022-08-05 15:42 ` [PATCH v9 26/27] samples: add first Rust examples Miguel Ojeda
2022-08-06 13:14   ` Konstantin Shelekhin
2022-08-17 21:02     ` Miguel Ojeda
2022-08-18  9:04       ` Konstantin Shelekhin
2022-08-17 20:28   ` Kees Cook
2022-08-05 15:42 ` [PATCH v9 27/27] MAINTAINERS: Rust Miguel Ojeda
2022-08-17 20:28   ` Kees Cook
2022-08-17 20:43     ` Miguel Ojeda
     [not found] ` <20220805154231.31257-8-ojeda@kernel.org>
2022-08-17 20:07   ` [PATCH v9 07/27] rust: import upstream `alloc` crate Kees Cook
2022-08-17 21:00     ` Miguel Ojeda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).