aboutsummaryrefslogtreecommitdiff
path: root/rust/qemu-api/src
AgeCommit message (Collapse)AuthorFilesLines
2024-12-19rust: re-export C types from qemu-api submodulesPaolo Bonzini4-15/+18
Long term we do not want device code to use "bindings" at all, so make it possible to get the relevant types from the other modules of qemu-api. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-19rust: rename qemu-api modules to follow C code a bit morePaolo Bonzini6-49/+83
A full match would mean calling them qom::object and hw::core::qdev. For now, keep the names shorter but still a bit easier to find. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-19rust: qom: add possibility of overriding unparentPaolo Bonzini2-5/+45
Add a blanket definition of ClassInitImpl<ObjectClass> that thunks ObjectImpl::UNPARENT and overrides it in ObjectClass if it is not None. ClassInitImpl<DeviceClass> can now call its superclass's ClassInitImpl, so that the C and Rust hierarchies match more closely. This is mostly done as an example of implementing the metaclass hierarchy under ClassInitImpl. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-19rust: qom: put class_init together from multiple ClassInitImpl<>Paolo Bonzini3-55/+124
Parameterize the implementation of ClassInitImpl so that it is possible to call up the chain of implementations, one superclass at a time starting at ClassInitImpl<Self::Class>. In order to avoid having to implement (for example) ClassInitImpl<PL011Class>, also remove the dummy PL011Class and PL011LuminaryClass structs and specify the same ObjectType::Class as the superclass. In the future this default behavior can be handled by a procedural macro, by looking at the first field in the struct. Note that the new trait is safe: the calls are started by rust_class_init<>(), which is not public and can convert the class pointer to a Rust reference. Since CLASS_BASE_INIT applies to the type that is being defined, and only to it, move it to ObjectImpl. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-19rust/qemu-api: Use device_class_set_props_nRichard Henderson1-5/+6
This means we can update declare_properties to drop the zero terminator at the end of the array as well. Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Lei Yang <leiyang@redhat.com> Link: https://lore.kernel.org/r/20241218134251.4724-18-richard.henderson@linaro.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-11rust: qom: change the parent type to an associated typePaolo Bonzini1-8/+4
Avoid duplicated code to retrieve the QOM type strings from the Rust type. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-11rust: qom: split ObjectType from ObjectImpl traitPaolo Bonzini4-13/+37
Define a separate trait for fields that also applies to classes that are defined by C code. This makes it possible to add metadata to core classes, which has multiple uses: - it makes it possible to access the parent struct's TYPE_* for types that are defined in Rust code, and to avoid repeating it in every subclass - implementors of ObjectType will be allowed to implement the IsA<> trait and therefore to perform typesafe casts from one class to another. - in the future, an ObjectType could be created with Foo::new() in a type-safe manner, without having to pass a TYPE_* constant. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-11rust: qom: move bridge for TypeInfo functions out of pl011Paolo Bonzini1-4/+57
Allow the ObjectImpl trait to expose Rust functions that avoid raw pointers (though INSTANCE_INIT for example is still unsafe). ObjectImpl::TYPE_INFO adds thunks around the functions in ObjectImpl. While at it, document `TypeInfo`. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: qdev: move bridge for realize and reset functions out of pl011Paolo Bonzini2-7/+31
Allow the DeviceImpl trait to expose safe Rust functions. rust_device_class_init<> adds thunks around the functions in DeviceImpl. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: qdev: move device_class_init! body to generic function, ClassInitImpl ↵Paolo Bonzini1-16/+71
implementation to macro Use a trait to access the former parameters to device_class_init!. This allows hiding the details of the class_init implementation behind a generic function and makes higher-level functionality available from qemu_api. The implementation of ClassInitImpl is then the same for all devices and is easily macroized. Later on, we can remove the need to implement ClassInitImpl by hand for all device types, and stop making rust_device_class_init<>() public. While at it, document the members of DeviceImpl. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: qom: move ClassInitImpl to the instance sidePaolo Bonzini1-4/+4
Put all traits on the instance struct, which makes it possible to reuse class structs if no new virtual methods or class fields are added. This is almost always the case for devices (because they are leaf classes), which is the primary use case for Rust. This is also simpler: soon we will find the implemented methods without macros, and this removes the need to go from the class struct to the instance struct to find the implementation of the *Impl traits. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: qom: convert type_info! macro to an associated constPaolo Bonzini1-28/+22
type_info! is only used in the definition of ObjectImpl::TYPE_INFO, and in fact in all of them. Pull type_info!'s definition into the ObjectImpl trait, thus simplifying the external interface of qemu_api::definitions. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: qom: rename Class trait to ClassInitImplPaolo Bonzini1-3/+22
While at it, document it. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: qom: add default definitions for ObjectImplPaolo Bonzini1-4/+4
Remove a bunch of duplicate const definitions. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: add a bit operation modulePaolo Bonzini3-0/+122
The bindgen supports `static inline` function binding since v0.64.0 as an experimental feature (`--wrap-static-fns`), and stabilizes it after v0.70.0. But the oldest version of bindgen supported by QEMU is v0.60.1, so there's no way to generate the binding for deposit64() which is `static inline` (in include/qemu/bitops.h). Instead, implement it by hand in Rust and make it available for all unsigned types through an IntegerExt trait. Since it only involves bit operations, the Rust version of the code is almost identical to the original C version, but it applies to more types than just u64. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Co-authored-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: add bindings for interrupt sourcesPaolo Bonzini3-0/+120
The InterruptSource bindings let us call qemu_set_irq() and sysbus_init_irq() as safe code. Interrupt sources, qemu_irq in C code, are pointers to IRQState objects. They are QOM link properties and can be written to outside the control of the device (i.e. from a shared reference); therefore they must be interior-mutable in Rust. Since thread-safety is provided by the BQL, what we want here is the newly-introduced BqlCell. A pointer to the contents of the BqlCell (an IRQState**, or equivalently qemu_irq*) is then passed to the C sysbus_init_irq function. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: define preludePaolo Bonzini2-0/+11
Add a module that will contain frequently used traits and occasionally structs. They can be included quickly with "use qemu_api::prelude::*". Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: cell: add BQL-enforcing RefCell variantPaolo Bonzini1-10/+534
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>
2024-12-10rust: cell: add BQL-enforcing Cell variantPaolo Bonzini2-0/+299
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>
2024-12-10rust/qemu-api: Fix fragment-specifiers in define_property macroJunjie Mao1-2/+2
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>
2024-12-10rust: fix doc test syntaxPaolo Bonzini1-3/+3
Allow "cargo test --doc" to pass. Reviewed-by: Junjie Mao <junjie.mao@hotmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-10rust: build: establish a baseline of lints across all cratesPaolo Bonzini1-3/+3
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>
2024-12-10rust: allow using build-root bindings.rs from cargoPaolo Bonzini2-22/+29
Right now, using cargo with QEMU requires copying by hand the bindings.rs to the source tree. Instead, we can use an include file to escape the cage of cargo's mandated source directory structure. By running cargo within meson's "devenv" and adding a MESON_BUILD_ROOT environment variable, it is easy for build.rs to find the file. However, the file must be symlinked into cargo's output directory for rust-analyzer to find it. Suggested-by: Junjie Mao <junjie.mao@hotmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-11-05rust: do not use --generate-cstrPaolo Bonzini1-0/+10
--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-05rust: do not use MaybeUninit::zeroed()Paolo Bonzini1-14/+77
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-05rust: introduce alternative implementation of offset_of!Junjie Mao4-9/+174
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-05rust: introduce a c_str macroPaolo Bonzini3-1/+55
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-05rust: use std::os::raw instead of core::ffiPaolo Bonzini4-13/+16
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-05rust: add definitions for vmstateManos Pitsidianakis3-21/+363
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-05rust: provide safe wrapper for MaybeUninit::zeroed()Paolo Bonzini3-4/+28
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-05rust: make properties array immutablePaolo Bonzini1-34/+8
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-05rust: clean up define_property macroPaolo Bonzini1-24/+7
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-05rust: cleanup module_init!, use it from #[derive(Object)]Paolo Bonzini1-38/+27
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-05rust: build integration test for the qemu_api cratePaolo Bonzini2-52/+0
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-05rust: modernize link_section usage for ELF platformsPaolo Bonzini1-4/+10
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-05rust: remove uses of #[no_mangle]Paolo Bonzini2-3/+0
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-05rust: do not use --no-size_t-is-usizePaolo Bonzini1-3/+3
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-05meson: pass rustc_args when building all cratesPaolo Bonzini1-4/+6
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-10-11rust: add crate to expose bindings and interfacesManos Pitsidianakis4-0/+440
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>