extern int __init efi_reuse_config(u64 tables, int nr_tables);
 extern void efi_delete_dummy_variable(void);
 extern void efi_switch_mm(struct mm_struct *mm);
-extern void efi_recover_from_page_fault(unsigned long phys_addr);
+extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr);
 extern void efi_free_boot_services(void);
 
 /* kexec external ABI */
 
 #include <linux/prefetch.h>            /* prefetchw                    */
 #include <linux/context_tracking.h>    /* exception_enter(), ...       */
 #include <linux/uaccess.h>             /* faulthandler_disabled()      */
-#include <linux/efi.h>                 /* efi_recover_from_page_fault()*/
+#include <linux/efi.h>                 /* efi_crash_gracefully_on_page_fault()*/
 #include <linux/mm_types.h>
 
 #include <asm/cpufeature.h>            /* boot_cpu_has, ...            */
 #include <asm/vsyscall.h>              /* emulate_vsyscall             */
 #include <asm/vm86.h>                  /* struct vm86                  */
 #include <asm/mmu_context.h>           /* vma_pkey()                   */
-#include <asm/efi.h>                   /* efi_recover_from_page_fault()*/
+#include <asm/efi.h>                   /* efi_crash_gracefully_on_page_fault()*/
 #include <asm/desc.h>                  /* store_idt(), ...             */
 #include <asm/cpu_entry_area.h>                /* exception stack              */
 #include <asm/pgtable_areas.h>         /* VMALLOC_START, ...           */
 #endif
 
        /*
-        * Buggy firmware could access regions which might page fault, try to
-        * recover from such faults.
+        * Buggy firmware could access regions which might page fault.  If
+        * this happens, EFI has a special OOPS path that will try to
+        * avoid hanging the system.
         */
        if (IS_ENABLED(CONFIG_EFI))
-               efi_recover_from_page_fault(address);
+               efi_crash_gracefully_on_page_fault(address);
 
 oops:
        /*
 
  * @return: Returns, if the page fault is not handled. This function
  * will never return if the page fault is handled successfully.
  */
-void efi_recover_from_page_fault(unsigned long phys_addr)
+void efi_crash_gracefully_on_page_fault(unsigned long phys_addr)
 {
        if (!IS_ENABLED(CONFIG_X86_64))
                return;
 
+       /*
+        * If we get an interrupt/NMI while processing an EFI runtime service
+        * then this is a regular OOPS, not an EFI failure.
+        */
+       if (in_interrupt())
+               return;
+
        /*
         * Make sure that an efi runtime service caused the page fault.
+        * READ_ONCE() because we might be OOPSing in a different thread,
+        * and we don't want to trip KTSAN while trying to OOPS.
         */
-       if (efi_rts_work.efi_rts_id == EFI_NONE)
+       if (READ_ONCE(efi_rts_work.efi_rts_id) == EFI_NONE ||
+           current_work() != &efi_rts_work.work)
                return;
 
        /*
                set_current_state(TASK_IDLE);
                schedule();
        }
-
-       return;
 }