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,6 +181,26 @@ err:
181 return ret; 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 int kvm_sync_vcpus(void) 204 int kvm_sync_vcpus(void)
185 { 205 {
186 CPUState *env; 206 CPUState *env;
@@ -72,6 +72,9 @@ int kvm_vm_ioctl(KVMState *s, int type, ...); @@ -72,6 +72,9 @@ int kvm_vm_ioctl(KVMState *s, int type, ...);
72 72
73 int kvm_vcpu_ioctl(CPUState *env, int type, ...); 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 /* Arch specific hooks */ 78 /* Arch specific hooks */
76 79
77 int kvm_arch_post_run(CPUState *env, struct kvm_run *run); 80 int kvm_arch_post_run(CPUState *env, struct kvm_run *run);
target-i386/cpu.h
@@ -669,6 +669,7 @@ typedef struct CPUX86State { @@ -669,6 +669,7 @@ typedef struct CPUX86State {
669 669
670 /* For KVM */ 670 /* For KVM */
671 uint64_t interrupt_bitmap[256 / 64]; 671 uint64_t interrupt_bitmap[256 / 64];
  672 + uint32_t mp_state;
672 673
673 /* in order to simplify APIC support, we leave this pointer to the 674 /* in order to simplify APIC support, we leave this pointer to the
674 user */ 675 user */
@@ -837,7 +838,7 @@ static inline int cpu_get_time_fast(void) @@ -837,7 +838,7 @@ static inline int cpu_get_time_fast(void)
837 #define cpu_signal_handler cpu_x86_signal_handler 838 #define cpu_signal_handler cpu_x86_signal_handler
838 #define cpu_list x86_cpu_list 839 #define cpu_list x86_cpu_list
839 840
840 -#define CPU_SAVE_VERSION 8 841 +#define CPU_SAVE_VERSION 9
841 842
842 /* MMU modes definitions */ 843 /* MMU modes definitions */
843 #define MMU_MODE0_SUFFIX _kernel 844 #define MMU_MODE0_SUFFIX _kernel
target-i386/kvm.c
@@ -126,6 +126,8 @@ int kvm_arch_init_vcpu(CPUState *env) @@ -126,6 +126,8 @@ int kvm_arch_init_vcpu(CPUState *env)
126 uint32_t limit, i, j, cpuid_i; 126 uint32_t limit, i, j, cpuid_i;
127 uint32_t unused; 127 uint32_t unused;
128 128
  129 + env->mp_state = KVM_MP_STATE_RUNNABLE;
  130 +
129 cpuid_i = 0; 131 cpuid_i = 0;
130 132
131 cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); 133 cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
@@ -648,6 +650,14 @@ int kvm_arch_put_registers(CPUState *env) @@ -648,6 +650,14 @@ int kvm_arch_put_registers(CPUState *env)
648 if (ret < 0) 650 if (ret < 0)
649 return ret; 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 return 0; 661 return 0;
652 } 662 }
653 663
target-i386/machine.c
@@ -140,6 +140,12 @@ void cpu_save(QEMUFile *f, void *opaque) @@ -140,6 +140,12 @@ void cpu_save(QEMUFile *f, void *opaque)
140 qemu_put_be64s(f, &env->mtrr_var[i].base); 140 qemu_put_be64s(f, &env->mtrr_var[i].base);
141 qemu_put_be64s(f, &env->mtrr_var[i].mask); 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 #ifdef USE_X86LDOUBLE 151 #ifdef USE_X86LDOUBLE
@@ -174,8 +180,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) @@ -174,8 +180,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
174 uint16_t fpus, fpuc, fptag, fpregs_format; 180 uint16_t fpus, fpuc, fptag, fpregs_format;
175 int32_t a20_mask; 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 return -EINVAL; 184 return -EINVAL;
180 for(i = 0; i < CPU_NB_REGS; i++) 185 for(i = 0; i < CPU_NB_REGS; i++)
181 qemu_get_betls(f, &env->regs[i]); 186 qemu_get_betls(f, &env->regs[i]);
@@ -319,6 +324,13 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) @@ -319,6 +324,13 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
319 qemu_get_be64s(f, &env->mtrr_var[i].mask); 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 /* XXX: ensure compatiblity for halted bit ? */ 335 /* XXX: ensure compatiblity for halted bit ? */
324 /* XXX: compute redundant hflags bits */ 336 /* XXX: compute redundant hflags bits */