Skip to content

Commit

Permalink
Merge tag 'efi-next-for-v6.3' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/efi/efi

Pull EFI updates from Ard Biesheuvel:
 "A healthy mix of EFI contributions this time:

   - Performance tweaks for efifb earlycon (Andy)

   - Preparatory refactoring and cleanup work in the efivar layer, which
     is needed to accommodate the Snapdragon arm64 laptops that expose
     their EFI variable store via a TEE secure world API (Johan)

   - Enhancements to the EFI memory map handling so that Xen dom0 can
     safely access EFI configuration tables (Demi Marie)

   - Wire up the newly introduced IBT/BTI flag in the EFI memory
     attributes table, so that firmware that is generated with ENDBR/BTI
     landing pads will be mapped with enforcement enabled

   - Clean up how we check and print the EFI revision exposed by the
     firmware

   - Incorporate EFI memory attributes protocol definition and wire it
     up in the EFI zboot code (Evgeniy)

     This ensures that these images can execute under new and stricter
     rules regarding the default memory permissions for EFI page
     allocations (More work is in progress here)

   - CPER header cleanup (Dan Williams)

   - Use a raw spinlock to protect the EFI runtime services stack on
     arm64 to ensure the correct semantics under -rt (Pierre)

   - EFI framebuffer quirk for Lenovo Ideapad (Darrell)"

* tag 'efi-next-for-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi: (24 commits)
  firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3
  arm64: efi: Make efi_rt_lock a raw_spinlock
  efi: Add mixed-mode thunk recipe for GetMemoryAttributes
  efi: x86: Wire up IBT annotation in memory attributes table
  efi: arm64: Wire up BTI annotation in memory attributes table
  efi: Discover BTI support in runtime services regions
  efi/cper, cxl: Remove cxl_err.h
  efi: Use standard format for printing the EFI revision
  efi: Drop minimum EFI version check at boot
  efi: zboot: Use EFI protocol to remap code/data with the right attributes
  efi/libstub: Add memory attribute protocol definitions
  efi: efivars: prevent double registration
  efi: verify that variable services are supported
  efivarfs: always register filesystem
  efi: efivars: add efivars printk prefix
  efi: Warn if trying to reserve memory under Xen
  efi: Actually enable the ESRT under Xen
  efi: Apply allowlist to EFI configuration tables when running under Xen
  efi: xen: Implement memory descriptor lookup based on hypercall
  efi: memmap: Disregard bogus entries instead of returning them
  ...
  • Loading branch information
Linus Torvalds committed Feb 23, 2023
2 parents f2b98d0 + e1d4471 commit 06e1a81
Show file tree
Hide file tree
Showing 30 changed files with 389 additions and 116 deletions.
2 changes: 1 addition & 1 deletion arch/arm/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ void efi_init(void);
void arm_efi_init(void);

int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, bool);

#define arch_efi_call_virt_setup() efi_virtmap_load()
#define arch_efi_call_virt_teardown() efi_virtmap_unload()
Expand Down
5 changes: 3 additions & 2 deletions arch/arm/kernel/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
}

int __init efi_set_mapping_permissions(struct mm_struct *mm,
efi_memory_desc_t *md)
efi_memory_desc_t *md,
bool ignored)
{
unsigned long base, size;

Expand Down Expand Up @@ -71,7 +72,7 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
* If stricter permissions were specified, apply them now.
*/
if (md->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP))
return efi_set_mapping_permissions(mm, md);
return efi_set_mapping_permissions(mm, md, false);
return 0;
}

Expand Down
9 changes: 5 additions & 4 deletions arch/arm64/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ bool efi_runtime_fixup_exception(struct pt_regs *regs, const char *msg)
#endif

int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md,
bool has_bti);

#define arch_efi_call_virt_setup() \
({ \
efi_virtmap_load(); \
__efi_fpsimd_begin(); \
spin_lock(&efi_rt_lock); \
raw_spin_lock(&efi_rt_lock); \
})

#undef arch_efi_call_virt
Expand All @@ -42,12 +43,12 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);

#define arch_efi_call_virt_teardown() \
({ \
spin_unlock(&efi_rt_lock); \
raw_spin_unlock(&efi_rt_lock); \
__efi_fpsimd_end(); \
efi_virtmap_unload(); \
})

extern spinlock_t efi_rt_lock;
extern raw_spinlock_t efi_rt_lock;
extern u64 *efi_rt_stack_top;
efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);

Expand Down
20 changes: 16 additions & 4 deletions arch/arm64/kernel/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,34 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
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;
}

int __init efi_set_mapping_permissions(struct mm_struct *mm,
efi_memory_desc_t *md)
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);

Expand All @@ -128,7 +140,7 @@ int __init efi_set_mapping_permissions(struct mm_struct *mm,
*/
return apply_to_page_range(mm, md->virt_addr,
md->num_pages << EFI_PAGE_SHIFT,
set_permissions, md);
set_permissions, &data);
}

