Commit 8d2ba1fb9c8e7006e10d71fa51a020977f14c8b0

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent e9283f8b

kvm: Rework VCPU synchronization

During startup and after reset we have to synchronize user space to the
in-kernel KVM state. Namely, we need to transfer the VCPU registers when
they change due to VCPU as well as APIC reset.

This patch refactors the required hooks so that kvm_init_vcpu registers
its own per-VCPU reset handler and adds a cpu_synchronize_state to the
APIC reset. That way we no longer depend on the new reset order (and can
drop this disliked interface again) and we can even drop a KVM hook in
main().

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
hw/apic.c
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
23 #include "msix.h" 23 #include "msix.h"
24 #include "qemu-timer.h" 24 #include "qemu-timer.h"
25 #include "host-utils.h" 25 #include "host-utils.h"
  26 +#include "kvm.h"
26 27
27 //#define DEBUG_APIC 28 //#define DEBUG_APIC
28 29
@@ -953,6 +954,8 @@ static void apic_reset(void *opaque) @@ -953,6 +954,8 @@ static void apic_reset(void *opaque)
953 */ 954 */
954 s->lvt[APIC_LVT_LINT0] = 0x700; 955 s->lvt[APIC_LVT_LINT0] = 0x700;
955 } 956 }
  957 +
  958 + cpu_synchronize_state(s->cpu_env, 1);
956 } 959 }
957 960
958 static CPUReadMemoryFunc *apic_mem_read[3] = { 961 static CPUReadMemoryFunc *apic_mem_read[3] = {
kvm-all.c
@@ -143,6 +143,15 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot) @@ -143,6 +143,15 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
143 return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); 143 return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
144 } 144 }
145 145
  146 +static void kvm_reset_vcpu(void *opaque)
  147 +{
  148 + CPUState *env = opaque;
  149 +
  150 + if (kvm_arch_put_registers(env)) {
  151 + fprintf(stderr, "Fatal: kvm vcpu reset failed\n");
  152 + abort();
  153 + }
  154 +}
146 155
147 int kvm_init_vcpu(CPUState *env) 156 int kvm_init_vcpu(CPUState *env)
148 { 157 {
@@ -176,7 +185,10 @@ int kvm_init_vcpu(CPUState *env) @@ -176,7 +185,10 @@ int kvm_init_vcpu(CPUState *env)
176 } 185 }
177 186
178 ret = kvm_arch_init_vcpu(env); 187 ret = kvm_arch_init_vcpu(env);
179 - 188 + if (ret == 0) {
  189 + qemu_register_reset(kvm_reset_vcpu, 0, env);
  190 + ret = kvm_arch_put_registers(env);
  191 + }
180 err: 192 err:
181 return ret; 193 return ret;
182 } 194 }
@@ -201,21 +213,6 @@ int kvm_get_mp_state(CPUState *env) @@ -201,21 +213,6 @@ int kvm_get_mp_state(CPUState *env)
201 return 0; 213 return 0;
202 } 214 }
203 215
204 -int kvm_sync_vcpus(void)  
205 -{  
206 - CPUState *env;  
207 -  
208 - for (env = first_cpu; env != NULL; env = env->next_cpu) {  
209 - int ret;  
210 -  
211 - ret = kvm_arch_put_registers(env);  
212 - if (ret)  
213 - return ret;  
214 - }  
215 -  
216 - return 0;  
217 -}  
218 -  
219 /* 216 /*
220 * dirty pages logging control 217 * dirty pages logging control
221 */ 218 */
@@ -397,11 +394,6 @@ int kvm_check_extension(KVMState *s, unsigned int extension) @@ -397,11 +394,6 @@ int kvm_check_extension(KVMState *s, unsigned int extension)
397 return ret; 394 return ret;
398 } 395 }
399 396
400 -static void kvm_reset_vcpus(void *opaque)  
401 -{  
402 - kvm_sync_vcpus();  
403 -}  
404 -  
405 int kvm_init(int smp_cpus) 397 int kvm_init(int smp_cpus)
406 { 398 {
407 static const char upgrade_note[] = 399 static const char upgrade_note[] =
@@ -492,8 +484,6 @@ int kvm_init(int smp_cpus) @@ -492,8 +484,6 @@ int kvm_init(int smp_cpus)
492 if (ret < 0) 484 if (ret < 0)
493 goto err; 485 goto err;
494 486
495 - qemu_register_reset(kvm_reset_vcpus, INT_MAX, NULL);  
496 -  
497 kvm_state = s; 487 kvm_state = s;
498 488
499 return 0; 489 return 0;
@@ -32,7 +32,6 @@ struct kvm_run; @@ -32,7 +32,6 @@ struct kvm_run;
32 int kvm_init(int smp_cpus); 32 int kvm_init(int smp_cpus);
33 33
34 int kvm_init_vcpu(CPUState *env); 34 int kvm_init_vcpu(CPUState *env);
35 -int kvm_sync_vcpus(void);  
36 35
37 int kvm_cpu_exec(CPUState *env); 36 int kvm_cpu_exec(CPUState *env);
38 37
@@ -6057,17 +6057,6 @@ int main(int argc, char **argv, char **envp) @@ -6057,17 +6057,6 @@ int main(int argc, char **argv, char **envp)
6057 6057
6058 current_machine = machine; 6058 current_machine = machine;
6059 6059
6060 - /* Set KVM's vcpu state to qemu's initial CPUState. */  
6061 - if (kvm_enabled()) {  
6062 - int ret;  
6063 -  
6064 - ret = kvm_sync_vcpus();  
6065 - if (ret < 0) {  
6066 - fprintf(stderr, "failed to initialize vcpus\n");  
6067 - exit(1);  
6068 - }  
6069 - }  
6070 -  
6071 /* init USB devices */ 6060 /* init USB devices */
6072 if (usb_enabled) { 6061 if (usb_enabled) {
6073 for(i = 0; i < usb_devices_index; i++) { 6062 for(i = 0; i < usb_devices_index; i++) {