kvm: Stop on all fatal exit reasons
Ensure that we stop the guest whenever we face a fatal or unknown exit reason. If we stop, we also have to enforce a cpu loop exit. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
646042e1ab
commit
73aaec4a39
15
kvm-all.c
15
kvm-all.c
|
@ -815,7 +815,7 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KVM_CAP_INTERNAL_ERROR_DATA
|
#ifdef KVM_CAP_INTERNAL_ERROR_DATA
|
||||||
static void kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
|
static int kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) {
|
if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) {
|
||||||
|
@ -833,13 +833,13 @@ static void kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
|
||||||
if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) {
|
if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) {
|
||||||
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)) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* FIXME: Should trigger a qmp message to let management know
|
/* FIXME: Should trigger a qmp message to let management know
|
||||||
* something went wrong.
|
* something went wrong.
|
||||||
*/
|
*/
|
||||||
vm_stop(0);
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -967,16 +967,19 @@ int kvm_cpu_exec(CPUState *env)
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_UNKNOWN:
|
case KVM_EXIT_UNKNOWN:
|
||||||
DPRINTF("kvm_exit_unknown\n");
|
DPRINTF("kvm_exit_unknown\n");
|
||||||
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_FAIL_ENTRY:
|
case KVM_EXIT_FAIL_ENTRY:
|
||||||
DPRINTF("kvm_exit_fail_entry\n");
|
DPRINTF("kvm_exit_fail_entry\n");
|
||||||
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_EXCEPTION:
|
case KVM_EXIT_EXCEPTION:
|
||||||
DPRINTF("kvm_exit_exception\n");
|
DPRINTF("kvm_exit_exception\n");
|
||||||
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
#ifdef KVM_CAP_INTERNAL_ERROR_DATA
|
#ifdef KVM_CAP_INTERNAL_ERROR_DATA
|
||||||
case KVM_EXIT_INTERNAL_ERROR:
|
case KVM_EXIT_INTERNAL_ERROR:
|
||||||
kvm_handle_internal_error(env, run);
|
ret = kvm_handle_internal_error(env, run);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case KVM_EXIT_DEBUG:
|
case KVM_EXIT_DEBUG:
|
||||||
|
@ -997,6 +1000,10 @@ int kvm_cpu_exec(CPUState *env)
|
||||||
}
|
}
|
||||||
} while (ret > 0);
|
} while (ret > 0);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
vm_stop(0);
|
||||||
|
env->exit_request = 1;
|
||||||
|
}
|
||||||
if (env->exit_request) {
|
if (env->exit_request) {
|
||||||
env->exit_request = 0;
|
env->exit_request = 0;
|
||||||
env->exception_index = EXCP_INTERRUPT;
|
env->exception_index = EXCP_INTERRUPT;
|
||||||
|
|
|
@ -1537,6 +1537,10 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
|
||||||
case KVM_EXIT_SET_TPR:
|
case KVM_EXIT_SET_TPR:
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -307,6 +307,10 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
|
||||||
dprintf("handle halt\n");
|
dprintf("handle halt\n");
|
||||||
ret = kvmppc_handle_halt(env);
|
ret = kvmppc_handle_halt(env);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue