Commit Graph

35 Commits

Author SHA1 Message Date
Paolo Bonzini
ce4a144cf8 rust: do not use --generate-cstr
--generate-cstr is a good idea and generally the right thing to do,
but it is not available in Debian 12 and Ubuntu 22.04.  Work around
the absence.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:17 +01:00
Paolo Bonzini
bb42965dd4 rust: do not use MaybeUninit::zeroed()
MaybeUninit::zeroed() is handy but is not available as a "const" function
until Rust 1.75.0.

Remove the default implementation of Zeroable::ZERO, and write by hand
the definitions for those types that need it.  It may be possible to
add automatic implementation of the trait, via a procedural macro and/or
a trick similar to offset_of!, but do it the easy way for now.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:17 +01:00
Junjie Mao
f351840088 rust: introduce alternative implementation of offset_of!
offset_of! was stabilized in Rust 1.77.0.  Use an alternative implemenation
that was found on the Rust forums, and whose author agreed to license as
MIT for use in QEMU.

The alternative allows only one level of field access, but apart
from this can be used just by replacing core::mem::offset_of! with
qemu_api::offset_of!.

The actual implementation of offset_of! is done in a declarative macro,
but for simplicity and to avoid introducing an extra level of indentation,
the trigger is a procedural macro #[derive(offsets)].

The procedural macro is perhaps a bit overengineered, but it helps
introducing some idioms that will be useful in the future as well.

Signed-off-by: Junjie Mao <junjie.mao@hotmail.com>
Co-developed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:16 +01:00
Paolo Bonzini
39c8faefb5 rust: create a cargo workspace
Workspaces allows tracking dependencies for multiple crates at once,
by having a single Cargo.lock file at the top of the rust/ tree.
Because QEMU's Cargo.lock files have to be synchronized with the versions
of crates in subprojects/, using a workspace avoids the need to copy
over the Cargo.lock file when adding a new device (and thus a new crate)
under rust/hw/.

In addition, workspaces let cargo download and build dependencies just
once.  While right now we have one leaf crate (hw/char/pl011), this
will not be the case once more devices are added.

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:16 +01:00
Paolo Bonzini
907d2bbb80 rust: synchronize dependencies between subprojects and Cargo.lock
The next commit will introduce a new build.rs dependency for rust/qemu-api,
version_check.  Before adding it, ensure that all dependencies are
synchronized between the Meson- and cargo-based build systems.

Note that it's not clear whether in the long term we'll use Cargo for
anything; it seems that the three main uses (clippy, rustfmt, rustdoc)
can all be invoked manually---either via glue code in QEMU, or by
extending Meson to gain the relevant functionality.  However, for
the time being we're stuck with Cargo so it should at least look at
the same code as the rest of the build system.

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:16 +01:00
Paolo Bonzini
718e255f0a rust: introduce a c_str macro
This allows CStr constants to be defined easily on Rust 1.63.0, while
checking that there are no embedded NULs.  c"" literals were only
stabilized in Rust 1.77.0.

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:16 +01:00
Paolo Bonzini
9f7d4520d6 rust: use std::os::raw instead of core::ffi
core::ffi::c_* types were introduced in Rust 1.64.0.  Use the older types
in std::os::raw, which are now aliases of the types in core::ffi.  There is
no need to compile QEMU as no_std, so this is acceptable as long as we support
a version of Debian with Rust 1.63.0.

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:16 +01:00
Manos Pitsidianakis
230b710bf4 rust/pl011: Use correct masks for IBRD and FBRD
Port fix from commit cd247eae16
"hw/char/pl011: Use correct masks for IBRD and FBRD"

Related issue: <https://gitlab.com/qemu-project/qemu/-/issues/2610>

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20241024-rust-round-2-v1-9-051e7a25b978@linaro.org
2024-11-05 14:18:16 +01:00
Manos Pitsidianakis
d38723f568 rust/pl011: remove commented out C code
This code juxtaposed what should be happening according to the C device
model but is not needed now that this has been reviewed (I hope) and its
validity checked against what the C device does (I hope, again).

No functional change.

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20241024-rust-round-2-v1-8-051e7a25b978@linaro.org
2024-11-05 14:18:16 +01:00
Manos Pitsidianakis
2e06e72d2e rust/pl011: add TYPE_PL011_LUMINARY device
Add a device specialization for the Luminary UART device.

