Before using Mutex<> to protect HPETRegisters, it's necessary to apply Migratable<> wrapper and ToMigrationState first since there's no pre-defined VMState for Mutex<>.
Though HPETRegistersMigration and HPETTimerRegistersMigration structs are generated by ToMigrationState macro, their VMStates still need to be implemented by hand. Signed-off-by: Zhao Liu <[email protected]> --- rust/hw/timer/hpet/src/device.rs | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/rust/hw/timer/hpet/src/device.rs b/rust/hw/timer/hpet/src/device.rs index 73a1c87abd95..42e2e8d070c3 100644 --- a/rust/hw/timer/hpet/src/device.rs +++ b/rust/hw/timer/hpet/src/device.rs @@ -18,7 +18,7 @@ }; use migration::{ self, impl_vmstate_struct, vmstate_fields, vmstate_of, vmstate_subsections, vmstate_validate, - VMStateDescription, VMStateDescriptionBuilder, + Migratable, ToMigrationState, VMStateDescription, VMStateDescriptionBuilder, }; use qom::{prelude::*, ObjectImpl, ParentField, ParentInit}; use system::{ @@ -184,7 +184,7 @@ fn timer_handler(timer_cell: &BqlRefCell<HPETTimer>) { } #[repr(C)] -#[derive(Debug, Default)] +#[derive(Debug, Default, ToMigrationState)] pub struct HPETTimerRegisters { // Memory-mapped, software visible timer registers /// Timer N Configuration and Capability Register @@ -663,7 +663,7 @@ fn write( } #[repr(C)] -#[derive(Default)] +#[derive(Default, ToMigrationState)] pub struct HPETRegisters { // HPET block Registers: Memory-mapped, software visible registers /// General Capabilities and ID Register @@ -701,7 +701,7 @@ fn is_timer_int_active(&self, index: usize) -> bool { pub struct HPETState { parent_obj: ParentField<SysBusDevice>, iomem: MemoryRegion, - regs: BqlRefCell<HPETRegisters>, + regs: Migratable<BqlRefCell<HPETRegisters>>, // Internal state /// Capabilities that QEMU HPET supports. @@ -1120,16 +1120,17 @@ impl ObjectImpl for HPETState { }) .build(); +// HPETTimerRegistersMigration is generated by ToMigrationState macro. impl_vmstate_struct!( - HPETTimerRegisters, - VMStateDescriptionBuilder::<HPETTimerRegisters>::new() + HPETTimerRegistersMigration, + VMStateDescriptionBuilder::<HPETTimerRegistersMigration>::new() .name(c"hpet_timer/regs") .version_id(1) .minimum_version_id(1) .fields(vmstate_fields! { - vmstate_of!(HPETTimerRegisters, config), - vmstate_of!(HPETTimerRegisters, cmp), - vmstate_of!(HPETTimerRegisters, fsb), + vmstate_of!(HPETTimerRegistersMigration, config), + vmstate_of!(HPETTimerRegistersMigration, cmp), + vmstate_of!(HPETTimerRegistersMigration, fsb), }) .build() ); @@ -1151,17 +1152,18 @@ impl ObjectImpl for HPETState { const VALIDATE_TIMERS_NAME: &CStr = c"num_timers must match"; +// HPETRegistersMigration is generated by ToMigrationState macro. impl_vmstate_struct!( - HPETRegisters, - VMStateDescriptionBuilder::<HPETRegisters>::new() + HPETRegistersMigration, + VMStateDescriptionBuilder::<HPETRegistersMigration>::new() .name(c"hpet/regs") .version_id(2) .minimum_version_id(2) .fields(vmstate_fields! { - vmstate_of!(HPETRegisters, config), - vmstate_of!(HPETRegisters, int_status), - vmstate_of!(HPETRegisters, counter), - vmstate_of!(HPETRegisters, tn_regs), + vmstate_of!(HPETRegistersMigration, config), + vmstate_of!(HPETRegistersMigration, int_status), + vmstate_of!(HPETRegistersMigration, counter), + vmstate_of!(HPETRegistersMigration, tn_regs), }) .build() ); -- 2.34.1
