Skip to content

Commit

Permalink
Merge tag 'efi-fixes-for-v6.2-2' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/efi/efi

Pull EFI fixes from Ard Biesheuvel:
 "Another couple of EFI fixes, of which the first two were already in
  -next when I sent out the previous PR, but they caused some issues on
  non-EFI boots so I let them simmer for a bit longer.

   - ensure the EFI ResetSystem and ACPI PRM calls are recognized as
     users of the EFI runtime, and therefore protected against
     exceptions

   - account for the EFI runtime stack in the stacktrace code

   - remove Matthew Garrett's MAINTAINERS entry for efivarfs"

* tag 'efi-fixes-for-v6.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
  efi: Remove Matthew Garrett as efivarfs maintainer
  arm64: efi: Account for the EFI runtime stack in stack unwinder
  arm64: efi: Avoid workqueue to check whether EFI runtime is live
  • Loading branch information
Linus Torvalds committed Jan 23, 2023
2 parents 2475bf0 + e1fabbc commit 9946f09
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 2 deletions.
1 change: 0 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7615,7 +7615,6 @@ S: Maintained
F: drivers/firmware/efi/test/

EFI VARIABLE FILESYSTEM
M: Matthew Garrett <matthew.garrett@nebula.com>
M: Jeremy Kerr <jk@ozlabs.org>
M: Ard Biesheuvel <ardb@kernel.org>
L: linux-efi@vger.kernel.org
Expand Down
9 changes: 9 additions & 0 deletions arch/arm64/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,17 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
})

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

/*
* efi_rt_stack_top[-1] contains the value the stack pointer had before
* switching to the EFI runtime stack.
*/
#define current_in_efi() \
(!preemptible() && efi_rt_stack_top != NULL && \
on_task_stack(current, READ_ONCE(efi_rt_stack_top[-1]), 1))

#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)

/*
Expand Down
15 changes: 15 additions & 0 deletions arch/arm64/include/asm/stacktrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,19 @@ static inline struct stack_info stackinfo_get_sdei_critical(void)
#define stackinfo_get_sdei_critical() stackinfo_get_unknown()
#endif

#ifdef CONFIG_EFI
extern u64 *efi_rt_stack_top;

static inline struct stack_info stackinfo_get_efi(void)
{
unsigned long high = (u64)efi_rt_stack_top;
unsigned long low = high - THREAD_SIZE;

return (struct stack_info) {
.low = low,
.high = high,
};
}
#endif

#endif /* __ASM_STACKTRACE_H */
6 changes: 6 additions & 0 deletions arch/arm64/kernel/efi-rt-wrapper.S
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ SYM_FUNC_START(__efi_rt_asm_wrapper)
mov x4, x6
blr x8

mov x16, sp
mov sp, x29
str xzr, [x16, #8] // clear recorded task SP value

ldp x1, x2, [sp, #16]
cmp x2, x18
ldp x29, x30, [sp], #112
Expand All @@ -71,6 +74,9 @@ SYM_FUNC_END(__efi_rt_asm_wrapper)
SYM_CODE_START(__efi_rt_asm_recover)
mov sp, x30

ldr_l x16, efi_rt_stack_top // clear recorded task SP value
str xzr, [x16, #-8]

ldp x19, x20, [sp, #32]
ldp x21, x22, [sp, #48]
ldp x23, x24, [sp, #64]
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/kernel/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/init.h>

#include <asm/efi.h>
#include <asm/stacktrace.h>

static bool region_is_misaligned(const efi_memory_desc_t *md)
{
Expand Down Expand Up @@ -154,7 +155,7 @@ asmlinkage efi_status_t __efi_rt_asm_recover(void);
bool efi_runtime_fixup_exception(struct pt_regs *regs, const char *msg)
{
/* Check whether the exception occurred while running the firmware */
if (current_work() != &efi_rts_work.work || regs->pc >= TASK_SIZE_64)
if (!current_in_efi() || regs->pc >= TASK_SIZE_64)
return false;

pr_err(FW_BUG "Unable to handle %s in EFI runtime service\n", msg);
Expand Down
12 changes: 12 additions & 0 deletions arch/arm64/kernel/stacktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
* Copyright (C) 2012 ARM Ltd.
*/
#include <linux/kernel.h>
#include <linux/efi.h>
#include <linux/export.h>
#include <linux/ftrace.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/task_stack.h>
#include <linux/stacktrace.h>

#include <asm/efi.h>
#include <asm/irq.h>
#include <asm/stack_pointer.h>
#include <asm/stacktrace.h>
Expand Down Expand Up @@ -186,6 +188,13 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
: stackinfo_get_unknown(); \
})

#define STACKINFO_EFI \
({ \
((task == current) && current_in_efi()) \
? stackinfo_get_efi() \
: stackinfo_get_unknown(); \
})

noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
void *cookie, struct task_struct *task,
struct pt_regs *regs)
Expand All @@ -199,6 +208,9 @@ noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
#if defined(CONFIG_VMAP_STACK) && defined(CONFIG_ARM_SDE_INTERFACE)
STACKINFO_SDEI(normal),
STACKINFO_SDEI(critical),
#endif
#ifdef CONFIG_EFI
STACKINFO_EFI,
#endif
};
struct unwind_state state = {
Expand Down

0 comments on commit 9946f09

Please sign in to comment.