Rust support
Subsystems (27)
Miguel Ojeda
maintainerv3 cover Rust support
Rust support
This is the patch series (v3) 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:
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]/
## Infrastructure updates
There have been several improvements to the overall Rust support:
- The compiler has been upgraded to Rust 1.58.0.
- Added automatic detection of whether there is a suitable Rust toolchain available (CONFIG_RUST_IS_AVAILABLE, which replaces HAS_RUST), and made CONFIG_RUST depend on it. It also comes with an easy way for users/developers to understand why the Rust toolchain might not be available: a Makefile target is provided (rustavailable) which explains why that is the case, using the same logic that Kbuild/Kconfig use.
- Removed the !COMPILE_TEST gate, which will eventually allow us to increase testing the Rust support in places that run all{yes,mod}config.
- Other build system improvements, such as improved cleaning behavior.
- Documentation: reorganization, new section on naming, clarifications...
One of the unstable features we need, -Zsymbol-mangling-version=v0, is getting stabilized in 1.59.0. Another one, maybe_uninit_extra, will be in 1.60.0. As usual, please see the following link for the live list of unstable features we are using:
https://github.com/Rust-for-Linux/linux/issues/2
## Abstractions and driver updates
Some of the improvements to the abstractions and example drivers are:
- Added IdArray and IdTable which will be used in buses to allow drivers to specify device ID tables that are guaranteed to be zero-terminated at compile time.
- Updated amba to use the new constant device ID table support.
- Initial common clock framework abstractions.
- Platform drivers are now defined by implementing a trait. Includes a new macro for simplified registration of platform drivers and a new sample/template.
- dev_* printing macros.
- {read,write}*_relaxed methods for IoMem<T>.
- Simplified file operations by removing FileOpener.
- Added ThisModule to the arguments of driver registration.
- A basic template for an out-of-tree Linux kernel module written in Rust can be found in:
https://github.com/Rust-for-Linux/rust-out-of-tree-module
## Patch series status
Like we mentioned last time, 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 has just arrived in linux-next, thus the first run will happen in a day. Similarly, the preview docs for this series can be seen at:
https://rust-for-linux.github.io/docs/kernel/
## Conferences, meetings and liaisons
We would want to thank you the venues we were invited to:
- Open Source Summit Japan 2021
## 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:
- Nick Desaulniers, Masahiro Yamada and Greg Kroah-Hartman for their reviews & feedback on the previous round.
- Maciej Falkowski for adding the initial common clock framework abstractions and the {read,write}*_relaxed methods to IoMem<T>.
- Daniel Xu for improving the docs and File.
- Mauro Baladés for improving the CI.
- SeongJae Park for the rust-next patch to fix the -mm tree.
- Hsiang-Cheng Yang for fixing a typo.
- bjorn3 and Gary Guo for all the input on Rust compiler details and all the reviews and suggestions.
- Josh Triplett for pushing -Zsymbol-mangling-version=v0 to the finish line.
- Philip Herrons (and his supporters Open Source Security and Embecosm) et. al. for their ongoing work on GCC Rust.
- Antoni Boucher (and his supporters) et. al. for their ongoing work on rustc_codegen_gcc.
- 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 (1):
kallsyms: use the correct buffer size for symbols
Gary Guo (2):
rust: add build_error crate
vsprintf: add new %pA format specifier
Miguel Ojeda (13):
kallsyms: support "big" kernel symbols
kallsyms: increase maximum kernel symbol length to 512
rust: add C helpers
rust: add compiler_builtins crate
rust: add alloc crate
rust: add macros crate
rust: export generated symbols
scripts: add generate_rust_analyzer.py
scripts: decode_stacktrace: demangle Rust symbols
docs: add Rust documentation
Kbuild: add Rust support
samples: add Rust examples
MAINTAINERS: Rust
Wedson Almeida Filho (3):
rust: add kernel crate
[RFC] drivers: gpio: PrimeCell PL061 in Rust
[RFC] drivers: android: Binder IPC in Rust
.gitignore | 5 + .rustfmt.toml | 12 + Documentation/doc-guide/kernel-doc.rst | 3 + Documentation/index.rst | 1 + Documentation/kbuild/kbuild.rst | 4 + Documentation/process/changes.rst | 42 + Documentation/rust/arch-support.rst | 35 + Documentation/rust/assets/favicon-16x16.png | Bin 0 -> 798 bytes Documentation/rust/assets/favicon-32x32.png | Bin 0 -> 2076 bytes Documentation/rust/assets/rust-logo.png | Bin 0 -> 53976 bytes Documentation/rust/coding-guidelines.rst | 151 + Documentation/rust/general-information.rst | 80 + Documentation/rust/index.rst | 21 + Documentation/rust/quick-start.rst | 231 ++ MAINTAINERS | 16 + Makefile | 152 +- arch/arm/rust/target.json | 27 + arch/arm64/rust/target.json | 34 + arch/powerpc/rust/target.json | 29 + arch/riscv/Makefile | 1 + arch/riscv/rust/rv32ima.json | 36 + arch/riscv/rust/rv32imac.json | 36 + arch/riscv/rust/rv64ima.json | 36 + arch/riscv/rust/rv64imac.json | 36 + arch/x86/rust/target.json | 36 + drivers/android/Kconfig | 7 + drivers/android/Makefile | 2 + drivers/android/allocation.rs | 266 ++ drivers/android/context.rs | 80 + drivers/android/defs.rs | 99 + drivers/android/node.rs | 476 +++ drivers/android/process.rs | 964 +++++ drivers/android/range_alloc.rs | 189 + drivers/android/rust_binder.rs | 114 + drivers/android/thread.rs | 871 +++++ drivers/android/transaction.rs | 326 ++ drivers/gpio/Kconfig | 8 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio_pl061_rust.rs | 362 ++ include/linux/kallsyms.h | 2 +- include/linux/spinlock.h | 17 +- include/uapi/linux/android/binder.h | 28 +- init/Kconfig | 44 +- kernel/kallsyms.c | 26 +- kernel/livepatch/core.c | 4 +- kernel/printk/printk.c | 5 +- lib/Kconfig.debug | 144 + lib/rust.h | 14 + lib/vsprintf.c | 7 + rust/.gitignore | 7 + rust/Makefile | 352 ++ rust/alloc/README.md | 32 + rust/alloc/alloc.rs | 427 +++ rust/alloc/borrow.rs | 498 +++ rust/alloc/boxed.rs | 1847 ++++++++++ rust/alloc/collections/mod.rs | 156 + rust/alloc/fmt.rs | 601 ++++ rust/alloc/lib.rs | 217 ++ rust/alloc/macros.rs | 126 + rust/alloc/raw_vec.rs | 549 +++ rust/alloc/slice.rs | 1279 +++++++ rust/alloc/str.rs | 624 ++++ rust/alloc/string.rs | 2864 +++++++++++++++ rust/alloc/vec/drain.rs | 159 + rust/alloc/vec/drain_filter.rs | 145 + rust/alloc/vec/into_iter.rs | 356 ++ rust/alloc/vec/is_zero.rs | 106 + rust/alloc/vec/mod.rs | 3359 ++++++++++++++++++ rust/alloc/vec/partial_eq.rs | 49 + rust/alloc/vec/set_len_on_drop.rs | 30 + rust/alloc/vec/spec_extend.rs | 172 + rust/bindgen_parameters | 13 + rust/build_error.rs | 29 + rust/compiler_builtins.rs | 57 + rust/exports.c | 16 + rust/helpers.c | 508 +++ rust/kernel/allocator.rs | 65 + rust/kernel/amba.rs | 259 ++ rust/kernel/bindings.rs | 47 + rust/kernel/bindings_helper.h | 31 + rust/kernel/buffer.rs | 52 + rust/kernel/build_assert.rs | 80 + rust/kernel/c_types.rs | 119 + rust/kernel/chrdev.rs | 209 ++ rust/kernel/clk.rs | 75 + rust/kernel/cred.rs | 73 + rust/kernel/device.rs | 549 +++ rust/kernel/driver.rs | 440 +++ rust/kernel/error.rs | 542 +++ rust/kernel/file.rs | 147 + rust/kernel/file_operations.rs | 726 ++++ rust/kernel/gpio.rs | 477 +++ rust/kernel/io_buffer.rs | 153 + rust/kernel/io_mem.rs | 227 ++ rust/kernel/iov_iter.rs | 81 + rust/kernel/irq.rs | 409 +++ rust/kernel/lib.rs | 262 ++ rust/kernel/linked_list.rs | 247 ++ rust/kernel/miscdev.rs | 196 + rust/kernel/module_param.rs | 497 +++ rust/kernel/of.rs | 63 + rust/kernel/pages.rs | 162 + rust/kernel/platform.rs | 224 ++ rust/kernel/power.rs | 118 + rust/kernel/prelude.rs | 36 + rust/kernel/print.rs | 441 +++ rust/kernel/random.rs | 50 + rust/kernel/raw_list.rs | 361 ++ rust/kernel/rbtree.rs | 562 +++ rust/kernel/revocable.rs | 163 + rust/kernel/security.rs | 36 + rust/kernel/static_assert.rs | 39 + rust/kernel/std_vendor.rs | 150 + rust/kernel/str.rs | 375 ++ rust/kernel/sync/arc.rs | 500 +++ rust/kernel/sync/condvar.rs | 138 + rust/kernel/sync/guard.rs | 181 + rust/kernel/sync/locked_by.rs | 112 + rust/kernel/sync/mod.rs | 92 + rust/kernel/sync/mutex.rs | 112 + rust/kernel/sync/revocable_mutex.rs | 184 + rust/kernel/sync/seqlock.rs | 202 ++ rust/kernel/sync/spinlock.rs | 180 + rust/kernel/sysctl.rs | 197 + rust/kernel/task.rs | 182 + rust/kernel/types.rs | 486 +++ rust/kernel/user_ptr.rs | 175 + rust/macros/helpers.rs | 79 + rust/macros/lib.rs | 94 + rust/macros/module.rs | 622 ++++ samples/Kconfig | 2 + samples/Makefile | 1 + samples/rust/Kconfig | 123 + samples/rust/Makefile | 13 + samples/rust/rust_chrdev.rs | 53 + samples/rust/rust_minimal.rs | 38 + samples/rust/rust_miscdev.rs | 147 + samples/rust/rust_module_parameters.rs | 72 + samples/rust/rust_platform.rs | 25 + samples/rust/rust_print.rs | 57 + samples/rust/rust_random.rs | 64 + samples/rust/rust_semaphore.rs | 175 + samples/rust/rust_semaphore_c.c | 212 ++ samples/rust/rust_stack_probing.rs | 40 + samples/rust/rust_sync.rs | 81 + scripts/Kconfig.include | 6 +- scripts/Makefile.build | 22 + scripts/Makefile.debug | 10 + scripts/Makefile.lib | 12 + scripts/Makefile.modfinal | 8 +- scripts/cc-version.sh | 12 +- scripts/decode_stacktrace.sh | 14 + scripts/generate_rust_analyzer.py | 133 + scripts/is_rust_module.sh | 19 + scripts/kallsyms.c | 40 +- scripts/kconfig/confdata.c | 75 + scripts/min-tool-version.sh | 6 + scripts/rust-is-available-bindgen-libclang.h | 2 + scripts/rust-is-available.sh | 159 + tools/include/linux/kallsyms.h | 2 +- tools/lib/perf/include/perf/event.h | 2 +- tools/lib/symbol/kallsyms.h | 2 +- 162 files changed, 33506 insertions(+), 58 deletions(-) create mode 100644 .rustfmt.toml create mode 100644 Documentation/rust/arch-support.rst create mode 100644 Documentation/rust/assets/favicon-16x16.png create mode 100644 Documentation/rust/assets/favicon-32x32.png create mode 100644 Documentation/rust/assets/rust-logo.png 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 arch/arm/rust/target.json create mode 100644 arch/arm64/rust/target.json create mode 100644 arch/powerpc/rust/target.json create mode 100644 arch/riscv/rust/rv32ima.json create mode 100644 arch/riscv/rust/rv32imac.json create mode 100644 arch/riscv/rust/rv64ima.json create mode 100644 arch/riscv/rust/rv64imac.json create mode 100644 arch/x86/rust/target.json create mode 100644 drivers/android/allocation.rs create mode 100644 drivers/android/context.rs create mode 100644 drivers/android/defs.rs create mode 100644 drivers/android/node.rs create mode 100644 drivers/android/process.rs create mode 100644 drivers/android/range_alloc.rs create mode 100644 drivers/android/rust_binder.rs create mode 100644 drivers/android/thread.rs create mode 100644 drivers/android/transaction.rs create mode 100644 drivers/gpio/gpio_pl061_rust.rs create mode 100644 lib/rust.h 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/fmt.rs create mode 100644 rust/alloc/lib.rs create mode 100644 rust/alloc/macros.rs create mode 100644 rust/alloc/raw_vec.rs create mode 100644 rust/alloc/slice.rs create mode 100644 rust/alloc/str.rs create mode 100644 rust/alloc/string.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/alloc/vec/set_len_on_drop.rs create mode 100644 rust/alloc/vec/spec_extend.rs create mode 100644 rust/bindgen_parameters create mode 100644 rust/build_error.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/amba.rs create mode 100644 rust/kernel/bindings.rs create mode 100644 rust/kernel/bindings_helper.h create mode 100644 rust/kernel/buffer.rs create mode 100644 rust/kernel/build_assert.rs create mode 100644 rust/kernel/c_types.rs create mode 100644 rust/kernel/chrdev.rs create mode 100644 rust/kernel/clk.rs create mode 100644 rust/kernel/cred.rs create mode 100644 rust/kernel/device.rs create mode 100644 rust/kernel/driver.rs create mode 100644 rust/kernel/error.rs create mode 100644 rust/kernel/file.rs create mode 100644 rust/kernel/file_operations.rs create mode 100644 rust/kernel/gpio.rs create mode 100644 rust/kernel/io_buffer.rs create mode 100644 rust/kernel/io_mem.rs create mode 100644 rust/kernel/iov_iter.rs create mode 100644 rust/kernel/irq.rs create mode 100644 rust/kernel/lib.rs create mode 100644 rust/kernel/linked_list.rs create mode 100644 rust/kernel/miscdev.rs create mode 100644 rust/kernel/module_param.rs create mode 100644 rust/kernel/of.rs create mode 100644 rust/kernel/pages.rs create mode 100644 rust/kernel/platform.rs create mode 100644 rust/kernel/power.rs create mode 100644 rust/kernel/prelude.rs create mode 100644 rust/kernel/print.rs create mode 100644 rust/kernel/random.rs create mode 100644 rust/kernel/raw_list.rs create mode 100644 rust/kernel/rbtree.rs create mode 100644 rust/kernel/revocable.rs create mode 100644 rust/kernel/security.rs create mode 100644 rust/kernel/static_assert.rs create mode 100644 rust/kernel/std_vendor.rs create mode 100644 rust/kernel/str.rs create mode 100644 rust/kernel/sync/arc.rs create mode 100644 rust/kernel/sync/condvar.rs create mode 100644 rust/kernel/sync/guard.rs create mode 100644 rust/kernel/sync/locked_by.rs create mode 100644 rust/kernel/sync/mod.rs create mode 100644 rust/kernel/sync/mutex.rs create mode 100644 rust/kernel/sync/revocable_mutex.rs create mode 100644 rust/kernel/sync/seqlock.rs create mode 100644 rust/kernel/sync/spinlock.rs create mode 100644 rust/kernel/sysctl.rs create mode 100644 rust/kernel/task.rs create mode 100644 rust/kernel/types.rs create mode 100644 rust/kernel/user_ptr.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/rust_chrdev.rs create mode 100644 samples/rust/rust_minimal.rs create mode 100644 samples/rust/rust_miscdev.rs create mode 100644 samples/rust/rust_module_parameters.rs create mode 100644 samples/rust/rust_platform.rs create mode 100644 samples/rust/rust_print.rs create mode 100644 samples/rust/rust_random.rs create mode 100644 samples/rust/rust_semaphore.rs create mode 100644 samples/rust/rust_semaphore_c.c create mode 100644 samples/rust/rust_stack_probing.rs create mode 100644 samples/rust/rust_sync.rs create mode 100755 scripts/generate_rust_analyzer.py create mode 100755 scripts/is_rust_module.sh create mode 100644 scripts/rust-is-available-bindgen-libclang.h create mode 100755 scripts/rust-is-available.sh
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 1/19 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, and therefore we need to 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), we use ULEB128 to keep smaller symbols in 1 byte, with the rest in 2 bytes.
--- kernel/kallsyms.c | 26 ++++++++++++++++++++++---- scripts/kallsyms.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 7 deletions(-)
kernel/kallsyms.c +22 -4
@@ -69,12 +69,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
@@ -127,7 +135,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,
@@ -141,8 +149,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; }
scripts/kallsyms.c +26 -3
@@ -470,12 +470,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" );
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 2/19 kallsyms: increase maximum kernel symbol length to 512
In reply to Miguel OjedaRust 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.
--- include/linux/kallsyms.h | 2 +- kernel/livepatch/core.c | 4 ++-- scripts/kallsyms.c | 2 +- tools/include/linux/kallsyms.h | 2 +- tools/lib/perf/include/perf/event.h | 2 +- tools/lib/symbol/kallsyms.h | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-)
include/linux/kallsyms.h +1 -1
@@ -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) + \
kernel/livepatch/core.c +2 -2
@@ -213,7 +213,7 @@ static int klp_resolve_symbols(Elf64_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(Elf64_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",
scripts/kallsyms.c +1 -1
@@ -27,7 +27,7 @@#define ARRAY_SIZE (arr) (sizeof(arr) / sizeof(arr[0])) -#define KSYM_NAME_LEN 128 +#define KSYM_NAME_LEN 512struct sym_entry {unsigned long long addr;
tools/include/linux/kallsyms.h +1 -1
@@ -6,7 +6,7 @@#include <stdio.h> #include <unistd.h> -#define KSYM_NAME_LEN 128 +#define KSYM_NAME_LEN 512struct module ;
tools/lib/perf/include/perf/event.h +1 -1
@@ -95,7 +95,7 @@ struct perf_record_throttle { };#ifndef KSYM_NAME_LEN -#define KSYM_NAME_LEN 256 +#define KSYM_NAME_LEN 512#endif struct perf_record_ksymbol {
tools/lib/symbol/kallsyms.h +1 -1
@@ -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)
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 3/19 kallsyms: use the correct buffer size for symbols
In reply to Miguel OjedaFrom: Boqun Feng <[email protected]>
The buffered name size should be larger than KSYM_NAME_LEN, otherwise we cannot tell whether the size of a symbol name is too long.
--- scripts/kallsyms.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
scripts/kallsyms.c +6 -3
@@ -27,6 +27,9 @@#define ARRAY_SIZE (arr) (sizeof(arr) / sizeof(arr[0])) +#define _stringify_1 (x) #x +#define _stringify (x) _stringify_1(x) +#define KSYM_NAME_LEN 512struct sym_entry {
@@ -197,15 +200,15 @@ 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 +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) "s\n", &addr, &type, name);if (rc !=3 ) { -if (rc !=EOF &&fgets (name,500 , in) ==NULL ) +if (rc !=EOF &&fgets (name,KSYM_NAME_LEN +1 , in) ==NULL )fprintf (stderr,"Read error or end of file.\n" );return NULL ; }
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 4/19 rust: add C helpers
In reply to Miguel OjedaThis source file contains forwarders to C macros and inlined functions.
--- rust/helpers.c | 508 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 508 insertions(+) create mode 100644 rust/helpers.c
rust/helpers.c new file +508 -0
@@ -0,0 +1,508 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/bug.h> +#include <linux/build_bug.h> +#include <linux/clk.h> +#include <linux/uaccess.h> +#include <linux/sched/signal.h> +#include <linux/gfp.h> +#include <linux/highmem.h> +#include <linux/uio.h> +#include <linux/errname.h> +#include <linux/mutex.h> +#include <linux/platform_device.h> +#include <linux/security.h> +#include <asm/io.h> +#include <linux/irq.h> +#include <linux/irqchip/chained_irq.h> +#include <linux/irqdomain.h> +#include <linux/amba/bus.h> +#include <linux/of_device.h> + +__noreturn void rust_helper_BUG (void ) +{ +BUG (); +} + +void rust_helper_clk_disable_unprepare (struct clk *clk) +{ +return clk_disable_unprepare (clk); +} +EXPORT_SYMBOL_GPL (rust_helper_clk_disable_unprepare); + +int rust_helper_clk_prepare_enable (struct clk *clk) +{ +return clk_prepare_enable (clk); +} +EXPORT_SYMBOL_GPL (rust_helper_clk_prepare_enable); + +unsigned long rust_helper_copy_from_user (void *to,const void __user *from,unsigned long n) +{ +return copy_from_user (to, from, n); +} + +unsigned long rust_helper_copy_to_user (void __user *to,const void *from,unsigned long n) +{ +return copy_to_user (to, from, n); +} + +unsigned long rust_helper_clear_user (void __user *to,unsigned long n) +{ +return clear_user (to, n); +} + +void __iomem *rust_helper_ioremap (resource_size_t offset,unsigned long size) +{ +return ioremap (offset, size); +} +EXPORT_SYMBOL_GPL (rust_helper_ioremap); + +u8 rust_helper_readb (const volatile void __iomem *addr) +{ +return readb (addr); +} +EXPORT_SYMBOL_GPL (rust_helper_readb); + +u16 rust_helper_readw (const volatile void __iomem *addr) +{ +return readw (addr); +} +EXPORT_SYMBOL_GPL (rust_helper_readw); + +u32 rust_helper_readl (const volatile void __iomem *addr) +{ +return readl (addr); +} +EXPORT_SYMBOL_GPL (rust_helper_readl); + +#ifdef CONFIG_64BIT +u64 rust_helper_readq (const volatile void __iomem *addr) +{ +return readq (addr); +} +EXPORT_SYMBOL_GPL (rust_helper_readq); +#endif + +void rust_helper_writeb (u8 value,volatile void __iomem *addr) +{ +writeb (value, addr); +} +EXPORT_SYMBOL_GPL (rust_helper_writeb); + +void rust_helper_writew (u16 value,volatile void __iomem *addr) +{ +writew (value, addr); +} +EXPORT_SYMBOL_GPL (rust_helper_writew); + +void rust_helper_writel (u32 value,volatile void __iomem *addr) +{ +writel (value, addr); +} +EXPORT_SYMBOL_GPL (rust_helper_writel); + +#ifdef CONFIG_64BIT +void rust_helper_writeq (u64 value,volatile void __iomem *addr) +{ +writeq (value, addr); +} +EXPORT_SYMBOL_GPL (rust_helper_writeq); +#endif + +u8 rust_helper_readb_relaxed (const volatile void __iomem *addr) +{ +return readb_relaxed (addr); +} +EXPORT_SYMBOL_GPL (rust_helper_readb_relaxed); + +u16 rust_helper_readw_relaxed (const volatile void __iomem *addr) +{ +return readw_relaxed (addr); +} +EXPORT_SYMBOL_GPL (rust_helper_readw_relaxed); + +u32 rust_helper_readl_relaxed (const volatile void __iomem *addr) +{ +return readl_relaxed (addr); +} +EXPORT_SYMBOL_GPL (rust_helper_readl_relaxed); + +#ifdef CONFIG_64BIT +u64 rust_helper_readq_relaxed (const volatile void __iomem *addr) +{ +return readq_relaxed (addr); +} +EXPORT_SYMBOL_GPL (rust_helper_readq_relaxed); +#endif + +void rust_helper_writeb_relaxed (u8 value,volatile void __iomem *addr) +{ +writeb_relaxed (value, addr); +} +EXPORT_SYMBOL_GPL (rust_helper_writeb_relaxed); + +void rust_helper_writew_relaxed (u16 value,volatile void __iomem *addr) +{ +writew_relaxed (value, addr); +} +EXPORT_SYMBOL_GPL (rust_helper_writew_relaxed); + +void rust_helper_writel_relaxed (u32 value,volatile void __iomem *addr) +{ +writel_relaxed (value, addr); +} +EXPORT_SYMBOL_GPL (rust_helper_writel_relaxed); + +#ifdef CONFIG_64BIT +void rust_helper_writeq_relaxed (u64 value,volatile void __iomem *addr) +{ +writeq_relaxed (value, addr); +} +EXPORT_SYMBOL_GPL (rust_helper_writeq_relaxed); +#endif +void rust_helper___spin_lock_init (spinlock_t *lock,const char *name, +struct lock_class_key *key) +{ +#ifdef CONFIG_DEBUG_SPINLOCK +__spin_lock_init (lock, name, key); +#else +spin_lock_init (lock); +#endif +} +EXPORT_SYMBOL_GPL (rust_helper___spin_lock_init); + +void rust_helper_spin_lock (spinlock_t *lock) +{ +spin_lock (lock); +} +EXPORT_SYMBOL_GPL (rust_helper_spin_lock); + +void rust_helper_spin_unlock (spinlock_t *lock) +{ +spin_unlock (lock); +} +EXPORT_SYMBOL_GPL (rust_helper_spin_unlock); + +unsigned long rust_helper_spin_lock_irqsave (spinlock_t *lock) +{ +unsigned long flags; +spin_lock_irqsave (lock, flags); +return flags; +} +EXPORT_SYMBOL_GPL (rust_helper_spin_lock_irqsave); + +void rust_helper_spin_unlock_irqrestore (spinlock_t *lock,unsigned long flags) +{ +spin_unlock_irqrestore (lock, flags); +} +EXPORT_SYMBOL_GPL (rust_helper_spin_unlock_irqrestore); + +void rust_helper_init_wait (struct wait_queue_entry *wq_entry) +{ +init_wait (wq_entry); +} +EXPORT_SYMBOL_GPL (rust_helper_init_wait); + +int rust_helper_signal_pending (struct task_struct *t) +{ +return signal_pending (t); +} +EXPORT_SYMBOL_GPL (rust_helper_signal_pending); + +struct page *rust_helper_alloc_pages (gfp_t gfp_mask,unsigned int order) +{ +return alloc_pages (gfp_mask, order); +} +EXPORT_SYMBOL_GPL (rust_helper_alloc_pages); + +void *rust_helper_kmap (struct page *page) +{ +return kmap (page); +} +EXPORT_SYMBOL_GPL (rust_helper_kmap); + +void rust_helper_kunmap (struct page *page) +{ +return kunmap (page); +} +EXPORT_SYMBOL_GPL (rust_helper_kunmap); + +int rust_helper_cond_resched (void ) +{ +return cond_resched (); +} +EXPORT_SYMBOL_GPL (rust_helper_cond_resched); + +size_t rust_helper_copy_from_iter (void *addr,size_t bytes,struct iov_iter *i) +{ +return copy_from_iter (addr, bytes, i); +} +EXPORT_SYMBOL_GPL (rust_helper_copy_from_iter); + +size_t rust_helper_copy_to_iter (const void *addr,size_t bytes,struct iov_iter *i) +{ +return copy_to_iter (addr, bytes, i); +} +EXPORT_SYMBOL_GPL (rust_helper_copy_to_iter); + +bool rust_helper_IS_ERR (__force const void *ptr) +{ +return IS_ERR (ptr); +} +EXPORT_SYMBOL_GPL (rust_helper_IS_ERR); + +long rust_helper_PTR_ERR (__force const void *ptr) +{ +return PTR_ERR (ptr); +} +EXPORT_SYMBOL_GPL (rust_helper_PTR_ERR); + +const char *rust_helper_errname (int err) +{ +return errname (err); +} +EXPORT_SYMBOL_GPL (rust_helper_errname); + +void rust_helper_mutex_lock (struct mutex *lock) +{ +mutex_lock (lock); +} +EXPORT_SYMBOL_GPL (rust_helper_mutex_lock); + +void rust_helper_amba_set_drvdata (struct amba_device *dev,void *data) +{ +amba_set_drvdata (dev, data); +} +EXPORT_SYMBOL_GPL (rust_helper_amba_set_drvdata); + +void *rust_helper_amba_get_drvdata (struct amba_device *dev) +{ +return amba_get_drvdata (dev); +} +EXPORT_SYMBOL_GPL (rust_helper_amba_get_drvdata); + +void * +rust_helper_platform_get_drvdata (const struct platform_device *pdev) +{ +return platform_get_drvdata (pdev); +} +EXPORT_SYMBOL_GPL (rust_helper_platform_get_drvdata); + +void +rust_helper_platform_set_drvdata (struct platform_device *pdev, +void *data) +{ +return platform_set_drvdata (pdev, data); +} +EXPORT_SYMBOL_GPL (rust_helper_platform_set_drvdata); + +refcount_t rust_helper_REFCOUNT_INIT (int n) +{ +return (refcount_t )REFCOUNT_INIT (n); +} +EXPORT_SYMBOL_GPL (rust_helper_REFCOUNT_INIT); + +void rust_helper_refcount_inc (refcount_t *r) +{ +refcount_inc (r); +} +EXPORT_SYMBOL_GPL (rust_helper_refcount_inc); + +bool rust_helper_refcount_dec_and_test (refcount_t *r) +{ +return refcount_dec_and_test (r); +} +EXPORT_SYMBOL_GPL (rust_helper_refcount_dec_and_test); + +void rust_helper_rb_link_node (struct rb_node *node,struct rb_node *parent, +struct rb_node **rb_link) +{ +rb_link_node (node, parent, rb_link); +} +EXPORT_SYMBOL_GPL (rust_helper_rb_link_node); + +struct task_struct *rust_helper_get_current (void ) +{ +return current; +} +EXPORT_SYMBOL_GPL (rust_helper_get_current); + +void rust_helper_get_task_struct (struct task_struct * t) +{ +get_task_struct (t); +} +EXPORT_SYMBOL_GPL (rust_helper_get_task_struct); + +void rust_helper_put_task_struct (struct task_struct * t) +{ +put_task_struct (t); +} +EXPORT_SYMBOL_GPL (rust_helper_put_task_struct); + +int rust_helper_security_binder_set_context_mgr (const struct cred *mgr) +{ +return security_binder_set_context_mgr (mgr); +} +EXPORT_SYMBOL_GPL (rust_helper_security_binder_set_context_mgr); + +int rust_helper_security_binder_transaction (const struct cred *from, +const struct cred *to) +{ +return security_binder_transaction (from, to); +} +EXPORT_SYMBOL_GPL (rust_helper_security_binder_transaction); + +int rust_helper_security_binder_transfer_binder (const struct cred *from, +const struct cred *to) +{ +return security_binder_transfer_binder (from, to); +} +EXPORT_SYMBOL_GPL (rust_helper_security_binder_transfer_binder); + +int rust_helper_security_binder_transfer_file (const struct cred *from, +const struct cred *to, +struct file *file) +{ +return security_binder_transfer_file (from, to, file); +} +EXPORT_SYMBOL_GPL (rust_helper_security_binder_transfer_file); + +void rust_helper_rcu_read_lock (void ) +{ +rcu_read_lock (); +} +EXPORT_SYMBOL_GPL (rust_helper_rcu_read_lock); + +void rust_helper_rcu_read_unlock (void ) +{ +rcu_read_unlock (); +} +EXPORT_SYMBOL_GPL (rust_helper_rcu_read_unlock); + +void rust_helper_synchronize_rcu (void ) +{ +synchronize_rcu (); +} +EXPORT_SYMBOL_GPL (rust_helper_synchronize_rcu); + +void *rust_helper_dev_get_drvdata (struct device *dev) +{ +return dev_get_drvdata (dev); +} +EXPORT_SYMBOL_GPL (rust_helper_dev_get_drvdata); + +const char *rust_helper_dev_name (const struct device *dev) +{ +return dev_name (dev); +} +EXPORT_SYMBOL_GPL (rust_helper_dev_name); + +void rust_helper___seqcount_init (seqcount_t *s,const char *name, +struct lock_class_key *key) +{ +__seqcount_init (s, name, key); +} +EXPORT_SYMBOL_GPL (rust_helper___seqcount_init); + +unsigned rust_helper_read_seqcount_begin (seqcount_t *s) +{ +return read_seqcount_begin (s); +} +EXPORT_SYMBOL_GPL (rust_helper_read_seqcount_begin); + +int rust_helper_read_seqcount_retry (seqcount_t *s,unsigned start) +{ +return read_seqcount_retry (s, start); +} +EXPORT_SYMBOL_GPL (rust_helper_read_seqcount_retry); + +void rust_helper_write_seqcount_begin (seqcount_t *s) +{ +do_write_seqcount_begin (s); +} +EXPORT_SYMBOL_GPL (rust_helper_write_seqcount_begin); + +void rust_helper_write_seqcount_end (seqcount_t *s) +{ +do_write_seqcount_end (s); +} +EXPORT_SYMBOL_GPL (rust_helper_write_seqcount_end); + +void rust_helper_irq_set_handler_locked (struct irq_data *data, +irq_flow_handler_t handler) +{ +irq_set_handler_locked (data, handler); +} +EXPORT_SYMBOL_GPL (rust_helper_irq_set_handler_locked); + +void *rust_helper_irq_data_get_irq_chip_data (struct irq_data *d) +{ +return irq_data_get_irq_chip_data (d); +} +EXPORT_SYMBOL_GPL (rust_helper_irq_data_get_irq_chip_data); + +struct irq_chip *rust_helper_irq_desc_get_chip (struct irq_desc *desc) +{ +return irq_desc_get_chip (desc); +} +EXPORT_SYMBOL_GPL (rust_helper_irq_desc_get_chip); + +void *rust_helper_irq_desc_get_handler_data (struct irq_desc *desc) +{ +return irq_desc_get_handler_data (desc); +} +EXPORT_SYMBOL_GPL (rust_helper_irq_desc_get_handler_data); + +void rust_helper_chained_irq_enter (struct irq_chip *chip, +struct irq_desc *desc) +{ +chained_irq_enter (chip, desc); +} +EXPORT_SYMBOL_GPL (rust_helper_chained_irq_enter); + +void rust_helper_chained_irq_exit (struct irq_chip *chip, +struct irq_desc *desc) +{ +chained_irq_exit (chip, desc); +} +EXPORT_SYMBOL_GPL (rust_helper_chained_irq_exit); + +const struct cred *rust_helper_get_cred (const struct cred *cred) +{ +return get_cred (cred); +} +EXPORT_SYMBOL_GPL (rust_helper_get_cred); + +void rust_helper_put_cred (const struct cred *cred) { +put_cred (cred); +} +EXPORT_SYMBOL_GPL (rust_helper_put_cred); + +const struct of_device_id *rust_helper_of_match_device ( +const struct of_device_id *matches,const struct device *dev) +{ +return of_match_device (matches, dev); +} +EXPORT_SYMBOL_GPL (rust_helper_of_match_device); + +/* 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" +);
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 5/19 rust: add `compiler_builtins` crate
In reply to Miguel OjedaRust 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.
--- rust/compiler_builtins.rs | 57 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 rust/compiler_builtins.rs
rust/compiler_builtins.rs new file +57 -0
@@ -0,0 +1,57 @@ +// 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 floating-point 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! ("`i128` should not be used" , { + __ashrti3, + __muloti4, + __multi3, +}); + +define_panicking_intrinsics! ("`u128` should not be used" , { + __ashlti3, + __lshrti3, + __udivmodti4, + __udivti3, + __umodti3, +}); + +#[cfg(target_arch = "arm" )] +define_panicking_intrinsics! ("`u64` division/modulo should not be used" , { + __aeabi_uldivmod, + __mulodi4, +});
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 6/19 rust: add `alloc` crate
In reply to Miguel OjedaThis crate is a subset of the Rust standard library alloc, with some additions on top.
This is needed because upstream support for fallible allocations is a work in progress (i.e. the try_* versions of methods which return a Result instead of panicking).
Having the library in-tree also gives us a bit more freedom to experiment with new interfaces and allows us to iterate quickly.
Eventually, the goal is to have everything the kernel needs in upstream alloc and drop it from the kernel tree.
--- rust/alloc/README.md | 32 + rust/alloc/alloc.rs | 427 ++++ rust/alloc/borrow.rs | 498 +++++ rust/alloc/boxed.rs | 1847 ++++++++++++++++ rust/alloc/collections/mod.rs | 156 ++ rust/alloc/fmt.rs | 601 ++++++ rust/alloc/lib.rs | 217 ++ rust/alloc/macros.rs | 126 ++ rust/alloc/raw_vec.rs | 549 +++++ rust/alloc/slice.rs | 1279 +++++++++++ rust/alloc/str.rs | 624 ++++++ rust/alloc/string.rs | 2864 ++++++++++++++++++++++++ rust/alloc/vec/drain.rs | 159 ++ rust/alloc/vec/drain_filter.rs | 145 ++ rust/alloc/vec/into_iter.rs | 356 +++ rust/alloc/vec/is_zero.rs | 106 + rust/alloc/vec/mod.rs | 3359 +++++++++++++++++++++++++++++ rust/alloc/vec/partial_eq.rs | 49 + rust/alloc/vec/set_len_on_drop.rs | 30 + rust/alloc/vec/spec_extend.rs | 172 ++ 20 files changed, 13596 insertions(+) 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/fmt.rs create mode 100644 rust/alloc/lib.rs create mode 100644 rust/alloc/macros.rs create mode 100644 rust/alloc/raw_vec.rs create mode 100644 rust/alloc/slice.rs create mode 100644 rust/alloc/str.rs create mode 100644 rust/alloc/string.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/alloc/vec/set_len_on_drop.rs create mode 100644 rust/alloc/vec/spec_extend.rs
rust/alloc/README.md new file +32 -0
@@ -0,0 +1,32 @@ +# `alloc` + +These source files come from the Rust standard library, hosted in +the https://github.com/rust-lang/rust repository. For copyright +details, see https://github.com/rust-lang/rust/blob/master/COPYRIGHT. + +Please note that these files should be kept as close as possible to +upstream. In general, only additions should be performed (e.g. new +methods). Eventually, changes should make it into upstream so that, +at some point, this fork can be dropped from the kernel tree. + + +## Rationale + +On one hand, kernel folks wanted to keep `alloc` in-tree to have more +freedom in both workflow and actual features if actually needed +(e.g. receiver types if we ended up using them), which is reasonable. + +On the other hand, Rust folks wanted to keep `alloc` as close as +upstream as possible and avoid as much divergence as possible, which +is also reasonable. + +We agreed on a middle-ground: we would keep a subset of `alloc` +in-tree that would be as small and as close as possible to upstream. +Then, upstream can start adding the functions that we add to `alloc` +etc., until we reach a point where the kernel already knows exactly +what it needs in `alloc` and all the new methods are merged into +upstream, so that we can drop `alloc` from the kernel tree and go back +to using the upstream one. + +By doing this, the kernel can go a bit faster now, and Rust can +slowly incorporate and discuss the changes as needed.
rust/alloc/alloc.rs new file +427 -0
427 lines not on this page · raw message
rust/alloc/borrow.rs new file +498 -0
498 lines not on this page · raw message
rust/alloc/boxed.rs new file +1847 -0
1,847 lines not on this page · raw message
rust/alloc/collections/mod.rs new file +156 -0
156 lines not on this page · raw message
rust/alloc/fmt.rs new file +601 -0
40 lines not on this page · raw message
rust/alloc/lib.rs new file +217 -0
217 lines not on this page · raw message
rust/alloc/macros.rs new file +126 -0
126 lines not on this page · raw message
rust/alloc/raw_vec.rs new file +549 -0
549 lines not on this page · raw message
rust/alloc/slice.rs new file +1279 -0
1,279 lines not on this page · raw message
rust/alloc/str.rs new file +624 -0
624 lines not on this page · raw message
rust/alloc/string.rs new file +2864 -0
2,864 lines not on this page · raw message
rust/alloc/vec/drain.rs new file +159 -0
159 lines not on this page · raw message
rust/alloc/vec/drain_filter.rs new file +145 -0
145 lines not on this page · raw message
rust/alloc/vec/into_iter.rs new file +356 -0
356 lines not on this page · raw message
rust/alloc/vec/is_zero.rs new file +106 -0
106 lines not on this page · raw message
rust/alloc/vec/mod.rs new file +3359 -0
3,359 lines not on this page · raw message
rust/alloc/vec/partial_eq.rs new file +49 -0
49 lines not on this page · raw message
rust/alloc/vec/set_len_on_drop.rs new file +30 -0
Lines of this file are not shown. View the raw message.
rust/alloc/vec/spec_extend.rs new file +172 -0
172 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.34.1
Part of the diff is not shown here. View the raw message.
Miguel Ojeda
maintainerPATCH v3 7/19 rust: add `build_error` crate
In reply to Miguel OjedaFrom: Gary Guo <[email protected]>
The build_error crate provides the build_error function which is then used to provide the build_error! and the build_assert! macros.
build_assert! is intended to be used when static_assert! cannot be used, e.g. when the condition refers to generic parameters or parameters of an inline function.
--- rust/build_error.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 rust/build_error.rs
rust/build_error.rs new file +29 -0
@@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Build-time error. +//! +//! This crate provides a function `build_error`, which will panic in +//! compile-time if executed in const context, and will cause a build error +//! if not executed at compile time and the optimizer does not optimise away the +//! call. +//! +//! It is used by `build_assert!` in the kernel crate, allowing checking of +//! conditions that could be checked statically, but could not be enforced in +//! Rust yet (e.g. perform some checks in const functions, but those +//! functions could still be called in the runtime). + +#![no_std] + +/// Panics if executed in const context, or triggers a build error if not. +#[inline(never)] +#[cold] +#[no_mangle] +#[track_caller] +pub const fn build_error (msg: &'staticstr ) -> ! { +panic! ("{}" , msg); +} + +#[cfg( CONFIG_RUST_BUILD_ASSERT_WARN )] +#[link_section = ".gnu.warning.build_error" ] +#[used] +static BUILD_ERROR_WARNING : [u8 ;45 ] = *b"call to build_error present after compilation" ;
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 8/19 rust: add `macros` crate
In reply to Miguel OjedaThis crate contains all the procedural macros ("proc macros") shared by all the kernel.
Procedural macros allow to create syntax extensions. They run at compile-time and can consume as well as produce Rust syntax.
For instance, the module! macro that is used by Rust modules is implemented here. It allows to easily declare the equivalent information to the MODULE_* macros in C modules, e.g.:
module! {
type: RustMinimal,
name: b"rust_minimal",
author: b"Rust for Linux Contributors",
description: b"Rust minimal sample",
license: b"GPL v2",
}--- rust/macros/helpers.rs | 79 ++++++ rust/macros/lib.rs | 94 +++++++ rust/macros/module.rs | 622 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 795 insertions(+) create mode 100644 rust/macros/helpers.rs create mode 100644 rust/macros/lib.rs create mode 100644 rust/macros/module.rs
rust/macros/helpers.rs new file +79 -0
@@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0 + +use proc_macro::{token_stream,Group ,TokenTree }; + +pub (crate )fn try_ident (it: &mut token_stream::IntoIter ) ->Option <String > { +if let Some (TokenTree ::Ident (ident)) = it.next () { +Some (ident.to_string ()) + }else { +None + } +} + +pub (crate )fn try_literal (it: &mut token_stream::IntoIter ) ->Option <String > { +if let Some (TokenTree ::Literal (literal)) = it.next () { +Some (literal.to_string ()) + }else { +None + } +} + +pub (crate )fn try_byte_string (it: &mut token_stream::IntoIter ) ->Option <String > { +try_literal (it).and_then (|byte_string| { +if byte_string.starts_with ("b\"" ) && byte_string.ends_with ('\"' ) { +Some (byte_string[2 ..byte_string.len () -1 ].to_string ()) + }else { +None + } + }) +} + +pub (crate )fn expect_ident (it: &mut token_stream::IntoIter ) ->String { +try_ident (it).expect ("Expected Ident" ) +} + +pub (crate )fn expect_punct (it: &mut token_stream::IntoIter ) ->char { +if let TokenTree ::Punct (punct) = it.next ().expect ("Reached end of token stream for Punct" ) { + punct.as_char () + }else { +panic! ("Expected Punct" ); + } +} + +pub (crate )fn expect_literal (it: &mut token_stream::IntoIter ) ->String { +try_literal (it).expect ("Expected Literal" ) +} + +pub (crate )fn expect_group (it: &mut token_stream::IntoIter ) ->Group { +if let TokenTree ::Group (group) = it.next ().expect ("Reached end of token stream for Group" ) { + group + }else { +panic! ("Expected Group" ); + } +} + +pub (crate )fn expect_byte_string (it: &mut token_stream::IntoIter ) ->String { +try_byte_string (it).expect ("Expected byte string" ) +} + +pub (crate )fn expect_end (it: &mut token_stream::IntoIter ) { +if it.next ().is_some () { +panic! ("Expected end" ); + } +} + +pub (crate )fn get_literal (it: &mut token_stream::IntoIter , expected_name: &str ) ->String { +assert_eq! (expect_ident (it), expected_name); +assert_eq! (expect_punct (it),':' ); +let literal =expect_literal (it); +assert_eq! (expect_punct (it),',' ); + literal +} + +pub (crate )fn get_byte_string (it: &mut token_stream::IntoIter , expected_name: &str ) ->String { +assert_eq! (expect_ident (it), expected_name); +assert_eq! (expect_punct (it),':' ); +let byte_string =expect_byte_string (it); +assert_eq! (expect_punct (it),',' ); + byte_string +}
rust/macros/lib.rs new file +94 -0
94 lines not on this page · raw message
rust/macros/module.rs new file +622 -0
622 lines not on this page · raw message
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 9/19 rust: add `kernel` crate
In reply to Miguel OjedaFrom: 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.
--- include/linux/spinlock.h | 17 +- kernel/printk/printk.c | 5 +- rust/kernel/allocator.rs | 65 +++ rust/kernel/amba.rs | 259 ++++++++++ rust/kernel/bindings.rs | 47 ++ rust/kernel/bindings_helper.h | 31 ++ rust/kernel/buffer.rs | 52 ++ rust/kernel/build_assert.rs | 80 +++ rust/kernel/c_types.rs | 119 +++++ rust/kernel/chrdev.rs | 209 ++++++++ rust/kernel/clk.rs | 75 +++ rust/kernel/cred.rs | 73 +++ rust/kernel/device.rs | 549 +++++++++++++++++++++ rust/kernel/driver.rs | 440 +++++++++++++++++ rust/kernel/error.rs | 542 +++++++++++++++++++++ rust/kernel/file.rs | 147 ++++++ rust/kernel/file_operations.rs | 726 ++++++++++++++++++++++++++++ rust/kernel/gpio.rs | 477 ++++++++++++++++++ rust/kernel/io_buffer.rs | 153 ++++++ rust/kernel/io_mem.rs | 227 +++++++++ rust/kernel/iov_iter.rs | 81 ++++ rust/kernel/irq.rs | 409 ++++++++++++++++ rust/kernel/lib.rs | 262 ++++++++++ rust/kernel/linked_list.rs | 247 ++++++++++ rust/kernel/miscdev.rs | 196 ++++++++ rust/kernel/module_param.rs | 497 +++++++++++++++++++ rust/kernel/of.rs | 63 +++ rust/kernel/pages.rs | 162 +++++++ rust/kernel/platform.rs | 224 +++++++++ rust/kernel/power.rs | 118 +++++ rust/kernel/prelude.rs | 36 ++ rust/kernel/print.rs | 441 +++++++++++++++++ rust/kernel/random.rs | 50 ++ rust/kernel/raw_list.rs | 361 ++++++++++++++ rust/kernel/rbtree.rs | 562 +++++++++++++++++++++ rust/kernel/revocable.rs | 163 +++++++ rust/kernel/security.rs | 36 ++ rust/kernel/static_assert.rs | 39 ++ rust/kernel/std_vendor.rs | 150 ++++++ rust/kernel/str.rs | 375 ++++++++++++++ rust/kernel/sync/arc.rs | 500 +++++++++++++++++++ rust/kernel/sync/condvar.rs | 138 ++++++ rust/kernel/sync/guard.rs | 181 +++++++ rust/kernel/sync/locked_by.rs | 112 +++++ rust/kernel/sync/mod.rs | 92 ++++ rust/kernel/sync/mutex.rs | 112 +++++ rust/kernel/sync/revocable_mutex.rs | 184 +++++++ rust/kernel/sync/seqlock.rs | 202 ++++++++ rust/kernel/sync/spinlock.rs | 180 +++++++ rust/kernel/sysctl.rs | 197 ++++++++ rust/kernel/task.rs | 182 +++++++ rust/kernel/types.rs | 486 +++++++++++++++++++ rust/kernel/user_ptr.rs | 175 +++++++ 53 files changed, 11499 insertions(+), 7 deletions(-) create mode 100644 rust/kernel/allocator.rs create mode 100644 rust/kernel/amba.rs create mode 100644 rust/kernel/bindings.rs create mode 100644 rust/kernel/bindings_helper.h create mode 100644 rust/kernel/buffer.rs create mode 100644 rust/kernel/build_assert.rs create mode 100644 rust/kernel/c_types.rs create mode 100644 rust/kernel/chrdev.rs create mode 100644 rust/kernel/clk.rs create mode 100644 rust/kernel/cred.rs create mode 100644 rust/kernel/device.rs create mode 100644 rust/kernel/driver.rs create mode 100644 rust/kernel/error.rs create mode 100644 rust/kernel/file.rs create mode 100644 rust/kernel/file_operations.rs create mode 100644 rust/kernel/gpio.rs create mode 100644 rust/kernel/io_buffer.rs create mode 100644 rust/kernel/io_mem.rs create mode 100644 rust/kernel/iov_iter.rs create mode 100644 rust/kernel/irq.rs create mode 100644 rust/kernel/lib.rs create mode 100644 rust/kernel/linked_list.rs create mode 100644 rust/kernel/miscdev.rs create mode 100644 rust/kernel/module_param.rs create mode 100644 rust/kernel/of.rs create mode 100644 rust/kernel/pages.rs create mode 100644 rust/kernel/platform.rs create mode 100644 rust/kernel/power.rs create mode 100644 rust/kernel/prelude.rs create mode 100644 rust/kernel/print.rs create mode 100644 rust/kernel/random.rs create mode 100644 rust/kernel/raw_list.rs create mode 100644 rust/kernel/rbtree.rs create mode 100644 rust/kernel/revocable.rs create mode 100644 rust/kernel/security.rs create mode 100644 rust/kernel/static_assert.rs create mode 100644 rust/kernel/std_vendor.rs create mode 100644 rust/kernel/str.rs create mode 100644 rust/kernel/sync/arc.rs create mode 100644 rust/kernel/sync/condvar.rs create mode 100644 rust/kernel/sync/guard.rs create mode 100644 rust/kernel/sync/locked_by.rs create mode 100644 rust/kernel/sync/mod.rs create mode 100644 rust/kernel/sync/mutex.rs create mode 100644 rust/kernel/sync/revocable_mutex.rs create mode 100644 rust/kernel/sync/seqlock.rs create mode 100644 rust/kernel/sync/spinlock.rs create mode 100644 rust/kernel/sysctl.rs create mode 100644 rust/kernel/task.rs create mode 100644 rust/kernel/types.rs create mode 100644 rust/kernel/user_ptr.rs
include/linux/spinlock.h +11 -6
@@ -326,12 +326,17 @@ static __always_inline raw_spinlock_t *spinlock_check(spinlock_t *lock)#ifdef CONFIG_DEBUG_SPINLOCK -# define spin_lock_init (lock) \ -do { \ - static struct lock_class_key __key; \ - \ - __raw_spin_lock_init(spinlock_check(lock), \ - #lock, &__key, LD_WAIT_CONFIG); \ +static inline void __spin_lock_init (spinlock_t *lock,const char *name, +struct lock_class_key *key) +{ +__raw_spin_lock_init (spinlock_check (lock), name, key,LD_WAIT_CONFIG ); +} + +# define spin_lock_init (lock) \ +do { \ + static struct lock_class_key __key; \ + \ + __spin_lock_init(lock, #lock, &__key); \ } while (0)#else
kernel/printk/printk.c +4 -1
@@ -392,7 +392,10 @@ static struct latched_seq clear_seq = {/* the maximum size of a formatted record (i.e. with prefix added per line) */ #define CONSOLE_LOG_MAX 1024 -/* the maximum size allowed to be reserved for a record */ +/* +* The maximum size allowed to be reserved for a record. +* Keep in sync with rust/kernel/print.rs. +*/ #define LOG_LINE_MAX (CONSOLE_LOG_MAX - PREFIX_MAX)#define LOG_LEVEL (v) ((v) & 0x07)
rust/kernel/allocator.rs new file +65 -0
65 lines not on this page · raw message
rust/kernel/amba.rs new file +259 -0
259 lines not on this page · raw message
rust/kernel/bindings.rs new file +47 -0
47 lines not on this page · raw message
rust/kernel/bindings_helper.h new file +31 -0
@@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include <linux/cdev.h> +#include <linux/clk.h> +#include <linux/errname.h> +#include <linux/fs.h> +#include <linux/module.h> +#include <linux/random.h> +#include <linux/slab.h> +#include <linux/sysctl.h> +#include <linux/uaccess.h> +#include <linux/uio.h> +#include <linux/version.h> +#include <linux/miscdevice.h> +#include <linux/poll.h> +#include <linux/mm.h> +#include <linux/file.h> +#include <uapi/linux/android/binder.h> +#include <linux/platform_device.h> +#include <linux/of_platform.h> +#include <linux/security.h> +#include <asm/io.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/irqdomain.h> +#include <linux/amba/bus.h> +#include <linux/gpio/driver.h> + +// `bindgen` gets confused at certain things +const gfp_t BINDINGS_GFP_KERNEL =GFP_KERNEL ; +const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;
rust/kernel/buffer.rs new file +52 -0
52 lines not on this page · raw message
rust/kernel/build_assert.rs new file +80 -0
80 lines not on this page · raw message
rust/kernel/c_types.rs new file +119 -0
119 lines not on this page · raw message
rust/kernel/chrdev.rs new file +209 -0
209 lines not on this page · raw message
rust/kernel/clk.rs new file +75 -0
75 lines not on this page · raw message
rust/kernel/cred.rs new file +73 -0
73 lines not on this page · raw message
rust/kernel/device.rs new file +549 -0
549 lines not on this page · raw message
rust/kernel/driver.rs new file +440 -0
440 lines not on this page · raw message
rust/kernel/error.rs new file +542 -0
542 lines not on this page · raw message
rust/kernel/file.rs new file +147 -0
147 lines not on this page · raw message
rust/kernel/file_operations.rs new file +726 -0
278 lines not on this page · raw message
rust/kernel/gpio.rs new file +477 -0
477 lines not on this page · raw message
rust/kernel/io_buffer.rs new file +153 -0
153 lines not on this page · raw message
rust/kernel/io_mem.rs new file +227 -0
227 lines not on this page · raw message
rust/kernel/iov_iter.rs new file +81 -0
81 lines not on this page · raw message
rust/kernel/irq.rs new file +409 -0
409 lines not on this page · raw message
rust/kernel/lib.rs new file +262 -0
262 lines not on this page · raw message
rust/kernel/linked_list.rs new file +247 -0
247 lines not on this page · raw message
rust/kernel/miscdev.rs new file +196 -0
196 lines not on this page · raw message
rust/kernel/module_param.rs new file +497 -0
497 lines not on this page · raw message
rust/kernel/of.rs new file +63 -0
63 lines not on this page · raw message
rust/kernel/pages.rs new file +162 -0
162 lines not on this page · raw message
rust/kernel/platform.rs new file +224 -0
224 lines not on this page · raw message
rust/kernel/power.rs new file +118 -0
118 lines not on this page · raw message
rust/kernel/print.rs new file +441 -0
441 lines not on this page · raw message
rust/kernel/random.rs new file +50 -0
50 lines not on this page · raw message
rust/kernel/raw_list.rs new file +361 -0
361 lines not on this page · raw message
rust/kernel/rbtree.rs new file +562 -0
562 lines not on this page · raw message
rust/kernel/revocable.rs new file +163 -0
163 lines not on this page · raw message
rust/kernel/std_vendor.rs new file +150 -0
150 lines not on this page · raw message
rust/kernel/str.rs new file +375 -0
375 lines not on this page · raw message
rust/kernel/sync/arc.rs new file +500 -0
500 lines not on this page · raw message
rust/kernel/sync/condvar.rs new file +138 -0
138 lines not on this page · raw message
rust/kernel/sync/guard.rs new file +181 -0
181 lines not on this page · raw message
rust/kernel/sync/locked_by.rs new file +112 -0
112 lines not on this page · raw message
rust/kernel/sync/mod.rs new file +92 -0
92 lines not on this page · raw message
rust/kernel/sync/mutex.rs new file +112 -0
112 lines not on this page · raw message
rust/kernel/sync/revocable_mutex.rs new file +184 -0
184 lines not on this page · raw message
rust/kernel/sync/seqlock.rs new file +202 -0
202 lines not on this page · raw message
rust/kernel/sync/spinlock.rs new file +180 -0
180 lines not on this page · raw message
rust/kernel/sysctl.rs new file +197 -0
197 lines not on this page · raw message
rust/kernel/task.rs new file +182 -0
182 lines not on this page · raw message
rust/kernel/types.rs new file +486 -0
486 lines not on this page · raw message
rust/kernel/user_ptr.rs new file +175 -0
175 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.34.1
Part of the diff is not shown here. View the raw message.
Miguel Ojeda
maintainerPATCH v3 10/19 rust: export generated symbols
In reply to Miguel OjedaAll symbols are reexported reusing the EXPORT_SYMBOL_GPL macro from C. The lists of symbols are generated on the fly.
There are three main sets of symbols to distinguish:
- The ones from the core and alloc crates (from the Rust standard library). The code is licensed as Apache/MIT.
- The ones from our abstractions in the kernel crate.
- The helpers (already exported since they are not generated).
We export everything as GPL. This ensures we do not mistakenly expose GPL kernel symbols/features as non-GPL, even indirectly.
--- rust/exports.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 rust/exports.c
rust/exports.c new file +16 -0
@@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// A hack to export Rust symbols for loadable modules without having to redo +// the entire `include/linux/export.h` logic in Rust. +// +// This requires the Rust's new/future `v0` mangling scheme because the default +// one ("legacy") uses invalid characters for C identifiers (thus we cannot use +// the `EXPORT_SYMBOL_*` macros). + +#include <linux/module.h> + +#define EXPORT_SYMBOL_RUST_GPL (sym) extern int sym; EXPORT_SYMBOL_GPL(sym); + +#include "exports_core_generated.h" +#include "exports_alloc_generated.h" +#include "exports_kernel_generated.h"
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 11/19 vsprintf: add new `%pA` format specifier
In reply to Miguel OjedaFrom: 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.
--- lib/rust.h | 14 ++++++++++++++ lib/vsprintf.c | 7 +++++++ 2 files changed, 21 insertions(+) create mode 100644 lib/rust.h
lib/rust.h new file +14 -0
@@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LIB_RUST_H +#define _LIB_RUST_H + +#ifdef CONFIG_RUST +char *rust_fmt_argument (char * buf,char * end,void *ptr); +#else +static inline char *rust_fmt_argument (char * buf,char * end,void *ptr) +{ +return NULL ; +} +#endif + +#endif /* _LIB_RUST_H */
lib/vsprintf.c +7 -0
@@ -52,6 +52,7 @@#include <linux/string_helpers.h> #include "kstrtox.h" +#include "rust.h" static noinline unsigned long long simple_strntoull (const char *startp,size_t max_chars,char **endp,unsigned int base) {
@@ -2388,6 +2389,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,
@@ -2460,6 +2465,8 @@ 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' : +return rust_fmt_argument (buf, end, ptr);case 'x' :return pointer_string (buf, end, ptr, spec);case 'e' :
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 12/19 scripts: add `generate_rust_analyzer.py`
In reply to Miguel OjedaThe 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.
--- scripts/generate_rust_analyzer.py | 133 ++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100755 scripts/generate_rust_analyzer.py
scripts/generate_rust_analyzer.py new file +133 -0
@@ -0,0 +1,133 @@ +#!/usr/bin/env python3 +"""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( + "build_error", + srctree / "rust" / "build_error.rs", + ["core", "compiler_builtins"], + ) + + append_crate( + "kernel", + srctree / "rust" / "kernel" / "lib.rs", + ["core", "alloc", "macros", "build_error"], + cfg=cfg, + ) + crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True)) + 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()
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 13/19 scripts: decode_stacktrace: demangle Rust symbols
In reply to Miguel OjedaRecent versions of both Binutils (c++filt) and LLVM (llvm-cxxfilt) provide Rust v0 mangling support.
---
I would like to use this patch for discussing the demangling topic.
The following discusses the different approaches we could take.
# Leave demangling to userspace
This is the easiest and less invasive approach, the one implemented by this patch.
The decode_stacktrace.sh script is already needed to map the offsets to the source code. Therefore, we could also take the chance to demangle the symbols here.
With this approach, we do not need to introduce any change in the vsprintf machinery and we minimize the risk of breaking user tools.
Note that, if we take this approach, it is likely we want to ask for a minimum version of either of the tools (since there may be users of the script that do not have recent enough toolchains).
# Demangling in kernelspace on-the-fly
That is, at backtrace print time, we demangle the Rust symbols.
The size of the code that would be needed is fairly small; around 5 KiB using the "official" library (written in Rust), e.g.:
text data bss dec hex filename
7799976 1689820 2129920 11619716 b14d84 vmlinux
7801111 1693916 2129920 11624947 b161f3 vmlinux + demanglingWe can remove a few bits from the official library, e.g. punycode support that we do not need (all our identifiers will be ASCII), but it does not make a substantial difference.
The official library performs the demangling without requiring allocations. However, of course, it will increased our stack usage and complexity, specially considering a stack dump may be requested in not ideal conditions.
Furthermore, this approach (and the ones below) likely require adding a new %p specifier (or a new modifier to existing ones) if we do not want to affect non-backtrace uses of the B/S ones. Also, it is unclear whether we should write the demangled versions in an extra, different line or replace the real symbol -- we could be breaking user tools relying on parsing backtraces (e.g. our own decode_stacktrace.sh). For instance, they could be relying on having real symbols there, or may break due to e.g. spaces.
# Demangling at compile-time
This implies having kallsyms demangle all the Rust symbols.
The size of this data is around the same order of magnitude of the non-demangled ones. However, this is notably more than the demangling code (see previous point), e.g. 120 KiB (uncompressed) in a small kernel.
This approach also brings the same concerns regarding modifying the backtrace printing (see previous point).
# Demangling at compile-time and substituting symbols by hashes
One variation of the previous alternative is avoiding the mangled names inside the kernel, by hashing them. This would avoid having to support "big symbols" and would also reduce the size of the kallsyms tables, while still allowing to link modules.
However, if we do not have the real symbols around, then we do not have the possibility of providing both the mangled and demangled versions in the backtrace, which brings us back to the issues related to breaking userspace tools. There are also other places other than backtraces using "real" symbols that users may be relying on, such as /proc/*/stack.
scripts/decode_stacktrace.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
scripts/decode_stacktrace.sh +14 -0
@@ -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"
@@ -169,6 +177,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)" }
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 14/19 docs: add Rust documentation
In reply to Miguel OjedaMost 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 binary assets used for the rustdoc target and a few other small changes elsewhere in the documentation folder.
--- Documentation/doc-guide/kernel-doc.rst | 3 + Documentation/index.rst | 1 + Documentation/kbuild/kbuild.rst | 4 + Documentation/process/changes.rst | 42 ++++ Documentation/rust/arch-support.rst | 35 +++ Documentation/rust/assets/favicon-16x16.png | Bin 0 -> 798 bytes Documentation/rust/assets/favicon-32x32.png | Bin 0 -> 2076 bytes Documentation/rust/assets/rust-logo.png | Bin 0 -> 53976 bytes Documentation/rust/coding-guidelines.rst | 151 +++++++++++++ Documentation/rust/general-information.rst | 80 +++++++ Documentation/rust/index.rst | 21 ++ Documentation/rust/quick-start.rst | 231 ++++++++++++++++++++ 12 files changed, 568 insertions(+) create mode 100644 Documentation/rust/arch-support.rst create mode 100644 Documentation/rust/assets/favicon-16x16.png create mode 100644 Documentation/rust/assets/favicon-32x32.png create mode 100644 Documentation/rust/assets/rust-logo.png 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
Documentation/doc-guide/kernel-doc.rst +3 -0
@@ -11,6 +11,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/docs.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
Documentation/index.rst +1 -0
@@ -82,6 +82,7 @@ merged much easier. maintainer/index fault-injection/index livepatch/index + rust/index Kernel API documentation
Documentation/kbuild/kbuild.rst +4 -0
@@ -57,6 +57,10 @@ CFLAGS_MODULE ------------- Additional module specific options to use for $(CC). +KRUSTFLAGS +---------- +Additional options to the Rust compiler (for built-in and modules). + LDFLAGS_MODULE -------------- Additional options used for $(LD) when linking modules.
Documentation/process/changes.rst +42 -0
66 lines not on this page · raw message
Documentation/rust/arch-support.rst new file +35 -0
@@ -0,0 +1,35 @@ +.. _rust_arch_support: + +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 (see :ref:`kbuild_llvm`). +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. + +.. list-table:: + :widths: 10 10 10 + :header-rows: 1 + + * - Architecture + - Level of support + - Constraints + * - ``arm`` + - Maintained + - ``armv6`` and compatible only, ``RUST_OPT_LEVEL >= 2`` + * - ``arm64`` + - Maintained + - None + * - ``powerpc`` + - Maintained + - ``ppc64le`` only, ``RUST_OPT_LEVEL < 2`` requires ``CONFIG_THREAD_SHIFT=15`` + * - ``riscv`` + - Maintained + - ``riscv64`` only + * - ``x86`` + - Maintained + - ``x86_64`` only
Documentation/rust/assets/favicon-16x16.png new file binary +0 -0
Documentation/rust/assets/favicon-32x32.png new file binary +0 -0
Documentation/rust/assets/rust-logo.png new file binary +0 -0
Documentation/rust/coding-guidelines.rst new file +151 -0
151 lines not on this page · raw message
Documentation/rust/general-information.rst new file +80 -0
80 lines not on this page · raw message
Documentation/rust/index.rst new file +21 -0
@@ -0,0 +1,21 @@ +Rust +==== + +Documentation related to Rust within the kernel. To start using Rust +in the kernel, please read the +:ref:`Documentation/rust/quick-start.rst <rust_quick_start>` guide. + +.. toctree:: + :maxdepth: 1 + + quick-start + general-information + coding-guidelines + arch-support + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex`
Documentation/rust/quick-start.rst new file +231 -0
231 lines not on this page · raw message
Signature · 1 line
2.34.1
Jonathan Corbet
maintainerRe: [PATCH v3 14/19] docs: add Rust documentation
Quoted 10 lines · Miguel Ojeda
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 binary assets used for the
rustdoctarget and a few other small changes elsewhere in the documentation folder.
Glad to see documentation!
That said, I have one little request...
Quoted 8 lines
Documentation/doc-guide/kernel-doc.rst | 3 + Documentation/index.rst | 1 + Documentation/kbuild/kbuild.rst | 4 + Documentation/process/changes.rst | 42 ++++ Documentation/rust/arch-support.rst | 35 +++ Documentation/rust/assets/favicon-16x16.png | Bin 0 -> 798 bytes Documentation/rust/assets/favicon-32x32.png | Bin 0 -> 2076 bytes Documentation/rust/assets/rust-logo.png | Bin 0 -> 53976 bytes
We have really tried to keep binary files (like PNG images) out of the documentation tree. If we really need these images, can they be provided in SVG form?
Thanks,
jon
Re: [PATCH v3 14/19] docs: add Rust documentation
Quoted 4 lines · Jonathan Corbet
We have really tried to keep binary files (like PNG images) out of the documentation tree. If we really need these images, can they be provided in SVG form?
Yeah, they are not critical -- I can change them to a single SVG, or use Tux, or drop them (although it is a nice way to tell one is not in the Rust standard library docs).
Is there a preferred SVG version of Tux? (I cannot find one in the tree, only the GIF one at Doc/logo.gif). If not, perhaps we could ask permission to integrate one like https://github.com/garrett/Tux.
Cheers,
Miguel
Miguel Ojeda
maintainerPATCH v3 15/19 Kbuild: add Rust support
In reply to Miguel OjedaHaving all the new files in place, we now enable Rust support in the build system, including Kconfig entries related to Rust, the Rust configuration printer, the target definition files, the version detection script and a few other bits.
In the future, we will likely want to generate the target files on the fly via a script.
--- .gitignore | 5 + .rustfmt.toml | 12 + Makefile | 152 +++++++- arch/arm/rust/target.json | 27 ++ arch/arm64/rust/target.json | 34 ++ arch/powerpc/rust/target.json | 29 ++ arch/riscv/Makefile | 1 + arch/riscv/rust/rv32ima.json | 36 ++ arch/riscv/rust/rv32imac.json | 36 ++ arch/riscv/rust/rv64ima.json | 36 ++ arch/riscv/rust/rv64imac.json | 36 ++ arch/x86/rust/target.json | 36 ++ init/Kconfig | 44 ++- lib/Kconfig.debug | 144 ++++++++ rust/.gitignore | 7 + rust/Makefile | 352 +++++++++++++++++++ rust/bindgen_parameters | 13 + scripts/Kconfig.include | 6 +- scripts/Makefile.build | 22 ++ scripts/Makefile.debug | 10 + scripts/Makefile.lib | 12 + scripts/Makefile.modfinal | 8 +- scripts/cc-version.sh | 12 +- scripts/is_rust_module.sh | 19 + scripts/kconfig/confdata.c | 75 ++++ scripts/min-tool-version.sh | 6 + scripts/rust-is-available-bindgen-libclang.h | 2 + scripts/rust-is-available.sh | 159 +++++++++ 28 files changed, 1310 insertions(+), 21 deletions(-) create mode 100644 .rustfmt.toml create mode 100644 arch/arm/rust/target.json create mode 100644 arch/arm64/rust/target.json create mode 100644 arch/powerpc/rust/target.json create mode 100644 arch/riscv/rust/rv32ima.json create mode 100644 arch/riscv/rust/rv32imac.json create mode 100644 arch/riscv/rust/rv64ima.json create mode 100644 arch/riscv/rust/rv64imac.json create mode 100644 arch/x86/rust/target.json create mode 100644 rust/.gitignore create mode 100644 rust/Makefile create mode 100644 rust/bindgen_parameters create mode 100755 scripts/is_rust_module.sh create mode 100644 scripts/rust-is-available-bindgen-libclang.h create mode 100755 scripts/rust-is-available.sh
.gitignore +5 -0
@@ -37,6 +37,7 @@ *.o *.o.* *.patch +*.rmeta *.s *.so *.so.dbg
@@ -96,6 +97,7 @@ modules.order !.gitattributes !.gitignore !.mailmap +!.rustfmt.toml # # Generated include files
@@ -161,3 +163,6 @@ x509.genkey # Documentation toolchain sphinx_*/ + +# Rust analyzer configuration +/rust-project.json
.rustfmt.toml new file +12 -0
@@ -0,0 +1,12 @@ +edition = "2021" +newline_style = "Unix" + +# Unstable options that help catching some mistakes in formatting and that we may want to enable +# when they become stable. +# +# They are kept here since they are useful to run from time to time. +#format_code_in_doc_comments = true +#reorder_impl_items = true +#comment_width = 100 +#wrap_comments = true +#normalize_comments = true
Makefile +144 -8
280 lines not on this page · raw message
arch/arm/rust/target.json new file +27 -0
@@ -0,0 +1,27 @@ +{ + "arch": "arm", + "crt-static-respected": true, + "data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", + "dynamic-linking": true, + "env": "gnu", + "executables": true, + "features": "+strict-align,+v6", + "function-sections": false, + "has-elf-tls": true, + "has-rpath": true, + "linker-is-gnu": true, + "llvm-target": "arm-unknown-linux-gnueabi", + "max-atomic-width": 64, + "os": "linux", + "position-independent-executables": true, + "pre-link-args": { + "gcc": [ + "-Wl,--as-needed", + "-Wl,-z,noexecstack" + ] + }, + "relocation-model": "static", + "target-family": "unix", + "target-mcount": "\u0001__gnu_mcount_nc", + "target-pointer-width": "32" +}
arch/arm64/rust/target.json new file +34 -0
@@ -0,0 +1,34 @@ +{ + "arch": "aarch64", + "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", + "disable-redzone": true, + "emit-debug-gdb-scripts": false, + "env": "gnu", + "features": "+strict-align,+neon,+fp-armv8", + "frame-pointer": "always", + "function-sections": false, + "linker-flavor": "gcc", + "linker-is-gnu": true, + "llvm-target": "aarch64-unknown-none", + "max-atomic-width": 128, + "needs-plt": true, + "os": "none", + "panic-strategy": "abort", + "position-independent-executables": true, + "pre-link-args": { + "gcc": [ + "-Wl,--as-needed", + "-Wl,-z,noexecstack", + "-m64" + ] + }, + "relocation-model": "static", + "relro-level": "full", + "stack-probes": { + "kind": "none" + }, + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "64", + "vendor": "" +}
arch/powerpc/rust/target.json new file +29 -0
@@ -0,0 +1,29 @@ +{ + "arch": "powerpc64", + "code-model": "large", + "cpu": "ppc64le", + "data-layout": "e-m:e-i64:64-n32:64", + "env": "gnu", + "features": "-altivec,-vsx,-hard-float", + "function-sections": false, + "linker-flavor": "gcc", + "linker-is-gnu": true, + "llvm-target": "powerpc64le-elf", + "max-atomic-width": 64, + "os": "none", + "panic-strategy": "abort", + "position-independent-executables": true, + "pre-link-args": { + "gcc": [ + "-Wl,--as-needed", + "-Wl,-z,noexecstack", + "-m64" + ] + }, + "relocation-model": "static", + "relro-level": "full", + "target-family": "unix", + "target-mcount": "_mcount", + "target-endian": "little", + "target-pointer-width": "64" +}
arch/riscv/Makefile +1 -0
@@ -52,6 +52,7 @@ riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y)) KBUILD_AFLAGS += -march=$(riscv-march-y) +KBUILD_RUST_TARGET := $(srctree)/arch/riscv/rust/$(subst fd,,$(riscv-march-y)).json KBUILD_CFLAGS += -mno-save-restore KBUILD_CFLAGS += -DCONFIG_PAGE_OFFSET=$(CONFIG_PAGE_OFFSET)
arch/riscv/rust/rv32ima.json new file +36 -0
@@ -0,0 +1,36 @@ +{ + "arch": "riscv32", + "code-model": "medium", + "cpu": "generic-rv32", + "data-layout": "e-m:e-p:32:32-i64:64-n32-S128", + "disable-redzone": true, + "emit-debug-gdb-scripts": false, + "env": "gnu", + "features": "+m,+a", + "frame-pointer": "always", + "function-sections": false, + "linker-flavor": "gcc", + "linker-is-gnu": true, + "llvm-target": "riscv32", + "max-atomic-width": 32, + "needs-plt": true, + "os": "none", + "panic-strategy": "abort", + "position-independent-executables": true, + "pre-link-args": { + "gcc": [ + "-Wl,--as-needed", + "-Wl,-z,noexecstack", + "-m32" + ] + }, + "relocation-model": "static", + "relro-level": "full", + "stack-probes": { + "kind": "none" + }, + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "32", + "vendor": "" +}
arch/riscv/rust/rv32imac.json new file +36 -0
@@ -0,0 +1,36 @@ +{ + "arch": "riscv32", + "code-model": "medium", + "cpu": "generic-rv32", + "data-layout": "e-m:e-p:32:32-i64:64-n32-S128", + "disable-redzone": true, + "emit-debug-gdb-scripts": false, + "env": "gnu", + "features": "+m,+a,+c", + "frame-pointer": "always", + "function-sections": false, + "linker-flavor": "gcc", + "linker-is-gnu": true, + "llvm-target": "riscv32", + "max-atomic-width": 32, + "needs-plt": true, + "os": "none", + "panic-strategy": "abort", + "position-independent-executables": true, + "pre-link-args": { + "gcc": [ + "-Wl,--as-needed", + "-Wl,-z,noexecstack", + "-m32" + ] + }, + "relocation-model": "static", + "relro-level": "full", + "stack-probes": { + "kind": "none" + }, + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "32", + "vendor": "" +}
arch/riscv/rust/rv64ima.json new file +36 -0
@@ -0,0 +1,36 @@ +{ + "arch": "riscv64", + "code-model": "medium", + "cpu": "generic-rv64", + "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n64-S128", + "disable-redzone": true, + "emit-debug-gdb-scripts": false, + "env": "gnu", + "features": "+m,+a", + "frame-pointer": "always", + "function-sections": false, + "linker-flavor": "gcc", + "linker-is-gnu": true, + "llvm-target": "riscv64", + "max-atomic-width": 64, + "needs-plt": true, + "os": "none", + "panic-strategy": "abort", + "position-independent-executables": true, + "pre-link-args": { + "gcc": [ + "-Wl,--as-needed", + "-Wl,-z,noexecstack", + "-m64" + ] + }, + "relocation-model": "static", + "relro-level": "full", + "stack-probes": { + "kind": "none" + }, + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "64", + "vendor": "" +}
arch/riscv/rust/rv64imac.json new file +36 -0
@@ -0,0 +1,36 @@ +{ + "arch": "riscv64", + "code-model": "medium", + "cpu": "generic-rv64", + "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n64-S128", + "disable-redzone": true, + "emit-debug-gdb-scripts": false, + "env": "gnu", + "features": "+m,+a,+c", + "frame-pointer": "always", + "function-sections": false, + "linker-flavor": "gcc", + "linker-is-gnu": true, + "llvm-target": "riscv64", + "max-atomic-width": 64, + "needs-plt": true, + "os": "none", + "panic-strategy": "abort", + "position-independent-executables": true, + "pre-link-args": { + "gcc": [ + "-Wl,--as-needed", + "-Wl,-z,noexecstack", + "-m64" + ] + }, + "relocation-model": "static", + "relro-level": "full", + "stack-probes": { + "kind": "none" + }, + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "64", + "vendor": "" +}
arch/x86/rust/target.json new file +36 -0
@@ -0,0 +1,36 @@ +{ + "arch": "x86_64", + "code-model": "kernel", + "cpu": "x86-64", + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", + "disable-redzone": true, + "emit-debug-gdb-scripts": false, + "env": "gnu", + "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float", + "frame-pointer": "always", + "function-sections": false, + "linker-flavor": "gcc", + "linker-is-gnu": true, + "llvm-target": "x86_64-elf", + "max-atomic-width": 64, + "needs-plt": true, + "os": "none", + "panic-strategy": "abort", + "position-independent-executables": true, + "pre-link-args": { + "gcc": [ + "-Wl,--as-needed", + "-Wl,-z,noexecstack", + "-m64" + ] + }, + "relocation-model": "static", + "relro-level": "full", + "stack-probes": { + "kind": "none" + }, + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "64", + "vendor": "unknown" +}
init/Kconfig +43 -1
62 lines not on this page · raw message
lib/Kconfig.debug +144 -0
150 lines not on this page · raw message
rust/.gitignore new file +7 -0
@@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + +bindings_generated.rs +bindings_helpers_generated.rs +exports_*_generated.h +doc/ +test/
rust/Makefile new file +352 -0
352 lines not on this page · raw message
rust/bindgen_parameters new file +13 -0
@@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 + +--opaque-type xregs_state +--opaque-type desc_struct +--opaque-type arch_lbr_state +--opaque-type local_apic + +# If SMP is disabled, `arch_spinlock_t` is defined as a ZST which triggers a Rust +# warning. We don't need to peek into it anyway. +--opaque-type spinlock + +# `seccomp`'s comment gets understood as a doctest +--no-doc-comments
scripts/Kconfig.include +3 -3
@@ -36,12 +36,12 @@ ld-option = $(success,$(LD) -v $(1)) as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o /dev/null -) # check if $(CC) and $(LD) exist -$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found) +$(error-if,$(failure,command -v $(CC)),C compiler '$(CC)' not found) $(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found) -# Get the compiler name, version, and error out if it is not supported. +# Get the C compiler name, version, and error out if it is not supported. cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC)) -$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is not supported.) +$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this C compiler is not supported.) cc-name := $(shell,set -- $(cc-info) && echo $1) cc-version := $(shell,set -- $(cc-info) && echo $2)
scripts/Makefile.build +22 -0
@@ -26,6 +26,7 @@ EXTRA_CPPFLAGS := EXTRA_LDFLAGS := asflags-y := ccflags-y := +rustflags-y := cppflags-y := ldflags-y :=
@@ -323,6 +324,27 @@ quiet_cmd_cc_lst_c = MKLST $@ $(obj)/%.lst: $(src)/%.c FORCE $(call if_changed_dep,cc_lst_c) +# Compile Rust sources (.rs) +# --------------------------------------------------------------------------- + +# Need to use absolute path here and have symbolic links resolved; +# otherwise rustdoc and rustc compute different hashes for the target. +rust_cross_flags := --target=$(realpath $(KBUILD_RUST_TARGET)) + +quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_o_rs = \ + RUST_MODFILE=$(modfile) \ + $(RUSTC_OR_CLIPPY) $(rust_flags) $(rust_cross_flags) \ + -Zallow-features=allocator_api,bench_black_box,concat_idents,generic_associated_types,global_asm \ + --extern alloc --extern kernel \ + --crate-type rlib --out-dir $(obj) -L $(objtree)/rust/ \ + --crate-name $(patsubst %.o,%,$(notdir $@)) $<; \ + mv $(obj)/$(subst .o,,$(notdir $@)).d $(depfile); \ + sed -i '/^\#/d' $(depfile) + +$(obj)/%.o: $(src)/%.rs FORCE + $(call if_changed_dep,rustc_o_rs) + # Compile assembler sources (.S) # ---------------------------------------------------------------------------
scripts/Makefile.debug +10 -0
@@ -1,4 +1,5 @@ DEBUG_CFLAGS := +DEBUG_RUSTFLAGS := ifdef CONFIG_DEBUG_INFO_SPLIT DEBUG_CFLAGS += -gsplit-dwarf
@@ -10,6 +11,12 @@ ifndef CONFIG_AS_IS_LLVM KBUILD_AFLAGS += -Wa,-gdwarf-2 endif +ifdef CONFIG_DEBUG_INFO_REDUCED +DEBUG_RUSTFLAGS += -Cdebuginfo=1 +else +DEBUG_RUSTFLAGS += -Cdebuginfo=2 +endif + ifndef CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT dwarf-version-$(CONFIG_DEBUG_INFO_DWARF4) := 4 dwarf-version-$(CONFIG_DEBUG_INFO_DWARF5) := 5
@@ -31,3 +38,6 @@ endif KBUILD_CFLAGS += $(DEBUG_CFLAGS) export DEBUG_CFLAGS + +KBUILD_RUSTFLAGS += $(DEBUG_RUSTFLAGS) +export DEBUG_RUSTFLAGS
scripts/Makefile.lib +12 -0
@@ -8,6 +8,7 @@ ldflags-y += $(EXTRA_LDFLAGS) # flags that take effect in current and sub directories KBUILD_AFLAGS += $(subdir-asflags-y) KBUILD_CFLAGS += $(subdir-ccflags-y) +KBUILD_RUSTFLAGS += $(subdir-rustflags-y) # Figure out what we need to build from the various variables # ===========================================================================
@@ -133,6 +134,10 @@ _c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \ $(filter-out $(ccflags-remove-y), \ $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \ $(CFLAGS_$(target-stem).o)) +_rust_flags = $(filter-out $(RUSTFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(rustflags-remove-y), \ + $(KBUILD_RUSTFLAGS) $(rustflags-y)) \ + $(RUSTFLAGS_$(target-stem).o)) _a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \ $(filter-out $(asflags-remove-y), \ $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \
@@ -202,6 +207,11 @@ modkern_cflags = \ $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags)) +modkern_rustflags = \ + $(if $(part-of-module), \ + $(KBUILD_RUSTFLAGS_MODULE) $(RUSTFLAGS_MODULE), \ + $(KBUILD_RUSTFLAGS_KERNEL) $(RUSTFLAGS_KERNEL)) + modkern_aflags = $(if $(part-of-module), \ $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL))
@@ -211,6 +221,8 @@ c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(_c_flags) $(modkern_cflags) \ $(basename_flags) $(modname_flags) +rust_flags = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg + a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(_a_flags) $(modkern_aflags)
scripts/Makefile.modfinal +5 -3
@@ -39,11 +39,13 @@ quiet_cmd_ld_ko_o = LD [M] $@ quiet_cmd_btf_ko = BTF [M] $@ cmd_btf_ko = \ - if [ -f vmlinux ]; then \ + if [ ! -f vmlinux ]; then \ + printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ + elif $(srctree)/scripts/is_rust_module.sh $@; then \ + printf "Skipping BTF generation for %s because it's a Rust module\n" $@ 1>&2; \ + else \ LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \ $(RESOLVE_BTFIDS) -b vmlinux $@; \ - else \ - printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ fi; # Same as newer-prereqs, but allows to exclude specified extra dependencies
scripts/cc-version.sh +6 -6
@@ -1,13 +1,13 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 # -# Print the compiler name and its version in a 5 or 6-digit form. +# Print the C compiler name and its version in a 5 or 6-digit form. # Also, perform the minimum version check. set -e -# Print the compiler name and some version components. -get_compiler_info() +# Print the C compiler name and some version components. +get_c_compiler_info() { cat <<- EOF | "$@" -E -P -x c - 2>/dev/null #if defined(__clang__)
@@ -32,7 +32,7 @@ get_canonical_version() # $@ instead of $1 because multiple words might be given, e.g. CC="ccache gcc". orig_args="$@" -set -- $(get_compiler_info "$@") +set -- $(get_c_compiler_info "$@") name=$1
@@ -52,7 +52,7 @@ ICC) min_version=$($min_tool_version icc) ;; *) - echo "$orig_args: unknown compiler" >&2 + echo "$orig_args: unknown C compiler" >&2 exit 1 ;; esac
@@ -62,7 +62,7 @@ min_cversion=$(get_canonical_version $min_version) if [ "$cversion" -lt "$min_cversion" ]; then echo >&2 "***" - echo >&2 "*** Compiler is too old." + echo >&2 "*** C compiler is too old." echo >&2 "*** Your $name version: $version" echo >&2 "*** Minimum $name version: $min_version" echo >&2 "***"
scripts/is_rust_module.sh new file +19 -0
@@ -0,0 +1,19 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# is_rust_module.sh MOD.ko +# +# Returns 0 if MOD.ko is a rust module, 1 otherwise. + +set -e +module="$*" + +while IFS= read -r line +do + # Any symbol beginning with "_R" is a v0 mangled rust symbol + if [[ $line =~ ^[0-9a-fA-F]+[[:space:]]+[uUtTrR][[:space:]]+_R[^[:space:]]+$ ]]; then + exit 0 + fi +done < <(nm "$module") + +exit 1
scripts/kconfig/confdata.c +75 -0
99 lines not on this page · raw message
scripts/min-tool-version.sh +6 -0
@@ -31,6 +31,12 @@ llvm) echo 10.0.1 fi ;; +rustc) + echo 1.58.0 + ;; +bindgen) + echo 0.56.0 + ;; *) echo "$1: unknown tool" >&2 exit 1
scripts/rust-is-available-bindgen-libclang.h new file +2 -0
@@ -0,0 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#pragma message("clang version " __clang_version__)
scripts/rust-is-available.sh new file +159 -0
159 lines not on this page · raw message
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 16/19 samples: add Rust examples
In reply to Miguel OjedaA set of Rust modules that showcase how Rust modules look like and how to use the abstracted kernel features.
These samples also double as tests in the CI.
The semaphore sample comes with a C version for comparison.
--- samples/Kconfig | 2 + samples/Makefile | 1 + samples/rust/Kconfig | 123 ++++++++++++++ samples/rust/Makefile | 13 ++ samples/rust/rust_chrdev.rs | 53 +++++++ samples/rust/rust_minimal.rs | 38 +++++ samples/rust/rust_miscdev.rs | 147 +++++++++++++++++ samples/rust/rust_module_parameters.rs | 72 +++++++++ samples/rust/rust_platform.rs | 25 +++ samples/rust/rust_print.rs | 57 +++++++ samples/rust/rust_random.rs | 64 ++++++++ samples/rust/rust_semaphore.rs | 175 ++++++++++++++++++++ samples/rust/rust_semaphore_c.c | 212 +++++++++++++++++++++++++ samples/rust/rust_stack_probing.rs | 40 +++++ samples/rust/rust_sync.rs | 81 ++++++++++ 15 files changed, 1103 insertions(+) create mode 100644 samples/rust/Kconfig create mode 100644 samples/rust/Makefile create mode 100644 samples/rust/rust_chrdev.rs create mode 100644 samples/rust/rust_minimal.rs create mode 100644 samples/rust/rust_miscdev.rs create mode 100644 samples/rust/rust_module_parameters.rs create mode 100644 samples/rust/rust_platform.rs create mode 100644 samples/rust/rust_print.rs create mode 100644 samples/rust/rust_random.rs create mode 100644 samples/rust/rust_semaphore.rs create mode 100644 samples/rust/rust_semaphore_c.c create mode 100644 samples/rust/rust_stack_probing.rs create mode 100644 samples/rust/rust_sync.rs
samples/Kconfig +2 -0
@@ -241,6 +241,8 @@ config SAMPLE_WATCH_QUEUE Build example userspace program to use the new mount_notify(), sb_notify() syscalls and the KEYCTL_WATCH_KEY keyctl() function. +source "samples/rust/Kconfig" + endif # SAMPLES config HAVE_SAMPLE_FTRACE_DIRECT
samples/Makefile +1 -0
@@ -32,3 +32,4 @@ obj-$(CONFIG_SAMPLE_INTEL_MEI) += mei/ subdir-$(CONFIG_SAMPLE_WATCHDOG) += watchdog subdir-$(CONFIG_SAMPLE_WATCH_QUEUE) += watch_queue obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak/ +obj-$(CONFIG_SAMPLES_RUST) += rust/
samples/rust/Kconfig new file +123 -0
123 lines not on this page · raw message
samples/rust/Makefile new file +13 -0
@@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_SAMPLE_RUST_MINIMAL) += rust_minimal.o +obj-$(CONFIG_SAMPLE_RUST_PRINT) += rust_print.o +obj-$(CONFIG_SAMPLE_RUST_MODULE_PARAMETERS) += rust_module_parameters.o +obj-$(CONFIG_SAMPLE_RUST_SYNC) += rust_sync.o +obj-$(CONFIG_SAMPLE_RUST_CHRDEV) += rust_chrdev.o +obj-$(CONFIG_SAMPLE_RUST_MISCDEV) += rust_miscdev.o +obj-$(CONFIG_SAMPLE_RUST_STACK_PROBING) += rust_stack_probing.o +obj-$(CONFIG_SAMPLE_RUST_SEMAPHORE) += rust_semaphore.o +obj-$(CONFIG_SAMPLE_RUST_SEMAPHORE_C) += rust_semaphore_c.o +obj-$(CONFIG_SAMPLE_RUST_RANDOM) += rust_random.o +obj-$(CONFIG_SAMPLE_RUST_PLATFORM) += rust_platform.o
samples/rust/rust_chrdev.rs new file +53 -0
53 lines not on this page · raw message
samples/rust/rust_minimal.rs new file +38 -0
@@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Rust minimal sample + +#![no_std] +#![feature(allocator_api, global_asm)] + +use kernel::prelude::*; + +module! { +type :RustMinimal , +name :b"rust_minimal" , + author:b"Rust for Linux Contributors" , + description:b"Rust minimal sample" , + license:b"GPL v2" , +} + +struct RustMinimal { + message:String , +} + +impl KernelModule for RustMinimal { +fn init (_name: &'staticCStr , _module: &'staticThisModule ) ->Result <Self > { +pr_info! ("Rust minimal sample (init)\n" ); +pr_info! ("Am I built-in? {}\n" , !cfg! (MODULE )); + +Ok (RustMinimal { + message:"on the heap!" .try_to_owned ()?, + }) + } +} + +impl Drop for RustMinimal { +fn drop (&mut self) { +pr_info! ("My message is {}\n" , self.message); +pr_info! ("Rust minimal sample (exit)\n" ); + } +}
samples/rust/rust_miscdev.rs new file +147 -0
147 lines not on this page · raw message
samples/rust/rust_module_parameters.rs new file +72 -0
72 lines not on this page · raw message
samples/rust/rust_platform.rs new file +25 -0
@@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Rust platform device driver sample. + +#![no_std] +#![feature(allocator_api, global_asm)] + +use kernel::{module_platform_driver, of, platform, prelude::*}; + +module_platform_driver! { +type :Driver , +name :b"rust_platform" , + license:b"GPL v2" , +} + +struct Driver ; +impl platform::Driver for Driver { + kernel::define_of_id_table! {(), [ + (of::DeviceId ::Compatible (b"rust,sample" ),None ), + ]} + +fn probe (_dev: &mut platform::Device , _id_info:Option <&Self ::IdInfo >) ->Result { +Ok (()) + } +}
samples/rust/rust_print.rs new file +57 -0
57 lines not on this page · raw message
samples/rust/rust_random.rs new file +64 -0
64 lines not on this page · raw message
samples/rust/rust_semaphore.rs new file +175 -0
175 lines not on this page · raw message
samples/rust/rust_semaphore_c.c new file +212 -0
212 lines not on this page · raw message
samples/rust/rust_stack_probing.rs new file +40 -0
@@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Rust stack probing sample + +#![no_std] +#![feature(allocator_api, global_asm)] +#![feature(bench_black_box)] + +use kernel::prelude::*; + +module! { +type :RustStackProbing , +name :b"rust_stack_probing" , + author:b"Rust for Linux Contributors" , + description:b"Rust stack probing sample" , + license:b"GPL v2" , +} + +struct RustStackProbing ; + +impl KernelModule for RustStackProbing { +fn init (_name: &'staticCStr , _module: &'staticThisModule ) ->Result <Self > { +pr_info! ("Rust stack probing sample (init)\n" ); + +// Including this large variable on the stack will trigger +// stack probing on the supported archs. +// This will verify that stack probing does not lead to +// any errors if we need to link `__rust_probestack`. +let x: [u64 ;514 ] = core::hint::black_box ([5 ;514 ]); +pr_info! ("Large array has length: {}\n" , x.len ()); + +Ok (RustStackProbing ) + } +} + +impl Drop for RustStackProbing { +fn drop (&mut self) { +pr_info! ("Rust stack probing sample (exit)\n" ); + } +}
samples/rust/rust_sync.rs new file +81 -0
81 lines not on this page · raw message
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerPATCH v3 17/19 MAINTAINERS: Rust
In reply to Miguel OjedaMiguel, Alex and Wedson will be maintaining the Rust support.
--- MAINTAINERS | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
MAINTAINERS +16 -0
@@ -16578,6 +16578,22 @@ L: [email protected] S: Maintained F: drivers/infiniband/ulp/rtrs/ +RUST +M: Miguel Ojeda <[email protected]> +M: Alex Gaynor <[email protected]> +M: Wedson Almeida Filho <[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: rust/ +F: samples/rust/ +F: Documentation/rust/ +F: lib/rust.h +F: scripts/*rust* +K: \b(?i:rust)\b + RXRPC SOCKETS (AF_RXRPC) M: David Howells <[email protected]> M: Marc Dionne <[email protected]>
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerRFC PATCH v3 18/19 drivers: gpio: PrimeCell PL061 in Rust
In reply to Miguel OjedaFrom: Wedson Almeida Filho <[email protected]>
A port to Rust of the PrimeCell PL061 GPIO driver.
This module is a work in progress and will be sent for review later on, as well as separately from the Rust support.
However, it is included to show how an actual working module written in Rust may look like.
--- drivers/gpio/Kconfig | 8 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio_pl061_rust.rs | 362 ++++++++++++++++++++++++++++++++ 3 files changed, 371 insertions(+) create mode 100644 drivers/gpio/gpio_pl061_rust.rs
drivers/gpio/Kconfig +8 -0
@@ -471,6 +471,14 @@ config GPIO_PL061 help Say yes here to support the PrimeCell PL061 GPIO device. +config GPIO_PL061_RUST + tristate "PrimeCell PL061 GPIO support written in Rust" + depends on ARM_AMBA && RUST + select IRQ_DOMAIN + select GPIOLIB_IRQCHIP + help + Say yes here to support the PrimeCell PL061 GPIO device + config GPIO_PMIC_EIC_SPRD tristate "Spreadtrum PMIC EIC support" depends on MFD_SC27XX_PMIC || COMPILE_TEST
drivers/gpio/Makefile +1 -0
@@ -118,6 +118,7 @@ obj-$(CONFIG_GPIO_PCIE_IDIO_24) += gpio-pcie-idio-24.o obj-$(CONFIG_GPIO_PCI_IDIO_16) += gpio-pci-idio-16.o obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o +obj-$(CONFIG_GPIO_PL061_RUST) += gpio_pl061_rust.o obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
drivers/gpio/gpio_pl061_rust.rs new file +362 -0
362 lines not on this page · raw message
Signature · 1 line
2.34.1
Miguel Ojeda
maintainerRFC PATCH v3 19/19 drivers: android: Binder IPC in Rust
In reply to Miguel OjedaFrom: Wedson Almeida Filho <[email protected]>
A port to Rust of the Android Binder IPC mechanism.
This module is a work in progress and will be sent for review later on, as well as separately from the Rust support.
However, it is included to show how an actual working module written in Rust may look like.
--- drivers/android/Kconfig | 7 + drivers/android/Makefile | 2 + drivers/android/allocation.rs | 266 ++++++++ drivers/android/context.rs | 80 +++ drivers/android/defs.rs | 99 +++ drivers/android/node.rs | 476 ++++++++++++++ drivers/android/process.rs | 964 ++++++++++++++++++++++++++++ drivers/android/range_alloc.rs | 189 ++++++ drivers/android/rust_binder.rs | 114 ++++ drivers/android/thread.rs | 871 +++++++++++++++++++++++++ drivers/android/transaction.rs | 326 ++++++++++ include/uapi/linux/android/binder.h | 28 +- 12 files changed, 3409 insertions(+), 13 deletions(-) create mode 100644 drivers/android/allocation.rs create mode 100644 drivers/android/context.rs create mode 100644 drivers/android/defs.rs create mode 100644 drivers/android/node.rs create mode 100644 drivers/android/process.rs create mode 100644 drivers/android/range_alloc.rs create mode 100644 drivers/android/rust_binder.rs create mode 100644 drivers/android/thread.rs create mode 100644 drivers/android/transaction.rs
drivers/android/Kconfig +7 -0
@@ -20,6 +20,13 @@ config ANDROID_BINDER_IPC Android process, using Binder to identify, invoke and pass arguments between said processes. +config ANDROID_BINDER_IPC_RUST + bool "Android Binder IPC Driver in Rust" + depends on MMU && RUST + default n + help + Implementation of the Binder IPC in Rust. + config ANDROID_BINDERFS bool "Android Binderfs filesystem" depends on ANDROID_BINDER_IPC
drivers/android/Makefile +2 -0
@@ -4,3 +4,5 @@ ccflags-y += -I$(src) # needed for trace events obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o + +obj-$(CONFIG_ANDROID_BINDER_IPC_RUST) += rust_binder.o
drivers/android/allocation.rs new file +266 -0
266 lines not on this page · raw message
drivers/android/context.rs new file +80 -0
80 lines not on this page · raw message
drivers/android/defs.rs new file +99 -0
99 lines not on this page · raw message
drivers/android/node.rs new file +476 -0
476 lines not on this page · raw message
drivers/android/process.rs new file +964 -0
964 lines not on this page · raw message
drivers/android/range_alloc.rs new file +189 -0
189 lines not on this page · raw message
drivers/android/rust_binder.rs new file +114 -0
114 lines not on this page · raw message
drivers/android/thread.rs new file +871 -0
794 lines not on this page · raw message
drivers/android/transaction.rs new file +326 -0
326 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.34.1
Part of the diff is not shown here. View the raw message.