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:
Jan Kiszka 2011-01-21 21:48:06 +01:00 committed by Marcelo Tosatti
parent 646042e1ab
commit 73aaec4a39
3 changed files with 19 additions and 4 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;