2022-09-27 13:52:48

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 00/27] Rust support

Rust support

This is the patch series (v10) 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:

[email protected]

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/[email protected]/
v1: https://lore.kernel.org/lkml/[email protected]/
v2: https://lore.kernel.org/lkml/[email protected]/
v3: https://lore.kernel.org/lkml/[email protected]/
v4: https://lore.kernel.org/lkml/[email protected]/
v5: https://lore.kernel.org/lkml/[email protected]/
v6: https://lore.kernel.org/lkml/[email protected]/
v7: https://lore.kernel.org/lkml/[email protected]/
v8: https://lore.kernel.org/lkml/[email protected]/
v9: https://lore.kernel.org/lkml/[email protected]/

This is v9 with only minimal/trivial changes, intended for v6.1:

- `scripts/kallsyms.c`: replaced `sizeof` with `ARRAY_SIZE`.

- `scripts/kallsyms.c`: added a comment on `KSYM_NAME_LEN_BUFFER`
to clarify why the `_Static_assert` is needed.

- `Makefile`: added a comment on `export RUSTC_BOOTSTRAP := 1` to
explain that it enables unstable features in the stable compiler.

- Moved `min-tool-version.sh` changes to commit "scripts: add
`rust_is_available.sh`".

- Reworded commit "rust: import upstream `alloc` crate" to add
a script snippet to verify that the contents match upstream.

- Reworded commit "rust: add C helpers" to explain that the file
will grow over time.

- Picked `Reviewed-by` and `Tested-by` tags.

- Rebased on top of v6.0-rc7, which clears a few conflicts.

Most of the code has been around in linux-next for some months now.
In particular, v9 has been 7 weeks there.


## 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/v9 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

Thanks a lot to everyone that joined us in LPC 2022 (Linux Plumbers
Conference) for the Rust MC (microconference)!

https://lpc.events/event/16/sessions/150/
https://www.youtube.com/watch?v=Xw9pKeJ-4Bw

In addition, I would like to personally thank Google and ISRG
(Internet Security Research Group) for sponsoring Kangrejos,
the Rust for Linux workshop; and everyone that made the effort
to travel to Spain before LPC:

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:

- Kees Cook, Nick Desaulniers, Konstantin Shelekhin and Masahiro
Yamada for their reviews of some of the v9 patches.

- Matthew Wilcox, Linus Torvalds, comex, Eric W. Biederman,
Greg Kroah-Hartman and Geert Stappers for their feedback on v9.

- Asahi Lina for working on her M1 GPU driver.

- FUJITA Tomonori for continuing his work on PCI, IRQ, BAR, DMA,
`ioremap`... support for a NVMe Rust driver, as well as adding
`be16/32/64` and `le16/32/64` types.

- Li Hongyu for working on making the `get_id_info` function more
general so that it is not tied to `platform`, continuing the work
on the virtio abstraction and the `virtio-net` driver, which
includes abstractions for `ethtool`, `scatterlist`, NAPI...

- Arnaldo Carvalho de Melo for releasing `pahole` 1.24 with support
for `--lang` and `--lang_exclude`, useful "to exclude Rust compile
units while aspects of the DWARF generated for it get sorted out
in a way that the kernel BPF verifier don't refuse loading the BTF
generated from them".

- Martin Rodriguez Reboredo for working on USB abstractions as well
as using the new `pahole` `--lang_exclude` feature to exclude
Rust compilation units.

- David Gow for fixing the UML support.

- Adam Bratschi-Kaye for redoing his debugfs implementation without
`seq_file`.

- Alice Ryhl for continuing her work on adding `BINDER_TYPE_PTR`
support.

- Philipp Gesang for updating the `sysctl` module to deal with
commit 32927393dc1c ("sysctl: pass kernel pointers to
->proc_handler") as well as improving the `module!` macro to allow
overriding the name of module param constants.

- Masahiro Yamada for proposing a refactor of the Kbuild support for
Rust as well as removing the `-v` option of the
`rust_is_available.sh` script.

- Russell Currey for making `scripts/rust_is_available.sh`
compatible with using multiple words for `$CC`, e.g. for `ccache`.

- Jalil David Salamé Messina for marking the `bit` function as
`const` so that it can be used for e.g. creating `const` masks.

- Jon Olson for continuing his work on a `cpu` module with utilities
for SMP systems.

- Raghvender for working on improving a check on
`scripts/rust-is-available.sh`.

- Angelos for working on using `NonZeroI16` as the `Error` inner
type.

- Finn Behrens for updating his work on making it possible to
compile the kernel on macOS with Rust enabled.

- Kaviraj Kanagaraj for suggesting improvements to the quick start
guide.

- Sergio González Collado for suggesting improvements to the
`Makefile` to show an extra message.

- 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 Rust GCC.

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

- Emilio Cobos Álvarez, Christian Poveda 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 `ARRAY_SIZE` 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 | 8 +
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 | 53 +-
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, 12552 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: f76349cf41451c5c42a99f18a9163377e4b364ff
--
2.37.3


2022-09-27 13:53:15

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 15/27] scripts: checkpatch: diagnose uses of `%pA` in the C side as errors

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 <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: Joe Perches <[email protected]>
Signed-off-by: Joe Perches <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
scripts/checkpatch.pl | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 79e759aac543..74a769310adf 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -6783,15 +6783,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.3

2022-09-27 13:53:37

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 25/27] x86: enable initial Rust support

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.

Reviewed-by: Kees Cook <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: David Gow <[email protected]>
Signed-off-by: David Gow <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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 f9920f1341c8..3ca198742b10 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -257,6 +257,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 bafbd905e6e7..2d7e640674c6 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.3

2022-09-27 13:53:44

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 05/27] kallsyms: increase maximum kernel symbol length to 512

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 <[email protected]>
Reviewed-by: Petr Mladek <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: Gary Guo <[email protected]>
Signed-off-by: Gary Guo <[email protected]>
Co-developed-by: Boqun Feng <[email protected]>
Signed-off-by: Boqun Feng <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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 6502c4001f01..c4793301a27e 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -30,7 +30,7 @@
#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.
@@ -39,7 +39,7 @@
* for the fscanf() format string. Therefore, a _Static_assert() is
* used instead to maintain the relationship with KSYM_NAME_LEN.
*/
-#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 93bf93a59c99..d8ae4e944467 100644
--- a/tools/lib/perf/include/perf/event.h
+++ b/tools/lib/perf/include/perf/event.h
@@ -97,7 +97,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.3

2022-09-27 13:55:45

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 04/27] kallsyms: support "big" kernel symbols

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 <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: Gary Guo <[email protected]>
Signed-off-by: Gary Guo <[email protected]>
Co-developed-by: Boqun Feng <[email protected]>
Signed-off-by: Boqun Feng <[email protected]>
Co-developed-by: Matthew Wilcox <[email protected]>
Signed-off-by: Matthew Wilcox <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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 3e7e2c2ad2f7..fc5e26348d25 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -50,12 +50,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
@@ -108,7 +116,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,
@@ -122,8 +130,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 411ff5058b51..6502c4001f01 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -487,12 +487,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.3

2022-09-27 13:55:49

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 06/27] rust: add C helpers

Introduces the source file that will contain forwarders to C macros
and inlined functions.

Initially this only contains a single helper, but will gain more as
more functionality is added to the `kernel` crate in the future.

Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Geoffrey Thomas <[email protected]>
Signed-off-by: Geoffrey Thomas <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: Sven Van Asbroeck <[email protected]>
Signed-off-by: Sven Van Asbroeck <[email protected]>
Co-developed-by: Gary Guo <[email protected]>
Signed-off-by: Gary Guo <[email protected]>
Co-developed-by: Boqun Feng <[email protected]>
Signed-off-by: Boqun Feng <[email protected]>
Co-developed-by: Maciej Falkowski <[email protected]>
Signed-off-by: Maciej Falkowski <[email protected]>
Co-developed-by: Wei Liu <[email protected]>
Signed-off-by: Wei Liu <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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.3

2022-09-27 14:11:15

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 19/27] scripts: add `generate_rust_target.rs`

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.

Reviewed-by: Kees Cook <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: David Gow <[email protected]>
Signed-off-by: David Gow <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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.3

2022-09-27 14:11:38

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 26/27] samples: add first Rust examples

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.

Reviewed-by: Kees Cook <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Finn Behrens <[email protected]>
Signed-off-by: Finn Behrens <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: Milan Landaverde <[email protected]>
Signed-off-by: Milan Landaverde <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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.3

2022-09-27 14:11:52

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 21/27] scripts: add `is_rust_module.sh`

From: Daniel Xu <[email protected]>

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.

Reviewed-by: Kees Cook <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Daniel Xu <[email protected]>
Co-developed-by: Miguel Ojeda <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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.3

2022-09-27 14:12:38

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 17/27] scripts: decode_stacktrace: demangle Rust symbols

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

Reviewed-by: Kees Cook <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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.3

2022-09-27 14:16:24

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 14/27] vsprintf: add new `%pA` format specifier

From: Gary Guo <[email protected]>

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 <[email protected]>
Acked-by: Petr Mladek <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Gary Guo <[email protected]>
Co-developed-by: Miguel Ojeda <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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.3

2022-09-27 14:18:47

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 24/27] docs: add Rust documentation

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 <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Finn Behrens <[email protected]>
Signed-off-by: Finn Behrens <[email protected]>
Co-developed-by: Adam Bratschi-Kaye <[email protected]>
Signed-off-by: Adam Bratschi-Kaye <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: Michael Ellerman <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Co-developed-by: Sven Van Asbroeck <[email protected]>
Signed-off-by: Sven Van Asbroeck <[email protected]>
Co-developed-by: Wu XiangCheng <[email protected]>
Signed-off-by: Wu XiangCheng <[email protected]>
Co-developed-by: Gary Guo <[email protected]>
Signed-off-by: Gary Guo <[email protected]>
Co-developed-by: Boris-Chengbiao Zhou <[email protected]>
Signed-off-by: Boris-Chengbiao Zhou <[email protected]>
Co-developed-by: Yuki Okushi <[email protected]>
Signed-off-by: Yuki Okushi <[email protected]>
Co-developed-by: Wei Liu <[email protected]>
Signed-off-by: Wei Liu <[email protected]>
Co-developed-by: Daniel Xu <[email protected]>
Signed-off-by: Daniel Xu <[email protected]>
Co-developed-by: Julian Merkle <[email protected]>
Signed-off-by: Julian Merkle <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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 9c779bd7a751..1dcbd7332476 100644
--- a/Documentation/doc-guide/kernel-doc.rst
+++ b/Documentation/doc-guide/kernel-doc.rst
@@ -14,6 +14,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 4737c18c97ff..00722aa20cd7 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.3

2022-09-27 14:19:20

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 18/27] scripts: add `generate_rust_analyzer.py`

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.

Reviewed-by: Kees Cook <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Finn Behrens <[email protected]>
Signed-off-by: Finn Behrens <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: Gary Guo <[email protected]>
Signed-off-by: Gary Guo <[email protected]>
Co-developed-by: Boris-Chengbiao Zhou <[email protected]>
Signed-off-by: Boris-Chengbiao Zhou <[email protected]>
Co-developed-by: Björn Roy Baron <[email protected]>
Signed-off-by: Björn Roy Baron <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
.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.3

2022-09-27 14:19:27

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 12/27] rust: add `kernel` crate

From: Wedson Almeida Filho <[email protected]>

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 <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Geoffrey Thomas <[email protected]>
Signed-off-by: Geoffrey Thomas <[email protected]>
Co-developed-by: Finn Behrens <[email protected]>
Signed-off-by: Finn Behrens <[email protected]>
Co-developed-by: Adam Bratschi-Kaye <[email protected]>
Signed-off-by: Adam Bratschi-Kaye <[email protected]>
Co-developed-by: Sven Van Asbroeck <[email protected]>
Signed-off-by: Sven Van Asbroeck <[email protected]>
Co-developed-by: Gary Guo <[email protected]>
Signed-off-by: Gary Guo <[email protected]>
Co-developed-by: Boris-Chengbiao Zhou <[email protected]>
Signed-off-by: Boris-Chengbiao Zhou <[email protected]>
Co-developed-by: Boqun Feng <[email protected]>
Signed-off-by: Boqun Feng <[email protected]>
Co-developed-by: Fox Chen <[email protected]>
Signed-off-by: Fox Chen <[email protected]>
Co-developed-by: Viktor Garske <[email protected]>
Signed-off-by: Viktor Garske <[email protected]>
Co-developed-by: Dariusz Sosnowski <[email protected]>
Signed-off-by: Dariusz Sosnowski <[email protected]>
Co-developed-by: Léo Lanteri Thauvin <[email protected]>
Signed-off-by: Léo Lanteri Thauvin <[email protected]>
Co-developed-by: Niklas Mohrin <[email protected]>
Signed-off-by: Niklas Mohrin <[email protected]>
Co-developed-by: Milan Landaverde <[email protected]>
Signed-off-by: Milan Landaverde <[email protected]>
Co-developed-by: Morgan Bartlett <[email protected]>
Signed-off-by: Morgan Bartlett <[email protected]>
Co-developed-by: Maciej Falkowski <[email protected]>
Signed-off-by: Maciej Falkowski <[email protected]>
Co-developed-by: Nándor István Krácser <[email protected]>
Signed-off-by: Nándor István Krácser <[email protected]>
Co-developed-by: David Gow <[email protected]>
Signed-off-by: David Gow <[email protected]>
Co-developed-by: John Baublitz <[email protected]>
Signed-off-by: John Baublitz <[email protected]>
Co-developed-by: Björn Roy Baron <[email protected]>
Signed-off-by: Björn Roy Baron <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: Miguel Ojeda <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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.3

2022-09-27 14:20:00

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 02/27] kallsyms: avoid hardcoding buffer size

From: Boqun Feng <[email protected]>

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.

Reviewed-by: Kees Cook <[email protected]>
Signed-off-by: Boqun Feng <[email protected]>
Co-developed-by: Miguel Ojeda <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
scripts/kallsyms.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 8551513f9311..25e2fe5fbcd4 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, ARRAY_SIZE(name), in) == NULL)
fprintf(stderr, "Read error or end of file.\n");
--
2.37.3

2022-09-27 14:20:09

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 09/27] rust: add `compiler_builtins` crate

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.

Reviewed-by: Kees Cook <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: Sven Van Asbroeck <[email protected]>
Signed-off-by: Sven Van Asbroeck <[email protected]>
Co-developed-by: Gary Guo <[email protected]>
Signed-off-by: Gary Guo <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
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.3

2022-09-27 14:21:06

by Miguel Ojeda

[permalink] [raw]
Subject: [PATCH v10 27/27] MAINTAINERS: Rust

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

Boqun, Gary and Björn will be reviewers.

Reviewed-by: Kees Cook <[email protected]>
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
MAINTAINERS | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f5ca4aefd184..944dc265b64d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17758,6 +17758,24 @@ F: include/rv/
F: kernel/trace/rv/
F: tools/verification/

+RUST
+M: Miguel Ojeda <[email protected]>
+M: Alex Gaynor <[email protected]>
+M: Wedson Almeida Filho <[email protected]>
+R: Boqun Feng <[email protected]>
+R: Gary Guo <[email protected]>
+R: Björn Roy Baron <[email protected]>
+L: [email protected]
+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 <[email protected]>
M: Marc Dionne <[email protected]>
--
2.37.3

2022-09-27 14:26:27

by Geert Stappers

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Tue, Sep 27, 2022 at 03:14:58PM +0200, Miguel Ojeda wrote:
> Miguel, Alex and Wedson will be maintaining the Rust support.
>
> Boqun, Gary and Bj?rn will be reviewers.
>
> Reviewed-by: Kees Cook <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> MAINTAINERS | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f5ca4aefd184..944dc265b64d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -17758,6 +17758,24 @@ F: include/rv/
> F: kernel/trace/rv/
> F: tools/verification/
>
> +RUST
> +M: Miguel Ojeda <[email protected]>
> +M: Alex Gaynor <[email protected]>
> +M: Wedson Almeida Filho <[email protected]>
<screenshot from="response of a reply-to-all that I just did">
** Address not found **

Your message wasn't delivered to [email protected] because the
address couldn't be found, or is unable to receive mail.

Learn more here: https://support.google.com/mail/answer/6596

The response was:

The email account that you tried to reach does not exist. Please try
double-checking the recipient's email address for typos or unnecessary
spaces. Learn more at https://support.google.com/mail/answer/6596
</screenshot>

> +R: Boqun Feng <[email protected]>
> +R: Gary Guo <[email protected]>
> +R: Bj?rn Roy Baron <[email protected]>
> +L: [email protected]
> +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 <[email protected]>
> M: Marc Dionne <[email protected]>
> --
> 2.37.3
>

Groeten
Geert Stappers
--
Silence is hard to parse

2022-09-27 15:03:40

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 05/27] kallsyms: increase maximum kernel symbol length to 512

On Tue, Sep 27, 2022 at 03:14:36PM +0200, Miguel Ojeda wrote:
> 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 <[email protected]>
> Reviewed-by: Petr Mladek <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Co-developed-by: Gary Guo <[email protected]>
> Signed-off-by: Gary Guo <[email protected]>
> Co-developed-by: Boqun Feng <[email protected]>
> Signed-off-by: Boqun Feng <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> 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(-)

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 15:05:25

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 14/27] vsprintf: add new `%pA` format specifier

On Tue, Sep 27, 2022 at 03:14:45PM +0200, Miguel Ojeda wrote:
> From: Gary Guo <[email protected]>
>
> 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 <[email protected]>
> Acked-by: Petr Mladek <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Gary Guo <[email protected]>
> Co-developed-by: Miguel Ojeda <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> Documentation/core-api/printk-formats.rst | 10 ++++++++++
> lib/vsprintf.c | 13 +++++++++++++
> 2 files changed, 23 insertions(+)

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 15:24:25

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 02/27] kallsyms: avoid hardcoding buffer size

On Tue, Sep 27, 2022 at 03:14:33PM +0200, Miguel Ojeda wrote:
> From: Boqun Feng <[email protected]>
>
> 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.
>
> Reviewed-by: Kees Cook <[email protected]>
> Signed-off-by: Boqun Feng <[email protected]>
> Co-developed-by: Miguel Ojeda <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> scripts/kallsyms.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 15:27:33

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Tue, Sep 27, 2022 at 04:11:38PM +0200, Geert Stappers wrote:
> On Tue, Sep 27, 2022 at 03:14:58PM +0200, Miguel Ojeda wrote:
> > Miguel, Alex and Wedson will be maintaining the Rust support.
> >
> > Boqun, Gary and Bj?rn will be reviewers.
> >
> > Reviewed-by: Kees Cook <[email protected]>
> > Co-developed-by: Alex Gaynor <[email protected]>
> > Signed-off-by: Alex Gaynor <[email protected]>
> > Co-developed-by: Wedson Almeida Filho <[email protected]>
> > Signed-off-by: Wedson Almeida Filho <[email protected]>
> > Signed-off-by: Miguel Ojeda <[email protected]>
> > ---
> > MAINTAINERS | 18 ++++++++++++++++++
> > 1 file changed, 18 insertions(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index f5ca4aefd184..944dc265b64d 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -17758,6 +17758,24 @@ F: include/rv/
> > F: kernel/trace/rv/
> > F: tools/verification/
> >
> > +RUST
> > +M: Miguel Ojeda <[email protected]>
> > +M: Alex Gaynor <[email protected]>
> > +M: Wedson Almeida Filho <[email protected]>
> <screenshot from="response of a reply-to-all that I just did">
> ** Address not found **
>
> Your message wasn't delivered to [email protected] because the
> address couldn't be found, or is unable to receive mail.
>
> Learn more here: https://support.google.com/mail/answer/6596
>
> The response was:
>
> The email account that you tried to reach does not exist. Please try
> double-checking the recipient's email address for typos or unnecessary
> spaces. Learn more at https://support.google.com/mail/answer/6596
> </screenshot>

Wedson, can you send (or Ack) the following patch? :)

