aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2021-11-24 15:43:46 +0000
committerMichael Brown <mcb30@ipxe.org>2021-11-24 15:43:46 +0000
commit81e3351b9b6ffc6c5ea4c3863617457e6f5abb28 (patch)
tree137fda7208fd3c7b2311f92d6dcc91a82da2bb34
parent562c74e1ea52a399f7a6c416e35d98f4b37888cf (diff)
downloadipxe-efi_watchdog.zip
ipxe-efi_watchdog.tar.gz
ipxe-efi_watchdog.tar.bz2
[efi] Disable EFI watchdog timer when shutting down to boot an OSefi_watchdog
The UEFI specification mandates that the EFI watchdog timer should be disabled by the platform firmware as part of the ExitBootServices() call, but some platforms (e.g. Hyper-V) are observed to occasionally forget to do so, resulting in a reboot approximately five minutes after starting the operating system. Work around these firmware bugs by disabling the watchdog timer ourselves. Requested-by: Andreas Hammarskjöld <junior@2PintSoftware.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/interface/efi/efi_watchdog.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/interface/efi/efi_watchdog.c b/src/interface/efi/efi_watchdog.c
index 7061f81..dcc9a56 100644
--- a/src/interface/efi/efi_watchdog.c
+++ b/src/interface/efi/efi_watchdog.c
@@ -34,6 +34,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <ipxe/retry.h>
#include <ipxe/timer.h>
+#include <ipxe/init.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_watchdog.h>
@@ -80,3 +81,36 @@ static void efi_watchdog_expired ( struct retry_timer *timer,
/** Watchdog holdoff timer */
struct retry_timer efi_watchdog = TIMER_INIT ( efi_watchdog_expired );
+
+/**
+ * Disable watching when shutting down to boot an operating system
+ *
+ * @v booting System is shutting down for OS boot
+ */
+static void efi_watchdog_shutdown ( int booting ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+ EFI_STATUS efirc;
+ int rc;
+
+ /* If we are shutting down to boot an operating system, then
+ * disable the boot services watchdog timer. The UEFI
+ * specification mandates that the platform firmware does this
+ * as part of the ExitBootServices() call, but some platforms
+ * (e.g. Hyper-V) are observed to occasionally forget to do
+ * so, resulting in a reboot approximately five minutes after
+ * starting the operating system.
+ */
+ if ( booting &&
+ ( ( efirc = bs->SetWatchdogTimer ( 0, 0, 0, NULL ) ) != 0 ) ) {
+ rc = -EEFI ( efirc );
+ DBGC ( &efi_watchdog, "EFI could not disable watchdog timer: "
+ "%s\n", strerror ( rc ) );
+ /* Nothing we can do */
+ }
+}
+
+/** Watchdog startup/shutdown function */
+struct startup_fn efi_watchdog_startup_fn __startup_fn ( STARTUP_EARLY ) = {
+ .name = "efi_watchdog",
+ .shutdown = efi_watchdog_shutdown,
+};