RustInQemu: Difference between revisions

From QEMU
 
(65 intermediate revisions by 3 users not shown)
Line 1: Line 1:
For the old RustInQemu page, see [[RustInQemu/2022]]
For the old RustInQemu page, see [[RustInQemu/2022]]


== Active efforts in 2024 ==
== Active effort ==


* <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]
* [[ChangeLog/10.0#Rust|Current state]]
* 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]
* [https://www.qemu.org/docs/master/devel/rust.html Documentation]
** Meson and configure integration
* Roadmap: [https://lore.kernel.org/all/cc40943e-dec1-4890-a1d9-579350ce296f@pbonzini.local/ November 2024] | [https://lore.kernel.org/qemu-devel/17ad81c3-98fc-44c2-8f65-f5e2cc07030b@gnu.org/ January 2025]
** 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.
* <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]
-->


== Past efforts ==
== Past efforts ==
Line 16: Line 16:
* <code>[RFC v3 00/32] Rust binding for QAPI and qemu-ga QMP handler examples</code><br />[https://patchew.org/QEMU/20210907121943.3498701-1-marcandre.lureau@redhat.com/ on patchew] [https://lore.kernel.org/qemu-devel/20210907121943.3498701-1-marcandre.lureau@redhat.com/ on lore]
* <code>[RFC v3 00/32] Rust binding for QAPI and qemu-ga QMP handler examples</code><br />[https://patchew.org/QEMU/20210907121943.3498701-1-marcandre.lureau@redhat.com/ on patchew] [https://lore.kernel.org/qemu-devel/20210907121943.3498701-1-marcandre.lureau@redhat.com/ on lore]


== Minimum supported version ==
== Work in progress ==
* 1.56.0: 2021 edition
=== Paolo ===
* 1.59.0: const <tt>CStr::from_bytes_with_nul_unchecked</tt> (needed by cstr crate, see below)
* Posted: Opaque<> (to split crates and also first step for annotated pinning)
* 1.64.0: <tt>std::ffi::c_*</tt> (can use libc or std::os::raw)
* Planned: chardev
* 1.74.0: Clippy can be configured in Cargo.toml
* Later: pinned_init... maybe use MaybeUninit as a first step?
* 1.77.0: C string literals, offset_of!
* Upstream Meson: "objects:", rustdoc, <tt>-C prefer-dynamic</tt>
**alternative: cstr crate, [https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=10a22a9b8393abd7b541d8fc844bc0df with_offsets macro]
 
=== Manos ===
* Documentation
 
=== Zhao ===
* HPET live migration.
 
=== Kevin ===
* Executing async code, block driver implementations
** https://lore.kernel.org/qemu-devel/20250211214328.640374-1-kwolf@redhat.com/


== TODO ==
== TODO ==
[https://patchew.org/QEMU/rust-pl011-rfc-v4.git.manos.pitsidianakis@linaro.org/ Done]:
=== Bugs ===
* module structure should resemble the C part of the tree?
* Integration tests are linked with libqemuutil as link_whole, which does not work when modules are enabled
* only generate bindings.rs.inc once
** [https://github.com/mesonbuild/meson/pull/14031 meson seems to be buggy and does not allow using link_with instead?]
* disabling the cast_ptr_alignment lint is too broad
** probably best to require meson 1.8.0 anyway as it has nicer integration with clippy, and possibly rustdoc
* Add BQL abstraction for tests - avoid running them with "--test-threads 1"
* [https://github.com/mesonbuild/meson/issues/8828 Distros would prefer to link libstd dynamically]; Rust-enabled QEMU binaries are huge


[https://lore.kernel.org/qemu-devel/9a83a260-4f4c-477b-a6e1-c8d78d1f3039@redhat.com/ To do (patch available)]:
=== Nice things to have ===
* update bundled meson to 1.5.0
* [https://github.com/mesonbuild/meson/pull/13933 run doctests with meson test]
* add support for --rustc and RUSTC environment variables
* Remove need for manual "meson subprojects update --reset" when updating packagefiles/
* remove --no-include-path-detection from bindgen invocation
* Improve tool integration
* rename subprojects to use Meson 1.5.0+ convention and add meson.override_dependency() call
** Run code checks a la "meson test --suite codecheck"? (clippy and rustfmt)
* add support for cross compilation of Rust subprojects (<tt>native: true</tt> for deps of procedural macro crates)
* rustfmt currently requires nightly, decide what to do about it
* fix licenses for Rust subprojects
* Place rustdoc output for master somewhere?
* fix cfgs so that proc-macro2 can be compiled with 1.63.0
* split qemu_api into multiple crates
* demonstrate patching of subprojects (needed for bilge-impl to support 1.63.0)
* more QOM procedural macros
** generate qdev properties
** generate parts of TypeInfo?
** monomorphization of <tt>T: IsA&lt;Class&gt;</tt> to <tt>&T</tt> (like the momo crate)
* distros need dynamically linked libstd
** rewrite all main()s in Rust and use [https://github.com/mesonbuild/meson/issues/14224 -C prefer-dynamic]?
** or should Meson be able to link C programs with rlibs?


After commit:
=== New code to write===
* add more safety docs
* feature parity for pl011
* trait to generate all-zero structs without having to type "unsafe { MaybeUninit::zeroed().assume_init() }"
* safe object creation with [https://docs.rs/pinned-init/ pinned_init, originating from Linux])
* use ctor instead of non-portable linker magic, and the cstr crate instead of CStr statics or c""
* complete vmstate bindings
* TODO comments when the code is doing potential undefined behavior
* Generic Rust<->C interop, Error (https://github.com/bonzini/rust-qemu)
* single cargo workspace for clippy etc.?
* DMA (investigate vm-memory?)
* CI integration
* Trace/log
** clean up lints (see below)
* lower minimum supported version in QEMU code too (Debian needs 1.63.0)
* eliminate undefined behavior:
** no aliasing of &mut
** use MaybeUninit in instance_init (long-term: investigate [https://docs.rs/pinned-init/ pinned_init crate, originating from Linux])
 
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 ==
== Ideas for lints without breaking CI ==
Line 68: Line 75:
=== Miscellanea  ===
=== Miscellanea  ===


- <code>qemu-bridge-helper.c</code> Re-write SUID C executable with useful features.
* <code>qemu-bridge-helper.c</code> Re-write SUID C executable with useful features.
 
=== Bindings ===


* visitors/QOM properties, could be interesting for <code>hw/sensor/tmp105.c</code>...
=== Devices  ===
=== Devices  ===


- <code>hw/block/pflash_cfi01.c</code>, <code>hw/block/pflash_cfi02.c</code> (claimed, WIP)
* <code>hw/block/pflash_cfi01.c</code>, <code>hw/block/pflash_cfi02.c</code> (claimed, WIP)
 
** needs block bindings
- <code>hw/mem/nvdimm.c</code> (suggested by [[User:Manos|Manos]])
* <code>hw/timer/i8254.c</code> (claimed, WIP)
 
* <code>hw/mem/nvdimm.c</code> (suggested by [[User:Manos|Manos]])
- <code>hw/timer/i8254.c</code> (claimed, WIP)


[[Category:RustInQemu]]
[[Category:RustInQemu]]

Latest revision as of 14:12, 27 February 2025

For the old RustInQemu page, see RustInQemu/2022

Active effort


Past efforts

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

Work in progress

Paolo

  • Posted: Opaque<> (to split crates and also first step for annotated pinning)
  • Planned: chardev
  • Later: pinned_init... maybe use MaybeUninit as a first step?
  • Upstream Meson: "objects:", rustdoc, -C prefer-dynamic

Manos

  • Documentation

Zhao

  • HPET live migration.

Kevin

TODO

Bugs

Nice things to have

  • run doctests with meson test
  • Remove need for manual "meson subprojects update --reset" when updating packagefiles/
  • Improve tool integration
    • Run code checks a la "meson test --suite codecheck"? (clippy and rustfmt)
  • rustfmt currently requires nightly, decide what to do about it
  • Place rustdoc output for master somewhere?
  • split qemu_api into multiple crates
  • more QOM procedural macros
    • generate qdev properties
    • generate parts of TypeInfo?
    • monomorphization of T: IsA<Class> to &T (like the momo crate)
  • distros need dynamically linked libstd
    • rewrite all main()s in Rust and use -C prefer-dynamic?
    • or should Meson be able to link C programs with rlibs?

New code to write

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.

Bindings

  • visitors/QOM properties, could be interesting for hw/sensor/tmp105.c...

Devices

  • hw/block/pflash_cfi01.c, hw/block/pflash_cfi02.c (claimed, WIP)
    • needs block bindings
  • hw/timer/i8254.c (claimed, WIP)
  • hw/mem/nvdimm.c (suggested by Manos)