return 0;
 }
 
+struct set_perm_data {
+       const efi_memory_desc_t *md;
+       bool                    has_bti;
+};
+
 static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
 {
-       efi_memory_desc_t *md = data;
+       struct set_perm_data *spd = data;
+       const efi_memory_desc_t *md = spd->md;
        pte_t pte = READ_ONCE(*ptep);
 
        if (md->attribute & EFI_MEMORY_RO)
                pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
        if (md->attribute & EFI_MEMORY_XP)
                pte = set_pte_bit(pte, __pgprot(PTE_PXN));
+       else if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) &&
+                system_supports_bti() && spd->has_bti)
+               pte = set_pte_bit(pte, __pgprot(PTE_GP));
        set_pte(ptep, pte);
        return 0;
 }
                                       efi_memory_desc_t *md,
                                       bool has_bti)
 {
+       struct set_perm_data data = { md, has_bti };
+
        BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE &&
               md->type != EFI_RUNTIME_SERVICES_DATA);
 
         */
        return apply_to_page_range(mm, md->virt_addr,
                                   md->num_pages << EFI_PAGE_SHIFT,
-                                  set_permissions, md);
+                                  set_permissions, &data);
 }
 
 /*
 
 #include <linux/module.h>
 #include <linux/kexec.h>
 #include <linux/delay.h>
+#include <linux/efi.h>
 #include <linux/init.h>
 #include <linux/sched/signal.h>
 #include <linux/sched/debug.h>
 #include <asm/cpufeature.h>
 #include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
+#include <asm/efi.h>
 #include <asm/esr.h>
 #include <asm/exception.h>
 #include <asm/extable.h>
 
 void do_el1_bti(struct pt_regs *regs, unsigned long esr)
 {
+       if (efi_runtime_fixup_exception(regs, "BTI violation")) {
+               regs->pstate &= ~PSR_BTYPE_MASK;
+               return;
+       }
        die("Oops - BTI", regs, esr);
 }