Skip to content

Commit 93be285

Browse files
committed
efi: x86: Wire up IBT annotation in memory attributes table
UEFI v2.10 extends the EFI memory attributes table with a flag that indicates whether or not all RuntimeServicesCode regions were constructed with ENDBR landing pads, permitting the OS to map these regions with IBT restrictions enabled. So let's take this into account on x86 as well. Suggested-by: Peter Zijlstra <[email protected]> # ibt_save() changes Signed-off-by: Ard Biesheuvel <[email protected]> Acked-by: Dave Hansen <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]>
1 parent 1d95931 commit 93be285

File tree

5 files changed

+15
-7
lines changed

5 files changed

+15
-7
lines changed

arch/x86/include/asm/efi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ static inline void efi_fpu_end(void)
106106

107107
extern asmlinkage u64 __efi_call(void *fp, ...);
108108

109+
extern bool efi_disable_ibt_for_runtime;
110+
109111
#define efi_call(...) ({ \
110112
__efi_nargs_check(efi_call, 7, __VA_ARGS__); \
111113
__efi_call(__VA_ARGS__); \
@@ -121,7 +123,7 @@ extern asmlinkage u64 __efi_call(void *fp, ...);
121123

122124
#undef arch_efi_call_virt
123125
#define arch_efi_call_virt(p, f, args...) ({ \
124-
u64 ret, ibt = ibt_save(); \
126+
u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \
125127
ret = efi_call((void *)p->f, args); \
126128
ibt_restore(ibt); \
127129
ret; \

arch/x86/include/asm/ibt.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static inline bool is_endbr(u32 val)
7474
return val == gen_endbr();
7575
}
7676

77-
extern __noendbr u64 ibt_save(void);
77+
extern __noendbr u64 ibt_save(bool disable);
7878
extern __noendbr void ibt_restore(u64 save);
7979

8080
#else /* __ASSEMBLY__ */
@@ -100,7 +100,7 @@ extern __noendbr void ibt_restore(u64 save);
100100

101101
static inline bool is_endbr(u32 val) { return false; }
102102

103-
static inline u64 ibt_save(void) { return 0; }
103+
static inline u64 ibt_save(bool disable) { return 0; }
104104
static inline void ibt_restore(u64 save) { }
105105

106106
#else /* __ASSEMBLY__ */

arch/x86/kernel/apm_32.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ static long __apm_bios_call(void *_call)
609609

610610
apm_irq_save(flags);
611611
firmware_restrict_branch_speculation_start();
612-
ibt = ibt_save();
612+
ibt = ibt_save(true);
613613
APM_DO_SAVE_SEGS;
614614
apm_bios_call_asm(call->func, call->ebx, call->ecx,
615615
&call->eax, &call->ebx, &call->ecx, &call->edx,
@@ -690,7 +690,7 @@ static long __apm_bios_call_simple(void *_call)
690690

691691
apm_irq_save(flags);
692692
firmware_restrict_branch_speculation_start();
693-
ibt = ibt_save();
693+
ibt = ibt_save(true);
694694
APM_DO_SAVE_SEGS;
695695
error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
696696
&call->eax);

arch/x86/kernel/cpu/common.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,13 +571,14 @@ __setup("nopku", setup_disable_pku);
571571

572572
#ifdef CONFIG_X86_KERNEL_IBT
573573

574-
__noendbr u64 ibt_save(void)
574+
__noendbr u64 ibt_save(bool disable)
575575
{
576576
u64 msr = 0;
577577

578578
if (cpu_feature_enabled(X86_FEATURE_IBT)) {
579579
rdmsrl(MSR_IA32_S_CET, msr);
580-
wrmsrl(MSR_IA32_S_CET, msr & ~CET_ENDBR_EN);
580+
if (disable)
581+
wrmsrl(MSR_IA32_S_CET, msr & ~CET_ENDBR_EN);
581582
}
582583

583584
return msr;

arch/x86/platform/efi/efi_64.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,11 +389,15 @@ static int __init efi_update_mappings(efi_memory_desc_t *md, unsigned long pf)
389389
return err1 || err2;
390390
}
391391

392+
bool efi_disable_ibt_for_runtime __ro_after_init = true;
393+
392394
static int __init efi_update_mem_attr(struct mm_struct *mm, efi_memory_desc_t *md,
393395
bool has_ibt)
394396
{
395397
unsigned long pf = 0;
396398

399+
efi_disable_ibt_for_runtime |= !has_ibt;
400+
397401
if (md->attribute & EFI_MEMORY_XP)
398402
pf |= _PAGE_NX;
399403

@@ -415,6 +419,7 @@ void __init efi_runtime_update_mappings(void)
415419
* exists, since it is intended to supersede EFI_PROPERTIES_TABLE.
416420
*/
417421
if (efi_enabled(EFI_MEM_ATTR)) {
422+
efi_disable_ibt_for_runtime = false;
418423
efi_memattr_apply_permissions(NULL, efi_update_mem_attr);
419424
return;
420425
}

0 commit comments

Comments
 (0)