提交 8d2ba1fb 编写于 作者: J Jan Kiszka 提交者: Anthony Liguori

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: NJan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>
上级 e9283f8b
......@@ -23,6 +23,7 @@
#include "msix.h"
#include "qemu-timer.h"
#include "host-utils.h"
#include "kvm.h"
//#define DEBUG_APIC
......@@ -953,6 +954,8 @@ static void apic_reset(void *opaque)
*/
s->lvt[APIC_LVT_LINT0] = 0x700;
}
cpu_synchronize_state(s->cpu_env, 1);
}
static CPUReadMemoryFunc *apic_mem_read[3] = {
......
......@@ -143,6 +143,15 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
}
static void kvm_reset_vcpu(void *opaque)
{
CPUState *env = opaque;
if (kvm_arch_put_registers(env)) {
fprintf(stderr, "Fatal: kvm vcpu reset failed\n");
abort();
}
}
int kvm_init_vcpu(CPUState *env)
{
......@@ -176,7 +185,10 @@ int kvm_init_vcpu(CPUState *env)
}
ret = kvm_arch_init_vcpu(env);
if (ret == 0) {
qemu_register_reset(kvm_reset_vcpu, 0, env);
ret = kvm_arch_put_registers(env);
}
err:
return ret;
}
......@@ -201,21 +213,6 @@ int kvm_get_mp_state(CPUState *env)
return 0;
}
int kvm_sync_vcpus(void)
{
CPUState *env;
for (env = first_cpu; env != NULL; env = env->next_cpu) {
int ret;
ret = kvm_arch_put_registers(env);
if (ret)
return ret;
}
return 0;
}
/*
* dirty pages logging control
*/
......@@ -397,11 +394,6 @@ int kvm_check_extension(KVMState *s, unsigned int extension)
return ret;
}
static void kvm_reset_vcpus(void *opaque)
{
kvm_sync_vcpus();
}
int kvm_init(int smp_cpus)
{
static const char upgrade_note[] =
......@@ -492,8 +484,6 @@ int kvm_init(int smp_cpus)
if (ret < 0)
goto err;
qemu_register_reset(kvm_reset_vcpus, INT_MAX, NULL);
kvm_state = s;
return 0;
......
......@@ -32,7 +32,6 @@ struct kvm_run;
int kvm_init(int smp_cpus);
int kvm_init_vcpu(CPUState *env);
int kvm_sync_vcpus(void);
int kvm_cpu_exec(CPUState *env);
......
......@@ -6057,17 +6057,6 @@ int main(int argc, char **argv, char **envp)
current_machine = machine;
/* Set KVM's vcpu state to qemu's initial CPUState. */
if (kvm_enabled()) {
int ret;
ret = kvm_sync_vcpus();
if (ret < 0) {
fprintf(stderr, "failed to initialize vcpus\n");
exit(1);
}
}
/* init USB devices */
if (usb_enabled) {
for(i = 0; i < usb_devices_index; i++) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册