extern asmlinkage u64 __efi_call(void *fp, ...);
+extern bool efi_disable_ibt_for_runtime;
+
#define efi_call(...) ({ \
__efi_nargs_check(efi_call, 7, __VA_ARGS__); \
__efi_call(__VA_ARGS__); \
#undef arch_efi_call_virt
#define arch_efi_call_virt(p, f, args...) ({ \
- u64 ret, ibt = ibt_save(); \
+ u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \
ret = efi_call((void *)p->f, args); \
ibt_restore(ibt); \
ret; \
return val == gen_endbr();
}
-extern __noendbr u64 ibt_save(void);
+extern __noendbr u64 ibt_save(bool disable);
extern __noendbr void ibt_restore(u64 save);
#else /* __ASSEMBLY__ */
static inline bool is_endbr(u32 val) { return false; }
-static inline u64 ibt_save(void) { return 0; }
+static inline u64 ibt_save(bool disable) { return 0; }
static inline void ibt_restore(u64 save) { }
#else /* __ASSEMBLY__ */
apm_irq_save(flags);
firmware_restrict_branch_speculation_start();
- ibt = ibt_save();
+ ibt = ibt_save(true);
APM_DO_SAVE_SEGS;
apm_bios_call_asm(call->func, call->ebx, call->ecx,
&call->eax, &call->ebx, &call->ecx, &call->edx,
apm_irq_save(flags);
firmware_restrict_branch_speculation_start();
- ibt = ibt_save();
+ ibt = ibt_save(true);
APM_DO_SAVE_SEGS;
error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
&call->eax);
#ifdef CONFIG_X86_KERNEL_IBT
-__noendbr u64 ibt_save(void)
+__noendbr u64 ibt_save(bool disable)
{
u64 msr = 0;
if (cpu_feature_enabled(X86_FEATURE_IBT)) {
rdmsrl(MSR_IA32_S_CET, msr);
- wrmsrl(MSR_IA32_S_CET, msr & ~CET_ENDBR_EN);
+ if (disable)
+ wrmsrl(MSR_IA32_S_CET, msr & ~CET_ENDBR_EN);
}
return msr;
return err1 || err2;
}
+bool efi_disable_ibt_for_runtime __ro_after_init = true;
+
static int __init efi_update_mem_attr(struct mm_struct *mm, efi_memory_desc_t *md,
bool has_ibt)
{
unsigned long pf = 0;
+ efi_disable_ibt_for_runtime |= !has_ibt;
+
if (md->attribute & EFI_MEMORY_XP)
pf |= _PAGE_NX;
* exists, since it is intended to supersede EFI_PROPERTIES_TABLE.
*/
if (efi_enabled(EFI_MEM_ATTR)) {
+ efi_disable_ibt_for_runtime = false;
efi_memattr_apply_permissions(NULL, efi_update_mem_attr);
return;
}