|
|
3abf7a |
From adb570cb9034f647c0be5d1161be0e8699688cfa Mon Sep 17 00:00:00 2001
|
|
|
3abf7a |
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
|
|
3abf7a |
Date: Wed, 29 Mar 2017 17:22:07 +0200
|
|
|
3abf7a |
Subject: [PATCH] resume: Don't attempt to use generic reboot mechanisms on
|
|
|
989152 |
QEMU
|
|
|
989152 |
|
|
|
3abf7a |
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
3abf7a |
Message-id: <20170329172207.15471-2-dgilbert@redhat.com>
|
|
|
3abf7a |
Patchwork-id: 74584
|
|
|
3abf7a |
O-Subject: [RHEL-7.4 seabios PATCH 1/1] resume: Don't attempt to use generic reboot mechanisms on QEMU
|
|
|
3abf7a |
Bugzilla: 1428347
|
|
|
989152 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
3abf7a |
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
3abf7a |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
989152 |
|
|
|
989152 |
From: Kevin O'Connor <kevin@koconnor.net>
|
|
|
989152 |
|
|
|
989152 |
On QEMU it's necessary to manually reset the BIOS memory region
|
|
|
989152 |
between 0xc0000-0x100000 on a reboot. After this manual memory reset
|
|
|
989152 |
is completed, it's not valid to use the generic reset mechanisms.
|
|
|
989152 |
Rename qemu_prep_reset() to qemu_reboot() and change the function to
|
|
|
989152 |
immediately reboot after the code memcpy.
|
|
|
989152 |
|
|
|
989152 |
This fixes a bug that could cause code corruption on reboots - calling
|
|
|
989152 |
the udelay() function (as invoked by i8042_reboot and/or pci_reboot)
|
|
|
989152 |
was not valid after the BIOS was memcpy'd.
|
|
|
989152 |
|
|
|
989152 |
Reported-by: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
|
|
989152 |
Tested-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
989152 |
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
|
|
|
989152 |
(cherry picked from commit c68aff57ce317d9f2d69d20eba893a10d964f316)
|
|
|
989152 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
989152 |
---
|
|
|
989152 |
src/fw/shadow.c | 14 +++++++++++++-
|
|
|
3abf7a |
src/hw/pci.c | 1 -
|
|
|
3abf7a |
src/hw/pci.h | 2 ++
|
|
|
989152 |
src/resume.c | 4 ++--
|
|
|
989152 |
src/util.h | 2 +-
|
|
|
3abf7a |
5 files changed, 18 insertions(+), 5 deletions(-)
|
|
|
989152 |
|
|
|
989152 |
diff --git a/src/fw/shadow.c b/src/fw/shadow.c
|
|
|
3abf7a |
index cd02d3a..c80b266 100644
|
|
|
989152 |
--- a/src/fw/shadow.c
|
|
|
989152 |
+++ b/src/fw/shadow.c
|
|
|
3abf7a |
@@ -167,7 +167,7 @@ make_bios_readonly(void)
|
|
|
989152 |
}
|
|
|
989152 |
|
|
|
989152 |
void
|
|
|
989152 |
-qemu_prep_reset(void)
|
|
|
989152 |
+qemu_reboot(void)
|
|
|
989152 |
{
|
|
|
989152 |
if (!CONFIG_QEMU || runningOnXen())
|
|
|
989152 |
return;
|
|
|
3abf7a |
@@ -187,4 +187,16 @@ qemu_prep_reset(void)
|
|
|
989152 |
memcpy(hrp + 4, hrp + 4 + BIOS_SRC_OFFSET, cend - (hrp + 4));
|
|
|
989152 |
barrier();
|
|
|
989152 |
HaveRunPost = 0;
|
|
|
989152 |
+ barrier();
|
|
|
989152 |
+
|
|
|
989152 |
+ // Request a QEMU system reset. Do the reset in this function as
|
|
|
989152 |
+ // the BIOS code was overwritten above and not all BIOS
|
|
|
989152 |
+ // functionality may be available.
|
|
|
989152 |
+
|
|
|
989152 |
+ // Attempt PCI style reset
|
|
|
989152 |
+ outb(0x02, PORT_PCI_REBOOT);
|
|
|
989152 |
+ outb(0x06, PORT_PCI_REBOOT);
|
|
|
989152 |
+
|
|
|
989152 |
+ // Next try triple faulting the CPU to force a reset
|
|
|
989152 |
+ asm volatile("int3");
|
|
|
989152 |
}
|
|
|
3abf7a |
diff --git a/src/hw/pci.c b/src/hw/pci.c
|
|
|
3abf7a |
index 506ee56..8e3d617 100644
|
|
|
3abf7a |
--- a/src/hw/pci.c
|
|
|
3abf7a |
+++ b/src/hw/pci.c
|
|
|
3abf7a |
@@ -12,7 +12,6 @@
|
|
|
3abf7a |
#include "x86.h" // outl
|
|
|
3abf7a |
|
|
|
3abf7a |
#define PORT_PCI_CMD 0x0cf8
|
|
|
3abf7a |
-#define PORT_PCI_REBOOT 0x0cf9
|
|
|
3abf7a |
#define PORT_PCI_DATA 0x0cfc
|
|
|
3abf7a |
|
|
|
3abf7a |
void pci_config_writel(u16 bdf, u32 addr, u32 val)
|
|
|
3abf7a |
diff --git a/src/hw/pci.h b/src/hw/pci.h
|
|
|
3abf7a |
index bf50430..ee6e196 100644
|
|
|
3abf7a |
--- a/src/hw/pci.h
|
|
|
3abf7a |
+++ b/src/hw/pci.h
|
|
|
3abf7a |
@@ -3,6 +3,8 @@
|
|
|
3abf7a |
|
|
|
3abf7a |
#include "types.h" // u32
|
|
|
3abf7a |
|
|
|
3abf7a |
+#define PORT_PCI_REBOOT 0x0cf9
|
|
|
3abf7a |
+
|
|
|
3abf7a |
static inline u8 pci_bdf_to_bus(u16 bdf) {
|
|
|
3abf7a |
return bdf >> 8;
|
|
|
3abf7a |
}
|
|
|
989152 |
diff --git a/src/resume.c b/src/resume.c
|
|
|
3abf7a |
index 99fa34f..fb0b8a8 100644
|
|
|
989152 |
--- a/src/resume.c
|
|
|
989152 |
+++ b/src/resume.c
|
|
|
3abf7a |
@@ -125,8 +125,8 @@ tryReboot(void)
|
|
|
989152 |
{
|
|
|
989152 |
dprintf(1, "Attempting a hard reboot\n");
|
|
|
989152 |
|
|
|
989152 |
- // Setup for reset on qemu.
|
|
|
989152 |
- qemu_prep_reset();
|
|
|
989152 |
+ // Use a QEMU specific reboot on QEMU
|
|
|
989152 |
+ qemu_reboot();
|
|
|
989152 |
|
|
|
989152 |
// Reboot using ACPI RESET_REG
|
|
|
989152 |
acpi_reboot();
|
|
|
989152 |
diff --git a/src/util.h b/src/util.h
|
|
|
3abf7a |
index 557eb8b..1dfe463 100644
|
|
|
989152 |
--- a/src/util.h
|
|
|
989152 |
+++ b/src/util.h
|
|
|
3abf7a |
@@ -122,7 +122,7 @@ void pirtable_setup(void);
|
|
|
989152 |
// fw/shadow.c
|
|
|
989152 |
void make_bios_writable(void);
|
|
|
989152 |
void make_bios_readonly(void);
|
|
|
989152 |
-void qemu_prep_reset(void);
|
|
|
989152 |
+void qemu_reboot(void);
|
|
|
989152 |
|
|
|
989152 |
// fw/smbios.c
|
|
|
989152 |
void smbios_legacy_setup(void);
|
|
|
989152 |
--
|
|
|
989152 |
1.8.3.1
|
|
|
989152 |
|