Fixing hardware migration issues
v2 cover Fixing hardware migration issues
This set of patches is related to migration issues in hardware devices. Some of the devices had fields in their states that didn't saved and restored. These patches add missed fields to the new subsections of the vmstates. For several devices (like integratorcp) the patches add new vmstates, that didn't exist at all.
v2 changes:
* Used vmsd field of device classes instead of vm_state_register function (as suggested by Paolo Bonzini)
* Added more comments describing piix migration fix (as suggested by Paolo Bonzini)
* Some fields' initializations moved from pre_load to reset functions (as suggested by Paolo Bonzini)
* Removed patch of the rtl8139 module, because irq problem is solved by another patches (as suggested by Paolo Bonzini)
* Changed paddr synchronization in vapic (as suggested by Paolo Bonzini)
---
Pavel Dovgalyuk (12):
integratorcp: adding vmstate for save/restore
pcspk: adding vmstate for save/restore
fdc: adding vmstate for save/restore
parallel: adding vmstate for save/restore
serial: fixing vmstate for save/restore
apic_common: fixing loading vmstate
apic_common: vapic_paddr synchronization fix
hpet: fixing saving and loading process
pckbd: adding new fields to vmstate
piix: do not raise irq while loading vmstate
mc146818rtc: add missed field to vmstate
pl031: add missed field to vmstate
hw/arm/integratorcp.c | 38 +++++++ hw/audio/pcspk.c | 17 +++ hw/block/fdc.c | 74 +++++++++++++ hw/char/parallel.c | 19 +++ hw/char/serial.c | 265 ++++++++++++++++++++++++++++++++++++++++-------- hw/input/pckbd.c | 51 +++++++++ hw/intc/apic_common.c | 34 ++++++ hw/pci-host/piix.c | 26 ++++- hw/timer/hpet.c | 15 --- hw/timer/mc146818rtc.c | 25 +++++ hw/timer/pl031.c | 3 - 11 files changed, 502 insertions(+), 65 deletions(-)
Signature · 1 line
Pavel Dovgalyuk
PATCH v2 1/12 integratorcp: adding vmstate for save/restore
VMState added by this patch preserves correct
loading of the integratorcp device state.
--- hw/arm/integratorcp.c | 38 +++++++++++++++++++++++++++++++++++++- 1 files changed, 37 insertions(+), 1 deletions(-)
hw/arm/integratorcp.c +37 -1
@@ -42,6 +42,27 @@ typedef struct IntegratorCMState {uint32_t fiq_enabled; } IntegratorCMState; +static const VMStateDescription vmstate_integratorcm = { + .name ="integratorcm" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT32 (cm_osc, IntegratorCMState), +VMSTATE_UINT32 (cm_ctrl, IntegratorCMState), +VMSTATE_UINT32 (cm_lock, IntegratorCMState), +VMSTATE_UINT32 (cm_auxosc, IntegratorCMState), +VMSTATE_UINT32 (cm_sdram, IntegratorCMState), +VMSTATE_UINT32 (cm_init, IntegratorCMState), +VMSTATE_UINT32 (cm_flags, IntegratorCMState), +VMSTATE_UINT32 (cm_nvflags, IntegratorCMState), +VMSTATE_UINT32 (int_level, IntegratorCMState), +VMSTATE_UINT32 (irq_enabled, IntegratorCMState), +VMSTATE_UINT32 (fiq_enabled, IntegratorCMState), +VMSTATE_END_OF_LIST () + } +}; +static uint8_t integrator_spd[128 ] = {128 ,8 ,4 ,11 ,9 ,1 ,64 ,0 ,2 ,0xa0 ,0xa0 ,0 ,0 ,8 ,0 ,1 ,0xe ,4 ,0x1c ,1 ,2 ,0x20 ,0xc0 ,0 ,0 ,0 ,0 ,0x30 ,0x28 ,0x30 ,0x28 ,0x40
@@ -272,7 +293,7 @@ static int integratorcm_init(SysBusDevice *dev)sysbus_init_mmio (dev, &s->iomem);integratorcm_do_remap (s); -/* ??? Save/restore. */ +vmstate_register (NULL ,-1 , &vmstate_integratorcm, s);return 0 ; }
@@ -296,6 +317,20 @@ typedef struct icp_pic_state {qemu_irq parent_fiq; } icp_pic_state; + +static const VMStateDescription vmstate_icp_pic = { + .name ="icp_pic_state" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT32 (level, icp_pic_state), +VMSTATE_UINT32 (irq_enabled, icp_pic_state), +VMSTATE_UINT32 (fiq_enabled, icp_pic_state), +VMSTATE_END_OF_LIST () + } +}; +static void icp_pic_update (icp_pic_state *s) {uint32_t flags;
@@ -399,6 +434,7 @@ static int icp_pic_init(SysBusDevice *sbd)memory_region_init_io (&s->iomem,OBJECT (s), &icp_pic_ops, s,"icp-pic" ,0x00800000 );sysbus_init_mmio (sbd, &s->iomem); +vmstate_register (NULL ,-1 , &vmstate_icp_pic, s);return 0 ; }
Re: [Qemu-devel] [PATCH v2 01/12] integratorcp: adding vmstate for save/restore
Quoted 13 lines · Pavel Dovgalyuk
VMState added by this patch preserves correct
loading of the integratorcp device state.Signed-off-by Pavel Dovgalyuk <[email protected]>--- hw/arm/integratorcp.c | 38 +++++++++++++++++++++++++++++++++++++- 1 files changed, 37 insertions(+), 1 deletions(-)hw/arm/integratorcp.c +0
-0
hw/arm/integratorcp.c typedef struct IntegratorCMState { · line 49
Quoted 8 lines
hw/arm/integratorcp.c +5
-0@@ -42,6 +42,27 @@ typedef struct IntegratorCMState {uint32_t fiq_enabled; } IntegratorCMState; +static const VMStateDescription vmstate_integratorcm = { + .name ="integratorcm" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 ,
You don't need to specify minimum_version_id_old any more (if there's no load_state_old, and there usually isn't.)
Quoted 20 lines
hw/arm/integratorcp.c +16
-0+ .fields = (VMStateField[]) { +VMSTATE_UINT32 (cm_osc, IntegratorCMState), +VMSTATE_UINT32 (cm_ctrl, IntegratorCMState), +VMSTATE_UINT32 (cm_lock, IntegratorCMState), +VMSTATE_UINT32 (cm_auxosc, IntegratorCMState), +VMSTATE_UINT32 (cm_sdram, IntegratorCMState), +VMSTATE_UINT32 (cm_init, IntegratorCMState), +VMSTATE_UINT32 (cm_flags, IntegratorCMState), +VMSTATE_UINT32 (cm_nvflags, IntegratorCMState), +VMSTATE_UINT32 (int_level, IntegratorCMState), +VMSTATE_UINT32 (irq_enabled, IntegratorCMState), +VMSTATE_UINT32 (fiq_enabled, IntegratorCMState), +VMSTATE_END_OF_LIST () + } +}; +static uint8_t integrator_spd[128 ] = {128 ,8 ,4 ,11 ,9 ,1 ,64 ,0 ,2 ,0xa0 ,0xa0 ,0 ,0 ,8 ,0 ,1 ,0xe ,4 ,0x1c ,1 ,2 ,0x20 ,0xc0 ,0 ,0 ,0 ,0 ,0x30 ,0x28 ,0x30 ,0x28 ,0x40
hw/arm/integratorcp.c static int integratorcm_init(SysBusDevice *dev) · line 296
Quoted 5 lines
hw/arm/integratorcp.c +1
-1@@ -272,7 +293,7 @@ static int integratorcm_init(SysBusDevice *dev)sysbus_init_mmio (dev, &s->iomem);integratorcm_do_remap (s); -/* ??? Save/restore. */ +vmstate_register (NULL ,-1 , &vmstate_integratorcm, s);
No new uses of vmstate_register(), please. You want to set the dc->vmsd field in core_class_init(), I think.
Quoted 25 lines
hw/arm/integratorcp.c +14
-0return 0 ; }@@ -296,6 +317,20 @@ typedef struct icp_pic_state {qemu_irq parent_fiq; } icp_pic_state; + +static const VMStateDescription vmstate_icp_pic = { + .name ="icp_pic_state" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT32 (level, icp_pic_state), +VMSTATE_UINT32 (irq_enabled, icp_pic_state), +VMSTATE_UINT32 (fiq_enabled, icp_pic_state), +VMSTATE_END_OF_LIST () + } +}; +static void icp_pic_update (icp_pic_state *s) {uint32_t flags;
hw/arm/integratorcp.c static int icp_pic_init(SysBusDevice *sbd) · line 439
Quoted 6 lines
hw/arm/integratorcp.c +1
-0@@ -399,6 +434,7 @@ static int icp_pic_init(SysBusDevice *sbd)memory_region_init_io (&s->iomem,OBJECT (s), &icp_pic_ops, s,"icp-pic" ,0x00800000 );sysbus_init_mmio (sbd, &s->iomem); +vmstate_register (NULL ,-1 , &vmstate_icp_pic, s);return 0 ; }
Similar comments apply to this device.
thanks
-- PMM
PATCH v2 2/12 pcspk: adding vmstate for save/restore
In reply to Pavel DovgalyukVMState added by this patch preserves correct
loading of the PC speaker device state.
--- hw/audio/pcspk.c | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-)
hw/audio/pcspk.c +15 -2
@@ -50,8 +50,8 @@ typedef struct {unsigned int pit_count;unsigned int samples;unsigned int play_pos; -int data_on; -int dummy_refresh_clock; +uint8_t data_on; +uint8_t dummy_refresh_clock; } PCSpkState;static const char *s_spk ="pcspk" ;
@@ -163,6 +163,18 @@ static const MemoryRegionOps pcspk_io_ops = { }, }; +static const VMStateDescription vmstate_spk = { + .name ="pcspk" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT8 (data_on, PCSpkState), +VMSTATE_UINT8 (dummy_refresh_clock, PCSpkState), +VMSTATE_END_OF_LIST () + } +}; +static void pcspk_initfn (Object *obj) {PCSpkState *s =PC_SPEAKER (obj);
@@ -192,6 +204,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data) dc->realize = pcspk_realizefn;set_bit (DEVICE_CATEGORY_SOUND , dc->categories); + dc->vmsd = &vmstate_spk; dc->props = pcspk_properties;/* Reason: pointer property "pit", realize sets global pcspk_state */ dc->cannot_instantiate_with_device_add_yet = true;
Re: [Qemu-devel] [PATCH v2 02/12] pcspk: adding vmstate for save/restore
Il 28/08/2014 13:18, Pavel Dovgalyuk ha scritto:
Quoted 44 lines
VMState added by this patch preserves correct
loading of the PC speaker device state.Signed-off-by Pavel Dovgalyuk <[email protected]>--- hw/audio/pcspk.c | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-)hw/audio/pcspk.c +14
-2@@ -50,8 +50,8 @@ typedef struct {unsigned int pit_count;unsigned int samples;unsigned int play_pos; -int data_on; -int dummy_refresh_clock; +uint8_t data_on; +uint8_t dummy_refresh_clock; } PCSpkState;static const char *s_spk ="pcspk" ;@@ -163,6 +163,18 @@ static const MemoryRegionOps pcspk_io_ops = { }, }; +static const VMStateDescription vmstate_spk = { + .name ="pcspk" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT8 (data_on, PCSpkState), +VMSTATE_UINT8 (dummy_refresh_clock, PCSpkState), +VMSTATE_END_OF_LIST () + } +}; +static void pcspk_initfn (Object *obj) {PCSpkState *s =PC_SPEAKER (obj);
hw/audio/pcspk.c static void pcspk_class_initfn(ObjectClass *klass, void *data) · line 210
Quoted 7 lines
hw/audio/pcspk.c +1
-0@@ -192,6 +204,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data) dc->realize = pcspk_realizefn;set_bit (DEVICE_CATEGORY_SOUND , dc->categories); + dc->vmsd = &vmstate_spk; dc->props = pcspk_properties;/* Reason: pointer property "pit", realize sets global pcspk_state */ dc->cannot_instantiate_with_device_add_yet = true;
This breaks migration to 2.1 and earlier. Not a big deal, just a heads up for distributions.
Paolo
PATCH v2 3/12 fdc: adding vmstate for save/restore
In reply to Pavel DovgalyukVMState added by this patch preserves correct
loading of the FDC device state.
--- hw/block/fdc.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 74 insertions(+), 0 deletions(-)
hw/block/fdc.c +74 -0
@@ -695,10 +695,34 @@ static const VMStateDescription vmstate_fdrive_media_rate = { } }; +static bool fdrive_perpendicular_needed (void *opaque) +{ +FDrive *drive = opaque; + +return drive->perpendicular !=0 ; +} + +static const VMStateDescription vmstate_fdrive_perpendicular = { + .name ="fdrive/perpendicular" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_UINT8 (perpendicular, FDrive), +VMSTATE_END_OF_LIST () + } +}; + +static int fdrive_post_load (void *opaque,int version_id) +{ +fd_revalidate (opaque); +return 0 ; +} +static const VMStateDescription vmstate_fdrive = { .name ="fdrive" , .version_id =1 , .minimum_version_id =1 , + .post_load = fdrive_post_load, .fields = (VMStateField []) {VMSTATE_UINT8 (head, FDrive),VMSTATE_UINT8 (track, FDrive),
@@ -713,6 +737,9 @@ static const VMStateDescription vmstate_fdrive = { .vmsd = &vmstate_fdrive_media_rate, .needed = &fdrive_media_rate_needed, } , { + .vmsd = &vmstate_fdrive_perpendicular, + .needed = &fdrive_perpendicular_needed, + } , {/* empty */ } }
@@ -734,6 +761,40 @@ static int fdc_post_load(void *opaque, int version_id)return 0 ; } +static bool fdc_reset_sensei_needed (void *opaque) +{ +FDCtrl *s = opaque; + +return s->reset_sensei !=0 ; +} + +static const VMStateDescription vmstate_fdc_reset_sensei = { + .name ="fdc/reset_sensei" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_INT32 (reset_sensei, FDCtrl), +VMSTATE_END_OF_LIST () + } +}; + +static bool fdc_result_timer_needed (void *opaque) +{ +FDCtrl *s = opaque; + +return timer_pending (s->result_timer); +} + +static const VMStateDescription vmstate_fdc_result_timer = { + .name ="fdc/result_timer" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_TIMER (result_timer, FDCtrl), +VMSTATE_END_OF_LIST () + } +}; +static const VMStateDescription vmstate_fdc = { .name ="fdc" , .version_id =2 ,
@@ -770,6 +831,17 @@ static const VMStateDescription vmstate_fdc = { VMSTATE_STRUCT_ARRAY(drives, FDCtrl, MAX_FD, 1, vmstate_fdrive, FDrive),VMSTATE_END_OF_LIST () + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_fdc_reset_sensei, + .needed = fdc_reset_sensei_needed, + } , { + .vmsd = &vmstate_fdc_result_timer, + .needed = fdc_result_timer_needed, + } , { +/* empty */ + } } };
@@ -844,6 +916,8 @@ static void fdctrl_reset(FDCtrl *fdctrl, int do_irq) fdctrl->dor = FD_DOR_nRESET; fdctrl->dor |= (fdctrl->dma_chann !=-1 ) ?FD_DOR_DMAEN :0 ; fdctrl->msr =FD_MSR_RQM ; + fdctrl->reset_sensei =0 ; +timer_del (fdctrl->result_timer);/* FIFO state */ fdctrl->data_pos =0 ; fdctrl->data_len =0 ;
PATCH v2 4/12 parallel: adding vmstate for save/restore
In reply to Pavel DovgalyukVMState added by this patch preserves correct
loading of the parallel port controller state.
--- hw/char/parallel.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)
hw/char/parallel.c +19 -0
@@ -477,6 +477,24 @@ static const MemoryRegionPortio isa_parallel_portio_sw_list[] = { PORTIO_END_OF_LIST(), }; + +static const VMStateDescription vmstate_parallel_isa = { + .name ="parallel_isa" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT8 (state.dataw, ISAParallelState), +VMSTATE_UINT8 (state.datar, ISAParallelState), +VMSTATE_UINT8 (state.status, ISAParallelState), +VMSTATE_UINT8 (state.control, ISAParallelState), +VMSTATE_INT32 (state.irq_pending, ISAParallelState), +VMSTATE_INT32 (state.epp_timeout, ISAParallelState), +VMSTATE_END_OF_LIST () + } +}; + +static void parallel_isa_realizefn (DeviceState *dev,Error **errp) {static int index;
@@ -606,6 +624,7 @@ static void parallel_isa_class_initfn(ObjectClass *klass, void *data)DeviceClass *dc =DEVICE_CLASS (klass); dc->realize = parallel_isa_realizefn; + dc->vmsd = &vmstate_parallel_isa; dc->props = parallel_isa_properties;set_bit (DEVICE_CATEGORY_INPUT , dc->categories); }
PATCH v2 5/12 serial: fixing vmstate for save/restore
In reply to Pavel DovgalyukSome fields were added to VMState by this patch to preserve correct loading of the serial port controller state.
Updating FCR value while loading was also modified to disable generating an interrupt by loadvm.
--- hw/char/serial.c | 265 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 220 insertions(+), 45 deletions(-)
hw/char/serial.c +220 -45
@@ -272,6 +272,64 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) } +/* Setter for FCR. +is_load flag means, that value is set while loading VM state +and interrupt should not be invoked */ +static void serial_write_fcr (void *opaque,uint32_t val,int is_load) +{ +SerialState *s = opaque; + val = val &0xFF ; + +if (s->fcr == val) { +return ; + } + +/* Did the enable/disable flag change? If so, make sure FIFOs get flushed */ +if ((val ^ s->fcr) &UART_FCR_FE ) { + val |=UART_FCR_XFR |UART_FCR_RFR ; + } + +/* FIFO clear */ + +if (val &UART_FCR_RFR ) { +timer_del (s->fifo_timeout_timer); + s->timeout_ipending =0 ; +fifo8_reset (&s->recv_fifo); + } + +if (val &UART_FCR_XFR ) { +fifo8_reset (&s->xmit_fifo); + } + +if (val &UART_FCR_FE ) { + s->iir |=UART_IIR_FE ; +/* Set recv_fifo trigger Level */ +switch (val &0xC0 ) { +case UART_FCR_ITL_1 : + s->recv_fifo_itl =1 ; +break ; +case UART_FCR_ITL_2 : + s->recv_fifo_itl =4 ; +break ; +case UART_FCR_ITL_3 : + s->recv_fifo_itl =8 ; +break ; +case UART_FCR_ITL_4 : + s->recv_fifo_itl =14 ; +break ; + } + }else { + s->iir &= ~UART_IIR_FE ; + } + +/* Set fcr - or at least the bits in it that are supposed to "stick" */ + s->fcr = val &0xC9 ; + +if (!is_load) { +serial_update_irq (s); + } +} +static void serial_ioport_write (void *opaque,hwaddr addr,uint64_t val,unsigned size) {
@@ -327,50 +385,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, }break ;case 2 : - val = val &0xFF ; - -if (s->fcr == val) -break ; - -/* Did the enable/disable flag change? If so, make sure FIFOs get flushed */ -if ((val ^ s->fcr) &UART_FCR_FE ) - val |=UART_FCR_XFR |UART_FCR_RFR ; - -/* FIFO clear */ - -if (val &UART_FCR_RFR ) { -timer_del (s->fifo_timeout_timer); - s->timeout_ipending=0 ; -fifo8_reset (&s->recv_fifo); - } - -if (val &UART_FCR_XFR ) { -fifo8_reset (&s->xmit_fifo); - } - -if (val &UART_FCR_FE ) { - s->iir |=UART_IIR_FE ; -/* Set recv_fifo trigger Level */ -switch (val &0xC0 ) { -case UART_FCR_ITL_1 : - s->recv_fifo_itl =1 ; -break ; -case UART_FCR_ITL_2 : - s->recv_fifo_itl =4 ; -break ; -case UART_FCR_ITL_3 : - s->recv_fifo_itl =8 ; -break ; -case UART_FCR_ITL_4 : - s->recv_fifo_itl =14 ; -break ; - } - }else - s->iir &= ~UART_IIR_FE ; - -/* Set fcr - or at least the bits in it that are supposed to "stick" */ - s->fcr = val &0xC9 ; -serial_update_irq (s); +serial_write_fcr (s, val,0 );break ;case 3 : {
@@ -590,6 +605,14 @@ static void serial_pre_save(void *opaque) s->fcr_vmstate = s->fcr; } +static int serial_pre_load (void *opaque) +{ +SerialState *s = (SerialState *)opaque; + s->thr_ipending =-1 ; + s->poll_msl =-1 ; +return 0 ; +} +static int serial_post_load (void *opaque,int version_id) {SerialState *s = opaque;
@@ -597,17 +620,139 @@ static int serial_post_load(void *opaque, int version_id)if (version_id <3 ) { s->fcr_vmstate =0 ; } +if (s->thr_ipending ==-1 ) { + s->thr_ipending = ((s->iir &UART_IIR_ID ) ==UART_IIR_THRI ); + } + s->last_break_enable = (s->lcr >>6 ) &1 ;/* Initialize fcr via setter to perform essential side-effects */ -serial_ioport_write (s,0x02 , s->fcr_vmstate,1 ); +serial_write_fcr (s, s->fcr_vmstate,1 );serial_update_parameters (s);return 0 ; } +static bool serial_thr_ipending_needed (void *opaque) +{ +SerialState *s = opaque; +bool expected_value = ((s->iir &UART_IIR_ID ) ==UART_IIR_THRI ); +return s->thr_ipending != expected_value; +} + +const VMStateDescription vmstate_serial_thr_ipending = { + .name ="serial/thr_ipending" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_INT32 (thr_ipending, SerialState), +VMSTATE_END_OF_LIST () + } +}; + +static bool serial_tsr_needed (void *opaque) +{ +SerialState *s = (SerialState *)opaque; +return s->tsr_retry !=0 ; +} + +const VMStateDescription vmstate_serial_tsr = { + .name ="serial/tsr" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_INT32 (tsr_retry, SerialState), +VMSTATE_UINT8 (thr, SerialState), +VMSTATE_UINT8 (tsr, SerialState), +VMSTATE_END_OF_LIST () + } +}; + +static bool serial_recv_fifo_needed (void *opaque) +{ +SerialState *s = (SerialState *)opaque; +return !fifo8_is_empty (&s->recv_fifo); + +} + +const VMStateDescription vmstate_serial_recv_fifo = { + .name ="serial/recv_fifo" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_STRUCT (recv_fifo, SerialState,1 , vmstate_fifo8, Fifo8), +VMSTATE_END_OF_LIST () + } +}; + +static bool serial_xmit_fifo_needed (void *opaque) +{ +SerialState *s = (SerialState *)opaque; +return !fifo8_is_empty (&s->xmit_fifo); +} + +const VMStateDescription vmstate_serial_xmit_fifo = { + .name ="serial/xmit_fifo" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_STRUCT (xmit_fifo, SerialState,1 , vmstate_fifo8, Fifo8), +VMSTATE_END_OF_LIST () + } +}; + +static bool serial_fifo_timeout_timer_needed (void *opaque) +{ +SerialState *s = (SerialState *)opaque; +return timer_pending (s->fifo_timeout_timer); +} + +const VMStateDescription vmstate_serial_fifo_timeout_timer = { + .name ="serial/fifo_timeout_timer" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_TIMER (fifo_timeout_timer, SerialState), +VMSTATE_END_OF_LIST () + } +}; + +static bool serial_timeout_ipending_needed (void *opaque) +{ +SerialState *s = (SerialState *)opaque; +return s->timeout_ipending !=0 ; +} + +const VMStateDescription vmstate_serial_timeout_ipending = { + .name ="serial/timeout_ipending" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_INT32 (timeout_ipending, SerialState), +VMSTATE_END_OF_LIST () + } +}; + +static bool serial_poll_needed (void *opaque) +{ +SerialState *s = (SerialState *)opaque; +return s->poll_msl >=0 ; +} + +const VMStateDescription vmstate_serial_poll = { + .name ="serial/poll" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_INT32 (poll_msl, SerialState), +VMSTATE_TIMER (modem_status_poll, SerialState), +VMSTATE_END_OF_LIST () + } +}; +const VMStateDescription vmstate_serial = { .name ="serial" , .version_id =3 , .minimum_version_id =2 , .pre_save = serial_pre_save, + .pre_load = serial_pre_load, .post_load = serial_post_load, .fields = (VMStateField []) {VMSTATE_UINT16_V (divider, SerialState,2 ),
@@ -621,6 +766,32 @@ const VMStateDescription vmstate_serial = { VMSTATE_UINT8(scr, SerialState), VMSTATE_UINT8_V(fcr_vmstate, SerialState, 3),VMSTATE_END_OF_LIST () + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_serial_thr_ipending, + .needed = &serial_thr_ipending_needed, + } , { + .vmsd = &vmstate_serial_tsr, + .needed = &serial_tsr_needed, + } , { + .vmsd = &vmstate_serial_recv_fifo, + .needed = &serial_recv_fifo_needed, + } , { + .vmsd = &vmstate_serial_xmit_fifo, + .needed = &serial_xmit_fifo_needed, + } , { + .vmsd = &vmstate_serial_fifo_timeout_timer, + .needed = &serial_fifo_timeout_timer_needed, + } , { + .vmsd = &vmstate_serial_timeout_ipending, + .needed = &serial_timeout_ipending_needed, + } , { + .vmsd = &vmstate_serial_poll, + .needed = &serial_poll_needed, + } , { +/* empty */ + } } };
@@ -642,6 +813,10 @@ static void serial_reset(void *opaque) s->char_transmit_time = (get_ticks_per_sec () /9600 ) *10 ; s->poll_msl =0 ; + s->timeout_ipending =0 ; +timer_del (s->fifo_timeout_timer); +timer_del (s->modem_status_poll); +fifo8_reset (&s->recv_fifo);fifo8_reset (&s->xmit_fifo);
PATCH v2 6/12 apic_common: fixing loading vmstate
In reply to Pavel DovgalyukThis patch adds missed sipi_vector and wait_for_sipi fields to the new subsection of the vmstate of the apic_common module. Saving and loading of these fields makes migration of the apic state deterministic.
--- hw/intc/apic_common.c | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-)
hw/intc/apic_common.c +24 -0
@@ -345,6 +345,23 @@ static int apic_dispatch_post_load(void *opaque, int version_id)return 0 ; } +static bool apic_common_sipi_needed (void *opaque) +{ +APICCommonState *s =APIC_COMMON (opaque); +return s->wait_for_sipi !=0 ; +} + +static const VMStateDescription vmstate_apic_common_sipi = { + .name ="apic_sipi" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_INT32 (sipi_vector, APICCommonState), +VMSTATE_INT32 (wait_for_sipi, APICCommonState), +VMSTATE_END_OF_LIST () + } +}; +static const VMStateDescription vmstate_apic_common = { .name ="apic" , .version_id =3 ,
@@ -375,6 +392,13 @@ static const VMStateDescription vmstate_apic_common = { VMSTATE_INT64(timer_expiry, APICCommonState), /* open-coded timer state */VMSTATE_END_OF_LIST () + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_apic_common_sipi, + .needed = apic_common_sipi_needed, + }, +VMSTATE_END_OF_LIST () } };
Re: [Qemu-devel] [PATCH v2 06/12] apic_common: fixing loading vmstate
Il 28/08/2014 13:18, Pavel Dovgalyuk ha scritto:
Quoted 14 lines
This patch adds missed
sipi_vectorandwait_for_sipifields to the new subsection of the vmstate of theapic_commonmodule. Saving and loading of these fields makes migration of the apic state deterministic.Signed-off-by Pavel Dovgalyuk <[email protected]>--- hw/intc/apic_common.c | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-)hw/intc/apic_common.c +0
-0
hw/intc/apic_common.c static int apic_dispatch_post_load(void *opaque, int version_id) · line 352
Quoted 8 lines
hw/intc/apic_common.c +5
-0@@ -345,6 +345,23 @@ static int apic_dispatch_post_load(void *opaque, int version_id)return 0 ; } +static bool apic_common_sipi_needed (void *opaque) +{ +APICCommonState *s =APIC_COMMON (opaque); +return s->wait_for_sipi !=0 ; +}
vmstate_apic_common needs a pre_load function that sets wait_for_sipi to 0 (because the default is not zero, it's !cpu_is_bsp(s->cpu)).
Paolo
Quoted 29 lines
hw/intc/apic_common.c +18
-0+static const VMStateDescription vmstate_apic_common_sipi = { + .name ="apic_sipi" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_INT32 (sipi_vector, APICCommonState), +VMSTATE_INT32 (wait_for_sipi, APICCommonState), +VMSTATE_END_OF_LIST () + } +}; +static const VMStateDescription vmstate_apic_common = { .name ="apic" , .version_id =3 ,@@ -375,6 +392,13 @@ static const VMStateDescription vmstate_apic_common = { VMSTATE_INT64(timer_expiry, APICCommonState), /* open-coded timer state */VMSTATE_END_OF_LIST () + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_apic_common_sipi, + .needed = apic_common_sipi_needed, + }, +VMSTATE_END_OF_LIST () } };
PATCH v2 7/12 apic_common: vapic_paddr synchronization fix
In reply to Pavel DovgalyukThis patch postpones vapic_paddr initialization, which is perfromed by the migration functions. When vapic_paddr is synchronized within the migration process, apic_common functions could operate with incorrect apic state, if it hadn't loaded yet. This patch postpones the synchronization until whole virtual machine state is loaded.
--- hw/intc/apic_common.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-)
hw/intc/apic_common.c +9 -1
@@ -91,13 +91,21 @@ void apic_enable_tpr_access_reporting(DeviceState *dev, bool enable) } } +static void do_apic_enable_vapic (void *data) +{ +APICCommonState *s =APIC_COMMON (data); +APICCommonClass *info =APIC_COMMON_GET_CLASS (s); + + info->vapic_base_update (s); +} +void apic_enable_vapic (DeviceState *dev,hwaddr paddr) {APICCommonState *s =APIC_COMMON (dev);APICCommonClass *info =APIC_COMMON_GET_CLASS (s); s->vapic_paddr = paddr; - info->vapic_base_update (s); +run_on_cpu (CPU (s->cpu), do_apic_enable_vapic, s); } void apic_handle_tpr_access_report(DeviceState *dev, target_ulong ip,
PATCH v2 8/12 hpet: fixing saving and loading process
In reply to Pavel DovgalyukVM clock does not run while saving, so there is no need for saving the ticks in HPET. Also added saving of hpet_offset field.
--- hw/timer/hpet.c | 15 ++------------- 1 files changed, 2 insertions(+), 13 deletions(-)
hw/timer/hpet.c +2 -13
@@ -222,14 +222,6 @@ static void update_irq(struct HPETTimer *timer, int set) } } -static void hpet_pre_save (void *opaque) -{ -HPETState *s = opaque; - -/* save current counter value */ - s->hpet_counter =hpet_get_ticks (s); -} -static int hpet_pre_load (void *opaque) {HPETState *s = opaque;
@@ -255,9 +247,6 @@ static int hpet_post_load(void *opaque, int version_id) {HPETState *s = opaque; -/* Recalculate the offset between the main counter and guest time */ - s->hpet_offset =ticks_to_ns (s->hpet_counter) -qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ); -/* Push number of timers into capability returned via HPET_ID */ s->capability &= ~HPET_ID_NUM_TIM_MASK ; s->capability |= (s->num_timers -1 ) <<HPET_ID_NUM_TIM_SHIFT ;
@@ -306,15 +295,15 @@ static const VMStateDescription vmstate_hpet_timer = {static const VMStateDescription vmstate_hpet = { .name ="hpet" , - .version_id =2 , + .version_id =3 , .minimum_version_id =1 , - .pre_save = hpet_pre_save, .pre_load = hpet_pre_load, .post_load = hpet_post_load, .fields = (VMStateField []) {VMSTATE_UINT64 (config, HPETState),VMSTATE_UINT64 (isr, HPETState),VMSTATE_UINT64 (hpet_counter, HPETState), +VMSTATE_UINT64_V (hpet_offset, HPETState,3 ),VMSTATE_UINT8_V (num_timers, HPETState,2 ),VMSTATE_VALIDATE ("num_timers in range" , hpet_validate_num_timers), VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0,
Re: [Qemu-devel] [PATCH v2 08/12] hpet: fixing saving and loading process
Il 28/08/2014 13:19, Pavel Dovgalyuk ha scritto:
Quoted 46 lines
VM clock does not run while saving, so there is no need for saving the ticks in HPET. Also added saving of
hpet_offsetfield.Signed-off-by Pavel Dovgalyuk <[email protected]>--- hw/timer/hpet.c | 15 ++------------- 1 files changed, 2 insertions(+), 13 deletions(-)hw/timer/hpet.c +1
-13@@ -222,14 +222,6 @@ static void update_irq(struct HPETTimer *timer, int set) } } -static void hpet_pre_save (void *opaque) -{ -HPETState *s = opaque; - -/* save current counter value */ - s->hpet_counter =hpet_get_ticks (s); -} -static int hpet_pre_load (void *opaque) {HPETState *s = opaque;@@ -255,9 +247,6 @@ static int hpet_post_load(void *opaque, int version_id) {HPETState *s = opaque; -/* Recalculate the offset between the main counter and guest time */ - s->hpet_offset =ticks_to_ns (s->hpet_counter) -qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ); -/* Push number of timers into capability returned via HPET_ID */ s->capability &= ~HPET_ID_NUM_TIM_MASK ; s->capability |= (s->num_timers -1 ) <<HPET_ID_NUM_TIM_SHIFT ;@@ -306,15 +295,15 @@ static const VMStateDescription vmstate_hpet_timer = {static const VMStateDescription vmstate_hpet = { .name ="hpet" , - .version_id =2 , + .version_id =3 , .minimum_version_id =1 , - .pre_save = hpet_pre_save,
hw/timer/hpet.c static const VMStateDescription vmstate_hpet_timer = { · line 309
Quoted 10 lines
hw/timer/hpet.c +1
-0.pre_load = hpet_pre_load, .post_load = hpet_post_load, .fields = (VMStateField []) {VMSTATE_UINT64 (config, HPETState),VMSTATE_UINT64 (isr, HPETState),VMSTATE_UINT64 (hpet_counter, HPETState), +VMSTATE_UINT64_V (hpet_offset, HPETState,3 ),VMSTATE_UINT8_V (num_timers, HPETState,2 ),VMSTATE_VALIDATE ("num_timers in range" , hpet_validate_num_timers), VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0,
This also breaks migration to 2.1, unless you use -no-hpet.
Paolo
Re: [Qemu-devel] [PATCH v2 08/12] hpet: fixing saving and loading process
Il 28/08/2014 13:58, Paolo Bonzini ha scritto:
Quoted 1 line
This also breaks migration to 2.1, unless you use -no-hpet.
Actually, this is also only needed for your record/replay implementation.
Paolo
Re: [Qemu-devel] [PATCH v2 08/12] hpet: fixing saving and loading process
Quoted 5 lines
From: Paolo Bonzini [mailto:[email protected]] On Behalf Of Paolo Bonzini Il 28/08/2014 13:58, Paolo Bonzini ha scritto:
Quoted 1 line
This also breaks migration to 2.1, unless you use -no-hpet.
Actually, this is also only needed for your record/replay implementation.
Ok, I'll move it to the replay series.
Pavel Dovgalyuk
PATCH v2 9/12 pckbd: adding new fields to vmstate
In reply to Pavel DovgalyukThis patch adds outport to VMState to allow correct saving and restoring the state of PC keyboard controller.
--- hw/input/pckbd.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 0 deletions(-)
hw/input/pckbd.c +51 -0
@@ -131,6 +131,7 @@ typedef struct KBDState {uint8_t status;uint8_t mode;uint8_t outport; +bool outport_present;/* Bitmask of devices with data available. */ uint8_t pending;void *kbd;
@@ -367,18 +368,68 @@ static void kbd_reset(void *opaque) s->mode =KBD_MODE_KBD_INT |KBD_MODE_MOUSE_INT ; s->status =KBD_STAT_CMD |KBD_STAT_UNLOCKED ; s->outport =KBD_OUT_RESET |KBD_OUT_A20 ; + s->outport_present = false; +} + +static uint8_t kbd_outport_default (KBDState *s) +{ +return KBD_OUT_RESET |KBD_OUT_A20 + | (s->status &KBD_STAT_OBF ?KBD_OUT_OBF :0 ) + | (s->status &KBD_STAT_MOUSE_OBF ?KBD_OUT_MOUSE_OBF :0 ); +} + +static int kbd_outport_post_load (void *opaque,int version_id) +{ +KBDState *s = opaque; + s->outport_present = true; +return 0 ; +} + +static const VMStateDescription vmstate_kbd_outport = { + .name ="pckbd_outport" , + .version_id =1 , + .minimum_version_id =1 , + .post_load = kbd_outport_post_load, + .fields = (VMStateField []) { +VMSTATE_UINT8 (outport, KBDState), +VMSTATE_END_OF_LIST () + } +}; + +static bool kbd_outport_needed (void *opaque) +{ +KBDState *s = opaque; +return s->outport !=kbd_outport_default (s); +} + +static int kbd_post_load (void *opaque,int version_id) +{ +KBDState *s = opaque; +if (!s->outport_present) { + s->outport =kbd_outport_default (s); + } + s->outport_present = false; +return 0 ; }static const VMStateDescription vmstate_kbd = { .name ="pckbd" , .version_id =3 , .minimum_version_id =3 , + .post_load = kbd_post_load, .fields = (VMStateField []) {VMSTATE_UINT8 (write_cmd, KBDState),VMSTATE_UINT8 (status, KBDState),VMSTATE_UINT8 (mode, KBDState),VMSTATE_UINT8 (pending, KBDState),VMSTATE_END_OF_LIST () + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_kbd_outport, + .needed = kbd_outport_needed, + }, +VMSTATE_END_OF_LIST () } };
PATCH v2 10/12 piix: do not raise irq while loading vmstate
In reply to Pavel DovgalyukThis patch disables raising an irq while loading the state of PCI bridge. The aim of this patch is preserving the same behavior while saving and restoring the VM state. IRQ is not raised while saving the state of the bridge. That's why the behavior of the restored system will differ from the original one. This patch eliminates raising an irq and just restores the calculated state fields in post_load function.
--- hw/pci-host/piix.c | 26 ++++++++++++++++++++++++-- 1 files changed, 24 insertions(+), 2 deletions(-)
hw/pci-host/piix.c +24 -2
@@ -409,7 +409,7 @@ static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq) (pic_irq * PIIX_NUM_PIRQS)))); } -static void piix3_set_irq_level (PIIX3State *piix3,int pirq,int level) +static void piix3_set_irq_level_internal (PIIX3State *piix3,int pirq,int level) {int pic_irq;uint64_t mask;
@@ -422,6 +422,18 @@ static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level) mask =1ULL << ((pic_irq *PIIX_NUM_PIRQS ) + pirq); piix3->pic_levels &= ~mask; piix3->pic_levels |= mask * !!level; +} + +static void piix3_set_irq_level (PIIX3State *piix3,int pirq,int level) +{ +int pic_irq; + + pic_irq = piix3->dev.config[PIIX_PIRQC + pirq]; +if (pic_irq >=PIIX_NUM_PIC_IRQS ) { +return ; + } + +piix3_set_irq_level_internal (piix3, pirq, level);piix3_set_irq_pic (piix3, pic_irq); }
@@ -527,7 +539,17 @@ static void piix3_reset(void *opaque)static int piix3_post_load (void *opaque,int version_id) {PIIX3State *piix3 = opaque; -piix3_update_irq_levels (piix3); +int pirq; + +/* Update irq levels without raising an interrupt which +could be caused by piix3_update_irq_levels function. +Raising an irq will switch the system to the state +different to the saved one. */ + piix3->pic_levels =0 ; +for (pirq =0 ; pirq <PIIX_NUM_PIRQS ; pirq++) { +piix3_set_irq_level_internal (piix3, pirq, +pci_bus_get_irq_level (piix3->dev.bus, pirq)); + }return 0 ; }
PATCH v2 11/12 mc146818rtc: add missed field to vmstate
In reply to Pavel DovgalyukThis patch adds irq_reinject_on_ack_count field to VMState to allow correct saving/loading the state of MC146818 RTC.
--- hw/timer/mc146818rtc.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-)
hw/timer/mc146818rtc.c +25 -0
@@ -733,6 +733,22 @@ static int rtc_post_load(void *opaque, int version_id)return 0 ; } +static const VMStateDescription vmstate_rtc_irq_reinject_on_ack_count = { + .name ="irq_reinject_on_ack_count" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_UINT16 (irq_reinject_on_ack_count, RTCState), +VMSTATE_END_OF_LIST () + } +}; + +static bool rtc_irq_reinject_on_ack_count_needed (void *opaque) +{ +RTCState *s = (RTCState *)opaque; +return s->irq_reinject_on_ack_count !=0 ; +} +static const VMStateDescription vmstate_rtc = { .name ="mc146818rtc" , .version_id =3 ,
@@ -753,6 +769,14 @@ static const VMStateDescription vmstate_rtc = { VMSTATE_TIMER_V(update_timer, RTCState, 3), VMSTATE_UINT64_V(next_alarm_time, RTCState, 3),VMSTATE_END_OF_LIST () + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_rtc_irq_reinject_on_ack_count, + .needed = rtc_irq_reinject_on_ack_count_needed, + }, { +/* empty */ + } } };
@@ -785,6 +809,7 @@ static void rtc_reset(void *opaque) s->cmos_data[RTC_REG_B ] &= ~(REG_B_PIE |REG_B_AIE |REG_B_SQWE ); s->cmos_data[RTC_REG_C ] &= ~(REG_C_UF |REG_C_IRQF |REG_C_PF |REG_C_AF ); + s->irq_reinject_on_ack_count =0 ;check_update_timer (s);qemu_irq_lower (s->irq);
PATCH v2 12/12 pl031: add missed field to vmstate
In reply to Pavel DovgalyukThis patch adds timer which uses virtual clock to the VMState. Such timers are required for saving because virtual clock is the part of the virtual machine state.
--- hw/timer/pl031.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
hw/timer/pl031.c +2 -1
@@ -230,12 +230,13 @@ static int pl031_post_load(void *opaque, int version_id)static const VMStateDescription vmstate_pl031 = { .name ="pl031" , - .version_id =1 , + .version_id =2 , .minimum_version_id =1 , .pre_save = pl031_pre_save, .post_load = pl031_post_load, .fields = (VMStateField []) {VMSTATE_UINT32 (tick_offset_vmstate, PL031State), +VMSTATE_TIMER_V (timer, PL031State,2 ),VMSTATE_UINT32 (mr, PL031State),VMSTATE_UINT32 (lr, PL031State),VMSTATE_UINT32 (cr, PL031State),
Re: [Qemu-devel] [PATCH v2 12/12] pl031: add missed field to vmstate
Quoted 18 lines · Pavel Dovgalyuk
This patch adds timer which uses virtual clock to the VMState. Such timers are required for saving because virtual clock is the part of the virtual machine state.
Signed-off-by Pavel Dovgalyuk <[email protected]>--- hw/timer/pl031.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)hw/timer/pl031.c +0
-1@@ -230,12 +230,13 @@ static int pl031_post_load(void *opaque, int version_id)static const VMStateDescription vmstate_pl031 = { .name ="pl031" , - .version_id =1 ,
hw/timer/pl031.c static int pl031_post_load(void *opaque, int version_id) · line 242
Quoted 10 lines
hw/timer/pl031.c +2
-0+ .version_id = 2, .minimum_version_id = 1, .pre_save = pl031_pre_save, .post_load = pl031_post_load, .fields = (VMStateField []) {VMSTATE_UINT32 (tick_offset_vmstate, PL031State), +VMSTATE_TIMER_V (timer, PL031State,2 ),VMSTATE_UINT32 (mr, PL031State),VMSTATE_UINT32 (lr, PL031State),VMSTATE_UINT32 (cr, PL031State),
Looking at the code I'm not sure this patch is required. It looks like the intention is that the migrated state for the timer is in the tick_offset_vmstate: we have a pre-save hook that sets up that field, and then the post-load hook calls pl031_set_alarm() which will always completely reinitialise s->timer using timer_del() or timer_mod(). What am I missing?
thanks
-- PMM
Re: [Qemu-devel] [PATCH v2 12/12] pl031: add missed field to vmstate
Quoted 31 lines
From: Peter Maydell [mailto:[email protected]]
Quoted 18 lines · Pavel Dovgalyuk
This patch adds timer which uses virtual clock to the VMState. Such timers are required for saving because virtual clock is the part of the virtual machine state.
Signed-off-by Pavel Dovgalyuk <[email protected]>--- hw/timer/pl031.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)hw/timer/pl031.c +0
-1@@ -230,12 +230,13 @@ static int pl031_post_load(void *opaque, int version_id)static const VMStateDescription vmstate_pl031 = { .name ="pl031" , - .version_id =1 ,hw/timer/pl031.c static int pl031_post_load(void *opaque, int version_id) · line 242
Quoted 10 lines
hw/timer/pl031.c +2
-0+ .version_id = 2, .minimum_version_id = 1, .pre_save = pl031_pre_save, .post_load = pl031_post_load, .fields = (VMStateField []) {VMSTATE_UINT32 (tick_offset_vmstate, PL031State), +VMSTATE_TIMER_V (timer, PL031State,2 ),VMSTATE_UINT32 (mr, PL031State),VMSTATE_UINT32 (lr, PL031State),VMSTATE_UINT32 (cr, PL031State),
Quoted 7 lines
Looking at the code I'm not sure this patch is required. It looks like the intention is that the migrated state for the timer is in the
tick_offset_vmstate: we have a pre-save hook that sets up that field, and then the post-load hook callspl031_set_alarm()which will always completely reinitialises->timerusingtimer_del()ortimer_mod(). What am I missing?
You are right, this is replay-specific patch, I'll remove it from this series.
Pavel Dovgalyuk
Il 28/08/2014 13:18, Pavel Dovgalyuk ha scritto:
Quoted 30 lines
This set of patches is related to migration issues in hardware devices. Some of the devices had fields in their states that didn't saved and restored. These patches add missed fields to the new subsections of the vmstates. For several devices (like integratorcp) the patches add new vmstates, that didn't exist at all.
v2 changes:
* Used vmsd field of device classes instead ofvm_state_registerfunction (as suggested by Paolo Bonzini)
* Added more comments describing piix migration fix (as suggested by Paolo Bonzini)
* Some fields' initializations moved frompre_loadto reset functions (as suggested by Paolo Bonzini)
* Removed patch of the rtl8139 module, because irq problem is solved by another patches (as suggested by Paolo Bonzini)
* Changed paddr synchronization in vapic (as suggested by Paolo Bonzini)---
Pavel Dovgalyuk (12):
integratorcp: adding vmstate for save/restore
pcspk: adding vmstate for save/restore
fdc: adding vmstate for save/restore
parallel: adding vmstate for save/restore
serial: fixing vmstate for save/restore
apic_common: fixing loading vmstate
apic_common:vapic_paddrsynchronization fix
hpet: fixing saving and loading process
pckbd: adding new fields to vmstate
piix: do not raise irq while loading vmstate
mc146818rtc: add missed field to vmstate
pl031: add missed field to vmstate
Quoted 13 lines
hw/arm/integratorcp.c | 38 +++++++ hw/audio/pcspk.c | 17 +++ hw/block/fdc.c | 74 +++++++++++++ hw/char/parallel.c | 19 +++ hw/char/serial.c | 265 ++++++++++++++++++++++++++++++++++++++++-------- hw/input/pckbd.c | 51 +++++++++ hw/intc/apic_common.c | 34 ++++++ hw/pci-host/piix.c | 26 ++++- hw/timer/hpet.c | 15 --- hw/timer/mc146818rtc.c | 25 +++++ hw/timer/pl031.c | 3 - 11 files changed, 502 insertions(+), 65 deletions(-)
Peter, can you look at patches 1 and 12?
Paolo