Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1K8w3A-0001nc-Hv for qemu-devel@nongnu.org; Wed, 18 Jun 2008 07:42:04 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1K8w39-0001nQ-JK for qemu-devel@nongnu.org; Wed, 18 Jun 2008 07:42:04 -0400 Received: from [199.232.76.173] (port=37219 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K8w39-0001nN-FX for qemu-devel@nongnu.org; Wed, 18 Jun 2008 07:42:03 -0400 Received: from gecko.sbs.de ([194.138.37.40]:17687) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1K8w38-0005m1-Q5 for qemu-devel@nongnu.org; Wed, 18 Jun 2008 07:42:03 -0400 Received: from mail1.sbs.de (localhost [127.0.0.1]) by gecko.sbs.de (8.12.11.20060308/8.12.11) with ESMTP id m5IBfuP7008677 for ; Wed, 18 Jun 2008 13:41:56 +0200 Received: from [192.168.1.100] ([139.21.92.145]) by mail1.sbs.de (8.12.11.20060308/8.12.11) with ESMTP id m5IBftpo019100 for ; Wed, 18 Jun 2008 13:41:55 +0200 Message-ID: <4858F482.9050903@siemens.com> Date: Wed, 18 Jun 2008 13:41:54 +0200 From: Jan Kiszka MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH] save/restore interrupt_request across snapshots Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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. Signed-off-by: Jan Kiszka --- 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(-) Index: b/hw/pc.c =================================================================== --- a/hw/pc.c +++ b/hw/pc.c @@ -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); Index: b/target-i386/machine.c =================================================================== --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -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; Index: b/hw/etraxfs.c =================================================================== --- a/hw/etraxfs.c +++ b/hw/etraxfs.c @@ -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 */ Index: b/hw/sun4m.c =================================================================== --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -404,7 +404,7 @@ static void sun4m_hw_init(const struct h qemu_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 h cpu_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 s qemu_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; } Index: b/hw/sun4u.c =================================================================== --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -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); Index: b/target-arm/cpu.h =================================================================== --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -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 Index: b/target-arm/machine.c =================================================================== --- a/target-arm/machine.c +++ b/target-arm/machine.c @@ -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; } Index: b/target-cris/machine.c =================================================================== --- a/target-cris/machine.c +++ b/target-cris/machine.c @@ -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; } Index: b/target-sparc/machine.c =================================================================== --- a/target-sparc/machine.c +++ b/target-sparc/machine.c @@ -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; }