diff --git a/.mailmap b/.mailmap
index d175777af078..3a7fe4ee56fb 100644
--- a/.mailmap
+++ b/.mailmap
@@ -433,6 +433,7 @@ Vlad Dogaru <[email protected]> <[email protected]>
Vladimir Davydov <[email protected]> <[email protected]>
Vladimir Davydov <[email protected]> <[email protected]>
WeiXiong Liao <[email protected]> <[email protected]>
+Wedson Almeida Filho <[email protected]> <[email protected]>
Will Deacon <[email protected]> <[email protected]>
Wolfram Sang <[email protected]> <[email protected]>
Wolfram Sang <[email protected]> <[email protected]>

--
Kees Cook

2022-09-27 15:36:45

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Tue, Sep 27, 2022 at 08:19:44AM -0700, Kees Cook wrote:
> On Tue, Sep 27, 2022 at 04:11:38PM +0200, Geert Stappers wrote:
> > On Tue, Sep 27, 2022 at 03:14:58PM +0200, Miguel Ojeda wrote:
> > > Miguel, Alex and Wedson will be maintaining the Rust support.
> > >
> > > Boqun, Gary and Bj?rn will be reviewers.
> > >
> > > Reviewed-by: Kees Cook <[email protected]>
> > > Co-developed-by: Alex Gaynor <[email protected]>
> > > Signed-off-by: Alex Gaynor <[email protected]>
> > > Co-developed-by: Wedson Almeida Filho <[email protected]>
> > > Signed-off-by: Wedson Almeida Filho <[email protected]>
> > > Signed-off-by: Miguel Ojeda <[email protected]>
> > > ---
> > > MAINTAINERS | 18 ++++++++++++++++++
> > > 1 file changed, 18 insertions(+)
> > >
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index f5ca4aefd184..944dc265b64d 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -17758,6 +17758,24 @@ F: include/rv/
> > > F: kernel/trace/rv/
> > > F: tools/verification/
> > >
> > > +RUST
> > > +M: Miguel Ojeda <[email protected]>
> > > +M: Alex Gaynor <[email protected]>
> > > +M: Wedson Almeida Filho <[email protected]>
> > <screenshot from="response of a reply-to-all that I just did">
> > ** Address not found **
> >
> > Your message wasn't delivered to [email protected] because the
> > address couldn't be found, or is unable to receive mail.
> >
> > Learn more here: https://support.google.com/mail/answer/6596
> >
> > The response was:
> >
> > The email account that you tried to reach does not exist. Please try
> > double-checking the recipient's email address for typos or unnecessary
> > spaces. Learn more at https://support.google.com/mail/answer/6596
> > </screenshot>
>
> Wedson, can you send (or Ack) the following patch? :)
>
> diff --git a/.mailmap b/.mailmap
> index d175777af078..3a7fe4ee56fb 100644
> --- a/.mailmap
> +++ b/.mailmap
> @@ -433,6 +433,7 @@ Vlad Dogaru <[email protected]> <[email protected]>
> Vladimir Davydov <[email protected]> <[email protected]>
> Vladimir Davydov <[email protected]> <[email protected]>
> WeiXiong Liao <[email protected]> <[email protected]>
> +Wedson Almeida Filho <[email protected]> <[email protected]>

How about just fixing up the emails in these patches, which will keep us
from having bouncing ones for those of us who do not use the .mailmap
file.

thanks,

greg k-h

2022-09-27 15:46:02

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 04/27] kallsyms: support "big" kernel symbols

On Tue, Sep 27, 2022 at 03:14:35PM +0200, Miguel Ojeda wrote:
> 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 <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Co-developed-by: Gary Guo <[email protected]>
> Signed-off-by: Gary Guo <[email protected]>
> Co-developed-by: Boqun Feng <[email protected]>
> Signed-off-by: Boqun Feng <[email protected]>
> Co-developed-by: Matthew Wilcox <[email protected]>
> Signed-off-by: Matthew Wilcox <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> kernel/kallsyms.c | 26 ++++++++++++++++++++++----
> scripts/kallsyms.c | 29 ++++++++++++++++++++++++++---
> 2 files changed, 48 insertions(+), 7 deletions(-)

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 15:46:31

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 17/27] scripts: decode_stacktrace: demangle Rust symbols

On Tue, Sep 27, 2022 at 03:14:48PM +0200, Miguel Ojeda wrote:
> Recent versions of both Binutils (`c++filt`) and LLVM (`llvm-cxxfilt`)
> provide Rust v0 mangling support.
>
> Reviewed-by: Kees Cook <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> scripts/decode_stacktrace.sh | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 15:47:10

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 12/27] rust: add `kernel` crate

On Tue, Sep 27, 2022 at 03:14:43PM +0200, Miguel Ojeda wrote:
> +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 }

This feels "odd" to me. Why not just use __kmalloc() instead of
krealloc()? I think that will get you the same kasan tracking, and
should be a tiny bit faster (1-2 less function calls).

I guess it probably doesn't matter right now, just curious, and not a
big deal at all.

Other minor comments:


> +/// Contains the C-compatible error codes.
> +pub mod code {
> + /// Out of memory.
> + pub const ENOMEM: super::Error = super::Error(-(crate::bindings::ENOMEM as i32));
> +}

You'll be adding other error values here over time, right?


> +/// 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>;

What about functions that do have return functions of:
>= 0 number of bytes read/written/consumed/whatever
< 0 error code

Would that use Result or Error as a type? Or is it best just to not try
to model that mess in Rust calls? :)

> +macro_rules! pr_info (
> + ($($arg:tt)*) => (
> + $crate::print_macro!($crate::print::format_strings::INFO, $($arg)*)
> + )
> +);

In the long run, using "raw" print macros like this is usually not the
thing to do. Drivers always have a device to reference the message to,
and other things like filesystems and subsystems have a prefix to use as
well.

Hopefully not many will use these as-is and we can wrap them properly
later on.

Then there's the whole dynamic debug stuff, but that's a different
topic.

Anyway, all looks sane to me, sorry for the noise:

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 15:47:27

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 15/27] scripts: checkpatch: diagnose uses of `%pA` in the C side as errors

On Tue, Sep 27, 2022 at 03:14:46PM +0200, Miguel Ojeda wrote:
> 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 <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Co-developed-by: Joe Perches <[email protected]>
> Signed-off-by: Joe Perches <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> scripts/checkpatch.pl | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 15:48:15

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 21/27] scripts: add `is_rust_module.sh`

On Tue, Sep 27, 2022 at 03:14:52PM +0200, Miguel Ojeda wrote:
> From: Daniel Xu <[email protected]>
>
> 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.
>
> Reviewed-by: Kees Cook <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Daniel Xu <[email protected]>
> Co-developed-by: Miguel Ojeda <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> scripts/is_rust_module.sh | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
> create mode 100755 scripts/is_rust_module.sh

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 15:51:43

by Alex Gaynor

[permalink] [raw]
Subject: Re: [PATCH v10 12/27] rust: add `kernel` crate

On Tue, Sep 27, 2022 at 10:22 AM Greg Kroah-Hartman
<[email protected]> wrote:
>
> On Tue, Sep 27, 2022 at 03:14:43PM +0200, Miguel Ojeda wrote:
> > +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 }
>
> This feels "odd" to me. Why not just use __kmalloc() instead of
> krealloc()? I think that will get you the same kasan tracking, and
> should be a tiny bit faster (1-2 less function calls).
>

This may literally be the oldest code in the project :-). To the best
of my recollection, it's krealloc simply because that seemed like a
public API that worked. I don't think it even occurred to use to look
at __kmalloc.

> I guess it probably doesn't matter right now, just curious, and not a
> big deal at all.
>
> Other minor comments:
>
>
> > +/// Contains the C-compatible error codes.
> > +pub mod code {
> > + /// Out of memory.
> > + pub const ENOMEM: super::Error = super::Error(-(crate::bindings::ENOMEM as i32));
> > +}
>
> You'll be adding other error values here over time, right?
>

Yes -- this is the most minimal set that's needed for the initial
patch set. The full branch has every error constant bound.

>
> > +/// 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>;
>
> What about functions that do have return functions of:
> >= 0 number of bytes read/written/consumed/whatever
> < 0 error code
>
> Would that use Result or Error as a type? Or is it best just to not try
> to model that mess in Rust calls? :)
>

We'd model that as a `Result<usize>`. Negative values would become
`Err(EWHATEVER)` and non-negative values would be `Ok(n)`. Then at the
boundaries of Rust/C code we'd convert as appropriate.

