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