RustInQemu: Difference between revisions

From QEMU
 
(3 intermediate revisions by the same user not shown)
Line 4: Line 4:


* <code>Subject: [RFC 0/6] scripts: Rewrite simpletrace printer in Rust</code><br /><code>Date: Mon, 27 May 2024 16:14:15 +0800</code><br />[https://lore.kernel.org/qemu-devel/20240527081421.2258624-1-zhao1.liu@intel.com/ RFC v1]
* <code>Subject: [RFC 0/6] scripts: Rewrite simpletrace printer in Rust</code><br /><code>Date: Mon, 27 May 2024 16:14:15 +0800</code><br />[https://lore.kernel.org/qemu-devel/20240527081421.2258624-1-zhao1.liu@intel.com/ RFC v1]
* ARM PL011 UART device model in Rust<br /><code>Subject: [RFC PATCH v1 0/6] Implement ARM PL011 in Rust</code><br /><code>Date: Mon, 10 Jun 2024 21:22:35 +0300</code><br />[https://lore.kernel.org/qemu-devel/cover.rust-pl011-rfc-v1.git.manos.pitsidianakis@linaro.org/ RFC v1] [https://lore.kernel.org/qemu-devel/rust-pl011-rfc-v2.git.manos.pitsidianakis@linaro.org v2]
* ARM PL011 UART device model in Rust<br /><code>Subject: [RFC PATCH v1 0/6] Implement ARM PL011 in Rust</code><br /><code>Date: Mon, 10 Jun 2024 21:22:35 +0300</code><br />[https://lore.kernel.org/qemu-devel/cover.rust-pl011-rfc-v1.git.manos.pitsidianakis@linaro.org/ RFC v1] [https://lore.kernel.org/qemu-devel/rust-pl011-rfc-v6.git.manos.pitsidianakis@linaro.org/ v6]
** Meson integration
** Meson and configure integration
** Bindings generation
** Bindings generation
After some discussion we decided to use rustc directly without going through cargo and each external crate becomes a Meson subproject. Meson 1.5.0+'s support for <tt>method = cargo</tt> is pretty good for host-compiled packages, but it doesn't work for dependencies of build-compiled packages (i.e. dependencies of procedural macros). This is tracked by https://github.com/mesonbuild/meson/issues/11121. Until then, meson.build files for procedural macros and their dependencies have to be written by hand. (Currently _all_ dependencies use hand-written meson.build).
While cargo would be fine as an interim solution, using Meson to compile the Rust code removes some moving parts. The extra cost of writing meson.build files for dependencies is expected to be small and will mostly happen upfront.


== Past efforts ==
== Past efforts ==
Line 21: Line 25:


== TODO ==
== TODO ==
[https://patchew.org/QEMU/rust-pl011-rfc-v4.git.manos.pitsidianakis@linaro.org/ Before commit wishlist]:
[https://patchew.org/QEMU/rust-pl011-rfc-v4.git.manos.pitsidianakis@linaro.org/ Done]:
* TODO comments when the code is doing potential undefined behavior
* module structure should resemble the C part of the tree?
* module structure should resemble the C part of the tree?
* only generate bindings.rs.inc once
* only generate bindings.rs.inc once
* disabling the cast_ptr_alignment lint is too broad
[https://lore.kernel.org/qemu-devel/9a83a260-4f4c-477b-a6e1-c8d78d1f3039@redhat.com/ To do (patch available)]:
* update bundled meson to 1.5.0
* add support for --rustc and RUSTC environment variables
* remove --no-include-path-detection from bindgen invocation
* rename subprojects to use Meson 1.5.0+ convention and add meson.override_dependency() call
* add support for cross compilation of Rust subprojects (<tt>native: true</tt> for deps of procedural macro crates)
* fix licenses for Rust subprojects
* fix cfgs so that proc-macro2 can be compiled with 1.63.0
* demonstrate patching of subprojects (needed for bilge-impl to support 1.63.0)
After commit:
* add more safety docs
* trait to generate all-zero structs without having to type "unsafe { MaybeUninit::zeroed().assume_init() }"
* trait to generate all-zero structs without having to type "unsafe { MaybeUninit::zeroed().assume_init() }"
* avoid disabling lints that are too broad (cast_ptr_alignment, missing_safety_doc)
* add support for --cargo and CARGO environment variables
* use ctor instead of non-portable linker magic, and the cstr crate instead of CStr statics or c""
* use ctor instead of non-portable linker magic, and the cstr crate instead of CStr statics or c""
* check if -Wl,--whole-archive can be replaced with link_whole:
* TODO comments when the code is doing potential undefined behavior
 
* single cargo workspace for clippy etc.?
After commit:
* [https://lore.kernel.org/qemu-devel/1c53f8d2-3b33-404c-bb1c-38475087d7ae@redhat.com/ single cargo build]: using workspace instead of duplicating large parts of Cargo.toml
** Kconfig integration
* CI integration
* CI integration
** lints (see below)
** clean up lints (see below)
* lower minimum supported version (Debian needs 1.63.0)
* lower minimum supported version in QEMU code too (Debian needs 1.63.0)
* eliminate undefined behavior:
* eliminate undefined behavior:
** no aliasing of &mut
** no aliasing of &mut

Latest revision as of 13:07, 8 August 2024

For the old RustInQemu page, see RustInQemu/2022

Active efforts in 2024

  • Subject: [RFC 0/6] scripts: Rewrite simpletrace printer in Rust
    Date: Mon, 27 May 2024 16:14:15 +0800
    RFC v1
  • ARM PL011 UART device model in Rust
    Subject: [RFC PATCH v1 0/6] Implement ARM PL011 in Rust
    Date: Mon, 10 Jun 2024 21:22:35 +0300
    RFC v1 v6
    • Meson and configure integration
    • Bindings generation

After some discussion we decided to use rustc directly without going through cargo and each external crate becomes a Meson subproject. Meson 1.5.0+'s support for method = cargo is pretty good for host-compiled packages, but it doesn't work for dependencies of build-compiled packages (i.e. dependencies of procedural macros). This is tracked by https://github.com/mesonbuild/meson/issues/11121. Until then, meson.build files for procedural macros and their dependencies have to be written by hand. (Currently _all_ dependencies use hand-written meson.build).

While cargo would be fine as an interim solution, using Meson to compile the Rust code removes some moving parts. The extra cost of writing meson.build files for dependencies is expected to be small and will mostly happen upfront.

Past efforts

  • [RFC v3 00/32] Rust binding for QAPI and qemu-ga QMP handler examples
    on patchew on lore

Minimum supported version

  • 1.56.0: 2021 edition
  • 1.59.0: const CStr::from_bytes_with_nul_unchecked (needed by cstr crate, see below)
  • 1.64.0: std::ffi::c_* (can use libc or std::os::raw)
  • 1.74.0: Clippy can be configured in Cargo.toml
  • 1.77.0: C string literals, offset_of!

TODO

Done:

  • module structure should resemble the C part of the tree?
  • only generate bindings.rs.inc once
  • disabling the cast_ptr_alignment lint is too broad

To do (patch available):

  • update bundled meson to 1.5.0
  • add support for --rustc and RUSTC environment variables
  • remove --no-include-path-detection from bindgen invocation
  • rename subprojects to use Meson 1.5.0+ convention and add meson.override_dependency() call
  • add support for cross compilation of Rust subprojects (native: true for deps of procedural macro crates)
  • fix licenses for Rust subprojects
  • fix cfgs so that proc-macro2 can be compiled with 1.63.0
  • demonstrate patching of subprojects (needed for bilge-impl to support 1.63.0)

After commit:

  • add more safety docs
  • trait to generate all-zero structs without having to type "unsafe { MaybeUninit::zeroed().assume_init() }"
  • use ctor instead of non-portable linker magic, and the cstr crate instead of CStr statics or c""
  • TODO comments when the code is doing potential undefined behavior
  • single cargo workspace for clippy etc.?
  • CI integration
    • clean up lints (see below)
  • lower minimum supported version in QEMU code too (Debian needs 1.63.0)
  • eliminate undefined behavior:

other experiments at https://github.com/bonzini/rust-qemu

  • Generic Rust<->C interop, Error, QOM reference counting
  • Chardev
  • MemoryRegion, SysbusDevice

Ideas for lints without breaking CI

See https://github.com/bonzini/rust-qemu/commit/95b25f7c5f4e2694a85a5503050cc98da7562c7c

  • run clippy as part of "make check", possibly only if Rust is newer than some version (1.74.0 so that clippy can be configured in Cargo.toml?)
  • deny many individual lints, do not deny groups (complexity, perf, style, suspicious) on regular builds. allow unknown_lints.
  • add to CI a fallible job that runs on nightly clippy with -Dclippy::complexity -Dclippy::perf -Dclippy::suspicious -Dclippy::style -Dunknown_lints. the job should generally pass, and if a new lint triggers it probably should be added to Cargo.toml as either "allow" (rare) or "deny" (possibly after adding #[allow()] to the source).

Possible project targets

Miscellanea

- qemu-bridge-helper.c Re-write SUID C executable with useful features.

Devices

- hw/block/pflash_cfi01.c, hw/block/pflash_cfi02.c (claimed, WIP)

- hw/mem/nvdimm.c (suggested by Manos)

- hw/timer/i8254.c (claimed, WIP)