> > +macro_rules! pr_info (
> > + ($($arg:tt)*) => (
> > + $crate::print_macro!($crate::print::format_strings::INFO, $($arg)*)
> > + )
> > +);
>
> In the long run, using "raw" print macros like this is usually not the
> thing to do. Drivers always have a device to reference the message to,
> and other things like filesystems and subsystems have a prefix to use as
> well.
>
> Hopefully not many will use these as-is and we can wrap them properly
> later on.
>
> Then there's the whole dynamic debug stuff, but that's a different
> topic.
>
> Anyway, all looks sane to me, sorry for the noise:
>
> Reviewed-by: Greg Kroah-Hartman <[email protected]>

Cheers,
Alex

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

2022-09-27 15:52:16

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 06/27] rust: add C helpers

On Tue, Sep 27, 2022 at 03:14:37PM +0200, Miguel Ojeda wrote:
> Introduces the source file that will contain forwarders to C macros
> and inlined functions.
>
> Initially this only contains a single helper, but will gain more as
> more functionality is added to the `kernel` crate in the future.
>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Geoffrey Thomas <[email protected]>
> Signed-off-by: Geoffrey Thomas <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Co-developed-by: Sven Van Asbroeck <[email protected]>
> Signed-off-by: Sven Van Asbroeck <[email protected]>
> Co-developed-by: Gary Guo <[email protected]>
> Signed-off-by: Gary Guo <[email protected]>
> Co-developed-by: Boqun Feng <[email protected]>
> Signed-off-by: Boqun Feng <[email protected]>
> Co-developed-by: Maciej Falkowski <[email protected]>
> Signed-off-by: Maciej Falkowski <[email protected]>
> Co-developed-by: Wei Liu <[email protected]>
> Signed-off-by: Wei Liu <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> rust/helpers.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 51 insertions(+)
> create mode 100644 rust/helpers.c

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 15:59:01

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v10 12/27] rust: add `kernel` crate

On Tue, Sep 27, 2022 at 5:22 PM Greg Kroah-Hartman
<[email protected]> wrote:
>
> This feels "odd" to me. Why not just use __kmalloc() instead of
> krealloc()? I think that will get you the same kasan tracking, and
> should be a tiny bit faster (1-2 less function calls).
>
> I guess it probably doesn't matter right now, just curious, and not a
> big deal at all.

Yeah, nowadays I think a "C helper" could have been used instead.

> You'll be adding other error values here over time, right?

Indeed, I removed all the ones we didn't use in v8 to reduce it a bit
more. Sorry for the confusion! :)

> What about functions that do have return functions of:
> >= 0 number of bytes read/written/consumed/whatever
> < 0 error code
>
> Would that use Result or Error as a type? Or is it best just to not try
> to model that mess in Rust calls? :)

`Result`, i.e. the "number of bytes" part would go in the `Ok` variant
and the "error code" in the `Err` variant.

The benefit is that then you have to handle them "separately", i.e.
you cannot confuse the number of bytes for the error code by mistake,
or vice versa.

> In the long run, using "raw" print macros like this is usually not the
> thing to do. Drivers always have a device to reference the message to,
> and other things like filesystems and subsystems have a prefix to use as
> well.
>
> Hopefully not many will use these as-is and we can wrap them properly
> later on.

Definitely, we will have e.g. the `dev_*!` ones:

https://github.com/Rust-for-Linux/linux/blob/fcad53ca9071c7bf6a412640a82e679bad6d1cd4/rust/kernel/device.rs#L479-L502

> Anyway, all looks sane to me, sorry for the noise:
>
> Reviewed-by: Greg Kroah-Hartman <[email protected]>

Thanks a lot for taking a look!

Cheers,
Miguel

2022-09-27 16:04:37

by Wedson Almeida Filho

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Tue, 27 Sept 2022 at 16:19, Kees Cook <[email protected]> wrote:
>
> On Tue, Sep 27, 2022 at 04:11:38PM +0200, Geert Stappers wrote:
> > On Tue, Sep 27, 2022 at 03:14:58PM +0200, Miguel Ojeda wrote:
> > > Miguel, Alex and Wedson will be maintaining the Rust support.
> > >
> > > Boqun, Gary and Björn will be reviewers.
> > >
> > > Reviewed-by: Kees Cook <[email protected]>
> > > Co-developed-by: Alex Gaynor <[email protected]>
> > > Signed-off-by: Alex Gaynor <[email protected]>
> > > Co-developed-by: Wedson Almeida Filho <[email protected]>
> > > Signed-off-by: Wedson Almeida Filho <[email protected]>
> > > Signed-off-by: Miguel Ojeda <[email protected]>
> > > ---
> > > MAINTAINERS | 18 ++++++++++++++++++
> > > 1 file changed, 18 insertions(+)
> > >
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index f5ca4aefd184..944dc265b64d 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -17758,6 +17758,24 @@ F: include/rv/
> > > F: kernel/trace/rv/
> > > F: tools/verification/
> > >
> > > +RUST
> > > +M: Miguel Ojeda <[email protected]>
> > > +M: Alex Gaynor <[email protected]>
> > > +M: Wedson Almeida Filho <[email protected]>
> > <screenshot from="response of a reply-to-all that I just did">
> > ** Address not found **
> >
> > Your message wasn't delivered to [email protected] because the
> > address couldn't be found, or is unable to receive mail.
> >
> > Learn more here: https://support.google.com/mail/answer/6596
> >
> > The response was:
> >
> > The email account that you tried to reach does not exist. Please try
> > double-checking the recipient's email address for typos or unnecessary
> > spaces. Learn more at https://support.google.com/mail/answer/6596
> > </screenshot>
>
> Wedson, can you send (or Ack) the following patch? :)

Acked-by: Wedson Almeida Filho <[email protected]>

>
> diff --git a/.mailmap b/.mailmap
> index d175777af078..3a7fe4ee56fb 100644
> --- a/.mailmap
> +++ b/.mailmap
> @@ -433,6 +433,7 @@ Vlad Dogaru <[email protected]> <[email protected]>
> Vladimir Davydov <[email protected]> <[email protected]>
> Vladimir Davydov <[email protected]> <[email protected]>
> WeiXiong Liao <[email protected]> <[email protected]>
> +Wedson Almeida Filho <[email protected]> <[email protected]>
> Will Deacon <[email protected]> <[email protected]>
> Wolfram Sang <[email protected]> <[email protected]>
> Wolfram Sang <[email protected]> <[email protected]>
>
> --
> Kees Cook

2022-09-27 16:26:36

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Tue, Sep 27, 2022 at 03:14:56PM +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.
>
> Reviewed-by: Kees Cook <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Co-developed-by: David Gow <[email protected]>
> Signed-off-by: David Gow <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> 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(-)

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 16:32:20

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 26/27] samples: add first Rust examples

On Tue, Sep 27, 2022 at 03:14:57PM +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.
>
> Reviewed-by: Kees Cook <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Finn Behrens <[email protected]>
> Signed-off-by: Finn Behrens <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Co-developed-by: Milan Landaverde <[email protected]>
> Signed-off-by: Milan Landaverde <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>

Reviewed-by: Greg Kroah-Hartman <[email protected]>

2022-09-27 16:32:28

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Tue, Sep 27, 2022 at 5:34 PM Greg Kroah-Hartman
<[email protected]> wrote:
>
> How about just fixing up the emails in these patches, which will keep us
> from having bouncing ones for those of us who do not use the .mailmap
> file.

Sorry about that...

One question: if somebody wants to keep the Signed-off-bys and/or Git
authorship information using the old email for the patches (except the
`MAINTAINERS` entry), is that OK? (e.g. maybe because they did most of
the work in their previous company).

Cc'ing Maciej since I got a bounce too: is it OK using your personal address?

Thanks!

Cheers,
Miguel

2022-09-27 17:11:05

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Tue, Sep 27, 2022 at 03:14:58PM +0200, Miguel Ojeda wrote:
> Miguel, Alex and Wedson will be maintaining the Rust support.
>
> Boqun, Gary and Bj?rn will be reviewers.
>
> Reviewed-by: Kees Cook <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> MAINTAINERS | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f5ca4aefd184..944dc265b64d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -17758,6 +17758,24 @@ F: include/rv/
> F: kernel/trace/rv/
> F: tools/verification/
>
> +RUST
> +M: Miguel Ojeda <[email protected]>
> +M: Alex Gaynor <[email protected]>
> +M: Wedson Almeida Filho <[email protected]>

As was pointed out, please don't put a known-invalid email in this file.

thanks,

greg k-h

2022-09-27 17:54:55

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Tue, Sep 27, 2022 at 05:53:12PM +0200, Miguel Ojeda wrote:
> On Tue, Sep 27, 2022 at 5:34 PM Greg Kroah-Hartman
> <[email protected]> wrote:
> >
> > How about just fixing up the emails in these patches, which will keep us
> > from having bouncing ones for those of us who do not use the .mailmap
> > file.
>
> Sorry about that...
>
> One question: if somebody wants to keep the Signed-off-bys and/or Git
> authorship information using the old email for the patches (except the
> `MAINTAINERS` entry), is that OK? (e.g. maybe because they did most of
> the work in their previous company).

For known-broken emails, it's a pain as later on invocations of
scripts/get_maintainer.pl will use those emails.

So please just use known-good addresses to start with.

thanks,

greg k-h

2022-09-27 18:45:24

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Tue, Sep 27, 2022 at 06:39:27PM +0200, Greg Kroah-Hartman wrote:
> On Tue, Sep 27, 2022 at 05:53:12PM +0200, Miguel Ojeda wrote:
> > On Tue, Sep 27, 2022 at 5:34 PM Greg Kroah-Hartman
> > <[email protected]> wrote:
> > >
> > > How about just fixing up the emails in these patches, which will keep us
> > > from having bouncing ones for those of us who do not use the .mailmap
> > > file.
> >
> > Sorry about that...
> >
> > One question: if somebody wants to keep the Signed-off-bys and/or Git
> > authorship information using the old email for the patches (except the
> > `MAINTAINERS` entry), is that OK? (e.g. maybe because they did most of
> > the work in their previous company).
>
> For known-broken emails, it's a pain as later on invocations of
> scripts/get_maintainer.pl will use those emails.

