aboutsummaryrefslogtreecommitdiff
path: root/stand/efi
diff options
context:
space:
mode:
authorToomas Soome <tsoome@FreeBSD.org>2021-09-08 00:14:51 +0000
committerToomas Soome <tsoome@FreeBSD.org>2022-06-19 14:46:35 +0000
commita2e02d9d8e100bc41cf99b8fd04738954e48a94e (patch)
treecdc67b6f1b9da53a474ced809770e3aca58699c6 /stand/efi
parent6d25ea6d964165fd9a1859a645dedc35ce2606cc (diff)
downloadsrc-a2e02d9d8e100bc41cf99b8fd04738954e48a94e.tar.gz
src-a2e02d9d8e100bc41cf99b8fd04738954e48a94e.zip
loader.efi: fix panic() after BS off
panic() is using multiple services - attempting to read keyboard, accessing time functions and finally, exiting the loader. Protect all the accessed listed above. Note, when BS are off, we really can not just exit the loader, we only can reboot. MFC after: 1 week
Diffstat (limited to 'stand/efi')
-rw-r--r--stand/efi/include/efiapi.h2
-rw-r--r--stand/efi/libefi/delay.c3
-rw-r--r--stand/efi/libefi/efi_console.c6
-rw-r--r--stand/efi/loader/efi_main.c8
4 files changed, 15 insertions, 4 deletions
diff --git a/stand/efi/include/efiapi.h b/stand/efi/include/efiapi.h
index 0118027d4b3c..2347a4d9cf73 100644
--- a/stand/efi/include/efiapi.h
+++ b/stand/efi/include/efiapi.h
@@ -438,7 +438,7 @@ VOID
IN EFI_STATUS ResetStatus,
IN UINTN DataSize,
IN CHAR16 *ResetData OPTIONAL
- );
+ ) __dead2;
typedef
EFI_STATUS
diff --git a/stand/efi/libefi/delay.c b/stand/efi/libefi/delay.c
index 9eb123096636..9bf40d28f96b 100644
--- a/stand/efi/libefi/delay.c
+++ b/stand/efi/libefi/delay.c
@@ -33,5 +33,6 @@ __FBSDID("$FreeBSD$");
void
delay(int usecs)
{
- BS->Stall(usecs);
+ if (boot_services_active)
+ BS->Stall(usecs);
}
diff --git a/stand/efi/libefi/efi_console.c b/stand/efi/libefi/efi_console.c
index 7166b7a3cfbe..1aeb94344c58 100644
--- a/stand/efi/libefi/efi_console.c
+++ b/stand/efi/libefi/efi_console.c
@@ -1362,6 +1362,9 @@ efi_cons_getchar(void)
if ((c = keybuf_getchar()) != 0)
return (c);
+ if (!boot_services_active)
+ return (-1);
+
key_pending = 0;
if (coninex == NULL) {
@@ -1383,6 +1386,9 @@ efi_cons_poll(void)
if (keybuf_ischar() || key_pending)
return (1);
+ if (!boot_services_active)
+ return (0);
+
/*
* Some EFI implementation (u-boot for example) do not support
* WaitForKey().
diff --git a/stand/efi/loader/efi_main.c b/stand/efi/loader/efi_main.c
index 736c1aa56c99..3e1fa06638e9 100644
--- a/stand/efi/loader/efi_main.c
+++ b/stand/efi/loader/efi_main.c
@@ -40,8 +40,12 @@ void
efi_exit(EFI_STATUS exit_code)
{
- BS->FreePages(heap, EFI_SIZE_TO_PAGES(heapsize));
- BS->Exit(IH, exit_code, 0, NULL);
+ if (boot_services_active) {
+ BS->FreePages(heap, EFI_SIZE_TO_PAGES(heapsize));
+ BS->Exit(IH, exit_code, 0, NULL);
+ } else {
+ RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ }
}
void