aboutsummaryrefslogtreecommitdiff
path: root/rust/qemu-api/src/vmstate.rs
AgeCommit message (Collapse)AuthorFilesLines
10 daysrust/vmstate: Include complete crate path of VMStateFlags in vmstate_clockZhao Liu1-1/+4
The use of "bindings::*" masks incomplete path of VMStateFlags. Include complete crate path of VMStateFlags in vmstate_clock, and clean up "bindings::*" in device_class.rs of pl011. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-16-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10 daysrust/vmstate: Support vmstate_validateZhao Liu1-1/+51
In C version, VMSTATE_VALIDATE accepts the function pointer, which is used to check if some conditions of structure could meet, although the C version macro doesn't accept any structure as the opaque type. But it's hard to integrate VMSTATE_VALIDAE into vmstate_struct, a new macro has to be introduced to specifically handle the case corresponding to VMSTATE_VALIDATE. One of the difficulties is inferring the type of a callback by its name `test_fn`. We can't directly use `test_fn` as a parameter of test_cb_builder__() to get its type "F", because in this way, Rust compiler will be too conservative on drop check and complain "the destructor for this type cannot be evaluated in constant functions". Fortunately, PhantomData<T> could help in this case, because it is considered to never have a destructor, no matter its field type [*]. The `phantom__()` in the `call_func_with_field` macro provides a good example of using PhantomData to infer type. So copy this idea and apply it to the `vmstate_validate` macro. [*]: https://doc.rust-lang.org/std/ops/trait.Drop.html#drop-check Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-11-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10 daysrust/vmstate: Re-implement VMState trait for timer bindingZhao Liu1-7/+3
At present, Rust side has a timer binding "timer::Timer", so the vmstate for timer should base on that binding instead of the raw "binding::QEMUTimer". It's possible to apply impl_vmstate_transparent for cell::Opaque and then impl_vmstate_forward for timer::Timer. But binding::QEMUTimer shouldn't be used directly, so that vmstate for such raw timer type is useless. Thus, apply impl_vmstate_scalar for timer::Timer. And since Opaque<> is useful, apply impl_vmstate_transparent for cell::Opaque as well. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-10-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10 daysrust/vmstate: Relax array check when build varray in vmstate_structZhao Liu1-3/+9
The varry of structure created by vmstate_struct is different with vmstate_of. This is because vmstate_struct uses the `vmsd` to traverse the vmstates of structure's fields, rather than treating the structure directly as a well-defined vmstate. Therefore, there's no need to check array flag when building varray by vmstate_struct. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-9-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10 daysrust/vmstate: Fix unnecessary VMState bound of with_varray_flag()Zhao Liu1-1/+1
The VMState type bound is not used in with_varray_flag(). And for vmstate_struct, Rust cannot infer the type of `num` from the call_func_with_field(), so this causes the compiling error because it complains "cannot satisfy `_: VMState`" in with_varray_flag(). Note Rust can infer the type in vmstate_of macro so that with_varray_flag() can work at there. It is possible that the different initialization ways in the two macros cause differences in Rust's type inference. But in fact, the VMState type bound is not used in with_varray_flag() and vmstate_varray_flag() has already checked the VMState type, it's safe to drop VMState bound of with_varray_flag(), which can fix the above compiling error. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-8-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10 daysrust/vmstate: Fix "cannot infer type" error in vmstate_structZhao Liu1-7/+9
Rust cannot infer the type (it should be VMStateField) after Zeroable::ZERO, which cause the compiling error. To fix this error, call with_varray_flag() after VMStateField's initialization. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-7-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10 daysrust/vmstate: Fix type check for varray in vmstate_structZhao Liu1-1/+1
When pass a varray to vmstate_struct, the `type` parameter should be the type of the element in the varray, for example: vmstate_struct!(HPETState, timers, [0 .. num_timers], VMSTATE_HPET_TIMER, BqlRefCell<HPETTimer>).with_version_id(0) But this breaks current type check, because it checks the type of `field`, which is an array type (for the above example, type of timers is [BqlRefCell<HPETTimer>; 32], not BqlRefCell<HPETTimer>). But the current assert_field_type() can no longer be extended to include new arguments, so a variant of it (a second macro containing the `num = $num:ident` parameter) had to be added to handle array cases. In this new macro, it not only checks the type of element, but also checks whether the `num` (number of elements in varray) is out of range. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-6-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10 daysrust/vmstate: Fix size field of VMStateField with VMS_ARRAY_OF_POINTER flagZhao Liu1-0/+4
The `size` field of the VMStateField with VMS_ARRAY_OF_POINTER flag should stores the size of pointer, which depends on platform. Currently, `*const`, `*mut`, `NonNull`, `Box<>` and their wrapper are supported, and they have the same size as `usize`. Store the size (of `usize`) when VMS_ARRAY_OF_POINTER flag is set. The size may be changed when more smart pointers are supported, but now the size of "usize" is enough. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-5-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10 daysrust/vmstate: Fix num field when varray flags are setZhao Liu1-0/+1
Array type vmstate has the VMStateField with `num` equals its length. When the varray vmstate is built based a array type, the `num` field should be cleaned to 0, because varray uses `num_offset` instead of `num` to store elements number information. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-4-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10 daysrust/vmstate: Fix num_offset in vmstate macrosZhao Liu1-2/+2
`num_offset` is a member of `VMStateField`, and there's no need to use "." to access this field in a `VMStateField` instance. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-3-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10 daysrust/vmstate: Remove unnecessary unsafeZhao Liu1-1/+1
Remove the `unsafe` block of vmsd, because vmsd (passed to vmstate_struct) is defined in Rust side now, and it doesn't need `unsafe`. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250318130219.1799170-2-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: qdev: wrap Clock and DeviceState with Opaque<>Paolo Bonzini1-1/+1
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-06rust: vmstate: add std::pin::Pin as transparent wrapperPaolo Bonzini1-0/+1
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: fix doctestsPaolo Bonzini1-1/+1
Doctests were not being run by CI, and have broken. Fix them. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: vmstate: remove redundant link targetsPaolo Bonzini1-3/+2
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qdev: add clock creationPaolo Bonzini1-2/+2
Add a Rust version of qdev_init_clock_in, which can be used in instance_init. There are a couple differences with the C version: - in Rust the object keeps its own reference to the clock (in addition to the one embedded in the NamedClockList), and the reference is dropped automatically by instance_finalize(); this is encoded in the signature of DeviceClassMethods::init_clock_in, which makes the lifetime of the clock independent of that of the object it holds. This goes unnoticed in the C version and is due to the existence of aliases. - also, anything that happens during instance_init uses the pinned_init framework to operate on a partially initialized object, and is done through class methods (i.e. through DeviceClassMethods rather than DeviceMethods) because the device does not exist yet. Therefore, Rust code *must* create clocks from instance_init, which is stricter than C. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-02-13rust: qom: add reference counting functionalityPaolo Bonzini1-1/+5
Add a smart pointer that allows to add and remove references from QOM objects. It's important to note that while all QOM objects have a reference count, in practice not all of them have their lifetime guarded by it. Embedded objects, specifically, are confined to the lifetime of the owner. When writing Rust bindings this is important, because embedded objects are *never* used through the "Owned<>" smart pointer that is introduced here. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-23rust: vmstate: make order of parameters consistent in vmstate_clockPaolo Bonzini1-1/+1
Place struct_name before field_name, similar to offset_of. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-23rust: vmstate: remove translation of C vmstate macrosPaolo Bonzini1-251/+23
Keep vmstate_clock!; because it uses a field of type VMStateDescription, it cannot be converted to the VMState trait without access to the const_refs_static feature. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-23rust: qemu_api: add vmstate_structPaolo Bonzini1-0/+33
It is not type safe, but it's the best that can be done without const_refs_static. It can also be used with BqlCell and BqlRefCell. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-23rust: vmstate: add public utility macros to implement VMStatePaolo Bonzini1-3/+58
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-23rust: vmstate: implement VMState for scalar typesPaolo Bonzini1-2/+126
Scalar types are those that have their own VMStateInfo. This poses a problem in that references to VMStateInfo can only be included in associated consts starting with Rust 1.83.0, when the const_refs_static was stabilized. Removing the requirement is done by placing a limited list of VMStateInfos in an enum, and going from enum to &VMStateInfo only when building the VMStateField. The same thing cannot be done with VMS_STRUCT because the set of VMStateDescriptions extends to structs defined by the devices. Therefore, structs and cells cannot yet use vmstate_of!. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-23rust: vmstate: implement Zeroable for VMStateFieldPaolo Bonzini1-15/+3
This shortens a bit the constants. Do not bother using it in the vmstate macros since most of them will go away soon. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-23rust: vmstate: add varray support to vmstate_of!Paolo Bonzini1-2/+40
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-23rust: vmstate: implement VMState for non-leaf typesPaolo Bonzini1-1/+78
Arrays, pointers and cells use a VMStateField that is based on that for the inner type. The implementation therefore delegates to the VMState implementation of the inner type. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-01-23rust: vmstate: add new type safe implementationPaolo Bonzini1-6/+107
The existing translation of the C macros for vmstate does not make any attempt to type-check vmstate declarations against the struct, so introduce a new system that computes VMStateField based on the actual struct declaration. Macros do not have full access to the type system, therefore a full implementation of this scheme requires a helper trait to analyze the type and produce a VMStateField from it; a macro "vmstate_of!" accepts arguments similar to "offset_of!" and tricks the compiler into looking up the trait for the right type. The patch introduces not just vmstate_of!, but also the slightly too clever enabling macro call_func_with_field!. The particular trick used here was proposed on the users.rust-lang.org forum, so I take no merit and all the blame. Introduce the trait and some functions to access it; the actual implementation comes later. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-19rust: pl011: fix migration streamPaolo Bonzini1-22/+0
The Rust vmstate macros lack the type-safety of their C equivalents (so safe, much abstraction), and therefore they were predictably wrong. The registers have already been changed to 32-bits in the previous patch, but read_pos/read_count/read_trigger also have to be u32 instead of usize. The easiest way to do so is to let the FIFO use u32 indices instead of usize. My plan for making VMStateField typesafe is to have a trait to retrieve a basic VMStateField; for example something like vmstate_uint32 would become an implementation of the VMState trait on u32. Then you'd write something like "vmstate_of!(Type, field).with_version_id(2)". That is, vmstate_of retrieves the basic VMStateField and fills in the offset, and then more changes can be applied on top. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-12-19rust: re-export C types from qemu-api submodulesPaolo Bonzini1-4/+5
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-11-05rust: introduce alternative implementation of offset_of!Junjie Mao1-5/+5
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 Bonzini1-1/+1
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 Bonzini1-5/+5
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 Pitsidianakis1-0/+360
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>