FWIW, get_maintainer.pl does use .mailmap by default already.

> So please just use known-good addresses to start with.

Sure, that makes sense here too. I just sent the .mailmap patch because
Wedson does have other patches in the kernel too, so it wasn't just for
this case.

--
Kees Cook

2022-09-28 00:25:39

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Tue, Sep 27, 2022 at 05:53:12PM +0200, Miguel Ojeda wrote:
> On Tue, Sep 27, 2022 at 5:34 PM Greg Kroah-Hartman
> <[email protected]> wrote:
> >
> > How about just fixing up the emails in these patches, which will keep us
> > from having bouncing ones for those of us who do not use the .mailmap
> > file.
>
> Sorry about that...
>
> One question: if somebody wants to keep the Signed-off-bys and/or Git
> authorship information using the old email for the patches (except the
> `MAINTAINERS` entry), is that OK? (e.g. maybe because they did most of
> the work in their previous company).

IMO, the S-o-b's should stand since they're historical, but fixing
MAINTAINERS to be up-to-date makes sense.

--
Kees Cook

2022-09-28 10:24:46

by Sergey Senozhatsky

[permalink] [raw]
Subject: Re: [PATCH v10 14/27] vsprintf: add new `%pA` format specifier

On (22/09/27 15:14), Miguel Ojeda wrote:
> 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 <[email protected]>
> Acked-by: Petr Mladek <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Gary Guo <[email protected]>
> Co-developed-by: Miguel Ojeda <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>

Reviewed-by: Sergey Senozhatsky <[email protected]>

2022-09-28 12:06:16

by Wedson Almeida Filho

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Wed, 28 Sept 2022 at 01:11, Kees Cook <[email protected]> wrote:
>
> On Tue, Sep 27, 2022 at 05:53:12PM +0200, Miguel Ojeda wrote:
> > On Tue, Sep 27, 2022 at 5:34 PM Greg Kroah-Hartman
> > <[email protected]> wrote:
> > >
> > > How about just fixing up the emails in these patches, which will keep us
> > > from having bouncing ones for those of us who do not use the .mailmap
> > > file.
> >
> > Sorry about that...
> >
> > One question: if somebody wants to keep the Signed-off-bys and/or Git
> > authorship information using the old email for the patches (except the
> > `MAINTAINERS` entry), is that OK? (e.g. maybe because they did most of
> > the work in their previous company).
>
> IMO, the S-o-b's should stand since they're historical, but fixing
> MAINTAINERS to be up-to-date makes sense.

Our intent wasn't to have a known-invalid email in MAINTAINERS, it was
just my mistake: after leaving Google I updated my email in a lot of
places but missed this one. Apologies for that.

The patch below fixes this:

diff --git a/MAINTAINERS b/MAINTAINERS
index f4e31512bab8..e082270dd285 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17913,7 +17913,7 @@ F: tools/verification/
RUST
M: Miguel Ojeda <[email protected]>
M: Alex Gaynor <[email protected]>
-M: Wedson Almeida Filho <[email protected]>
+M: Wedson Almeida Filho <[email protected]>
R: Boqun Feng <[email protected]>
R: Gary Guo <[email protected]>
R: Björn Roy Baron <[email protected]>

Thanks,
-Wedson

2022-09-28 13:00:49

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v10 27/27] MAINTAINERS: Rust

On Wed, Sep 28, 2022 at 1:57 PM Wedson Almeida Filho <[email protected]> wrote:
>
> Our intent wasn't to have a known-invalid email in MAINTAINERS, it was
> just my mistake: after leaving Google I updated my email in a lot of
> places but missed this one. Apologies for that.

It was also mine for not realizing it! :)

> The patch below fixes this:

Thanks Wedson!

Kees and I discussed how to proceed earlier and so I updated a few
hours ago the branch collecting the tags we got so far and fixing your
email address in `MAINTAINERS`, so it is there in `rust-next` now:

https://github.com/Rust-for-Linux/linux/blob/fd9517a1603f083dfa88f3cf9dc67d26f6ba0ec0/MAINTAINERS#L17764

Cheers,
Miguel

2022-09-28 13:52:32

by Wei Liu

[permalink] [raw]
Subject: Re: [PATCH v10 09/27] rust: add `compiler_builtins` crate

On Tue, Sep 27, 2022 at 03:14:40PM +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.
>
> Reviewed-by: Kees Cook <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Co-developed-by: Sven Van Asbroeck <[email protected]>
> Signed-off-by: Sven Van Asbroeck <[email protected]>
> Co-developed-by: Gary Guo <[email protected]>
> Signed-off-by: Gary Guo <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>

Reviewed-by: Wei Liu <[email protected]>

2022-09-28 14:48:39

by Wei Liu

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Tue, Sep 27, 2022 at 03:14:56PM +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.
>
> Reviewed-by: Kees Cook <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Co-developed-by: David Gow <[email protected]>
> Signed-off-by: David Gow <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> ---
> 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 f9920f1341c8..3ca198742b10 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -257,6 +257,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 bafbd905e6e7..2d7e640674c6 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

I do wonder how many more things you will need to list here. As far as
I can tell there is also other avx512* flags for the x86_64 target.

That said, if this works today ...

Reviewed-by: Wei Liu <[email protected]>

2022-09-28 15:07:20

by Wei Liu

[permalink] [raw]
Subject: Re: [PATCH v10 02/27] kallsyms: avoid hardcoding buffer size

On Tue, Sep 27, 2022 at 03:14:33PM +0200, Miguel Ojeda wrote:
> From: Boqun Feng <[email protected]>
>
> 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.
>
> Reviewed-by: Kees Cook <[email protected]>
> Signed-off-by: Boqun Feng <[email protected]>
> Co-developed-by: Miguel Ojeda <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>

Reviewed-by: Wei Liu <[email protected]>

2022-09-28 15:13:57

by Wei Liu

[permalink] [raw]
Subject: Re: [PATCH v10 26/27] samples: add first Rust examples

On Tue, Sep 27, 2022 at 03:14:57PM +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.
>
> Reviewed-by: Kees Cook <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Finn Behrens <[email protected]>
> Signed-off-by: Finn Behrens <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Co-developed-by: Milan Landaverde <[email protected]>
> Signed-off-by: Milan Landaverde <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>

Reviewed-by: Wei Liu <[email protected]>

2022-09-28 15:25:20

by Wei Liu

[permalink] [raw]
Subject: Re: [PATCH v10 00/27] Rust support

On Tue, Sep 27, 2022 at 03:14:31PM +0200, Miguel Ojeda wrote:
>
> Miguel Ojeda (22):
> rust: import upstream `alloc` crate

I cannot find this patch in my inbox. That's probably filtered out by
the mailing list since it is too big.

I've gone to GitHub to take a look at the commit
753dece88d70a23b015e01674a662e683235c08f in the `rust-next` branch. It
looks good to me, so feel free to add

Reviewed-by: Wei Liu <[email protected]>

to that patch.

Thanks,
Wei.

2022-09-28 15:51:34

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v10 00/27] Rust support

On Wed, Sep 28, 2022 at 5:07 PM Wei Liu <[email protected]> wrote:
>
> I cannot find this patch in my inbox. That's probably filtered out by
> the mailing list since it is too big.

The patch reached lore in case you want to double-check:

https://lore.kernel.org/lkml/[email protected]/

I am Cc'ing [email protected] as suggested by Konstantin to
reduce the chance of problems, though I wouldn't expect to have issues
now since it is fairly smaller than v8 where we hit the issue.

Cheers,
Miguel

2022-09-28 16:29:39

by Wei Liu

[permalink] [raw]
Subject: Re: [PATCH v10 00/27] Rust support

On Wed, Sep 28, 2022 at 05:34:39PM +0200, Miguel Ojeda wrote:
> On Wed, Sep 28, 2022 at 5:07 PM Wei Liu <[email protected]> wrote:
> >
> > I cannot find this patch in my inbox. That's probably filtered out by
> > the mailing list since it is too big.
>
> The patch reached lore in case you want to double-check:
>
> https://lore.kernel.org/lkml/[email protected]/
>

I eyeballed it. Looks like it is the same one on GitHub.

2022-09-28 17:18:23

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Wed, Sep 28, 2022 at 4:32 PM Wei Liu <[email protected]> wrote:
>
> I do wonder how many more things you will need to list here. As far as
> I can tell there is also other avx512* flags for the x86_64 target.

Yeah, there are a lot of target features, but they are not getting enabled.

Eventually, a stable target spec alternative (e.g. all relevant target
feature flags) should be available, and then we can know what the
guaranteed behavior will be and thus decide better which flags to keep
or not depending on how explicit we want to be with respect to that.

For the moment I went for consistency with the line above, since that
was enough to disable everything we needed, though as you may have
noticed, 3dnow and mmx are not there, because I had to move them back
to the target spec [1].

[1] https://github.com/Rust-for-Linux/linux/commit/c5eae3a6e69c63dc8d69f51f74f74b853831ec71

Cheers,
Miguel

2022-10-07 17:30:10

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Tue, Sep 27, 2022 at 03:14:56PM +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.

Does it fail the build if required options are missing? Specifically are
things like kCFI and IBT enabled? Silently not handling those will
result in an unbootable image.

