Commit 059b8b1eb68c8fe65604baba7bb977d1ec120f96

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent 3a31f36a

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>
Showing 1 changed file with 23 additions and 7 deletions
target-i386/machine.c
... ... @@ -28,7 +28,8 @@ void cpu_save(QEMUFile *f, void *opaque)
28 28 uint16_t fptag, fpus, fpuc, fpregs_format;
29 29 uint32_t hflags;
30 30 int32_t a20_mask;
31   - int i;
  31 + int32_t pending_irq;
  32 + int i, bit;
32 33  
33 34 cpu_synchronize_state(env, 0);
34 35  
... ... @@ -141,11 +142,21 @@ void cpu_save(QEMUFile *f, void *opaque)
141 142 qemu_put_be64s(f, &env->mtrr_var[i].mask);
142 143 }
143 144  
144   - for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) {
145   - qemu_put_be64s(f, &env->interrupt_bitmap[i]);
  145 + /* KVM-related states */
  146 +
  147 + /* There can only be one pending IRQ set in the bitmap at a time, so try
  148 + to find it and save its number instead (-1 for none). */
  149 + pending_irq = -1;
  150 + for (i = 0; i < ARRAY_SIZE(env->interrupt_bitmap); i++) {
  151 + bit = ffsll(env->interrupt_bitmap[i]);
  152 + if (bit) {
  153 + pending_irq = i * 64 + bit - 1;
  154 + break;
  155 + }
146 156 }
147   - qemu_put_be64s(f, &env->tsc);
  157 + qemu_put_sbe32s(f, &pending_irq);
148 158 qemu_put_be32s(f, &env->mp_state);
  159 + qemu_put_be64s(f, &env->tsc);
149 160 }
150 161  
151 162 #ifdef USE_X86LDOUBLE
... ... @@ -179,6 +190,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
179 190 uint32_t hflags;
180 191 uint16_t fpus, fpuc, fptag, fpregs_format;
181 192 int32_t a20_mask;
  193 + int32_t pending_irq;
182 194  
183 195 if (version_id < 3 || version_id > CPU_SAVE_VERSION)
184 196 return -EINVAL;
... ... @@ -324,12 +336,16 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
324 336 qemu_get_be64s(f, &env->mtrr_var[i].mask);
325 337 }
326 338 }
  339 +
327 340 if (version_id >= 9) {
328   - for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) {
329   - qemu_get_be64s(f, &env->interrupt_bitmap[i]);
  341 + qemu_get_sbe32s(f, &pending_irq);
  342 + memset(&env->interrupt_bitmap, 0, sizeof(env->interrupt_bitmap));
  343 + if (pending_irq >= 0) {
  344 + env->interrupt_bitmap[pending_irq / 64] |=
  345 + (uint64_t)1 << (pending_irq % 64);
330 346 }
331   - qemu_get_be64s(f, &env->tsc);
332 347 qemu_get_be32s(f, &env->mp_state);
  348 + qemu_get_be64s(f, &env->tsc);
333 349 }
334 350  
335 351 /* XXX: ensure compatiblity for halted bit ? */
... ...