From b837e68d5a6c1a5945513f1995875445a1594c8a Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 9 Nov 2015 15:00:19 -0500 Subject: resume: Make KVM soft reboot loop detection more flexible 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 --- 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. -- cgit v1.1