diff options
author | Jan Kiszka <jan.kiszka@web.de> | 2009-06-27 09:27:22 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-06-29 14:18:08 -0500 |
commit | 059b8b1eb68c8fe65604baba7bb977d1ec120f96 (patch) | |
tree | 34c9c909f78a4344e364661d2ff5b5fd1a22e778 | |
parent | 3a31f36a07d8d6bf49a7da24c5570153de0fd79e (diff) |
KVM: x86: Refactor persistent CPU state
This patch aligns the KVM-related layout and encoding of the CPU state
to be saved to disk or migrated with qemu-kvm. The major differences are
reordering of fields and a compressed interrupt_bitmap into a single
number as there can be no more than one pending IRQ at a time.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r-- | target-i386/machine.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/target-i386/machine.c b/target-i386/machine.c index bb8b9dbd5a..259302cb0e 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -28,7 +28,8 @@ void cpu_save(QEMUFile *f, void *opaque) uint16_t fptag, fpus, fpuc, fpregs_format; uint32_t hflags; int32_t a20_mask; - int i; + int32_t pending_irq; + int i, bit; cpu_synchronize_state(env, 0); @@ -141,11 +142,21 @@ void cpu_save(QEMUFile *f, void *opaque) qemu_put_be64s(f, &env->mtrr_var[i].mask); } - for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) { - qemu_put_be64s(f, &env->interrupt_bitmap[i]); + /* KVM-related states */ + + /* There can only be one pending IRQ set in the bitmap at a time, so try + to find it and save its number instead (-1 for none). */ + pending_irq = -1; + for (i = 0; i < ARRAY_SIZE(env->interrupt_bitmap); i++) { + bit = ffsll(env->interrupt_bitmap[i]); + if (bit) { + pending_irq = i * 64 + bit - 1; + break; + } } - qemu_put_be64s(f, &env->tsc); + qemu_put_sbe32s(f, &pending_irq); qemu_put_be32s(f, &env->mp_state); + qemu_put_be64s(f, &env->tsc); } #ifdef USE_X86LDOUBLE @@ -179,6 +190,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) uint32_t hflags; uint16_t fpus, fpuc, fptag, fpregs_format; int32_t a20_mask; + int32_t pending_irq; if (version_id < 3 || version_id > CPU_SAVE_VERSION) return -EINVAL; @@ -324,12 +336,16 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be64s(f, &env->mtrr_var[i].mask); } } + if (version_id >= 9) { - for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) { - qemu_get_be64s(f, &env->interrupt_bitmap[i]); + qemu_get_sbe32s(f, &pending_irq); + memset(&env->interrupt_bitmap, 0, sizeof(env->interrupt_bitmap)); + if (pending_irq >= 0) { + env->interrupt_bitmap[pending_irq / 64] |= + (uint64_t)1 << (pending_irq % 64); } - qemu_get_be64s(f, &env->tsc); qemu_get_be32s(f, &env->mp_state); + qemu_get_be64s(f, &env->tsc); } /* XXX: ensure compatiblity for halted bit ? */ |