kvm: Rework inner loop of kvm_cpu_exec
Let kvm_cpu_exec return EXCP_* values consistently and generate those codes already inside its inner loop. This means we will now re-enter the kernel while ret == 0. Update kvm_handle_internal_error accordingly, but keep kvm_arch_handle_exit untouched, it will be converted in a separate step. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
dc77d341d2
commit
d73cd8f4ea
26
kvm-all.c
26
kvm-all.c
@ -831,7 +831,7 @@ static int kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
|
|||||||
fprintf(stderr, "emulation failure\n");
|
fprintf(stderr, "emulation failure\n");
|
||||||
if (!kvm_arch_stop_on_emulation_error(env)) {
|
if (!kvm_arch_stop_on_emulation_error(env)) {
|
||||||
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
|
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
|
||||||
return 0;
|
return EXCP_INTERRUPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* FIXME: Should trigger a qmp message to let management know
|
/* FIXME: Should trigger a qmp message to let management know
|
||||||
@ -931,14 +931,13 @@ int kvm_cpu_exec(CPUState *env)
|
|||||||
if (run_ret < 0) {
|
if (run_ret < 0) {
|
||||||
if (run_ret == -EINTR || run_ret == -EAGAIN) {
|
if (run_ret == -EINTR || run_ret == -EAGAIN) {
|
||||||
DPRINTF("io window exit\n");
|
DPRINTF("io window exit\n");
|
||||||
ret = 0;
|
ret = EXCP_INTERRUPT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DPRINTF("kvm run failed %s\n", strerror(-run_ret));
|
DPRINTF("kvm run failed %s\n", strerror(-run_ret));
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0; /* exit loop */
|
|
||||||
switch (run->exit_reason) {
|
switch (run->exit_reason) {
|
||||||
case KVM_EXIT_IO:
|
case KVM_EXIT_IO:
|
||||||
DPRINTF("handle_io\n");
|
DPRINTF("handle_io\n");
|
||||||
@ -947,7 +946,7 @@ int kvm_cpu_exec(CPUState *env)
|
|||||||
run->io.direction,
|
run->io.direction,
|
||||||
run->io.size,
|
run->io.size,
|
||||||
run->io.count);
|
run->io.count);
|
||||||
ret = 1;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_MMIO:
|
case KVM_EXIT_MMIO:
|
||||||
DPRINTF("handle_mmio\n");
|
DPRINTF("handle_mmio\n");
|
||||||
@ -955,14 +954,16 @@ int kvm_cpu_exec(CPUState *env)
|
|||||||
run->mmio.data,
|
run->mmio.data,
|
||||||
run->mmio.len,
|
run->mmio.len,
|
||||||
run->mmio.is_write);
|
run->mmio.is_write);
|
||||||
ret = 1;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_IRQ_WINDOW_OPEN:
|
case KVM_EXIT_IRQ_WINDOW_OPEN:
|
||||||
DPRINTF("irq_window_open\n");
|
DPRINTF("irq_window_open\n");
|
||||||
|
ret = EXCP_INTERRUPT;
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_SHUTDOWN:
|
case KVM_EXIT_SHUTDOWN:
|
||||||
DPRINTF("shutdown\n");
|
DPRINTF("shutdown\n");
|
||||||
qemu_system_reset_request();
|
qemu_system_reset_request();
|
||||||
|
ret = EXCP_INTERRUPT;
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_UNKNOWN:
|
case KVM_EXIT_UNKNOWN:
|
||||||
fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n",
|
fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n",
|
||||||
@ -979,28 +980,29 @@ int kvm_cpu_exec(CPUState *env)
|
|||||||
DPRINTF("kvm_exit_debug\n");
|
DPRINTF("kvm_exit_debug\n");
|
||||||
if (kvm_arch_debug(&run->debug.arch)) {
|
if (kvm_arch_debug(&run->debug.arch)) {
|
||||||
ret = EXCP_DEBUG;
|
ret = EXCP_DEBUG;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
/* re-enter, this exception was guest-internal */
|
/* re-enter, this exception was guest-internal */
|
||||||
ret = 1;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
#endif /* KVM_CAP_SET_GUEST_DEBUG */
|
#endif /* KVM_CAP_SET_GUEST_DEBUG */
|
||||||
default:
|
default:
|
||||||
DPRINTF("kvm_arch_handle_exit\n");
|
DPRINTF("kvm_arch_handle_exit\n");
|
||||||
ret = kvm_arch_handle_exit(env, run);
|
ret = kvm_arch_handle_exit(env, run);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = EXCP_INTERRUPT;
|
||||||
|
} else if (ret > 0) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (ret > 0);
|
} while (ret == 0);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
|
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
|
||||||
vm_stop(VMSTOP_PANIC);
|
vm_stop(VMSTOP_PANIC);
|
||||||
}
|
}
|
||||||
ret = EXCP_INTERRUPT;
|
|
||||||
|
|
||||||
#ifdef KVM_CAP_SET_GUEST_DEBUG
|
|
||||||
out:
|
|
||||||
#endif
|
|
||||||
env->exit_request = 0;
|
env->exit_request = 0;
|
||||||
cpu_single_env = NULL;
|
cpu_single_env = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user