diff options
author | Michael Brown <mcb30@ipxe.org> | 2021-11-24 15:43:46 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2021-11-24 15:43:46 +0000 |
commit | 81e3351b9b6ffc6c5ea4c3863617457e6f5abb28 (patch) | |
tree | 137fda7208fd3c7b2311f92d6dcc91a82da2bb34 | |
parent | 562c74e1ea52a399f7a6c416e35d98f4b37888cf (diff) | |
download | ipxe-efi_watchdog.tar.gz |
[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.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/interface/efi/efi_watchdog.c b/src/interface/efi/efi_watchdog.c index 7061f81d8..dcc9a5668 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, +}; |