efi_loader: implement task priority level (TPL)
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Fri, 15 Sep 2017 08:06:16 +0000 (10:06 +0200)
committerAlexander Graf <agraf@suse.de>
Mon, 18 Sep 2017 21:53:57 +0000 (23:53 +0200)
Define variable holding tpl.
Implement RaiseTPL and RestoreTPL.
Implement TPL check in efi_signal_event.
Implement TPL check in efi_wait_for_event.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
lib/efi_loader/efi_boottime.c

index 73793cd986724dd5e5a0c0c84224b6d46025d538..7c92a68bf46cf289de1f3273752ffae70953ee6c 100644 (file)
@@ -18,6 +18,9 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* Task priority level */
+static UINTN efi_tpl = TPL_APPLICATION;
+
 /* This list contains all the EFI objects our payload has access to */
 LIST_HEAD(efi_obj_list);
 
@@ -161,7 +164,9 @@ void efi_signal_event(struct efi_event *event)
 {
        if (event->notify_function) {
                event->queued = 1;
-               /* Put missing TPL check here */
+               /* Check TPL */
+               if (efi_tpl >= event->notify_tpl)
+                       return;
                EFI_CALL_VOID(event->notify_function(event,
                                                     event->notify_context));
        }
@@ -176,14 +181,31 @@ static efi_status_t efi_unsupported(const char *funcname)
 
 static unsigned long EFIAPI efi_raise_tpl(UINTN new_tpl)
 {
+       UINTN old_tpl = efi_tpl;
+
        EFI_ENTRY("0x%zx", new_tpl);
-       return EFI_EXIT(0);
+
+       if (new_tpl < efi_tpl)
+               debug("WARNING: new_tpl < current_tpl in %s\n", __func__);
+       efi_tpl = new_tpl;
+       if (efi_tpl > TPL_HIGH_LEVEL)
+               efi_tpl = TPL_HIGH_LEVEL;
+
+       EFI_EXIT(EFI_SUCCESS);
+       return old_tpl;
 }
 
 static void EFIAPI efi_restore_tpl(UINTN old_tpl)
 {
        EFI_ENTRY("0x%zx", old_tpl);
-       efi_unsupported(__func__);
+
+       if (old_tpl > efi_tpl)
+               debug("WARNING: old_tpl > current_tpl in %s\n", __func__);
+       efi_tpl = old_tpl;
+       if (efi_tpl > TPL_HIGH_LEVEL)
+               efi_tpl = TPL_HIGH_LEVEL;
+
+       EFI_EXIT(EFI_SUCCESS);
 }
 
 static efi_status_t EFIAPI efi_allocate_pages_ext(int type, int memory_type,
@@ -388,7 +410,9 @@ static efi_status_t EFIAPI efi_wait_for_event(unsigned long num_events,
        /* Check parameters */
        if (!num_events || !event)
                return EFI_EXIT(EFI_INVALID_PARAMETER);
-       /* Put missing TPL check here */
+       /* Check TPL */
+       if (efi_tpl != TPL_APPLICATION)
+               return EFI_EXIT(EFI_UNSUPPORTED);
        for (i = 0; i < num_events; ++i) {
                for (j = 0; j < ARRAY_SIZE(efi_events); ++j) {
                        if (event[i] == &efi_events[j])