aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kvm-all.c15
-rw-r--r--target-i386/kvm.c4
-rw-r--r--target-ppc/kvm.c4
3 files changed, 19 insertions, 4 deletions
diff --git a/kvm-all.c b/kvm-all.c
index 86ddbd6700..eaf927248f 100644
--- a/kvm-all.c
+++ b/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
-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)) {
@@ -833,13 +833,13 @@ static void kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) {
fprintf(stderr, "emulation failure\n");
if (!kvm_arch_stop_on_emulation_error(env)) {
- return;
+ return 0;
}
}
/* FIXME: Should trigger a qmp message to let management know
* something went wrong.
*/
- vm_stop(0);
+ return -1;
}
#endif
@@ -967,16 +967,19 @@ int kvm_cpu_exec(CPUState *env)
break;
case KVM_EXIT_UNKNOWN:
DPRINTF("kvm_exit_unknown\n");
+ ret = -1;
break;
case KVM_EXIT_FAIL_ENTRY:
DPRINTF("kvm_exit_fail_entry\n");
+ ret = -1;
break;
case KVM_EXIT_EXCEPTION:
DPRINTF("kvm_exit_exception\n");
+ ret = -1;
break;
#ifdef KVM_CAP_INTERNAL_ERROR_DATA
case KVM_EXIT_INTERNAL_ERROR:
- kvm_handle_internal_error(env, run);
+ ret = kvm_handle_internal_error(env, run);
break;
#endif
case KVM_EXIT_DEBUG:
@@ -997,6 +1000,10 @@ int kvm_cpu_exec(CPUState *env)
}
} while (ret > 0);
+ if (ret < 0) {
+ vm_stop(0);
+ env->exit_request = 1;
+ }
if (env->exit_request) {
env->exit_request = 0;
env->exception_index = EXCP_INTERRUPT;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 0aeb079004..6b4abaa6c0 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1537,6 +1537,10 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
case KVM_EXIT_SET_TPR:
ret = 1;
break;
+ default:
+ fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
+ ret = -1;
+ break;
}
return ret;
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 5caa07cba8..849b404b83 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -307,6 +307,10 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
dprintf("handle halt\n");
ret = kvmppc_handle_halt(env);
break;
+ default:
+ fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
+ ret = -1;
+ break;
}
return ret;