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,7 +28,8 @@ void cpu_save(QEMUFile *f, void *opaque)
28 uint16_t fptag, fpus, fpuc, fpregs_format; 28 uint16_t fptag, fpus, fpuc, fpregs_format;
29 uint32_t hflags; 29 uint32_t hflags;
30 int32_t a20_mask; 30 int32_t a20_mask;
31 - int i; 31 + int32_t pending_irq;
  32 + int i, bit;
32 33
33 cpu_synchronize_state(env, 0); 34 cpu_synchronize_state(env, 0);
34 35
@@ -141,11 +142,21 @@ void cpu_save(QEMUFile *f, void *opaque) @@ -141,11 +142,21 @@ void cpu_save(QEMUFile *f, void *opaque)
141 qemu_put_be64s(f, &env->mtrr_var[i].mask); 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 qemu_put_be32s(f, &env->mp_state); 158 qemu_put_be32s(f, &env->mp_state);
  159 + qemu_put_be64s(f, &env->tsc);
149 } 160 }
150 161
151 #ifdef USE_X86LDOUBLE 162 #ifdef USE_X86LDOUBLE
@@ -179,6 +190,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) @@ -179,6 +190,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
179 uint32_t hflags; 190 uint32_t hflags;
180 uint16_t fpus, fpuc, fptag, fpregs_format; 191 uint16_t fpus, fpuc, fptag, fpregs_format;
181 int32_t a20_mask; 192 int32_t a20_mask;
  193 + int32_t pending_irq;
182 194
183 if (version_id < 3 || version_id > CPU_SAVE_VERSION) 195 if (version_id < 3 || version_id > CPU_SAVE_VERSION)
184 return -EINVAL; 196 return -EINVAL;
@@ -324,12 +336,16 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) @@ -324,12 +336,16 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
324 qemu_get_be64s(f, &env->mtrr_var[i].mask); 336 qemu_get_be64s(f, &env->mtrr_var[i].mask);
325 } 337 }
326 } 338 }
  339 +
327 if (version_id >= 9) { 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 qemu_get_be32s(f, &env->mp_state); 347 qemu_get_be32s(f, &env->mp_state);
  348 + qemu_get_be64s(f, &env->tsc);
333 } 349 }
334 350
335 /* XXX: ensure compatiblity for halted bit ? */ 351 /* XXX: ensure compatiblity for halted bit ? */