From: Jan Kiszka <jan.kis...@siemens.com>

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.kis...@siemens.com>
---
 kvm-all.c         |   15 +++++++++++----
 target-i386/kvm.c |    4 ++++
 target-ppc/kvm.c  |    4 ++++
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 7518f2c..a46a3b6 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -774,7 +774,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)) {
@@ -792,13 +792,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
 
@@ -926,16 +926,19 @@ void 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:
@@ -956,6 +959,10 @@ void 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 fda07d2..2431a1f 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1534,6 +1534,10 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run 
*run)
         DPRINTF("handle_hlt\n");
         ret = kvm_handle_halt(env);
         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 5caa07c..849b404 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;
-- 
1.7.1


Reply via email to