diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2015-11-09 15:00:19 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2016-01-12 14:01:07 -0500 |
commit | b837e68d5a6c1a5945513f1995875445a1594c8a (patch) | |
tree | 47afc3c7cc77702367764067bcea656b00585618 /src/fw/shadow.c | |
parent | 3e8d75f3bef0f36a807303d58523ef5eba4a386f (diff) | |
download | seabios-b837e68d5a6c1a5945513f1995875445a1594c8a.tar.gz |
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 <kevin@koconnor.net>
Diffstat (limited to 'src/fw/shadow.c')
-rw-r--r-- | src/fw/shadow.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/fw/shadow.c b/src/fw/shadow.c index ee87d36e..4486884b 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; } |