Commit 059b8b1eb68c8fe65604baba7bb977d1ec120f96
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 ? */ | ... | ... |