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 | 15 +++++++++++++-- src/resume.c | 9 --------- 2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/src/fw/shadow.c b/src/fw/shadow.c index ee87d36..4486884 100644 --- a/src/fw/shadow.c +++ b/src/fw/shadow.c @@ -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; } diff --git a/src/resume.c b/src/resume.c index a5465d8..afeadcf 100644 --- a/src/resume.c +++ b/src/resume.c @@ -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.