As to missing mitigations; does it at least visibly warn people?

I'm very *very* uncomfortable having to 'support' a half-arsed compiler
like this.

2022-10-11 00:00:42

by Sami Tolvanen

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Fri, Oct 7, 2022 at 10:18 AM Peter Zijlstra <[email protected]> wrote:
>
> On Tue, Sep 27, 2022 at 03:14:56PM +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.
>
> Does it fail the build if required options are missing? Specifically are
> things like kCFI and IBT enabled? Silently not handling those will
> result in an unbootable image.

Rust supports IBT with -Z cf-protection=branch, but I don't see this
option being enabled in the kernel yet. Cross-language CFI is going to
require a lot more work though because the type systems are not quite
compatible:

https://github.com/rust-lang/rfcs/pull/3296

Sami

2022-10-11 08:26:43

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Mon, Oct 10, 2022 at 04:15:33PM -0700, Sami Tolvanen wrote:
> On Fri, Oct 7, 2022 at 10:18 AM Peter Zijlstra <[email protected]> wrote:
> >
> > On Tue, Sep 27, 2022 at 03:14:56PM +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.
> >
> > Does it fail the build if required options are missing? Specifically are
> > things like kCFI and IBT enabled? Silently not handling those will
> > result in an unbootable image.
>
> Rust supports IBT with -Z cf-protection=branch, but I don't see this
> option being enabled in the kernel yet. Cross-language CFI is going to
> require a lot more work though because the type systems are not quite
> compatible:

Right; so where does that leave us? Are we going to force disable rust
when kCFI is selected ?

2022-10-14 17:30:54

by Boqun Feng

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Fri, Oct 14, 2022 at 07:23:18PM +0200, Miguel Ojeda wrote:
> On Tue, Oct 11, 2022 at 10:04 AM Peter Zijlstra <[email protected]> wrote:
> >
> > Right; so where does that leave us? Are we going to force disable rust
> > when kCFI is selected ?
>
> Constraining it via `depends on !...` or similar as needed for the
> moment is fine, we have a few others too.
>

Right, and Peter, we actually need your help to figure out which configs
are related ;-)

Regards,
Boqun

> Cheers,
> Miguel

2022-10-14 18:07:26

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Tue, Oct 11, 2022 at 10:04 AM Peter Zijlstra <[email protected]> wrote:
>
> Right; so where does that leave us? Are we going to force disable rust
> when kCFI is selected ?

Constraining it via `depends on !...` or similar as needed for the
moment is fine, we have a few others too.

Cheers,
Miguel

2022-10-14 18:20:57

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Tue, Oct 11, 2022 at 1:16 AM Sami Tolvanen <[email protected]> wrote:
>
> Rust supports IBT with -Z cf-protection=branch, but I don't see this
> option being enabled in the kernel yet. Cross-language CFI is going to
> require a lot more work though because the type systems are not quite
> compatible:
>
> https://github.com/rust-lang/rfcs/pull/3296

I have pinged Ramon de C Valle as he is the author of the RFC above
and implementation work too; since a month or so ago he also leads the
Exploit Mitigations Project Group in Rust.

Cheers,
Miguel

2022-10-14 18:36:42

by Sami Tolvanen

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Fri, Oct 14, 2022 at 11:05 AM Miguel Ojeda
<[email protected]> wrote:
>
> On Tue, Oct 11, 2022 at 1:16 AM Sami Tolvanen <[email protected]> wrote:
> >
> > Rust supports IBT with -Z cf-protection=branch, but I don't see this
> > option being enabled in the kernel yet. Cross-language CFI is going to
> > require a lot more work though because the type systems are not quite
> > compatible:
> >
> > https://github.com/rust-lang/rfcs/pull/3296
>
> I have pinged Ramon de C Valle as he is the author of the RFC above
> and implementation work too; since a month or so ago he also leads the
> Exploit Mitigations Project Group in Rust.

Thanks, Miguel. I also talked to Ramon about KCFI earlier this week
and he expressed interest in helping with rustc support for it. In the
meanwhile, I think we can just add a depends on !CFI_CLANG to avoid
issues here.

Sami

2022-10-14 21:10:25

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Fri, Oct 14, 2022 at 8:35 PM Sami Tolvanen <[email protected]> wrote:
>
> Thanks, Miguel. I also talked to Ramon about KCFI earlier this week
> and he expressed interest in helping with rustc support for it. In the

Ah, that is great to hear -- thanks a lot to you both! (Cc'ing Ramon)

> meanwhile, I think we can just add a depends on !CFI_CLANG to avoid
> issues here.

ACK, thanks -- if you want to send the patch, please feel free to do so.

Cheers,
Miguel

2022-10-29 18:00:29

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH v10 04/27] kallsyms: support "big" kernel symbols

On Tue, Sep 27, 2022 at 03:14:35PM +0200, Miguel Ojeda wrote:
> 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 <[email protected]>
> Co-developed-by: Alex Gaynor <[email protected]>
> Signed-off-by: Alex Gaynor <[email protected]>
> Co-developed-by: Wedson Almeida Filho <[email protected]>
> Signed-off-by: Wedson Almeida Filho <[email protected]>
> Co-developed-by: Gary Guo <[email protected]>
> Signed-off-by: Gary Guo <[email protected]>
> Co-developed-by: Boqun Feng <[email protected]>
> Signed-off-by: Boqun Feng <[email protected]>
> Co-developed-by: Matthew Wilcox <[email protected]>
> Signed-off-by: Matthew Wilcox <[email protected]>
> Signed-off-by: Miguel Ojeda <[email protected]>
> Reviewed-by: Greg Kroah-Hartman <[email protected]>
> ---
> kernel/kallsyms.c | 26 ++++++++++++++++++++++----
> scripts/kallsyms.c | 29 ++++++++++++++++++++++++++---
> 2 files changed, 48 insertions(+), 7 deletions(-)
>

This patch results in the following spurious build error.

Building powerpc:allnoconfig ... failed
--------------
Error log:
Inconsistent kallsyms data
Try make KALLSYMS_EXTRA_PASS=1 as a workaround

Symbol file differences:
10c10
< 00009720 g .rodata 00000000 kallsyms_relative_base
---
> 0000971c g .rodata 00000000 kallsyms_relative_base
12,16c12,16
< 00009724 g .rodata 00000000 kallsyms_num_syms
< 00009728 g .rodata 00000000 kallsyms_names
< 00022628 g .rodata 00000000 kallsyms_markers
< 000226c0 g .rodata 00000000 kallsyms_token_table
< 00022a2c g .rodata 00000000 kallsyms_token_index
---
> 00009720 g .rodata 00000000 kallsyms_num_syms
> 00009724 g .rodata 00000000 kallsyms_names
> 00022618 g .rodata 00000000 kallsyms_markers
> 000226b0 g .rodata 00000000 kallsyms_token_table
> 00022a1c g .rodata 00000000 kallsyms_token_index

This is the only difference. There are no additional symbols.

Reverting this patch fixes the problem.

Guenter

2022-10-29 19:05:24

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH v10 04/27] kallsyms: support "big" kernel symbols

On Sat, Oct 29, 2022 at 10:41:49AM -0700, Guenter Roeck wrote:
> On Tue, Sep 27, 2022 at 03:14:35PM +0200, Miguel Ojeda wrote:
> > 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 <[email protected]>
> > Co-developed-by: Alex Gaynor <[email protected]>
> > Signed-off-by: Alex Gaynor <[email protected]>
> > Co-developed-by: Wedson Almeida Filho <[email protected]>
> > Signed-off-by: Wedson Almeida Filho <[email protected]>
> > Co-developed-by: Gary Guo <[email protected]>
> > Signed-off-by: Gary Guo <[email protected]>
> > Co-developed-by: Boqun Feng <[email protected]>
> > Signed-off-by: Boqun Feng <[email protected]>
> > Co-developed-by: Matthew Wilcox <[email protected]>
> > Signed-off-by: Matthew Wilcox <[email protected]>
> > Signed-off-by: Miguel Ojeda <[email protected]>
> > Reviewed-by: Greg Kroah-Hartman <[email protected]>
> > ---
> > kernel/kallsyms.c | 26 ++++++++++++++++++++++----
> > scripts/kallsyms.c | 29 ++++++++++++++++++++++++++---
> > 2 files changed, 48 insertions(+), 7 deletions(-)
> >
>
> This patch results in the following spurious build error.
>
> Building powerpc:allnoconfig ... failed
> --------------
> Error log:
> Inconsistent kallsyms data
> Try make KALLSYMS_EXTRA_PASS=1 as a workaround

I should have added: KALLSYMS_EXTRA_PASS=1 does not help.

Guenter

>
> Symbol file differences:
> 10c10
> < 00009720 g .rodata 00000000 kallsyms_relative_base
> ---
> > 0000971c g .rodata 00000000 kallsyms_relative_base
> 12,16c12,16
> < 00009724 g .rodata 00000000 kallsyms_num_syms
> < 00009728 g .rodata 00000000 kallsyms_names
> < 00022628 g .rodata 00000000 kallsyms_markers
> < 000226c0 g .rodata 00000000 kallsyms_token_table
> < 00022a2c g .rodata 00000000 kallsyms_token_index
> ---
> > 00009720 g .rodata 00000000 kallsyms_num_syms
> > 00009724 g .rodata 00000000 kallsyms_names
> > 00022618 g .rodata 00000000 kallsyms_markers
> > 000226b0 g .rodata 00000000 kallsyms_token_table
> > 00022a1c g .rodata 00000000 kallsyms_token_index
>
> This is the only difference. There are no additional symbols.
>
> Reverting this patch fixes the problem.
>
> Guenter

2023-10-09 16:01:27