This commit adds a DeviceId enum that utilizes the Index trait to return
different bytes depending on what device id the UART has (Arm -default-
or Luminary)

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20241024-rust-round-2-v1-6-051e7a25b978@linaro.org
2024-11-05 14:18:16 +01:00
Manos Pitsidianakis
2e57bb6b27 rust/pl011: move CLK_NAME static to function scope
We do not need to have CLK_NAME public nor a static. No functional change.

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20241024-rust-round-2-v1-5-051e7a25b978@linaro.org
2024-11-05 14:18:16 +01:00
Manos Pitsidianakis
93243319db rust/pl011: add support for migration
Declare the vmstate description of the PL011 device.

Based on a patch by Manos Pitsidianakis
(https://lore.kernel.org/qemu-devel/20241024-rust-round-2-v1-4-051e7a25b978@linaro.org/).

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20241024-rust-round-2-v1-4-051e7a25b978@linaro.org
2024-11-05 14:18:16 +01:00
Paolo Bonzini
113c668852 rust/pl011: fix default value for migrate-clock
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:16 +01:00
Manos Pitsidianakis
0a65e4124a rust: add definitions for vmstate
Add a new qemu_api module, `vmstate`. Declare a bunch of Rust
macros declared that are equivalent in spirit to the C macros in
include/migration/vmstate.h.

For example the Rust of equivalent of the C macro:

  VMSTATE_UINT32(field_name, struct_name)

is:

  vmstate_uint32!(field_name, StructName)

This breathtaking development will allow us to reach feature parity between
the Rust and C pl011 implementations.

Extracted from a patch by Manos Pitsidianakis
(https://lore.kernel.org/qemu-devel/20241024-rust-round-2-v1-4-051e7a25b978@linaro.org/).

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:16 +01:00
Paolo Bonzini
f60f3670fd rust: do not use TYPE_CHARDEV unnecessarily
In the invocation of qdev_prop_set_chr(), "chardev" is the name of a
property rather than a type and has to match the name of the property
in device_class.rs.  Do not use TYPE_CHARDEV here, just like in the C
version of pl011_create.

Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:16 +01:00
Paolo Bonzini
6e50bde1e1 rust: provide safe wrapper for MaybeUninit::zeroed()
MaybeUninit::zeroed() is handy, but it introduces unsafe (and has a
pretty heavy syntax in general).  Introduce a trait that provides the
same functionality while staying within safe Rust.

In addition, MaybeUninit::zeroed() is not available as a "const"
function until Rust 1.75.0, so this also prepares for having handwritten
implementations of the trait until we can assume that version.

Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:16 +01:00
Paolo Bonzini
c92c447ff0 rust: make properties array immutable
Now that device_class_set_props() takes a const pointer, the only part of
"define_property!" that needs to be non-const is the call to try_into().
This in turn will only break if offset_of returns a value with the most
significant bit set (i.e. a struct size that is >=2^31 or >= 2^63,
respectively on 32- and 64-bit system), which is impossible.

Just use a cast and clean everything up to remove the run-time
initialization.  This also removes a use of OnceLock, which was only
stabilized in 1.70.0.

Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:16 +01:00
Paolo Bonzini
03a573b960 rust: clean up define_property macro
Use the "struct update" syntax to initialize most of the fields to zero,
and simplify the handmade type-checking of $name.

Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:15 +01:00
Paolo Bonzini
e90d470733 rust: cleanup module_init!, use it from #[derive(Object)]
Remove the duplicate code by using the module_init! macro; at the same time,
simplify how module_init! is used, by taking inspiration from the implementation
of #[derive(Object)].

Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:15 +01:00
Paolo Bonzini
cde3c425d1 rust: build integration test for the qemu_api crate
Adjust the integration test to compile with a subset of QEMU object
files, and make it actually create an object of the class it defines.

Follow the Rust filesystem conventions, where tests go in tests/ if
they use the library in the same way any other code would.

Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:15 +01:00
Paolo Bonzini
4f7521916d rust: modernize link_section usage for ELF platforms
Some newer ABI implementations do not provide .ctors; and while
some linkers rewrite .ctors into .init_array, not all of them do.
Use the newer .init_array ABI, which works more reliably, and
apply it to all non-Apple, non-Windows platforms.

This is similar to how the ctor crate operates; without this change,
"#[derive(Object)]" does not work on Fedora 41.

Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:15 +01:00
Paolo Bonzini
2eb6274d12 rust: remove uses of #[no_mangle]
Mangled symbols do not cause any issue; disabling mangling is only useful if
C headers reference the Rust function, which is not the case here.

Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:15 +01:00
Paolo Bonzini
00ed18de35 rust: do not use --no-size_t-is-usize
This is not necessary and makes it harder to write code that is
portable between 32- and 64-bit systems: it adds extra casts even
though size_of, align_of or offset_of already return the right type.

Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:15 +01:00
Paolo Bonzini
b00bf4edee rust: do not always select X_PL011_RUST
Right now the Rust pl011 device is included in all QEMU system
emulator binaries if --enable-rust is passed.  This is not needed
since the board logic in hw/arm/Kconfig will pick it.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:15 +01:00
Paolo Bonzini
7b72c7dd0d meson: pass rustc_args when building all crates
rustc_args is needed to smooth the difference in warnings between the various
versions of rustc.  Always include those arguments.

Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:15 +01:00
Paolo Bonzini
be3fc97a09 meson: import rust module into a global variable
Tested-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:15 +01:00
Manos Pitsidianakis
37fdb2f56a rust: add PL011 device model
This commit adds a re-implementation of hw/char/pl011.c in Rust.

How to build:

1. Configure a QEMU build with:
   --enable-system --target-list=aarch64-softmmu --enable-rust
2. Launching a VM with qemu-system-aarch64 should use the Rust version
   of the pl011 device

Co-authored-by: Junjie Mao <junjie.mao@intel.com>
Co-authored-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Junjie Mao <junjie.mao@intel.com>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20241024-rust-round-2-v1-2-051e7a25b978@linaro.org
2024-11-05 14:18:15 +01:00
Manos Pitsidianakis
ca5aa28e24 Revert "rust: add PL011 device model"
Patch was applied with invalid authorship by accident, which confuses
git tooling that look at git blame for contributors etc.

Patch will be re-applied with correct authorship right after this
commit.

This reverts commit d0f0cd5b1f.

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20241024-rust-round-2-v1-1-051e7a25b978@linaro.org
2024-11-05 14:18:15 +01:00
Manos Pitsidianakis
b278b60d51 rust/wrapper.h: define memory_order enum
Add stub definition of memory_order enum in wrapper.h.

Creating Rust bindings from C code is done by passing the wrapper.h
header to `bindgen`. This fails when library dependencies that use
compiler headers are enabled, and the libclang that bindgen detects does
not match the expected clang version. So far this has only been observed
with the memory_order enum symbols from stdatomic.h. If we add the enum
definition to wrapper.h ourselves, the error does not happen.

Before this commit, if the mismatch happened the following error could
come up:

  /usr/include/liburing/barrier.h:72:10: error: use of undeclared identifier 'memory_order_release'
  /usr/include/liburing/barrier.h:75:9: error: use of undeclared identifier 'memory_order_acquire'
  /usr/include/liburing/barrier.h:75:9: error: use of undeclared identifier 'memory_order_acquire'
  /usr/include/liburing/barrier.h:68:9: error: use of undeclared identifier 'memory_order_relaxed'
  /usr/include/liburing/barrier.h:65:17: error: use of undeclared identifier 'memory_order_relaxed'
  /usr/include/liburing/barrier.h:75:9: error: use of undeclared identifier 'memory_order_acquire'
  /usr/include/liburing/barrier.h:75:9: error: use of undeclared identifier 'memory_order_acquire'
  /usr/include/liburing/barrier.h:72:10: error: use of undeclared identifier 'memory_order_release'
  panicked at [..]/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bindgen-cli-0.70.1/main.rs:45:36:
  Unable to generate bindings

To fix this (on my system) I would have to export CLANG_PATH and
LIBCLANG_PATH:

  export CLANG_PATH=/bin/clang-17
  export LIBCLANG_PATH=/usr/lib/llvm-17/lib

With these changes applied, bindgen is successful with both the
environment variables set and unset.

Since we're not using those symbols in the bindings (they are only used
by dependencies) this does not affect the generated bindings in any way.

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Link: https://lore.kernel.org/r/20241027-rust-wrapper-stdatomic-v2-1-dab27bbf93ea@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05 14:18:15 +01:00
Paolo Bonzini
95e82f9b38 meson: check in main meson.build for native Rust compiler
A working native Rust compiler is always needed in order to compile Rust
code, even when cross compiling, in order to build the procedural macros
that QEMU uses.

Right now, the check is done in rust/qemu-api-macros/meson.build, but this
has two disadvantages.  First, it makes the build fail when the Meson "rust"
option is set to "auto" (instead, Rust support should be disabled).  Second,
add_languages() is one of the few functions that are executed even by
"meson introspect", except that "meson introspect" executes both branches
of "if" statements!  Therefore, "meson introspect" tries to look for a
Rust compiler even if the option is disabled---and then fails because
the compiler is required by rust/qemu-api-macros/meson.build.  This is
visible for example if the compilation host has a stale
scripts/meson-buildoptions.sh and no rustc installed.

Both issues can be fixed by moving the check to the main meson.build,
together with the check for the cross compiler.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2024-10-14 15:48:05 +01:00
Paolo Bonzini
d0f0cd5b1f rust: add PL011 device model
This commit adds a re-implementation of hw/char/pl011.c in Rust.

How to build:

1. Configure a QEMU build with:
   --enable-system --target-list=aarch64-softmmu --enable-rust
2. Launching a VM with qemu-system-aarch64 should use the Rust version
   of the pl011 device

Co-authored-by: Junjie Mao <junjie.mao@intel.com>
Co-authored-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Junjie Mao <junjie.mao@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Link: https://lore.kernel.org/r/6ec1d4fb8db2a1d7ba94c73e65d9770371b7857d.1727961605.git.manos.pitsidianakis@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-10-11 12:32:17 +02:00
Manos Pitsidianakis
2b74dd9180 rust: add utility procedural macro crate
This commit adds a helper crate library, qemu-api-macros for derive (and
other procedural) macros to be used along qemu-api.

It needs to be a separate library because in Rust, procedural macros, or
macros that can generate arbitrary code, need to be special separate
compilation units.

Only one macro is introduced in this patch, #[derive(Object)]. It
generates a constructor to register a QOM TypeInfo on init and it must
be used on types that implement qemu_api::definitions::ObjectImpl trait.

Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Link: https://lore.kernel.org/r/dd645642406a6dc2060c6f3f17db2bc77ed67b59.1727961605.git.manos.pitsidianakis@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-10-11 12:32:17 +02:00
Manos Pitsidianakis
5a5110d290 rust: add crate to expose bindings and interfaces
Add rust/qemu-api, which exposes rust-bindgen generated FFI bindings and
provides some declaration macros for symbols visible to the rest of
QEMU.

Co-authored-by: Junjie Mao <junjie.mao@intel.com>
Co-authored-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Junjie Mao <junjie.mao@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Link: https://lore.kernel.org/r/0fb23fbe211761b263aacec03deaf85c0cc39995.1727961605.git.manos.pitsidianakis@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-10-11 12:32:17 +02:00
Manos Pitsidianakis
6fdc5bc173 rust: add bindgen step as a meson dependency
Add bindings_rs target for generating rust bindings to target-independent
qemu C APIs.

The bindings need be created before any rust crate that uses them is
compiled.

The bindings.rs file will end up in BUILDDIR/bindings.rs and have the
same name as a target:

  ninja bindings.rs

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Link: https://lore.kernel.org/r/1be89a27719049b7203eaf2eca8bbb75b33f18d4.1727961605.git.manos.pitsidianakis@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-10-11 12:32:17 +02:00
Manos Pitsidianakis
764a6ee9fe build-sys: Add rust feature option
Add rust feature in meson.build, configure, to prepare for adding Rust
code in the followup commits.

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Link: https://lore.kernel.org/r/14642d80fbccbc60f7aa78b449a7deb5e2784ed9.1727961605.git.manos.pitsidianakis@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-10-07 16:41:58 +02:00