c596199f | 15-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: cell: add BQL-enforcing RefCell variant
Similar to the existing BqlCell, introduce a custom interior mutability primitive that resembles RefCell but accounts for QEMU's threading model. Borrow
rust: cell: add BQL-enforcing RefCell variant
Similar to the existing BqlCell, introduce a custom interior mutability primitive that resembles RefCell but accounts for QEMU's threading model. Borrowing the RefCell requires proving that the BQL is held, and attempting to access without the BQL is a runtime panic.
Almost all of the code was taken from Rust's standard library, while removing unstable features and probably-unnecessary functionality that amounts to 60% of the original code. A lot of what's left is documentation, as well as unit tests in the form of doctests. These are not yet integrated in "make check" but can be run with "cargo test --doc".
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
8e194c0e | 15-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: cell: add BQL-enforcing Cell variant
QEMU objects usually have their pointer shared with the "outside world" very early in their lifetime, for example when they create their MemoryRegions. Be
rust: cell: add BQL-enforcing Cell variant
QEMU objects usually have their pointer shared with the "outside world" very early in their lifetime, for example when they create their MemoryRegions. Because at this point it is not valid anymore to create a &mut reference to the device, individual parts of the device struct must be made mutable in a controlled manner.
QEMU's Big Lock (BQL) effectively turns multi-threaded code into single-threaded code while device code runs, as long as the BQL is not released while the device is borrowed (because C code could sneak in and mutate the device). We can then introduce custom interior mutability primitives that are semantically similar to the standard library's (single-threaded) Cell and RefCell, but account for QEMU's threading model. Accessing the "BqlCell" or borrowing the "BqlRefCell" requires proving that the BQL is held, and attempting to access without the BQL is a runtime panic, similar to RefCell's already-borrowed panic.
With respect to naming I also considered omitting the "Bql" prefix or moving it to the module, e.g. qemu_api::bql::{Cell, RefCell}. However, this could easily lead to mistakes and confusion; for example rustc could suggest the wrong import, leading to subtle bugs.
As a start introduce the an equivalent of Cell. Almost all of the code was taken from Rust's standard library, while removing unstable features and probably-unnecessary functionality that constitute a large of the original code. A lot of what's left is documentation, as well as unit tests in the form of doctests. These are not yet integrated in "make check" but can be run with "cargo test --doc".
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
a3057c52 | 17-Oct-2024 |
Junjie Mao <junjie.mao@hotmail.com> |
rust/qemu-api: Fix fragment-specifiers in define_property macro
For the matcher of macro, "expr" is used for expressions, while "ident" is used for variable/function names, and "ty" matches types.
rust/qemu-api: Fix fragment-specifiers in define_property macro
For the matcher of macro, "expr" is used for expressions, while "ident" is used for variable/function names, and "ty" matches types.
In define_property macro, $field is a member name of type $state, so it should be defined as "ident", though offset_of! doesn't complain about this. $type is the type of $field, since it is not used in the macro, so that no type mismatch error is triggered either.
Fix fragment-specifiers of $field and $type.
Signed-off-by: Junjie Mao <junjie.mao@hotmail.com> Co-developed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20241017143245.1248589-2-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
2f9eec8f | 06-Nov-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
rust: build: establish a baseline of lints across all crates
Many lints that default to allow can be helpful in detecting bugs or keeping the code style homogeneous. Add them liberally, though perh
rust: build: establish a baseline of lints across all crates
Many lints that default to allow can be helpful in detecting bugs or keeping the code style homogeneous. Add them liberally, though perhaps not as liberally as in hw/char/pl011/src/lib.rs. In particular, enabling entire groups can be problematic because of bitrot when new links are added in the future.
For Clippy, this is actually a feature that is only present in Cargo 1.74.0 but, since we are not using Cargo to *build* QEMU, only developers will need a new-enough cargo and only to run tools such as clippy. The requirement does not apply to distros that are building QEMU.
Reviewed-by: Junjie Mao <junjie.mao@hotmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
ce4a144c | 25-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
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:
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>
show more ...
|
bb42965d | 18-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
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
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>
show more ...
|
f3518400 | 24-Oct-2024 |
Junjie Mao <junjie.mao@hotmail.com> |
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 lic
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>
show more ...
|
0a65e412 | 25-Oct-2024 |
Manos Pitsidianakis <manos.pitsidianakis@linaro.org> |
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 exa
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>
show more ...
|
6e50bde1 | 18-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
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 fu
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>
show more ...
|
c92c447f | 18-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
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
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>
show more ...
|
03a573b9 | 18-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
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@h
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>
show more ...
|
e90d4707 | 21-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
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 t
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>
show more ...
|
cde3c425 | 18-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
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
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>
show more ...
|
4f752191 | 18-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
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 .
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>
show more ...
|
2eb6274d | 18-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
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
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>
show more ...
|
00ed18de | 15-Oct-2024 |
Paolo Bonzini <pbonzini@redhat.com> |
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 of
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>
show more ...
|