:: commit ae2d924c147bf69ccb157c2062a6ce8415b92d10

mintsuki <mintsuki@protonmail.com> — 2021-07-06 07:59

parents: eadee3e6cb

efi: Properly propagate exits after loading an image using chainloading; do not try to return from panics if boot services were exited

diff --git a/stage23/lib/panic.s2.c b/stage23/lib/panic.s2.c
index 7acec053..f2fae794 100644
--- a/stage23/lib/panic.s2.c
+++ b/stage23/lib/panic.s2.c
@@ -26,13 +26,20 @@ __attribute__((noreturn)) void panic(const char *fmt, ...) {
     print("System halted.");
     rm_hcf();
 #elif defined (uefi)
-    print("Press [ENTER] to return to firmware.");
-    while (getchar() != '\n');
-    fb_clear(&fbinfo);
+    if (efi_boot_services_exited == false) {
+        print("Press [ENTER] to return to firmware.");
+        while (getchar() != '\n');
+        fb_clear(&fbinfo);
 
-    // release all uefi memory and return to firmware
-    pmm_release_uefi_mem();
-    uefi_call_wrapper(gBS->Exit, 4, efi_image_handle, EFI_ABORTED, 0, NULL);
-    __builtin_unreachable();
+        // release all uefi memory and return to firmware
+        pmm_release_uefi_mem();
+        uefi_call_wrapper(gBS->Exit, 4, efi_image_handle, EFI_ABORTED, 0, NULL);
+        __builtin_unreachable();
+    } else {
+        print("System halted.");
+        for (;;) {
+            asm ("hlt");
+        }
+    }
 #endif
 }
diff --git a/stage23/protos/chainload.c b/stage23/protos/chainload.c
index eae87b3e..f03f2027 100644
--- a/stage23/protos/chainload.c
+++ b/stage23/protos/chainload.c
@@ -189,9 +189,15 @@ void chainload(char *config) {
 
     new_handle_loaded_image->DeviceHandle = loader_loaded_image->DeviceHandle;
 
-    status = uefi_call_wrapper(gBS->StartImage, 3, new_handle, NULL, NULL);
+    UINTN exit_data_size = 0;
+    CHAR16 *exit_data = NULL;
+    EFI_STATUS exit_status = uefi_call_wrapper(gBS->StartImage, 3,
+                                 new_handle, &exit_data_size, &exit_data);
+
+    status = uefi_call_wrapper(gBS->Exit, 4,
+                          efi_image_handle, exit_status, exit_data_size, exit_data);
     if (status) {
-        panic("chainload: StartImage failure (%x)", status);
+        panic("chainload: Exit failure (%x)", status);
     }
 
     __builtin_unreachable();
tab: 248 wrap: offon