resume: Don't attempt to use generic reboot mechanisms on QEMU

On QEMU it's necessary to manually reset the BIOS memory region
between 0xc0000-0x100000 on a reboot.  After this manual memory reset
is completed, it's not valid to use the generic reset mechanisms.
Rename qemu_prep_reset() to qemu_reboot() and change the function to
immediately reboot after the code memcpy.

This fixes a bug that could cause code corruption on reboots - calling
the udelay() function (as invoked by i8042_reboot and/or pci_reboot)
was not valid after the BIOS was memcpy'd.

Reported-by: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Tested-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2017-03-03 10:48:45 -05:00
parent 1415d46dc8
commit c68aff57ce
5 changed files with 18 additions and 5 deletions

View File

@ -167,7 +167,7 @@ make_bios_readonly(void)
}
void
qemu_prep_reset(void)
qemu_reboot(void)
{
if (!CONFIG_QEMU || runningOnXen())
return;
@ -187,4 +187,16 @@ qemu_prep_reset(void)
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
// functionality may be available.
// Attempt PCI style reset
outb(0x02, PORT_PCI_REBOOT);
outb(0x06, PORT_PCI_REBOOT);
// Next try triple faulting the CPU to force a reset
asm volatile("int3");
}

View File

@ -12,7 +12,6 @@
#include "x86.h" // outl
#define PORT_PCI_CMD 0x0cf8
#define PORT_PCI_REBOOT 0x0cf9
#define PORT_PCI_DATA 0x0cfc
void pci_config_writel(u16 bdf, u32 addr, u32 val)

View File

@ -3,6 +3,8 @@
#include "types.h" // u32
#define PORT_PCI_REBOOT 0x0cf9
static inline u8 pci_bdf_to_bus(u16 bdf) {
return bdf >> 8;
}

View File

@ -125,8 +125,8 @@ tryReboot(void)
{
dprintf(1, "Attempting a hard reboot\n");
// Setup for reset on qemu.
qemu_prep_reset();
// Use a QEMU specific reboot on QEMU
qemu_reboot();
// Reboot using ACPI RESET_REG
acpi_reboot();

View File

@ -123,7 +123,7 @@ void pirtable_setup(void);
// fw/shadow.c
void make_bios_writable(void);
void make_bios_readonly(void);
void qemu_prep_reset(void);
void qemu_reboot(void);
// fw/smbios.c
void smbios_legacy_setup(void);