aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2018-02-22 20:29:27 -0500
committerKevin O'Connor <kevin@koconnor.net>2018-02-22 20:38:23 -0500
commit42812e062a77b27b0544c8e0d46d206afc3b2fae (patch)
treedac5f390de49c66aff7fd885c91f624d976e5910
parentaf0daeb2687ad2595482b8a71b02a082a5672ceb (diff)
downloadseabios-42812e062a77b27b0544c8e0d46d206afc3b2fae.zip
seabios-42812e062a77b27b0544c8e0d46d206afc3b2fae.tar.gz
seabios-42812e062a77b27b0544c8e0d46d206afc3b2fae.tar.bz2
shadow: Don't invoke a shutdown on reboot unless in a reboot loop
Old versions of KVM would map the same writable copy of the BIOS at both 0x000f0000 and 0xffff0000. As a result, a reboot on these machines would result in a reboot loop. So, the code attempts to check for that situation and invoke a shutdown instead. Commit b837e68d changed the check to run prior to the first reboot. However, this broke reboots on the QEMU isapc machine type. Change the reboot loop check to only be invoked after at least one reboot has been attempted. Reported-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--src/fw/shadow.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/src/fw/shadow.c b/src/fw/shadow.c
index c80b266..987eaf4 100644
--- a/src/fw/shadow.c
+++ b/src/fw/shadow.c
@@ -176,18 +176,23 @@ qemu_reboot(void)
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();
+ // There isn't a pristine copy of the BIOS at 0xffff0000 to copy
+ if (HaveRunPost == 3) {
+ // In a reboot loop. Try to shutdown the machine instead.
+ dprintf(1, "Unable to hard-reboot machine - attempting shutdown.\n");
+ apm_shutdown();
+ }
+ make_bios_writable();
+ HaveRunPost = 3;
+ } else {
+ // Copy the BIOS making sure to only reset HaveRunPost at end
+ make_bios_writable();
+ memcpy(cstart, cstart + BIOS_SRC_OFFSET, hrp - cstart);
+ memcpy(hrp + 4, hrp + 4 + BIOS_SRC_OFFSET, cend - (hrp + 4));
+ barrier();
+ HaveRunPost = 0;
+ barrier();
}
- // Copy the BIOS making sure to only reset HaveRunPost at end
- make_bios_writable();
- memcpy(cstart, cstart + BIOS_SRC_OFFSET, hrp - cstart);
- memcpy(hrp + 4, hrp + 4 + BIOS_SRC_OFFSET, cend - (hrp + 4));
- barrier();
- HaveRunPost = 0;
- barrier();
// Request a QEMU system reset. Do the reset in this function as
// the BIOS code was overwritten above and not all BIOS