/*
Expand All @@ -146,7 +158,7 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f)
return s;
}

DEFINE_SPINLOCK(efi_rt_lock);
DEFINE_RAW_SPINLOCK(efi_rt_lock);

asmlinkage u64 *efi_rt_stack_top __ro_after_init;

Expand Down
6 changes: 6 additions & 0 deletions arch/arm64/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#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>
Expand All @@ -34,6 +35,7 @@
#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>
Expand Down Expand Up @@ -491,6 +493,10 @@ void do_el0_bti(struct pt_regs *regs)

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);
}

Expand Down
2 changes: 1 addition & 1 deletion arch/ia64/kernel/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ efi_init (void)
*/
if (efi_systab == NULL)
panic("Whoa! Can't find EFI system table.\n");
if (efi_systab_check_header(&efi_systab->hdr, 1))
if (efi_systab_check_header(&efi_systab->hdr))
panic("Whoa! EFI system table signature incorrect\n");

efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor);
Expand Down
2 changes: 1 addition & 1 deletion arch/riscv/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extern void efi_init(void);
#endif

int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, bool);

#define arch_efi_call_virt_setup() ({ \
sync_kernel_mappings(efi_mm.pgd); \
Expand Down
3 changes: 2 additions & 1 deletion arch/riscv/kernel/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
}

int __init efi_set_mapping_permissions(struct mm_struct *mm,
efi_memory_desc_t *md)
efi_memory_desc_t *md,
bool ignored)
{
BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE &&
md->type != EFI_RUNTIME_SERVICES_DATA);
Expand Down
14 changes: 13 additions & 1 deletion arch/x86/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ static inline void efi_fpu_end(void)

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__); \
Expand All @@ -121,7 +123,7 @@ extern asmlinkage u64 __efi_call(void *fp, ...);

#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; \
Expand Down Expand Up @@ -335,6 +337,16 @@ static inline u32 efi64_convert_status(efi_status_t status)
#define __efi64_argmap_open_volume(prot, file) \
((prot), efi64_zero_upper(file))

/* Memory Attribute Protocol */
#define __efi64_argmap_get_memory_attributes(protocol, phys, size, flags) \
((protocol), __efi64_split(phys), __efi64_split(size), (flags))

#define __efi64_argmap_set_memory_attributes(protocol, phys, size, flags) \
((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags))

#define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \
((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags))

/*
* The macros below handle the plumbing for the argument mapping. To add a
* mapping for a specific EFI method, simply define a macro
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/include/asm/ibt.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static inline bool is_endbr(u32 val)
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__ */
Expand All @@ -100,7 +100,7 @@ extern __noendbr void ibt_restore(u64 save);

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__ */
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/apm_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ static long __apm_bios_call(void *_call)

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,
Expand Down Expand Up @@ -690,7 +690,7 @@ static long __apm_bios_call_simple(void *_call)

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);
Expand Down
5 changes: 3 additions & 2 deletions arch/x86/kernel/cpu/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -571,13 +571,14 @@ __setup("nopku", setup_disable_pku);

#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;
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/platform/efi/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static int __init efi_systab_init(unsigned long phys)
return -ENOMEM;
}

ret = efi_systab_check_header(hdr, 1);
ret = efi_systab_check_header(hdr);
if (ret) {
early_memunmap(p, size);
return ret;
Expand Down
8 changes: 7 additions & 1 deletion arch/x86/platform/efi/efi_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,10 +389,15 @@ static int __init efi_update_mappings(efi_memory_desc_t *md, unsigned long pf)
return err1 || err2;
}

static int __init efi_update_mem_attr(struct mm_struct *mm, efi_memory_desc_t *md)
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;

Expand All @@ -414,6 +419,7 @@ void __init efi_runtime_update_mappings(void)
* 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;
}
Expand Down
12 changes: 11 additions & 1 deletion drivers/firmware/efi/cper_cxl.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

#include <linux/cper.h>
#include "cper_cxl.h"
#include <linux/cxl_err.h>

#define PROT_ERR_VALID_AGENT_TYPE BIT_ULL(0)
#define PROT_ERR_VALID_AGENT_ADDRESS BIT_ULL(1)
Expand All @@ -19,6 +18,17 @@
#define PROT_ERR_VALID_DVSEC BIT_ULL(5)
#define PROT_ERR_VALID_ERROR_LOG BIT_ULL(6)

/* CXL RAS Capability Structure, CXL v3.0 sec 8.2.4.16 */
struct cxl_ras_capability_regs {
u32 uncor_status;
u32 uncor_mask;
u32 uncor_severity;
u32 cor_status;
u32 cor_mask;
u32 cap_control;
u32 header_log[16];
};

static const char * const prot_err_agent_type_strs[] = {
"Restricted CXL Device",
"Restricted CXL Host Downstream Port",
Expand Down
Loading

0 comments on commit 06e1a81

Please sign in to comment.