diff --git a/include/efi_loader.h b/include/efi_loader.h index 3c68b85b68..0fc2255f3f 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -297,15 +297,17 @@ enum efi_image_auth_status { * @exit_status: exit status passed to Exit() * @exit_data_size: exit data size passed to Exit() * @exit_data: exit data passed to Exit() - * @exit_jmp: long jump buffer for returning form started image + * @exit_jmp: long jump buffer for returning from started image * @entry: entry address of the relocated image + * @image_type: indicates if the image is an applicition or a driver + * @auth_status: indicates if the image is authenticated */ struct efi_loaded_image_obj { struct efi_object header; - efi_status_t exit_status; + efi_status_t *exit_status; efi_uintn_t *exit_data_size; u16 **exit_data; - struct jmp_buf_data exit_jmp; + struct jmp_buf_data *exit_jmp; EFIAPI efi_status_t (*entry)(efi_handle_t image_handle, struct efi_system_table *st); u16 image_type; diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 61dc72a23d..d3be2f94c6 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -275,7 +275,7 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle, memcpy(*load_options, lo.optional_data, size); ret = efi_set_load_options(*handle, size, *load_options); } else { - load_options = NULL; + *load_options = NULL; } error: diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 246b59d3b3..a89bdb3140 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -271,8 +271,8 @@ efi_status_t is_valid_tpl(efi_uintn_t tpl) * efi_signal_event() - signal an EFI event * @event: event to signal * - * This function signals an event. If the event belongs to an event group all - * events of the group are signaled. If they are of type EVT_NOTIFY_SIGNAL + * This function signals an event. If the event belongs to an event group, all + * events of the group are signaled. If they are of type EVT_NOTIFY_SIGNAL, * their notification function is queued. * * For the SignalEvent service see efi_signal_event_ext. @@ -2000,7 +2000,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle, } if (!efi_st_keep_devices) { - if IS_ENABLED(CONFIG_USB_DEVICE) + if (IS_ENABLED(CONFIG_USB_DEVICE)) udc_disconnect(); board_quiesce_devices(); dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); @@ -2899,6 +2899,8 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, efi_status_t ret; void *info; efi_handle_t parent_image = current_image; + efi_status_t exit_status; + struct jmp_buf_data exit_jmp; EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data); @@ -2920,9 +2922,11 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, image_obj->exit_data_size = exit_data_size; image_obj->exit_data = exit_data; + image_obj->exit_status = &exit_status; + image_obj->exit_jmp = &exit_jmp; /* call the image! */ - if (setjmp(&image_obj->exit_jmp)) { + if (setjmp(&exit_jmp)) { /* * We called the entry point of the child image with EFI_CALL * in the lines below. The child image called the Exit() boot @@ -2944,10 +2948,10 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, */ assert(__efi_entry_check()); EFI_PRINT("%lu returned by started image\n", - (unsigned long)((uintptr_t)image_obj->exit_status & + (unsigned long)((uintptr_t)exit_status & ~EFI_ERROR_MASK)); current_image = parent_image; - return EFI_EXIT(image_obj->exit_status); + return EFI_EXIT(exit_status); } current_image = image_handle; @@ -3130,6 +3134,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle, struct efi_loaded_image *loaded_image_protocol; struct efi_loaded_image_obj *image_obj = (struct efi_loaded_image_obj *)image_handle; + struct jmp_buf_data *exit_jmp; EFI_ENTRY("%p, %ld, %zu, %p", image_handle, exit_status, exit_data_size, exit_data); @@ -3171,6 +3176,9 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle, if (ret != EFI_SUCCESS) EFI_PRINT("%s: out of memory\n", __func__); } + /* efi_delete_image() frees image_obj. Copy before the call. */ + exit_jmp = image_obj->exit_jmp; + *image_obj->exit_status = exit_status; if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION || exit_status != EFI_SUCCESS) efi_delete_image(image_obj, loaded_image_protocol); @@ -3184,8 +3192,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle, */ efi_restore_gd(); - image_obj->exit_status = exit_status; - longjmp(&image_obj->exit_jmp, 1); + longjmp(exit_jmp, 1); panic("EFI application exited"); out: diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 011accab78..705109596e 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -14,6 +14,7 @@ #include #include #include +#include #define EFI_COUT_MODE_2 2 #define EFI_MAX_COUT_MODE 3 @@ -688,6 +689,17 @@ static efi_status_t efi_cin_read_key(struct efi_key_data *key) switch (ch) { case 0x1b: + /* + * If a second key is received within 10 ms, assume that we are + * dealing with an escape sequence. Otherwise consider this the + * escape key being hit. 10 ms is long enough to work fine at + * 1200 baud and above. + */ + udelay(10000); + if (!tstc()) { + pressed_key.scan_code = 23; + break; + } /* * Xterm Control Sequences * https://www.xfree86.org/4.8.0/ctlseqs.html