save/restore interrupt_request across snapshots
PATCH 1/1 save/restore interrupt_request across snapshots
Save interrupt_request state along with the cpu snapshot and restore it properly. This also solves the bug that pending interrupts before invocation of qemu_loadvm_state can tunnel into the resumed guest, causing invalid IRQs there.
Implementation covers ARM, CRIS, x86, and SPARC, ie. those archs that support snapshotting so far.
--- hw/etraxfs.c | 2 +- hw/pc.c | 2 +- hw/sun4m.c | 6 +++--- hw/sun4u.c | 2 +- target-arm/cpu.h | 2 +- target-arm/machine.c | 10 +++++++++- target-cris/machine.c | 8 ++++++++ target-i386/machine.c | 9 ++++++++- target-sparc/machine.c | 9 ++++++++- 9 files changed, 40 insertions(+), 10 deletions(-)
hw/pc.c +1 -1
@@ -766,7 +766,7 @@ static void pc_init1(ram_addr_t ram_size/* XXX: enable it in all cases */ env->cpuid_features |=CPUID_APIC ; } -register_savevm ("cpu" , i,5 , cpu_save, cpu_load, env); +register_savevm ("cpu" , i,6 , cpu_save, cpu_load, env);qemu_register_reset (main_cpu_reset, env);if (pci_enabled) {apic_init (env);
target-i386/machine.c +8 -1
@@ -135,6 +135,8 @@ void cpu_save(QEMUFile *f, void *opaque)qemu_put_be16s (f, &env->intercept_dr_write);qemu_put_be32s (f, &env->intercept_exceptions);qemu_put_8s (f, &env->v_tpr); + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }#ifdef USE_X86LDOUBLE
@@ -169,7 +171,7 @@ int cpu_load(QEMUFile *f, void *opaque,uint16_t fpus, fpuc, fptag, fpregs_format;int32_t a20_mask; -if (version_id !=3 && version_id !=4 && version_id !=5 ) +if (version_id <3 || version_id >6 )return -EINVAL ;for (i =0 ; i <CPU_NB_REGS ; i++)qemu_get_betls (f, &env->regs[i]);
@@ -292,6 +294,11 @@ int cpu_load(QEMUFile *f, void *opaque,qemu_get_be32s (f, &env->intercept_exceptions);qemu_get_8s (f, &env->v_tpr); } +if (version_id >=6 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + }/* XXX: ensure compatiblity for halted bit ? */ /* XXX: compute redundant hflags bits */ env->hflags = hflags;
hw/etraxfs.c +1 -1
@@ -67,7 +67,7 @@ void bareetraxfs_init (ram_addr_t ram_si cpu_model ="crisv32" ; } env =cpu_init (cpu_model); -register_savevm ("cpu" ,0 ,1 , cpu_save, cpu_load, env); +register_savevm ("cpu" ,0 ,2 , cpu_save, cpu_load, env);qemu_register_reset (main_cpu_reset, env);/* allocate RAM */
hw/sun4m.c +3 -3
@@ -404,7 +404,7 @@ static void sun4m_hw_init(const struct hqemu_register_reset (secondary_cpu_reset, env); env->halted =1 ; } -register_savevm ("cpu" , i,4 , cpu_save, cpu_load, env); +register_savevm ("cpu" , i,5 , cpu_save, cpu_load, env); cpu_irqs[i] =qemu_allocate_irqs (cpu_set_irq, envs[i],MAX_PILS ); env->prom_addr = hwdef->slavio_base; }
@@ -579,7 +579,7 @@ static void sun4c_hw_init(const struct hcpu_sparc_set_id (env,0 );qemu_register_reset (main_cpu_reset, env); -register_savevm ("cpu" ,0 ,4 , cpu_save, cpu_load, env); +register_savevm ("cpu" ,0 ,5 , cpu_save, cpu_load, env); cpu_irqs =qemu_allocate_irqs (cpu_set_irq, env,MAX_PILS ); env->prom_addr = hwdef->slavio_base;
@@ -1391,7 +1391,7 @@ static void sun4d_hw_init(const struct sqemu_register_reset (secondary_cpu_reset, env); env->halted =1 ; } -register_savevm ("cpu" , i,4 , cpu_save, cpu_load, env); +register_savevm ("cpu" , i,5 , cpu_save, cpu_load, env); cpu_irqs[i] =qemu_allocate_irqs (cpu_set_irq, envs[i],MAX_PILS ); env->prom_addr = hwdef->slavio_base; }
hw/sun4u.c +1 -1
@@ -260,7 +260,7 @@ static void sun4u_init(ram_addr_t RAM_si bh =qemu_bh_new (hstick_irq, env); env->hstick =ptimer_init (bh);ptimer_set_period (env->hstick,1ULL ); -register_savevm ("cpu" ,0 ,4 , cpu_save, cpu_load, env); +register_savevm ("cpu" ,0 ,5 , cpu_save, cpu_load, env);qemu_register_reset (main_cpu_reset, env);main_cpu_reset (env);
target-arm/cpu.h +1 -1
@@ -397,7 +397,7 @@ void cpu_arm_set_cp_io(CPUARMState *env,#define cpu_signal_handler cpu_arm_signal_handler#define cpu_list arm_cpu_list -#define ARM_CPU_SAVE_VERSION 1 +#define ARM_CPU_SAVE_VERSION 2/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-arm/machine.c +9 -1
@@ -113,6 +113,8 @@ void cpu_save(QEMUFile *f, void *opaque)qemu_put_be32 (f, env->v7m.current_sp);qemu_put_be32 (f, env->v7m.exception); } + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }int cpu_load (QEMUFile *f,void *opaque,int version_id)
@@ -120,7 +122,7 @@ int cpu_load(QEMUFile *f, void *opaque,CPUARMState *env = (CPUARMState *)opaque;int i; -if (version_id !=ARM_CPU_SAVE_VERSION ) +if (version_id <1 || version_id >ARM_CPU_SAVE_VERSION )return -EINVAL ;for (i =0 ; i <16 ; i++) {
@@ -209,6 +211,12 @@ int cpu_load(QEMUFile *f, void *opaque, env->v7m.exception =qemu_get_be32 (f); } +if (version_id >=2 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + } +return 0 ; }
target-cris/machine.c +8 -0
@@ -47,6 +47,8 @@ void cpu_save(QEMUFile *f, void *opaque) } } } + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }int cpu_load (QEMUFile *f,void *opaque,int version_id)
@@ -91,5 +93,11 @@ int cpu_load(QEMUFile *f, void *opaque, } } +if (version_id >=2 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + } +return 0 ; }
target-sparc/machine.c +8 -1
@@ -58,6 +58,8 @@ void cpu_save(QEMUFile *f, void *opaque)for (i =0 ; i <16 ; i++)qemu_put_be32s (f, &env->mmuregs[i]);#endif + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }int cpu_load (QEMUFile *f,void *opaque,int version_id)
@@ -66,7 +68,7 @@ int cpu_load(QEMUFile *f, void *opaque,int i;uint32_t tmp; -if (version_id !=4 ) +if (version_id <4 || version_id >5 )return -EINVAL ;for (i =0 ; i <8 ; i++)qemu_get_betls (f, &env->gregs[i]);
@@ -99,6 +101,11 @@ int cpu_load(QEMUFile *f, void *opaque,for (i =0 ; i <16 ; i++)qemu_get_be32s (f, &env->mmuregs[i]);#endif +if (version_id >=5 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + }tlb_flush (env,1 );return 0 ; }
PATCH RESEND 1/1 save/restore interrupt_request across snapshots
[ Rebased to latest SVN ]
Save interrupt_request state along with the cpu snapshot and restore it properly. This also solves the bug that pending interrupts before invocation of qemu_loadvm_state can tunnel into the resumed guest, causing invalid IRQs there.
Implementation covers ARM, CRIS, x86, and SPARC, ie. those archs that support snapshotting so far.
--- target-arm/cpu.h | 2 +- target-arm/machine.c | 10 +++++++++- target-cris/cpu.h | 2 +- target-cris/machine.c | 11 +++++++++++ target-i386/cpu.h | 2 +- target-i386/machine.c | 9 ++++++++- target-sparc/cpu.h | 2 +- target-sparc/machine.c | 9 ++++++++- 8 files changed, 40 insertions(+), 7 deletions(-)
target-i386/machine.c +8 -1
@@ -135,6 +135,8 @@ void cpu_save(QEMUFile *f, void *opaque)qemu_put_be16s (f, &env->intercept_dr_write);qemu_put_be32s (f, &env->intercept_exceptions);qemu_put_8s (f, &env->v_tpr); + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }#ifdef USE_X86LDOUBLE
@@ -169,7 +171,7 @@ int cpu_load(QEMUFile *f, void *opaque,uint16_t fpus, fpuc, fptag, fpregs_format;int32_t a20_mask; -if (version_id !=3 && version_id !=4 && version_id !=5 ) +if (version_id <3 || version_id >CPU_SAVE_VERSION )return -EINVAL ;for (i =0 ; i <CPU_NB_REGS ; i++)qemu_get_betls (f, &env->regs[i]);
@@ -292,6 +294,11 @@ int cpu_load(QEMUFile *f, void *opaque,qemu_get_be32s (f, &env->intercept_exceptions);qemu_get_8s (f, &env->v_tpr); } +if (version_id >=6 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + }/* XXX: ensure compatiblity for halted bit ? */ /* XXX: compute redundant hflags bits */ env->hflags = hflags;
target-arm/cpu.h +1 -1
@@ -397,7 +397,7 @@ void cpu_arm_set_cp_io(CPUARMState *env,#define cpu_signal_handler cpu_arm_signal_handler#define cpu_list arm_cpu_list -#define CPU_SAVE_VERSION 1 +#define CPU_SAVE_VERSION 2/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-arm/machine.c +9 -1
@@ -113,6 +113,8 @@ void cpu_save(QEMUFile *f, void *opaque)qemu_put_be32 (f, env->v7m.current_sp);qemu_put_be32 (f, env->v7m.exception); } + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }int cpu_load (QEMUFile *f,void *opaque,int version_id)
@@ -120,7 +122,7 @@ int cpu_load(QEMUFile *f, void *opaque,CPUARMState *env = (CPUARMState *)opaque;int i; -if (version_id !=CPU_SAVE_VERSION ) +if (version_id <1 || version_id >CPU_SAVE_VERSION )return -EINVAL ;for (i =0 ; i <16 ; i++) {
@@ -209,6 +211,12 @@ int cpu_load(QEMUFile *f, void *opaque, env->v7m.exception =qemu_get_be32 (f); } +if (version_id >=2 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + } +return 0 ; }
target-cris/machine.c +11 -0
@@ -47,6 +47,8 @@ void cpu_save(QEMUFile *f, void *opaque) } } } + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }int cpu_load (QEMUFile *f,void *opaque,int version_id)
@@ -56,6 +58,9 @@ int cpu_load(QEMUFile *f, void *opaque,int s;int mmu; +if (version_id <1 || version_id >CPU_SAVE_VERSION ) +return -EINVAL ; +for (i =0 ; i <16 ; i++) env->regs[i] =qemu_get_be32 (f);for (i =0 ; i <16 ; i++)
@@ -91,5 +96,11 @@ int cpu_load(QEMUFile *f, void *opaque, } } +if (version_id >=2 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + } +return 0 ; }
target-sparc/machine.c +8 -1
@@ -58,6 +58,8 @@ void cpu_save(QEMUFile *f, void *opaque)for (i =0 ; i <16 ; i++)qemu_put_be32s (f, &env->mmuregs[i]);#endif + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }int cpu_load (QEMUFile *f,void *opaque,int version_id)
@@ -66,7 +68,7 @@ int cpu_load(QEMUFile *f, void *opaque,int i;uint32_t tmp; -if (version_id !=4 ) +if (version_id <4 || version_id >CPU_SAVE_VERSION )return -EINVAL ;for (i =0 ; i <8 ; i++)qemu_get_betls (f, &env->gregs[i]);
@@ -99,6 +101,11 @@ int cpu_load(QEMUFile *f, void *opaque,for (i =0 ; i <16 ; i++)qemu_get_be32s (f, &env->mmuregs[i]);#endif +if (version_id >=5 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + }tlb_flush (env,1 );return 0 ; }
target-cris/cpu.h +1 -1
@@ -210,7 +210,7 @@ enum {#define cpu_gen_code cpu_cris_gen_code#define cpu_signal_handler cpu_cris_signal_handler -#define CPU_SAVE_VERSION 1 +#define CPU_SAVE_VERSION 2/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-i386/cpu.h +1 -1
@@ -726,7 +726,7 @@ static inline int cpu_get_time_fast(void#define cpu_signal_handler cpu_x86_signal_handler#define cpu_list x86_cpu_list -#define CPU_SAVE_VERSION 5 +#define CPU_SAVE_VERSION 6/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-sparc/cpu.h +1 -1
@@ -388,7 +388,7 @@ void cpu_check_irqs(CPUSPARCState *env);#define cpu_signal_handler cpu_sparc_signal_handler#define cpu_list sparc_cpu_list -#define CPU_SAVE_VERSION 4 +#define CPU_SAVE_VERSION 5/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _user
Quoted 4 lines
Save
interrupt_requeststate along with the cpu snapshot and restore it properly. This also solves the bug that pending interrupts before invocation ofqemu_loadvm_statecan tunnel into the resumed guest, causing invalid IRQs there.
I just checked in a patch which is a superset of this functionality.
Paul
Quoted 6 lines · Paul Brook
Quoted 4 lines
Save
interrupt_requeststate along with the cpu snapshot and restore it properly. This also solves the bug that pending interrupts before invocation ofqemu_loadvm_statecan tunnel into the resumed guest, causing invalid IRQs there.I just checked in a patch which is a superset of this functionality.
Nice cleanups!
( Well, except for
if (version_id != 3 && version_id != 4 && version_id != 5
&& version_id != 6):-> )
And after fixing this typo, it also works nicely:
exec.c +1 -1
@@ -463,7 +463,7 @@ static int cpu_common_load(QEMUFile *f,return -EINVAL ;qemu_get_be32s (f, &env->halted); -qemu_put_be32s (f, &env->interrupt_request); +qemu_get_be32s (f, &env->interrupt_request);tlb_flush (env,1 );return 0 ;
Jan
Quoted 8 lines · Jan Kiszka
Quoted 6 lines · Paul Brook
Quoted 4 lines
Save
interrupt_requeststate along with the cpu snapshot and restore it properly. This also solves the bug that pending interrupts before invocation ofqemu_loadvm_statecan tunnel into the resumed guest, causing invalid IRQs there.I just checked in a patch which is a superset of this functionality.
Quoted 8 lines
Nice cleanups!
( Well, except for
if (version_id != 3 && version_id != 4 && version_id != 5 && version_id != 6):-> )
I was tempted to rip it out altogether, and replace with
if (version_id != CPU_SAVE_VERSION)
IMHO explicitly enumerating all the versions we claim to be able to load isn't a bad thing.
exec.c static int cpu_common_load(QEMUFile *f, · line 466
Quoted 4 lines
And after fixing this typo, it also works nicely:
qemu_get_be32s(f, &env->halted);exec.c +1
-1-qemu_put_be32s (f, &env->interrupt_request); +qemu_get_be32s (f, &env->interrupt_request);
Good catch, thanks.
Paul
Quoted 10 lines · Jan Kiszka
[ Rebased to latest SVN ]
Save
interrupt_requeststate along with the cpu snapshot and restore it properly. This also solves the bug that pending interrupts before invocation ofqemu_loadvm_statecan tunnel into the resumed guest, causing invalid IRQs there.Implementation covers ARM, CRIS, x86, and SPARC, ie. those archs that support snapshotting so far.
Quoted 6 lines
Signed-off-by Jan Kiszka <[email protected]>--- target-arm/cpu.h | 2 +- target-arm/machine.c | 10 +++++++++- target-cris/cpu.h | 2 +- target-cris/machine.c | 11 +++++++++++
CRIS part look fine.
Best regards,
E
Quoted 198 lines
target-i386/cpu.h | 2 +- target-i386/machine.c | 9 ++++++++- target-sparc/cpu.h | 2 +- target-sparc/machine.c | 9 ++++++++- 8 files changed, 40 insertions(+), 7 deletions(-)Index:
b/target-i386/machine.c
===================================================================target-i386/machine.c +8
-1@@ -135,6 +135,8 @@ void cpu_save(QEMUFile *f, void *opaque)qemu_put_be16s (f, &env->intercept_dr_write);qemu_put_be32s (f, &env->intercept_exceptions);qemu_put_8s (f, &env->v_tpr); + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }#ifdef USE_X86LDOUBLE @@ -169,7 +171,7 @@ int cpu_load(QEMUFile *f, void *opaque,uint16_t fpus, fpuc, fptag, fpregs_format;int32_t a20_mask; -if (version_id !=3 && version_id !=4 && version_id !=5 ) +if (version_id <3 || version_id >CPU_SAVE_VERSION )return -EINVAL ;for (i =0 ; i <CPU_NB_REGS ; i++)qemu_get_betls (f, &env->regs[i]);@@ -292,6 +294,11 @@ int cpu_load(QEMUFile *f, void *opaque,qemu_get_be32s (f, &env->intercept_exceptions);qemu_get_8s (f, &env->v_tpr); } +if (version_id >=6 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + }/* XXX: ensure compatiblity for halted bit ? */ /* XXX: compute redundant hflags bits */ env->hflags = hflags;Index:
b/target-arm/cpu.h
===================================================================target-arm/cpu.h +1
-1@@ -397,7 +397,7 @@ void cpu_arm_set_cp_io(CPUARMState *env,#define cpu_signal_handler cpu_arm_signal_handler#define cpu_list arm_cpu_list -#define CPU_SAVE_VERSION 1 +#define CPU_SAVE_VERSION 2/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernelIndex:
b/target-arm/machine.c
===================================================================target-arm/machine.c +9
-1@@ -113,6 +113,8 @@ void cpu_save(QEMUFile *f, void *opaque)qemu_put_be32 (f, env->v7m.current_sp);qemu_put_be32 (f, env->v7m.exception); } + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }int cpu_load (QEMUFile *f,void *opaque,int version_id)@@ -120,7 +122,7 @@ int cpu_load(QEMUFile *f, void *opaque,CPUARMState *env = (CPUARMState *)opaque;int i; -if (version_id !=CPU_SAVE_VERSION ) +if (version_id <1 || version_id >CPU_SAVE_VERSION )return -EINVAL ;for (i =0 ; i <16 ; i++) {@@ -209,6 +211,12 @@ int cpu_load(QEMUFile *f, void *opaque, env->v7m.exception =qemu_get_be32 (f); } +if (version_id >=2 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + } +return 0 ; }Index:
b/target-cris/machine.c
===================================================================target-cris/machine.c +11
-0@@ -47,6 +47,8 @@ void cpu_save(QEMUFile *f, void *opaque) } } } + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }int cpu_load (QEMUFile *f,void *opaque,int version_id)@@ -56,6 +58,9 @@ int cpu_load(QEMUFile *f, void *opaque,int s;int mmu; +if (version_id <1 || version_id >CPU_SAVE_VERSION ) +return -EINVAL ; +for (i =0 ; i <16 ; i++) env->regs[i] =qemu_get_be32 (f);for (i =0 ; i <16 ; i++)@@ -91,5 +96,11 @@ int cpu_load(QEMUFile *f, void *opaque, } } +if (version_id >=2 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + } +return 0 ; }Index:
b/target-sparc/machine.c
===================================================================target-sparc/machine.c +8
-1@@ -58,6 +58,8 @@ void cpu_save(QEMUFile *f, void *opaque)for (i =0 ; i <16 ; i++)qemu_put_be32s (f, &env->mmuregs[i]);#endif + +qemu_put_be32s (f, (uint32_t *)&env->interrupt_request); }int cpu_load (QEMUFile *f,void *opaque,int version_id)@@ -66,7 +68,7 @@ int cpu_load(QEMUFile *f, void *opaque,int i;uint32_t tmp; -if (version_id !=4 ) +if (version_id <4 || version_id >CPU_SAVE_VERSION )return -EINVAL ;for (i =0 ; i <8 ; i++)qemu_get_betls (f, &env->gregs[i]);@@ -99,6 +101,11 @@ int cpu_load(QEMUFile *f, void *opaque,for (i =0 ; i <16 ; i++)qemu_get_be32s (f, &env->mmuregs[i]);#endif +if (version_id >=5 ) { +qemu_get_be32s (f, (uint32_t *)&env->interrupt_request); + }else { + env->interrupt_request =0 ; + }tlb_flush (env,1 );return 0 ; }Index:
b/target-cris/cpu.h
===================================================================target-cris/cpu.h +1
-1@@ -210,7 +210,7 @@ enum {#define cpu_gen_code cpu_cris_gen_code#define cpu_signal_handler cpu_cris_signal_handler -#define CPU_SAVE_VERSION 1 +#define CPU_SAVE_VERSION 2/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernelIndex:
b/target-i386/cpu.h
===================================================================target-i386/cpu.h +1
-1@@ -726,7 +726,7 @@ static inline int cpu_get_time_fast(void#define cpu_signal_handler cpu_x86_signal_handler#define cpu_list x86_cpu_list -#define CPU_SAVE_VERSION 5 +#define CPU_SAVE_VERSION 6/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernelIndex:
b/target-sparc/cpu.h
===================================================================target-sparc/cpu.h +1
-1@@ -388,7 +388,7 @@ void cpu_check_irqs(CPUSPARCState *env);#define cpu_signal_handler cpu_sparc_signal_handler#define cpu_list sparc_cpu_list -#define CPU_SAVE_VERSION 4 +#define CPU_SAVE_VERSION 5/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _user
Signature · 2 lines
Edgar E. Iglesias Axis Communications AB