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,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 ? */ |