by Matthew Maurer

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

I have a patchset enabling support for both KCFI and IBT in the
kernel, but it uses changes not yet landed in stable rustc, which is
why I haven't sent it to the list yet:
https://github.com/Rust-for-Linux/linux/pull/1034

We've backported the changes to rustc that need to be present onto the
Android copy of the compiler, but it will take 6-12 weeks for them to
hit stable rustc, which is what general Linux is using.

If the IBT part would be helpful by itself immediately, I can split
that out - it's only the KCFI portion that won't currently work.

On Fri, Oct 14, 2022 at 1:40 PM Miguel Ojeda
<[email protected]> wrote:
>
> On Fri, Oct 14, 2022 at 8:35 PM Sami Tolvanen <[email protected]> wrote:
> >
> > Thanks, Miguel. I also talked to Ramon about KCFI earlier this week
> > and he expressed interest in helping with rustc support for it. In the
>
> Ah, that is great to hear -- thanks a lot to you both! (Cc'ing Ramon)
>
> > meanwhile, I think we can just add a depends on !CFI_CLANG to avoid
> > issues here.
>
> ACK, thanks -- if you want to send the patch, please feel free to do so.
>
> Cheers,
> Miguel

2023-10-09 16:31:43

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Mon, Oct 9, 2023 at 6:01 PM Matthew Maurer <[email protected]> wrote:
>
> If the IBT part would be helpful by itself immediately, I can split
> that out - it's only the KCFI portion that won't currently work.

Thanks Matthew. I don't think we are in a rush, but if it is not too
much work to split it, that would be great, instead of adding the
restriction.

For retthunk, by the way, I forgot to mention to Greg above that (in
the original discussion with PeterZ) that I did a quick test back then
to hack the equivalent of `-mfunction-return=thunk-extern` into
`rustc` to show that the compiler could use it via LLVM (by passing
the attribute in the IR). At least at a basic level it seemed to work:
I got a userspace program to count the times that it went through the
return thunk. I didn't try to do anything on the kernel side, but at
least for the compiler side, it seemed OK. So it may be way easier (on
the compiler side) than the CFI work?

Cheers,
Miguel

2023-10-09 17:37:14

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Mon, Oct 09, 2023 at 06:31:13PM +0200, Miguel Ojeda wrote:
> On Mon, Oct 9, 2023 at 6:01 PM Matthew Maurer <[email protected]> wrote:
> >
> > If the IBT part would be helpful by itself immediately, I can split
> > that out - it's only the KCFI portion that won't currently work.
>
> Thanks Matthew. I don't think we are in a rush, but if it is not too
> much work to split it, that would be great, instead of adding the
> restriction.
>
> For retthunk, by the way, I forgot to mention to Greg above that (in
> the original discussion with PeterZ) that I did a quick test back then
> to hack the equivalent of `-mfunction-return=thunk-extern` into
> `rustc` to show that the compiler could use it via LLVM (by passing
> the attribute in the IR). At least at a basic level it seemed to work:
> I got a userspace program to count the times that it went through the
> return thunk. I didn't try to do anything on the kernel side, but at
> least for the compiler side, it seemed OK. So it may be way easier (on
> the compiler side) than the CFI work?

It should hopefully be much easier than CFI, it was a much simpler
change to gcc and clang when it landed.

thanks,

greg k-h

2023-10-12 10:48:40

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Fri, Oct 14, 2022 at 11:34:30AM -0700, Sami Tolvanen wrote:
> On Fri, Oct 14, 2022 at 11:05 AM Miguel Ojeda
> <[email protected]> wrote:
> >
> > On Tue, Oct 11, 2022 at 1:16 AM Sami Tolvanen <[email protected]> wrote:
> > >
> > > Rust supports IBT with -Z cf-protection=branch, but I don't see this
> > > option being enabled in the kernel yet. Cross-language CFI is going to
> > > require a lot more work though because the type systems are not quite
> > > compatible:
> > >
> > > https://github.com/rust-lang/rfcs/pull/3296
> >
> > I have pinged Ramon de C Valle as he is the author of the RFC above
> > and implementation work too; since a month or so ago he also leads the
> > Exploit Mitigations Project Group in Rust.
>
> Thanks, Miguel. I also talked to Ramon about KCFI earlier this week
> and he expressed interest in helping with rustc support for it. In the
> meanwhile, I think we can just add a depends on !CFI_CLANG to avoid
> issues here.

Having just read up on the thing it looks like the KCFI thing is
resolved.

I'm not sure I understand most of the objections in that thread through
-- enabling CFI *will* break stuff, so what.

Squashing the integer types seems a workable compromise I suppose. One
thing that's been floated in the past is adding a 'seed' attribute to
some functions in order to distinguish functions of otherwise identical
signature.

The Rust thing would then also need to support this attribute.

Are there any concrete plans for this? It would allow, for example,
to differentiate address_space_operations::swap_deactivate() from any
other random function that takes only a file argument, say:
locks_remove_file().

2023-10-12 17:51:59

by Sami Tolvanen

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Thu, Oct 12, 2023 at 3:47 AM Peter Zijlstra <[email protected]> wrote:
>
> On Fri, Oct 14, 2022 at 11:34:30AM -0700, Sami Tolvanen wrote:
> > On Fri, Oct 14, 2022 at 11:05 AM Miguel Ojeda
> > <[email protected]> wrote:
> > >
> > > On Tue, Oct 11, 2022 at 1:16 AM Sami Tolvanen <[email protected]> wrote:
> > > >
> > > > Rust supports IBT with -Z cf-protection=branch, but I don't see this
> > > > option being enabled in the kernel yet. Cross-language CFI is going to
> > > > require a lot more work though because the type systems are not quite
> > > > compatible:
> > > >
> > > > https://github.com/rust-lang/rfcs/pull/3296
> > >
> > > I have pinged Ramon de C Valle as he is the author of the RFC above
> > > and implementation work too; since a month or so ago he also leads the
> > > Exploit Mitigations Project Group in Rust.
> >
> > Thanks, Miguel. I also talked to Ramon about KCFI earlier this week
> > and he expressed interest in helping with rustc support for it. In the
> > meanwhile, I think we can just add a depends on !CFI_CLANG to avoid
> > issues here.
>
> Having just read up on the thing it looks like the KCFI thing is
> resolved.
>
> I'm not sure I understand most of the objections in that thread through
> -- enabling CFI *will* break stuff, so what.
>
> Squashing the integer types seems a workable compromise I suppose. One
> thing that's been floated in the past is adding a 'seed' attribute to
> some functions in order to distinguish functions of otherwise identical
> signature.
>
> The Rust thing would then also need to support this attribute.
>
> Are there any concrete plans for this? It would allow, for example,
> to differentiate address_space_operations::swap_deactivate() from any
> other random function that takes only a file argument, say:
> locks_remove_file().

I haven't really had time to look into it, so no concrete plans yet.
Adding an attribute shouldn't be terribly difficult, but Kees
expressed interest in automatic salting as well, which might be a more
involved project:

https://github.com/ClangBuiltLinux/linux/issues/1736

Sami

2023-10-12 18:31:41

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Thu, Oct 12, 2023 at 10:50:36AM -0700, Sami Tolvanen wrote:
> On Thu, Oct 12, 2023 at 3:47 AM Peter Zijlstra <[email protected]> wrote:
> >
> > On Fri, Oct 14, 2022 at 11:34:30AM -0700, Sami Tolvanen wrote:
> > > On Fri, Oct 14, 2022 at 11:05 AM Miguel Ojeda
> > > <[email protected]> wrote:
> > > >
> > > > On Tue, Oct 11, 2022 at 1:16 AM Sami Tolvanen <[email protected]> wrote:
> > > > >
> > > > > Rust supports IBT with -Z cf-protection=branch, but I don't see this
> > > > > option being enabled in the kernel yet. Cross-language CFI is going to
> > > > > require a lot more work though because the type systems are not quite
> > > > > compatible:
> > > > >
> > > > > https://github.com/rust-lang/rfcs/pull/3296
> > > >
> > > > I have pinged Ramon de C Valle as he is the author of the RFC above
> > > > and implementation work too; since a month or so ago he also leads the
> > > > Exploit Mitigations Project Group in Rust.
> > >
> > > Thanks, Miguel. I also talked to Ramon about KCFI earlier this week
> > > and he expressed interest in helping with rustc support for it. In the
> > > meanwhile, I think we can just add a depends on !CFI_CLANG to avoid
> > > issues here.
> >
> > Having just read up on the thing it looks like the KCFI thing is
> > resolved.
> >
> > I'm not sure I understand most of the objections in that thread through
> > -- enabling CFI *will* break stuff, so what.
> >
> > Squashing the integer types seems a workable compromise I suppose. One
> > thing that's been floated in the past is adding a 'seed' attribute to
> > some functions in order to distinguish functions of otherwise identical
> > signature.
> >
> > The Rust thing would then also need to support this attribute.
> >
> > Are there any concrete plans for this? It would allow, for example,
> > to differentiate address_space_operations::swap_deactivate() from any
> > other random function that takes only a file argument, say:
> > locks_remove_file().
>
> I haven't really had time to look into it, so no concrete plans yet.
> Adding an attribute shouldn't be terribly difficult, but Kees
> expressed interest in automatic salting as well, which might be a more
> involved project:
>
> https://github.com/ClangBuiltLinux/linux/issues/1736

Automatic would be nice, but having an attribute would let us at least
start the process manually (or apply salting from static analysis
output, etc).

-Kees

--
Kees Cook

2023-10-12 22:27:20

by Ramon de C Valle

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Thu, Oct 12, 2023 at 11:31 AM Kees Cook <[email protected]> wrote:
>
> On Thu, Oct 12, 2023 at 10:50:36AM -0700, Sami Tolvanen wrote:
> > On Thu, Oct 12, 2023 at 3:47 AM Peter Zijlstra <[email protected]> wrote:
> > >
> > > On Fri, Oct 14, 2022 at 11:34:30AM -0700, Sami Tolvanen wrote:
> > > > On Fri, Oct 14, 2022 at 11:05 AM Miguel Ojeda
> > > > <[email protected]> wrote:
> > > > >
> > > > > On Tue, Oct 11, 2022 at 1:16 AM Sami Tolvanen <[email protected]> wrote:
> > > > > >
> > > > > > Rust supports IBT with -Z cf-protection=branch, but I don't see this
> > > > > > option being enabled in the kernel yet. Cross-language CFI is going to
> > > > > > require a lot more work though because the type systems are not quite
> > > > > > compatible:
> > > > > >
> > > > > > https://github.com/rust-lang/rfcs/pull/3296
> > > > >
> > > > > I have pinged Ramon de C Valle as he is the author of the RFC above
> > > > > and implementation work too; since a month or so ago he also leads the
> > > > > Exploit Mitigations Project Group in Rust.
> > > >
> > > > Thanks, Miguel. I also talked to Ramon about KCFI earlier this week
> > > > and he expressed interest in helping with rustc support for it. In the
> > > > meanwhile, I think we can just add a depends on !CFI_CLANG to avoid
> > > > issues here.
> > >
> > > Having just read up on the thing it looks like the KCFI thing is
> > > resolved.
> > >
> > > I'm not sure I understand most of the objections in that thread through
> > > -- enabling CFI *will* break stuff, so what.
> > >
> > > Squashing the integer types seems a workable compromise I suppose. One
> > > thing that's been floated in the past is adding a 'seed' attribute to
> > > some functions in order to distinguish functions of otherwise identical
> > > signature.
> > >
> > > The Rust thing would then also need to support this attribute.
> > >
> > > Are there any concrete plans for this? It would allow, for example,
> > > to differentiate address_space_operations::swap_deactivate() from any
> > > other random function that takes only a file argument, say:
> > > locks_remove_file().
> >
> > I haven't really had time to look into it, so no concrete plans yet.
> > Adding an attribute shouldn't be terribly difficult, but Kees
> > expressed interest in automatic salting as well, which might be a more
> > involved project:
> >
> > https://github.com/ClangBuiltLinux/linux/issues/1736
>
> Automatic would be nice, but having an attribute would let us at least
> start the process manually (or apply salting from static analysis
> output, etc).

An idea would be to add something like the Rust cfi_encoding
attribute[1] and use it with something similar to the Newtype
Pattern[2], but in C[3], for aggregating function pointers that
otherwise would be aggregated in the same group in different groups.

[1]: https://doc.rust-lang.org/nightly/unstable-book/language-features/cfi-encoding.html
[2]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction
[3]: Wrapping a type in a struct should achieve something similar even
without using the cfi_encoding attribute since the encoding for
structs is <length><name>, where <name> is <unscoped-name>.

2023-10-13 07:51:03

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Thu, Oct 12, 2023 at 03:15:12PM -0700, Ramon de C Valle wrote:

> [1]:
> https://doc.rust-lang.org/nightly/unstable-book/language-features/cfi-encoding.html

I'm sorry, but that looks like a comment from where I'm sitting :-(
Worst part is it being on a line of it's own and thus unrelated to
anything.

This rust syntax is horrific..


> [2]:
> https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction

I don't speak enough rust to even begin following this :/

> [3]: Wrapping a type in a struct should achieve something similar even
> without using the cfi_encoding attribute since the encoding for structs in
> both are <length><name>, where <name> is <unscoped-name>.

You're not talking about C, right?

2023-10-13 12:18:20

by Ramon de C Valle

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Fri, Oct 13, 2023 at 12:50 AM Peter Zijlstra <[email protected]> wrote:
>
> On Thu, Oct 12, 2023 at 03:15:12PM -0700, Ramon de C Valle wrote:
>
> > [1]:
> > https://doc.rust-lang.org/nightly/unstable-book/language-features/cfi-encoding.html
>
> I'm sorry, but that looks like a comment from where I'm sitting :-(
> Worst part is it being on a line of it's own and thus unrelated to
> anything.
>
> This rust syntax is horrific..

I understand where you're coming from. I'm still getting used to Rust syntax.

>
>
> > [2]:
> > https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction
>
> I don't speak enough rust to even begin following this :/
>
> > [3]: Wrapping a type in a struct should achieve something similar even
> > without using the cfi_encoding attribute since the encoding for structs in
> > both are <length><name>, where <name> is <unscoped-name>.
>
> You're not talking about C, right?

Both C and repr(C) Rust structs have this encoding, but I understand
the problems with doing this in C since it doesn't have
repr(transparent) structs so there would be a lot of casting back and
forth. Maybe there is an alternative or this could be done for less
used function pairs?

2023-10-13 18:55:22

by Linus Torvalds

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Fri, 13 Oct 2023 at 05:18, Ramon de C Valle <[email protected]> wrote:
>
> Both C and repr(C) Rust structs have this encoding, but I understand
> the problems with doing this in C since it doesn't have
> repr(transparent) structs so there would be a lot of casting back and
> forth. Maybe there is an alternative or this could be done for less
> used function pairs?

We actually have some C variations of what I think people want to use
"repr(transparent) struct" for in Rust.

Of course, that is depending on what kind of context you want to use
it for, and I might have lost some background. But I'm assuming you're
talking about the situation where you want to treat two or more types
as being "compatible" within certain contexts.

There's the actual standard C "_Generic()" alternative, which allows
you to make macros etc that use different types transparently.

It's not very widely used in the kernel, because we only fairly
recently moved to require recent enough compiler versions, but we do
use it now in a couple of places.

And there's the much more traditional gcc extension in the form of the
__attribute__((__transparent_union__)) thing. In the kernel, that one
is even less used, and that one use is likely going away since the
need for it is going away.

But while it's not standard C, it's actually been supported by
relevant compilers for much longer than "_Generic" has, and is
designed exactly for the "I have a function that can take arguments of
different types", either because the types are bitwise identical (even
if _conceptually_ not the same), or simply because you have a
different argument that describes the type (the traditional C union
model).

I suspect, for example, that we *should* have used those transparent
unions for the "this function can take either a folio or a page" case,
instead of duplicating functions for the two uses.

But probably because few people aren familiar with the syntax, that's
not what happened.

Linus

2023-10-13 19:02:28

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On October 13, 2023 11:54:46 AM PDT, Linus Torvalds <[email protected]> wrote:
>On Fri, 13 Oct 2023 at 05:18, Ramon de C Valle <[email protected]> wrote:
>>
>> Both C and repr(C) Rust structs have this encoding, but I understand
>> the problems with doing this in C since it doesn't have
>> repr(transparent) structs so there would be a lot of casting back and
>> forth. Maybe there is an alternative or this could be done for less
>> used function pairs?
>
>We actually have some C variations of what I think people want to use
>"repr(transparent) struct" for in Rust.
>
>Of course, that is depending on what kind of context you want to use
>it for, and I might have lost some background. But I'm assuming you're
>talking about the situation where you want to treat two or more types
>as being "compatible" within certain contexts.
>
>There's the actual standard C "_Generic()" alternative, which allows
>you to make macros etc that use different types transparently.
>
>It's not very widely used in the kernel, because we only fairly
>recently moved to require recent enough compiler versions, but we do
>use it now in a couple of places.
>
>And there's the much more traditional gcc extension in the form of the
>__attribute__((__transparent_union__)) thing. In the kernel, that one
>is even less used, and that one use is likely going away since the
>need for it is going away.
>
>But while it's not standard C, it's actually been supported by
>relevant compilers for much longer than "_Generic" has, and is
>designed exactly for the "I have a function that can take arguments of
>different types", either because the types are bitwise identical (even
>if _conceptually_ not the same), or simply because you have a
>different argument that describes the type (the traditional C union
>model).
>
>I suspect, for example, that we *should* have used those transparent
>unions for the "this function can take either a folio or a page" case,
>instead of duplicating functions for the two uses.
>
>But probably because few people aren familiar with the syntax, that's
>not what happened.
>
> Linus

Transparent unions have been standard C since C99.

2023-10-13 19:23:24

by Linus Torvalds

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On Fri, 13 Oct 2023 at 12:01, H. Peter Anvin <[email protected]> wrote:
>
> Transparent unions have been standard C since C99.

Ahh, I didn't realize they made it into the standard.

In gcc, they've been usable for a lot longer (ie --std=gnu89 certainly
is happy with them), but the kernel never really picked up on them.

I think they've mainly been used by glibc for a couple of functions
that can take a couple of different types without complaining.

Linus

2023-10-14 20:40:13

by comex

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support



> On Oct 13, 2023, at 12:00 PM, H. Peter Anvin <[email protected]> wrote:
>
> Transparent unions have been standard C since C99.

I don’t think that’s right. Certainly __attribute__((transparent_union)) is not standard C; are you referring to a different feature?

2023-10-14 20:53:32

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH v10 25/27] x86: enable initial Rust support

On October 14, 2023 1:25:12 PM PDT, comex <[email protected]> wrote:
>
>
>> On Oct 13, 2023, at 12:00 PM, H. Peter Anvin <[email protected]> wrote:
>>
>> Transparent unions have been standard C since C99.
>
>I don’t think that’s right. Certainly __attribute__((transparent_union)) is not standard C; are you referring to a different feature?
>

My mistake... I was thinking about anonymous unions.