]> xenbits.xensource.com Git - seabios.git/commitdiff
resume: Make KVM soft reboot loop detection more flexible
authorKevin O'Connor <kevin@koconnor.net>
Mon, 9 Nov 2015 20:00:19 +0000 (15:00 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Tue, 12 Jan 2016 19:01:07 +0000 (14:01 -0500)
Move the check for soft reboot loops from resume.c to shadow.c and
directly check for the case where the copy of the BIOS in flash
appears to be a memory alias instead.  This prevents a hang if an
external reboot request occurs during the BIOS memcpy.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
src/fw/shadow.c
src/resume.c

index ee87d36e012ffc710efd006731b65f7f24cf72e6..4486884bd5d78428b1fe1e40b04504df07c52d34 100644 (file)
@@ -163,7 +163,18 @@ qemu_prep_reset(void)
         return;
     // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
     // reset, so do that manually before invoking a hard reset.
+    void *cstart = VSYMBOL(code32flat_start), *cend = VSYMBOL(code32flat_end);
+    void *hrp = &HaveRunPost;
+    if (readl(hrp + BIOS_SRC_OFFSET)) {
+        // Some old versions of KVM don't store a pristine copy of the
+        // BIOS in high memory.  Try to shutdown the machine instead.
+        dprintf(1, "Unable to hard-reboot machine - attempting shutdown.\n");
+        apm_shutdown();
+    }
+    // Copy the BIOS making sure to only reset HaveRunPost at end
     make_bios_writable();
-    memcpy(VSYMBOL(code32flat_start), VSYMBOL(code32flat_start) + BIOS_SRC_OFFSET
-           , SYMBOL(code32flat_end) - SYMBOL(code32flat_start));
+    memcpy(cstart, cstart + BIOS_SRC_OFFSET, hrp - cstart);
+    memcpy(hrp + 4, hrp + 4 + BIOS_SRC_OFFSET, cend - (hrp + 4));
+    barrier();
+    HaveRunPost = 0;
 }
index a5465d8774fa7fd2051520359f406288f2d7fdad..afeadcf24530f11713261a67425d3d204c47032d 100644 (file)
@@ -114,19 +114,10 @@ s3_resume(void)
     farcall16big(&br);
 }
 
-u8 HaveAttemptedReboot VARLOW;
-
 // Attempt to invoke a hard-reboot.
 static void
 tryReboot(void)
 {
-    if (HaveAttemptedReboot) {
-        // Hard reboot has failed - try to shutdown machine.
-        dprintf(1, "Unable to hard-reboot machine - attempting shutdown.\n");
-        apm_shutdown();
-    }
-    HaveAttemptedReboot = 1;
-
     dprintf(1, "Attempting a hard reboot\n");
 
     // Setup for reset on qemu.