From 9d116f42a38cb95a33da837e0b0b50d91e28906b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 21 Mar 2025 11:25:21 +0000 Subject: rust: assertions: add static_assert Add a new assertion that is similar to "const { assert!(...) }" but can be used outside functions and with older versions of Rust. A similar macro is found in Linux, whereas the "static_assertions" crate has a const_assert macro that produces worse error messages. Suggested-by: Peter Maydell Signed-off-by: Paolo Bonzini Reviewed-by: Zhao Liu Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell Link: https://lore.kernel.org/r/20250321112523.1774131-2-peter.maydell@linaro.org Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/assertions.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/assertions.rs b/rust/qemu-api/src/assertions.rs index 104dec3..bba38cf 100644 --- a/rust/qemu-api/src/assertions.rs +++ b/rust/qemu-api/src/assertions.rs @@ -120,3 +120,25 @@ macro_rules! assert_match { ); }; } + +/// Assert at compile time that an expression is true. This is similar +/// to `const { assert!(...); }` but it works outside functions, as well as +/// on versions of Rust before 1.79. +/// +/// # Examples +/// +/// ``` +/// # use qemu_api::static_assert; +/// static_assert!("abc".len() == 3); +/// ``` +/// +/// ```compile_fail +/// # use qemu_api::static_assert; +/// static_assert!("abc".len() == 2); // does not compile +/// ``` +#[macro_export] +macro_rules! static_assert { + ($x:expr) => { + const _: () = assert!($x); + }; +} -- cgit v1.1 From ea8a7ceba3aafe4de9e7306df663698809e8381a Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:05 +0800 Subject: rust/vmstate: Remove unnecessary unsafe 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 Link: https://lore.kernel.org/r/20250318130219.1799170-2-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index f0510ae..6698dfe 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -447,7 +447,7 @@ macro_rules! vmstate_struct { }, size: ::core::mem::size_of::<$type>(), flags: $crate::bindings::VMStateFlags::VMS_STRUCT, - vmsd: unsafe { $vmsd }, + vmsd: $vmsd, ..$crate::zeroable::Zeroable::ZERO $( .with_varray_flag($crate::call_func_with_field!( $crate::vmstate::vmstate_varray_flag, -- cgit v1.1 From 6ca5c3bedf3265358cf9033577dd30ed865d1cb3 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:06 +0800 Subject: rust/vmstate: Fix num_offset in vmstate macros `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 Link: https://lore.kernel.org/r/20250318130219.1799170-3-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 6698dfe..9533b12 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -208,7 +208,7 @@ macro_rules! vmstate_of { .as_bytes() .as_ptr() as *const ::std::os::raw::c_char, offset: $crate::offset_of!($struct_name, $field_name), - $(.num_offset: $crate::offset_of!($struct_name, $num),)? + $(num_offset: $crate::offset_of!($struct_name, $num),)? // The calls to `call_func_with_field!` are the magic that // computes most of the VMStateField from the type of the field. info: $crate::info_enum_to_ref!($crate::call_func_with_field!( @@ -440,7 +440,7 @@ macro_rules! vmstate_struct { name: ::core::concat!(::core::stringify!($field_name), "\0") .as_bytes() .as_ptr() as *const ::std::os::raw::c_char, - $(.num_offset: $crate::offset_of!($struct_name, $num),)? + $(num_offset: $crate::offset_of!($struct_name, $num),)? offset: { $crate::assert_field_type!($struct_name, $field_name, $type); $crate::offset_of!($struct_name, $field_name) -- cgit v1.1 From c3d80af5ecf4f00db4a8d3ac5eca6edc0c9f061e Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:07 +0800 Subject: rust/vmstate: Fix num field when varray flags are set 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 Link: https://lore.kernel.org/r/20250318130219.1799170-4-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 9533b12..e323330 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -275,6 +275,7 @@ impl VMStateField { assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) != 0); self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_ARRAY.0); self.flags = VMStateFlags(self.flags.0 | flag.0); + self.num = 0; // varray uses num_offset instead of num. self } -- cgit v1.1 From 20797069c71a90582078448b81de28f227a8403b Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:08 +0800 Subject: rust/vmstate: Fix size field of VMStateField with VMS_ARRAY_OF_POINTER flag 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 Link: https://lore.kernel.org/r/20250318130219.1799170-5-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index e323330..e2a1f7a 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -256,6 +256,10 @@ impl VMStateField { if (self.flags.0 & VMStateFlags::VMS_POINTER.0) != 0 { self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_POINTER.0); self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_ARRAY_OF_POINTER.0); + // VMS_ARRAY_OF_POINTER flag stores the size of pointer. + // FIXME: *const, *mut, NonNull and Box<> have the same size as usize. + // Resize if more smart pointers are supported. + self.size = std::mem::size_of::(); } self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_SINGLE.0); self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_ARRAY.0); -- cgit v1.1 From 618258256e6c60957100c5a01ab70f5473020cb9 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:09 +0800 Subject: rust/vmstate: Fix type check for varray in vmstate_struct 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).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; 32], not BqlRefCell). 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 Link: https://lore.kernel.org/r/20250318130219.1799170-6-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/assertions.rs | 15 +++++++++++++++ rust/qemu-api/src/vmstate.rs | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/assertions.rs b/rust/qemu-api/src/assertions.rs index bba38cf..eb12e94 100644 --- a/rust/qemu-api/src/assertions.rs +++ b/rust/qemu-api/src/assertions.rs @@ -91,6 +91,21 @@ macro_rules! assert_field_type { } }; }; + + ($t:ty, $i:tt, $ti:ty, num = $num:ident) => { + const _: () = { + #[allow(unused)] + fn assert_field_type(v: $t) { + fn types_must_be_equal(_: T) + where + T: $crate::assertions::EqType, + { + } + let index: usize = v.$num.try_into().unwrap(); + types_must_be_equal::<_, &$ti>(&v.$i[index]); + } + }; + }; } /// Assert that an expression matches a pattern. This can also be diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index e2a1f7a..9d9cdda 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -447,7 +447,7 @@ macro_rules! vmstate_struct { .as_ptr() as *const ::std::os::raw::c_char, $(num_offset: $crate::offset_of!($struct_name, $num),)? offset: { - $crate::assert_field_type!($struct_name, $field_name, $type); + $crate::assert_field_type!($struct_name, $field_name, $type $(, num = $num)?); $crate::offset_of!($struct_name, $field_name) }, size: ::core::mem::size_of::<$type>(), -- cgit v1.1 From 42c814b1395c39659270248d205deaaaa47a84f2 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:10 +0800 Subject: rust/vmstate: Fix "cannot infer type" error in vmstate_struct 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 Link: https://lore.kernel.org/r/20250318130219.1799170-7-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 9d9cdda..3be3a72 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -453,13 +453,15 @@ macro_rules! vmstate_struct { size: ::core::mem::size_of::<$type>(), flags: $crate::bindings::VMStateFlags::VMS_STRUCT, vmsd: $vmsd, - ..$crate::zeroable::Zeroable::ZERO $( - .with_varray_flag($crate::call_func_with_field!( - $crate::vmstate::vmstate_varray_flag, - $struct_name, - $num)) - $(.with_varray_multiply($factor))?)? - } + ..$crate::zeroable::Zeroable::ZERO + } $(.with_varray_flag( + $crate::call_func_with_field!( + $crate::vmstate::vmstate_varray_flag, + $struct_name, + $num + ) + ) + $(.with_varray_multiply($factor))?)? }; } -- cgit v1.1 From e5655e92a8b984129aed12f24fc50d6e3f63429d Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:11 +0800 Subject: rust/vmstate: Fix unnecessary VMState bound of with_varray_flag() 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 Link: https://lore.kernel.org/r/20250318130219.1799170-8-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 3be3a72..792a74f 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -275,7 +275,7 @@ impl VMStateField { } #[must_use] - pub const fn with_varray_flag(mut self, flag: VMStateFlags) -> VMStateField { + pub const fn with_varray_flag(mut self, flag: VMStateFlags) -> VMStateField { assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) != 0); self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_ARRAY.0); self.flags = VMStateFlags(self.flags.0 | flag.0); -- cgit v1.1 From 5006e39cfacbf37e6925239059ae6945e36cf74e Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:12 +0800 Subject: rust/vmstate: Relax array check when build varray in vmstate_struct 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 Link: https://lore.kernel.org/r/20250318130219.1799170-9-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 792a74f..0b5af1c 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -275,8 +275,7 @@ impl VMStateField { } #[must_use] - pub const fn with_varray_flag(mut self, flag: VMStateFlags) -> VMStateField { - assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) != 0); + pub const fn with_varray_flag_unchecked(mut self, flag: VMStateFlags) -> VMStateField { self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_ARRAY.0); self.flags = VMStateFlags(self.flags.0 | flag.0); self.num = 0; // varray uses num_offset instead of num. @@ -284,6 +283,13 @@ impl VMStateField { } #[must_use] + #[allow(unused_mut)] + pub const fn with_varray_flag(mut self, flag: VMStateFlags) -> VMStateField { + assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) != 0); + self.with_varray_flag_unchecked(flag) + } + + #[must_use] pub const fn with_varray_multiply(mut self, num: u32) -> VMStateField { assert!(num <= 0x7FFF_FFFFu32); self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_MULTIPLY_ELEMENTS.0); @@ -454,7 +460,7 @@ macro_rules! vmstate_struct { flags: $crate::bindings::VMStateFlags::VMS_STRUCT, vmsd: $vmsd, ..$crate::zeroable::Zeroable::ZERO - } $(.with_varray_flag( + } $(.with_varray_flag_unchecked( $crate::call_func_with_field!( $crate::vmstate::vmstate_varray_flag, $struct_name, -- cgit v1.1 From 3baf82e0a17bc037c9c564958a8b90814119d738 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:13 +0800 Subject: rust/vmstate: Re-implement VMState trait for timer binding 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 Link: https://lore.kernel.org/r/20250318130219.1799170-10-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 0b5af1c..01f06ed 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -27,12 +27,7 @@ use core::{marker::PhantomData, mem, ptr::NonNull}; pub use crate::bindings::{VMStateDescription, VMStateField}; -use crate::{ - bindings::{self, VMStateFlags}, - prelude::*, - qom::Owned, - zeroable::Zeroable, -}; +use crate::{bindings::VMStateFlags, prelude::*, qom::Owned, zeroable::Zeroable}; /// This macro is used to call a function with a generic argument bound /// to the type of a field. The function must take a @@ -344,6 +339,7 @@ impl_vmstate_transparent!(std::cell::UnsafeCell where T: VMState); impl_vmstate_transparent!(std::pin::Pin where T: VMState); impl_vmstate_transparent!(crate::cell::BqlCell where T: VMState); impl_vmstate_transparent!(crate::cell::BqlRefCell where T: VMState); +impl_vmstate_transparent!(crate::cell::Opaque where T: VMState); #[macro_export] macro_rules! impl_vmstate_bitsized { @@ -390,7 +386,7 @@ impl_vmstate_scalar!(vmstate_info_uint8, u8, VMS_VARRAY_UINT8); impl_vmstate_scalar!(vmstate_info_uint16, u16, VMS_VARRAY_UINT16); impl_vmstate_scalar!(vmstate_info_uint32, u32, VMS_VARRAY_UINT32); impl_vmstate_scalar!(vmstate_info_uint64, u64); -impl_vmstate_scalar!(vmstate_info_timer, bindings::QEMUTimer); +impl_vmstate_scalar!(vmstate_info_timer, crate::timer::Timer); // Pointer types using the underlying type's VMState plus VMS_POINTER // Note that references are not supported, though references to cells -- cgit v1.1 From b13100372180fdb052aa6bbce663eea0c59e5db4 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:14 +0800 Subject: rust/vmstate: Support vmstate_validate 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 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 Link: https://lore.kernel.org/r/20250318130219.1799170-11-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 52 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 01f06ed..9740931 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -25,9 +25,12 @@ //! functionality that is missing from `vmstate_of!`. use core::{marker::PhantomData, mem, ptr::NonNull}; +use std::os::raw::{c_int, c_void}; pub use crate::bindings::{VMStateDescription, VMStateField}; -use crate::{bindings::VMStateFlags, prelude::*, qom::Owned, zeroable::Zeroable}; +use crate::{ + bindings::VMStateFlags, callbacks::FnCall, prelude::*, qom::Owned, zeroable::Zeroable, +}; /// This macro is used to call a function with a generic argument bound /// to the type of a field. The function must take a @@ -508,6 +511,53 @@ macro_rules! vmstate_fields { }} } +pub extern "C" fn rust_vms_test_field_exists FnCall<(&'a T, u8), bool>>( + opaque: *mut c_void, + version_id: c_int, +) -> bool { + let owner: &T = unsafe { &*(opaque.cast::()) }; + let version: u8 = version_id.try_into().unwrap(); + // SAFETY: the opaque was passed as a reference to `T`. + F::call((owner, version)) +} + +pub type VMSFieldExistCb = unsafe extern "C" fn( + opaque: *mut std::os::raw::c_void, + version_id: std::os::raw::c_int, +) -> bool; + +#[doc(alias = "VMSTATE_VALIDATE")] +#[macro_export] +macro_rules! vmstate_validate { + ($struct_name:ty, $test_name:expr, $test_fn:expr $(,)?) => { + $crate::bindings::VMStateField { + name: ::std::ffi::CStr::as_ptr($test_name), + field_exists: { + const fn test_cb_builder__< + T, + F: for<'a> $crate::callbacks::FnCall<(&'a T, u8), bool>, + >( + _phantom: ::core::marker::PhantomData, + ) -> $crate::vmstate::VMSFieldExistCb { + let _: () = F::ASSERT_IS_SOME; + $crate::vmstate::rust_vms_test_field_exists:: + } + + const fn phantom__(_: &T) -> ::core::marker::PhantomData { + ::core::marker::PhantomData + } + Some(test_cb_builder__::<$struct_name, _>(phantom__(&$test_fn))) + }, + flags: $crate::bindings::VMStateFlags( + $crate::bindings::VMStateFlags::VMS_MUST_EXIST.0 + | $crate::bindings::VMStateFlags::VMS_ARRAY.0, + ), + num: 0, // 0 elements: no data, only run test_fn callback + ..$crate::zeroable::Zeroable::ZERO + } + }; +} + /// A transparent wrapper type for the `subsections` field of /// [`VMStateDescription`]. /// -- cgit v1.1 From f7b87e464c8e9d30661fb9f519ed14fb053cd415 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Tue, 18 Mar 2025 21:02:19 +0800 Subject: rust/vmstate: Include complete crate path of VMStateFlags in vmstate_clock 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 Link: https://lore.kernel.org/r/20250318130219.1799170-16-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'rust/qemu-api/src') diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 9740931..1b2b12e 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -487,7 +487,10 @@ macro_rules! vmstate_clock { $crate::offset_of!($struct_name, $field_name) }, size: ::core::mem::size_of::<*const $crate::qdev::Clock>(), - flags: VMStateFlags(VMStateFlags::VMS_STRUCT.0 | VMStateFlags::VMS_POINTER.0), + flags: $crate::bindings::VMStateFlags( + $crate::bindings::VMStateFlags::VMS_STRUCT.0 + | $crate::bindings::VMStateFlags::VMS_POINTER.0, + ), vmsd: unsafe { ::core::ptr::addr_of!($crate::bindings::vmstate_clock) }, ..$crate::zeroable::Zeroable::ZERO } -- cgit v1.1