mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-27 04:13:53 -06:00
rust: vmstate: add public utility macros to implement VMState
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
f2cb78bdbe
commit
00f89716a8
1 changed files with 58 additions and 3 deletions
|
@ -4,13 +4,18 @@
|
|||
|
||||
//! Helper macros to declare migration state for device models.
|
||||
//!
|
||||
//! This module includes three families of macros:
|
||||
//! This module includes four families of macros:
|
||||
//!
|
||||
//! * [`vmstate_unused!`](crate::vmstate_unused) and
|
||||
//! [`vmstate_of!`](crate::vmstate_of), which are used to express the
|
||||
//! migration format for a struct. This is based on the [`VMState`] trait,
|
||||
//! which is defined by all migrateable types.
|
||||
//!
|
||||
//! * [`impl_vmstate_forward`](crate::impl_vmstate_forward) and
|
||||
//! [`impl_vmstate_bitsized`](crate::impl_vmstate_bitsized), which help with
|
||||
//! the definition of the [`VMState`] trait (respectively for transparent
|
||||
//! structs and for `bilge`-defined types)
|
||||
//!
|
||||
//! * helper macros to declare a device model state struct, in particular
|
||||
//! [`vmstate_subsections`](crate::vmstate_subsections) and
|
||||
//! [`vmstate_fields`](crate::vmstate_fields).
|
||||
|
@ -134,7 +139,9 @@ macro_rules! info_enum_to_ref {
|
|||
/// # Safety
|
||||
///
|
||||
/// The contents of this trait go straight into structs that are parsed by C
|
||||
/// code and used to introspect into other structs. Be careful.
|
||||
/// code and used to introspect into other structs. Generally, you don't need
|
||||
/// to implement it except via macros that do it for you, such as
|
||||
/// `impl_vmstate_bitsized!`.
|
||||
pub unsafe trait VMState {
|
||||
/// The `info` member of a `VMStateField` is a pointer and as such cannot
|
||||
/// yet be included in the [`BASE`](VMState::BASE) associated constant;
|
||||
|
@ -188,7 +195,9 @@ pub const fn vmstate_varray_flag<T: VMState>(_: PhantomData<T>) -> VMStateFlags
|
|||
/// * an array of any of the above
|
||||
///
|
||||
/// In order to support other types, the trait `VMState` must be implemented
|
||||
/// for them.
|
||||
/// for them. The macros
|
||||
/// [`impl_vmstate_bitsized!`](crate::impl_vmstate_bitsized)
|
||||
/// and [`impl_vmstate_forward!`](crate::impl_vmstate_forward) help with this.
|
||||
#[macro_export]
|
||||
macro_rules! vmstate_of {
|
||||
($struct_name:ty, $field_name:ident $([0 .. $num:ident $(* $factor:expr)?])? $(,)?) => {
|
||||
|
@ -276,6 +285,32 @@ impl VMStateField {
|
|||
}
|
||||
}
|
||||
|
||||
/// This macro can be used (by just passing it a type) to forward the `VMState`
|
||||
/// trait to the first field of a tuple. This is a workaround for lack of
|
||||
/// support of nested [`offset_of`](core::mem::offset_of) until Rust 1.82.0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use qemu_api::vmstate::impl_vmstate_forward;
|
||||
/// pub struct Fifo([u8; 16]);
|
||||
/// impl_vmstate_forward!(Fifo);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! impl_vmstate_forward {
|
||||
// This is similar to impl_vmstate_transparent below, but it
|
||||
// uses the same trick as vmstate_of! to obtain the type of
|
||||
// the first field of the tuple
|
||||
($tuple:ty) => {
|
||||
unsafe impl $crate::vmstate::VMState for $tuple {
|
||||
const SCALAR_TYPE: $crate::vmstate::VMStateFieldType =
|
||||
$crate::call_func_with_field!($crate::vmstate::vmstate_scalar_type, $tuple, 0);
|
||||
const BASE: $crate::bindings::VMStateField =
|
||||
$crate::call_func_with_field!($crate::vmstate::vmstate_base, $tuple, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Transparent wrappers: just use the internal type
|
||||
|
||||
macro_rules! impl_vmstate_transparent {
|
||||
|
@ -296,6 +331,26 @@ impl_vmstate_transparent!(std::cell::UnsafeCell<T> where T: VMState);
|
|||
impl_vmstate_transparent!(crate::cell::BqlCell<T> where T: VMState);
|
||||
impl_vmstate_transparent!(crate::cell::BqlRefCell<T> where T: VMState);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_vmstate_bitsized {
|
||||
($type:ty) => {
|
||||
unsafe impl $crate::vmstate::VMState for $type {
|
||||
const SCALAR_TYPE: $crate::vmstate::VMStateFieldType =
|
||||
<<<$type as ::bilge::prelude::Bitsized>::ArbitraryInt
|
||||
as ::bilge::prelude::Number>::UnderlyingType
|
||||
as $crate::vmstate::VMState>::SCALAR_TYPE;
|
||||
const BASE: $crate::bindings::VMStateField =
|
||||
<<<$type as ::bilge::prelude::Bitsized>::ArbitraryInt
|
||||
as ::bilge::prelude::Number>::UnderlyingType
|
||||
as $crate::vmstate::VMState>::BASE;
|
||||
const VARRAY_FLAG: $crate::bindings::VMStateFlags =
|
||||
<<<$type as ::bilge::prelude::Bitsized>::ArbitraryInt
|
||||
as ::bilge::prelude::Number>::UnderlyingType
|
||||
as $crate::vmstate::VMState>::VARRAY_FLAG;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Scalar types using predefined VMStateInfos
|
||||
|
||||
macro_rules! impl_vmstate_scalar {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue