Patchwork [09/11] kvm, x86: unify sigbus handling, post1

login
register
mail settings
Submitter Jin Dongming
Date Oct. 14, 2010, 8:52 a.m.
Message ID <4CB6C4E3.9000001@np.css.fujitsu.com>
Download mbox | patch
Permalink /patch/67801/
State New
Headers show

Comments

Jin Dongming - Oct. 14, 2010, 8:52 a.m.
Explicitly duplicate blocks for next cleanup.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Tested-by: Jin Dongming <jin.dongming@np.css.fujitsu.com>
---
 qemu-kvm.c |   56 +++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 33 insertions(+), 23 deletions(-)

Patch

diff --git a/qemu-kvm.c b/qemu-kvm.c
index 16bc006..d96394b 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1223,12 +1223,20 @@  static void kvm_handle_sigbus(CPUState *env, int code, void *vaddr)
 {
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
     /* env == NULL: when main thread received a SIGBUS */
-    if (!env && (first_cpu->mcg_cap & MCG_SER_P) && vaddr
-        && code == BUS_MCEERR_AO) {
+    if (!env && vaddr && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
         ram_addr_t ram_addr;
         target_phys_addr_t paddr;
 
-        /* Hope we are lucky for AO MCE */
+        /* Give up MCE forwarding if immediate action required on main thread */
+        if (code == BUS_MCEERR_AR) {
+            goto out;
+        }
+
+        /* Check if recoverable MCE support is enabled */
+        if (!(first_cpu->mcg_cap & MCG_SER_P)){
+            goto out;
+        }
+
         if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
             !kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
             fprintf(stderr, "Hardware memory error for memory used by "
@@ -1236,19 +1244,22 @@  static void kvm_handle_sigbus(CPUState *env, int code, void *vaddr)
                     (unsigned long long)vaddr);
             return;
         }
+        /* Broadcast SRAO UCR to all vcpu threads */
         kvm_mce_inj_srao_broadcast(paddr);
         return;
     }
 
     /* env != NULL: when vcpu thread received a SIGBUS */
-    if (env && (env->mcg_cap & MCG_SER_P) && vaddr
-        && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
+    if (env && vaddr && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
         ram_addr_t ram_addr;
         unsigned long paddr;
 
-        /*
-         * If there is an MCE excpetion being processed, ignore this SRAO MCE
-         */
+        /* Check if recoverable MCE support is enabled */
+        if (!(env->mcg_cap & MCG_SER_P)){
+            goto out;
+        }
+
+        /* If there is an MCE exception being processed, ignore this SRAO MCE */
         if (code == BUS_MCEERR_AO && kvm_mce_in_progress(env)) {
             return;
         }
@@ -1256,13 +1267,9 @@  static void kvm_handle_sigbus(CPUState *env, int code, void *vaddr)
         if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
             !kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
             fprintf(stderr, "Hardware memory error for memory used by "
-                    "QEMU itself instaed of guest system!\n");
-            /* Hope we are lucky for AO MCE */
-            if (code == BUS_MCEERR_AO) {
-                return;
-            } else {
-                hardware_memory_error();
-            }
+                    "QEMU itself instead of guest system!: %llx\n",
+                    (unsigned long long)vaddr);
+            goto out;
         }
         if (code == BUS_MCEERR_AR) {
             /* Fake an Intel architectural Data Load SRAR UCR */
@@ -1273,15 +1280,18 @@  static void kvm_handle_sigbus(CPUState *env, int code, void *vaddr)
         }
         return;
     }
+out:
 #endif
-    {
-        if (code == BUS_MCEERR_AO) {
-            return;
-        } else if (code == BUS_MCEERR_AR) {
-            hardware_memory_error();
-        } else {
-            sigbus_reraise();
-        }
+    /* Hope we are lucky for AO MCE */
+    if (code == BUS_MCEERR_AO) {
+        return;
+    }
+
+    /* Abort in either way */
+    if (code == BUS_MCEERR_AR) {
+        hardware_memory_error();
+    } else {
+        sigbus_reraise();
     }
 }