[PATCH] efi_loader: update the timing of enabling and disabling EFI watchdog

Masahisa Kojima masahisa.kojima at linaro.org
Tue Feb 22 01:58:30 CET 2022


UEFI specification requires that 5 minutes watchdog timer is
armed before the firmware's boot manager invokes an EFI boot option.
This watchdog timer is updated as follows, according to the
UEFI specification.

 1) The EFI Image may reset or disable the watchdog timer as needed.
 2) If control is returned to the firmware's boot manager,
    the watchdog timer must be disabled.
 3) On successful completion of EFI_BOOT_SERVICES.ExitBootServices()
    the watchdog timer is disabled.

1) is up to the EFI image, and 3) is already implemented in U-Boot.
This patch implements 2), the watchdog is disabled when control is
returned to U-Boot.

In addition, current implementation arms the EFI watchdog at only
the first "bootefi" invocation. The EFI watchdog must be armed
in every EFI boot option invocation.

Signed-off-by: Masahisa Kojima <masahisa.kojima at linaro.org>
---
 cmd/bootefi.c                 | 17 +++++++++++++++++
 lib/efi_loader/efi_watchdog.c | 13 +------------
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 94d18ca73f..46eebd5ee2 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -353,6 +353,19 @@ static efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options)
 	/* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */
 	switch_to_non_secure_mode();
 
+	/*
+	 * The UEFI standard requires that the watchdog timer is set to five
+	 * minutes when invoking an EFI boot option.
+	 *
+	 * Unified Extensible Firmware Interface (UEFI), version 2.7 Errata A
+	 * 7.5. Miscellaneous Boot Services - EFI_BOOT_SERVICES.SetWatchdogTimer
+	 */
+	ret = efi_set_watchdog(300);
+	if (ret != EFI_SUCCESS) {
+		log_err("ERROR: Failed to set watchdog timer\n");
+		goto out;
+	}
+
 	/* Call our payload! */
 	ret = EFI_CALL(efi_start_image(handle, &exit_data_size, &exit_data));
 	if (ret != EFI_SUCCESS) {
@@ -366,11 +379,15 @@ static efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options)
 
 	efi_restore_gd();
 
+out:
 	free(load_options);
 
 	if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD))
 		efi_initrd_deregister();
 
+	/* Control is returned to U-Boot, disable EFI watchdog */
+	efi_set_watchdog(0);
+
 	return ret;
 }
 
diff --git a/lib/efi_loader/efi_watchdog.c b/lib/efi_loader/efi_watchdog.c
index 87ca6c5b0b..d741076dcd 100644
--- a/lib/efi_loader/efi_watchdog.c
+++ b/lib/efi_loader/efi_watchdog.c
@@ -75,17 +75,6 @@ efi_status_t efi_watchdog_register(void)
 		printf("ERROR: Failed to register watchdog event\n");
 		return r;
 	}
-	/*
-	 * The UEFI standard requires that the watchdog timer is set to five
-	 * minutes when invoking an EFI boot option.
-	 *
-	 * Unified Extensible Firmware Interface (UEFI), version 2.7 Errata A
-	 * 7.5. Miscellaneous Boot Services - EFI_BOOT_SERVICES.SetWatchdogTimer
-	 */
-	r = efi_set_watchdog(300);
-	if (r != EFI_SUCCESS) {
-		printf("ERROR: Failed to set watchdog timer\n");
-		return r;
-	}
+
 	return EFI_SUCCESS;
 }
-- 
2.17.1



More information about the U-Boot mailing list