The sixth version of patches for the Linux kernel with Rust language support

Miguel Ojeda, the author of the Rust-for-Linux project, proposed the release of v6 components for developing device drivers in the Rust language for consideration by Linux kernel developers. This is the seventh edition of the patches, taking into account the first version, published without a version number. Rust support is considered experimental, but is already included in the linux-next branch and is sufficiently developed to begin work on creating abstraction layers over kernel subsystems, as well as writing drivers and modules. The development is funded by Google and the ISRG (Internet Security Research Group), which is the founder of the Let's Encrypt project and promotes HTTPS and the development of technologies to improve Internet security.

In the new version:

  • The toolkit and a variant of the alloc library, freed from possible generation of a "panic" state when errors occur, have been updated to the release of Rust 1.60, which stabilizes support for the "maybe_uninit_extra" mode used in kernel patches.
  • Added the ability to run tests from the documentation (tests that are also used as examples in the documentation), through compile-time conversion of tests tied to the kernel API into KUnit tests executed during kernel loading.
  • Requirements have been adopted that tests should not result in a Clippy linter warning, just like Rust kernel code.
  • An initial implementation of the β€œnet” module with network functions is proposed. Rust code has access to kernel network structures such as Namespace (based on the struct net kernel structure), SkBuff (struct sk_buff), TcpListener, TcpStream (struct socket), Ipv4Addr (struct in_addr), SocketAddrV4 ( struct sockaddr_in) and their IPv6 equivalents.
  • There is initial support for asynchronous programming techniques (async), implemented in the form of the kasync module. For example, you can write asynchronous code to manipulate TCP sockets: async fn echo_server(stream: TcpStream) -> Result { let mut buf = [0u8; 1024]; loop { let n = stream.read(&mut buf).await?; if n == 0 { return Ok(()); } stream.write_all(&buf[..n]).await?; } }
  • Added net::filter module for manipulating network packet filters. Added example rust_netfilter.rs with a filter implementation in the Rust language.
  • Added implementation of a simple mutex smutex::Mutex, which does not require pinning.
  • Added NoWaitLock, which never waits for a lock, and if occupied by another thread, causes an error to be reported when attempting to acquire the lock instead of stopping the caller.
  • Added RawSpinLock, identified by raw_spinlock_t in the kernel, to apply to sections that cannot be idle.
  • Added ARef type for references to an object to which the reference counting mechanism is applied (always-refcounted).
  • The rustc_codegen_gcc backend, which allows you to use the libgccjit library from the GCC project as a code generator in rustc to provide rustc with support for architectures and optimizations available in GCC, has implemented the ability to bootstrapping the rustc compiler. Compiler promotion means the ability to use a GCC-based code generator in rustc to build the rustc compiler itself. In addition, the recent release of GCC 12.1 includes fixes to libgccjit necessary for rustc_codegen_gcc to work correctly. Preparations are underway to provide the ability to install rustc_codegen_gcc using the rustup utility.
  • The progress in the development of the GCC frontend gccrs with the implementation of the Rust language compiler based on GCC is noted. There are currently two full-time developers working on gccrs.

Recall that the proposed changes make it possible to use Rust as a second language for developing drivers and kernel modules. Rust support is presented as an option that is not enabled by default and does not result in the inclusion of Rust among the required build dependencies for the kernel. Using Rust to develop drivers will allow you to create safer and better drivers with minimal effort, free from problems such as accessing a memory area after it is freed, dereferencing null pointers, and buffer overruns.

Memory-safe handling is provided in Rust at compile time through reference checking, keeping track of object ownership and object lifetime (scope), as well as through evaluation of the correctness of memory access during code execution. Rust also provides protection against integer overflows, requires mandatory initialization of variable values ​​before use, handles errors better in the standard library, applies the concept of immutable references and variables by default, offers strong static typing to minimize logical errors.

Source: opennet.ru

Add a comment