Commit f8d926e9cd96e52ebcfd9ffdeab83c0d5e6b9622

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent d33a1810

kvm: x86: Save/restore KVM-specific CPU states

Save and restore all so far neglected KVM-specific CPU states. Handling
the TSC stabilizes migration in KVM mode. The interrupt_bitmap and
mp_state are currently unused, but will become relevant for in-kernel
irqchip support. By including proper saving/restoring already, we avoid
having to increment CPU_SAVE_VERSION later on once again.

v2:
 - initialize mp_state runnable (for the boot CPU)

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
kvm-all.c
... ... @@ -181,6 +181,26 @@ err:
181 181 return ret;
182 182 }
183 183  
  184 +int kvm_put_mp_state(CPUState *env)
  185 +{
  186 + struct kvm_mp_state mp_state = { .mp_state = env->mp_state };
  187 +
  188 + return kvm_vcpu_ioctl(env, KVM_SET_MP_STATE, &mp_state);
  189 +}
  190 +
  191 +int kvm_get_mp_state(CPUState *env)
  192 +{
  193 + struct kvm_mp_state mp_state;
  194 + int ret;
  195 +
  196 + ret = kvm_vcpu_ioctl(env, KVM_GET_MP_STATE, &mp_state);
  197 + if (ret < 0) {
  198 + return ret;
  199 + }
  200 + env->mp_state = mp_state.mp_state;
  201 + return 0;
  202 +}
  203 +
184 204 int kvm_sync_vcpus(void)
185 205 {
186 206 CPUState *env;
... ...
... ... @@ -72,6 +72,9 @@ int kvm_vm_ioctl(KVMState *s, int type, ...);
72 72  
73 73 int kvm_vcpu_ioctl(CPUState *env, int type, ...);
74 74  
  75 +int kvm_get_mp_state(CPUState *env);
  76 +int kvm_put_mp_state(CPUState *env);
  77 +
75 78 /* Arch specific hooks */
76 79  
77 80 int kvm_arch_post_run(CPUState *env, struct kvm_run *run);
... ...
target-i386/cpu.h
... ... @@ -669,6 +669,7 @@ typedef struct CPUX86State {
669 669  
670 670 /* For KVM */
671 671 uint64_t interrupt_bitmap[256 / 64];
  672 + uint32_t mp_state;
672 673  
673 674 /* in order to simplify APIC support, we leave this pointer to the
674 675 user */
... ... @@ -837,7 +838,7 @@ static inline int cpu_get_time_fast(void)
837 838 #define cpu_signal_handler cpu_x86_signal_handler
838 839 #define cpu_list x86_cpu_list
839 840  
840   -#define CPU_SAVE_VERSION 8
  841 +#define CPU_SAVE_VERSION 9
841 842  
842 843 /* MMU modes definitions */
843 844 #define MMU_MODE0_SUFFIX _kernel
... ...
target-i386/kvm.c
... ... @@ -126,6 +126,8 @@ int kvm_arch_init_vcpu(CPUState *env)
126 126 uint32_t limit, i, j, cpuid_i;
127 127 uint32_t unused;
128 128  
  129 + env->mp_state = KVM_MP_STATE_RUNNABLE;
  130 +
129 131 cpuid_i = 0;
130 132  
131 133 cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
... ... @@ -648,6 +650,14 @@ int kvm_arch_put_registers(CPUState *env)
648 650 if (ret < 0)
649 651 return ret;
650 652  
  653 + ret = kvm_put_mp_state(env);
  654 + if (ret < 0)
  655 + return ret;
  656 +
  657 + ret = kvm_get_mp_state(env);
  658 + if (ret < 0)
  659 + return ret;
  660 +
651 661 return 0;
652 662 }
653 663  
... ...
target-i386/machine.c
... ... @@ -140,6 +140,12 @@ void cpu_save(QEMUFile *f, void *opaque)
140 140 qemu_put_be64s(f, &env->mtrr_var[i].base);
141 141 qemu_put_be64s(f, &env->mtrr_var[i].mask);
142 142 }
  143 +
  144 + for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) {
  145 + qemu_put_be64s(f, &env->interrupt_bitmap[i]);
  146 + }
  147 + qemu_put_be64s(f, &env->tsc);
  148 + qemu_put_be32s(f, &env->mp_state);
143 149 }
144 150  
145 151 #ifdef USE_X86LDOUBLE
... ... @@ -174,8 +180,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
174 180 uint16_t fpus, fpuc, fptag, fpregs_format;
175 181 int32_t a20_mask;
176 182  
177   - if (version_id != 3 && version_id != 4 && version_id != 5
178   - && version_id != 6 && version_id != 7 && version_id != 8)
  183 + if (version_id < 3 || version_id > CPU_SAVE_VERSION)
179 184 return -EINVAL;
180 185 for(i = 0; i < CPU_NB_REGS; i++)
181 186 qemu_get_betls(f, &env->regs[i]);
... ... @@ -319,6 +324,13 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
319 324 qemu_get_be64s(f, &env->mtrr_var[i].mask);
320 325 }
321 326 }
  327 + if (version_id >= 9) {
  328 + for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) {
  329 + qemu_get_be64s(f, &env->interrupt_bitmap[i]);
  330 + }
  331 + qemu_get_be64s(f, &env->tsc);
  332 + qemu_get_be32s(f, &env->mp_state);
  333 + }
322 334  
323 335 /* XXX: ensure compatiblity for halted bit ? */
324 336 /* XXX: compute redundant hflags bits */
... ...