Skip to content

Commit 9946f09

Browse files
committed
Merge tag 'efi-fixes-for-v6.2-2' of git://git.kernel.org/pub/scm/linux/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
2 parents 2475bf0 + e1fabbc commit 9946f09

File tree

6 files changed

+44
-2
lines changed

6 files changed

+44
-2
lines changed

MAINTAINERS

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7615,7 +7615,6 @@ S: Maintained
76157615
F: drivers/firmware/efi/test/
76167616

76177617
EFI VARIABLE FILESYSTEM
7618-
M: Matthew Garrett <matthew.garrett@nebula.com>
76197618
M: Jeremy Kerr <jk@ozlabs.org>
76207619
M: Ard Biesheuvel <ardb@kernel.org>
76217620
L: linux-efi@vger.kernel.org

arch/arm64/include/asm/efi.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,17 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
4848
})
4949

5050
extern spinlock_t efi_rt_lock;
51+
extern u64 *efi_rt_stack_top;
5152
efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
5253

54+
/*
55+
* efi_rt_stack_top[-1] contains the value the stack pointer had before
56+
* switching to the EFI runtime stack.
57+
*/
58+
#define current_in_efi() \
59+
(!preemptible() && efi_rt_stack_top != NULL && \
60+
on_task_stack(current, READ_ONCE(efi_rt_stack_top[-1]), 1))
61+
5362
#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
5463

5564
/*

arch/arm64/include/asm/stacktrace.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,19 @@ static inline struct stack_info stackinfo_get_sdei_critical(void)
106106
#define stackinfo_get_sdei_critical() stackinfo_get_unknown()
107107
#endif
108108

109+
#ifdef CONFIG_EFI
110+
extern u64 *efi_rt_stack_top;
111+
112+
static inline struct stack_info stackinfo_get_efi(void)
113+
{
114+
unsigned long high = (u64)efi_rt_stack_top;
115+
unsigned long low = high - THREAD_SIZE;
116+
117+
return (struct stack_info) {
118+
.low = low,
119+
.high = high,
120+
};
121+
}
122+
#endif
123+
109124
#endif /* __ASM_STACKTRACE_H */

arch/arm64/kernel/efi-rt-wrapper.S

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ SYM_FUNC_START(__efi_rt_asm_wrapper)
4646
mov x4, x6
4747
blr x8
4848

49+
mov x16, sp
4950
mov sp, x29
51+
str xzr, [x16, #8] // clear recorded task SP value
52+
5053
ldp x1, x2, [sp, #16]
5154
cmp x2, x18
5255
ldp x29, x30, [sp], #112
@@ -71,6 +74,9 @@ SYM_FUNC_END(__efi_rt_asm_wrapper)
7174
SYM_CODE_START(__efi_rt_asm_recover)
7275
mov sp, x30
7376

77+
ldr_l x16, efi_rt_stack_top // clear recorded task SP value
78+
str xzr, [x16, #-8]
79+
7480
ldp x19, x20, [sp, #32]
7581
ldp x21, x22, [sp, #48]
7682
ldp x23, x24, [sp, #64]

arch/arm64/kernel/efi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/init.h>
1212

1313
#include <asm/efi.h>
14+
#include <asm/stacktrace.h>
1415

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

160161
pr_err(FW_BUG "Unable to handle %s in EFI runtime service\n", msg);

arch/arm64/kernel/stacktrace.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
* Copyright (C) 2012 ARM Ltd.
66
*/
77
#include <linux/kernel.h>
8+
#include <linux/efi.h>
89
#include <linux/export.h>
910
#include <linux/ftrace.h>
1011
#include <linux/sched.h>
1112
#include <linux/sched/debug.h>
1213
#include <linux/sched/task_stack.h>
1314
#include <linux/stacktrace.h>
1415

16+
#include <asm/efi.h>
1517
#include <asm/irq.h>
1618
#include <asm/stack_pointer.h>
1719
#include <asm/stacktrace.h>
@@ -186,6 +188,13 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
186188
: stackinfo_get_unknown(); \
187189
})
188190

191+
#define STACKINFO_EFI \
192+
({ \
193+
((task == current) && current_in_efi()) \
194+
? stackinfo_get_efi() \
195+
: stackinfo_get_unknown(); \
196+
})
197+
189198
noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
190199
void *cookie, struct task_struct *task,
191200
struct pt_regs *regs)
@@ -199,6 +208,9 @@ noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
199208
#if defined(CONFIG_VMAP_STACK) && defined(CONFIG_ARM_SDE_INTERFACE)
200209
STACKINFO_SDEI(normal),
201210
STACKINFO_SDEI(critical),
211+
#endif
212+
#ifdef CONFIG_EFI
213+
STACKINFO_EFI,
202214
#endif
203215
};
204216
struct unwind_state state = {

0 commit comments

Comments
 (0)