* [PATCH v4 resend 1/7] efi: Add missing static initializer for efi_mm::cpus_allowed_lock
2025-10-15 20:56 [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Ard Biesheuvel
@ 2025-10-15 20:56 ` Ard Biesheuvel
2025-10-15 20:56 ` [PATCH v4 resend 2/7] efi/runtime-wrappers: Keep track of the efi_runtime_lock owner Ard Biesheuvel
` (7 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2025-10-15 20:56 UTC (permalink / raw)
To: linux-efi
Cc: linux-kernel, linux-arm-kernel, Ard Biesheuvel, Will Deacon,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Catalin Marinas, Mark Brown, Pierre Gondois, Sami Mujawar, stable
From: Ard Biesheuvel <ardb@kernel.org>
Initialize the cpus_allowed_lock struct member of efi_mm.
Cc: <stable@vger.kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
drivers/firmware/efi/efi.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 1ce428e2ac8a..fc407d891348 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -74,6 +74,9 @@ struct mm_struct efi_mm = {
.page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
.mmlist = LIST_HEAD_INIT(efi_mm.mmlist),
.cpu_bitmap = { [BITS_TO_LONGS(NR_CPUS)] = 0},
+#ifdef CONFIG_SCHED_MM_CID
+ .cpus_allowed_lock = __RAW_SPIN_LOCK_UNLOCKED(efi_mm.cpus_allowed_lock),
+#endif
};
struct workqueue_struct *efi_rts_wq;
--
2.51.0.869.ge66316f041-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v4 resend 2/7] efi/runtime-wrappers: Keep track of the efi_runtime_lock owner
2025-10-15 20:56 [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Ard Biesheuvel
2025-10-15 20:56 ` [PATCH v4 resend 1/7] efi: Add missing static initializer for efi_mm::cpus_allowed_lock Ard Biesheuvel
@ 2025-10-15 20:56 ` Ard Biesheuvel
2025-10-15 20:56 ` [PATCH v4 resend 3/7] arm64/fpsimd: Don't warn when EFI execution context is preemptible Ard Biesheuvel
` (6 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2025-10-15 20:56 UTC (permalink / raw)
To: linux-efi
Cc: linux-kernel, linux-arm-kernel, Ard Biesheuvel, Will Deacon,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Catalin Marinas, Mark Brown, Pierre Gondois, Sami Mujawar
From: Ard Biesheuvel <ardb@kernel.org>
The EFI runtime wrappers use a file local semaphore to serialize access
to the EFI runtime services. This means that any calls to the arch
wrappers around the runtime services will also be serialized, removing
the need for redundant locking.
For robustness, add a facility that allows those arch wrappers to assert
that the semaphore was taken by the current task.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
drivers/firmware/efi/runtime-wrappers.c | 17 ++++++++++++++++-
include/linux/efi.h | 2 ++
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
index 708b777857d3..da8d29621644 100644
--- a/drivers/firmware/efi/runtime-wrappers.c
+++ b/drivers/firmware/efi/runtime-wrappers.c
@@ -202,6 +202,8 @@ void efi_call_virt_check_flags(unsigned long flags, const void *caller)
*/
static DEFINE_SEMAPHORE(efi_runtime_lock, 1);
+static struct task_struct *efi_runtime_lock_owner;
+
/*
* Expose the EFI runtime lock to the UV platform
*/
@@ -219,6 +221,8 @@ static void __nocfi efi_call_rts(struct work_struct *work)
efi_status_t status = EFI_NOT_FOUND;
unsigned long flags;
+ efi_runtime_lock_owner = current;
+
arch_efi_call_virt_setup();
flags = efi_call_virt_save_flags();
@@ -310,6 +314,7 @@ static void __nocfi efi_call_rts(struct work_struct *work)
efi_rts_work.status = status;
complete(&efi_rts_work.efi_rts_comp);
+ efi_runtime_lock_owner = NULL;
}
static efi_status_t __efi_queue_work(enum efi_rts_ids id,
@@ -444,8 +449,10 @@ virt_efi_set_variable_nb(efi_char16_t *name, efi_guid_t *vendor, u32 attr,
if (down_trylock(&efi_runtime_lock))
return EFI_NOT_READY;
+ efi_runtime_lock_owner = current;
status = efi_call_virt_pointer(efi.runtime, set_variable, name, vendor,
attr, data_size, data);
+ efi_runtime_lock_owner = NULL;
up(&efi_runtime_lock);
return status;
}
@@ -481,9 +488,11 @@ virt_efi_query_variable_info_nb(u32 attr, u64 *storage_space,
if (down_trylock(&efi_runtime_lock))
return EFI_NOT_READY;
+ efi_runtime_lock_owner = current;
status = efi_call_virt_pointer(efi.runtime, query_variable_info, attr,
storage_space, remaining_space,
max_variable_size);
+ efi_runtime_lock_owner = NULL;
up(&efi_runtime_lock);
return status;
}
@@ -509,12 +518,13 @@ virt_efi_reset_system(int reset_type, efi_status_t status,
return;
}
+ efi_runtime_lock_owner = current;
arch_efi_call_virt_setup();
efi_rts_work.efi_rts_id = EFI_RESET_SYSTEM;
arch_efi_call_virt(efi.runtime, reset_system, reset_type, status,
data_size, data);
arch_efi_call_virt_teardown();
-
+ efi_runtime_lock_owner = NULL;
up(&efi_runtime_lock);
}
@@ -587,3 +597,8 @@ efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *),
}
#endif
+
+void efi_runtime_assert_lock_held(void)
+{
+ WARN_ON(efi_runtime_lock_owner != current);
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index a98cc39e7aaa..b23ff8b83219 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1126,6 +1126,8 @@ static inline bool efi_runtime_disabled(void) { return true; }
extern void efi_call_virt_check_flags(unsigned long flags, const void *caller);
extern unsigned long efi_call_virt_save_flags(void);
+void efi_runtime_assert_lock_held(void);
+
enum efi_secureboot_mode {
efi_secureboot_mode_unset,
efi_secureboot_mode_unknown,
--
2.51.0.869.ge66316f041-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v4 resend 3/7] arm64/fpsimd: Don't warn when EFI execution context is preemptible
2025-10-15 20:56 [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Ard Biesheuvel
2025-10-15 20:56 ` [PATCH v4 resend 1/7] efi: Add missing static initializer for efi_mm::cpus_allowed_lock Ard Biesheuvel
2025-10-15 20:56 ` [PATCH v4 resend 2/7] efi/runtime-wrappers: Keep track of the efi_runtime_lock owner Ard Biesheuvel
@ 2025-10-15 20:56 ` Ard Biesheuvel
2025-11-04 15:52 ` Will Deacon
2025-10-15 20:56 ` [PATCH v4 resend 4/7] arm64/fpsimd: Permit kernel mode NEON with IRQs off Ard Biesheuvel
` (5 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Ard Biesheuvel @ 2025-10-15 20:56 UTC (permalink / raw)
To: linux-efi
Cc: linux-kernel, linux-arm-kernel, Ard Biesheuvel, Will Deacon,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Catalin Marinas, Mark Brown, Pierre Gondois, Sami Mujawar
From: Ard Biesheuvel <ardb@kernel.org>
Kernel mode FP/SIMD no longer requires preemption to be disabled, so
only warn on uses of FP/SIMD from preemptible context if the fallback
path is taken for cases where kernel mode NEON would not be allowed
otherwise.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/kernel/fpsimd.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index e3f8f51748bc..3d848c89604e 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1934,11 +1934,11 @@ void __efi_fpsimd_begin(void)
if (!system_supports_fpsimd())
return;
- WARN_ON(preemptible());
-
if (may_use_simd()) {
kernel_neon_begin();
} else {
+ WARN_ON(preemptible());
+
/*
* If !efi_sve_state, SVE can't be in use yet and doesn't need
* preserving:
--
2.51.0.869.ge66316f041-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v4 resend 3/7] arm64/fpsimd: Don't warn when EFI execution context is preemptible
2025-10-15 20:56 ` [PATCH v4 resend 3/7] arm64/fpsimd: Don't warn when EFI execution context is preemptible Ard Biesheuvel
@ 2025-11-04 15:52 ` Will Deacon
2025-11-04 16:00 ` Ard Biesheuvel
0 siblings, 1 reply; 15+ messages in thread
From: Will Deacon @ 2025-11-04 15:52 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-efi, linux-kernel, linux-arm-kernel, Ard Biesheuvel,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Catalin Marinas, Mark Brown, Pierre Gondois, Sami Mujawar
On Wed, Oct 15, 2025 at 10:56:38PM +0200, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
>
> Kernel mode FP/SIMD no longer requires preemption to be disabled, so
> only warn on uses of FP/SIMD from preemptible context if the fallback
> path is taken for cases where kernel mode NEON would not be allowed
> otherwise.
>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
> arch/arm64/kernel/fpsimd.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index e3f8f51748bc..3d848c89604e 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -1934,11 +1934,11 @@ void __efi_fpsimd_begin(void)
> if (!system_supports_fpsimd())
> return;
>
> - WARN_ON(preemptible());
> -
> if (may_use_simd()) {
> kernel_neon_begin();
> } else {
> + WARN_ON(preemptible());
> +
Given that may_use_simd() returns false on systems without support for
fpsimd, I wonder whether moving this WARN_ON() actually helps with
anything. That is, you probably shouldn't be calling __efi_fpsimd_begin()
from preemptible code regardless, no?
Will
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH v4 resend 3/7] arm64/fpsimd: Don't warn when EFI execution context is preemptible
2025-11-04 15:52 ` Will Deacon
@ 2025-11-04 16:00 ` Ard Biesheuvel
2025-11-04 16:16 ` Will Deacon
0 siblings, 1 reply; 15+ messages in thread
From: Ard Biesheuvel @ 2025-11-04 16:00 UTC (permalink / raw)
To: Will Deacon
Cc: Ard Biesheuvel, linux-efi, linux-kernel, linux-arm-kernel,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Catalin Marinas, Mark Brown, Pierre Gondois, Sami Mujawar
On Tue, 4 Nov 2025 at 16:52, Will Deacon <will@kernel.org> wrote:
>
> On Wed, Oct 15, 2025 at 10:56:38PM +0200, Ard Biesheuvel wrote:
> > From: Ard Biesheuvel <ardb@kernel.org>
> >
> > Kernel mode FP/SIMD no longer requires preemption to be disabled, so
> > only warn on uses of FP/SIMD from preemptible context if the fallback
> > path is taken for cases where kernel mode NEON would not be allowed
> > otherwise.
> >
> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > ---
> > arch/arm64/kernel/fpsimd.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> > index e3f8f51748bc..3d848c89604e 100644
> > --- a/arch/arm64/kernel/fpsimd.c
> > +++ b/arch/arm64/kernel/fpsimd.c
> > @@ -1934,11 +1934,11 @@ void __efi_fpsimd_begin(void)
> > if (!system_supports_fpsimd())
> > return;
> >
> > - WARN_ON(preemptible());
> > -
> > if (may_use_simd()) {
> > kernel_neon_begin();
> > } else {
> > + WARN_ON(preemptible());
> > +
>
> Given that may_use_simd() returns false on systems without support for
> fpsimd, I wonder whether moving this WARN_ON() actually helps with
> anything.
This code is only reachable if system_supports_fpsimd() returns true,
so may_use_simd() will only return false here when running in
hardirq/NMI context.
> That is, you probably shouldn't be calling __efi_fpsimd_begin()
> from preemptible code regardless, no?
>
Not sure I follow you here: __efi_fpsimd_begin() is generally called
from preemptible code, and it is the EFI runtime wrappers themselves
that disable preemption - that is the whole point of this series.
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH v4 resend 3/7] arm64/fpsimd: Don't warn when EFI execution context is preemptible
2025-11-04 16:00 ` Ard Biesheuvel
@ 2025-11-04 16:16 ` Will Deacon
0 siblings, 0 replies; 15+ messages in thread
From: Will Deacon @ 2025-11-04 16:16 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Ard Biesheuvel, linux-efi, linux-kernel, linux-arm-kernel,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Catalin Marinas, Mark Brown, Pierre Gondois, Sami Mujawar
On Tue, Nov 04, 2025 at 05:00:34PM +0100, Ard Biesheuvel wrote:
> On Tue, 4 Nov 2025 at 16:52, Will Deacon <will@kernel.org> wrote:
> >
> > On Wed, Oct 15, 2025 at 10:56:38PM +0200, Ard Biesheuvel wrote:
> > > From: Ard Biesheuvel <ardb@kernel.org>
> > >
> > > Kernel mode FP/SIMD no longer requires preemption to be disabled, so
> > > only warn on uses of FP/SIMD from preemptible context if the fallback
> > > path is taken for cases where kernel mode NEON would not be allowed
> > > otherwise.
> > >
> > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > > ---
> > > arch/arm64/kernel/fpsimd.c | 4 ++--
> > > 1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> > > index e3f8f51748bc..3d848c89604e 100644
> > > --- a/arch/arm64/kernel/fpsimd.c
> > > +++ b/arch/arm64/kernel/fpsimd.c
> > > @@ -1934,11 +1934,11 @@ void __efi_fpsimd_begin(void)
> > > if (!system_supports_fpsimd())
> > > return;
> > >
> > > - WARN_ON(preemptible());
> > > -
> > > if (may_use_simd()) {
> > > kernel_neon_begin();
> > > } else {
> > > + WARN_ON(preemptible());
> > > +
> >
> > Given that may_use_simd() returns false on systems without support for
> > fpsimd, I wonder whether moving this WARN_ON() actually helps with
> > anything.
>
> This code is only reachable if system_supports_fpsimd() returns true,
> so may_use_simd() will only return false here when running in
> hardirq/NMI context.
Sorry, I missed the check _right at the top of the hunk_!
>
> > That is, you probably shouldn't be calling __efi_fpsimd_begin()
> > from preemptible code regardless, no?
> >
>
> Not sure I follow you here: __efi_fpsimd_begin() is generally called
> from preemptible code, and it is the EFI runtime wrappers themselves
> that disable preemption - that is the whole point of this series.
Ignore me. I was reviewing this against the upstream
arch_efi_call_virt_setup/teardown() functions rather than in the context
of the changes made later in this series (specifically patch 5).
Will
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 resend 4/7] arm64/fpsimd: Permit kernel mode NEON with IRQs off
2025-10-15 20:56 [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Ard Biesheuvel
` (2 preceding siblings ...)
2025-10-15 20:56 ` [PATCH v4 resend 3/7] arm64/fpsimd: Don't warn when EFI execution context is preemptible Ard Biesheuvel
@ 2025-10-15 20:56 ` Ard Biesheuvel
2025-10-15 20:56 ` [PATCH v4 resend 5/7] arm64/efi: Drop efi_rt_lock spinlock from EFI arch wrapper Ard Biesheuvel
` (4 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2025-10-15 20:56 UTC (permalink / raw)
To: linux-efi
Cc: linux-kernel, linux-arm-kernel, Ard Biesheuvel, Will Deacon,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Catalin Marinas, Mark Brown, Pierre Gondois, Sami Mujawar
From: Ard Biesheuvel <ardb@kernel.org>
Currently, may_use_simd() will return false when called from a context
where IRQs are disabled. One notable case where this happens is when
calling the ResetSystem() EFI runtime service from the reboot/poweroff
code path. For this case alone, there is a substantial amount of FP/SIMD
support code to handle the corner case where a EFI runtime service is
invoked with IRQs disabled.
The only reason kernel mode SIMD is not allowed when IRQs are disabled
is that re-enabling softirqs in this case produces a noisy diagnostic
when lockdep is enabled. The warning is valid, in the sense that
delivering pending softirqs over the back of the call to
local_bh_enable() is problematic when IRQs are disabled.
While the API lacks a facility to simply mask and unmask softirqs
without triggering their delivery, disabling softirqs is not needed to
begin with when IRQs are disabled, given that softirqs are only every
taken asynchronously over the back of a hard IRQ.
So dis/enable softirq processing conditionally, based on whether IRQs
are enabled, and relax the check in may_use_simd().
Acked-by: Will Deacon <will@kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/include/asm/simd.h | 2 +-
arch/arm64/kernel/fpsimd.c | 25 +++++++++++++++-----
2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/include/asm/simd.h b/arch/arm64/include/asm/simd.h
index 8e86c9e70e48..abd642c92f86 100644
--- a/arch/arm64/include/asm/simd.h
+++ b/arch/arm64/include/asm/simd.h
@@ -29,7 +29,7 @@ static __must_check inline bool may_use_simd(void)
*/
return !WARN_ON(!system_capabilities_finalized()) &&
system_supports_fpsimd() &&
- !in_hardirq() && !irqs_disabled() && !in_nmi();
+ !in_hardirq() && !in_nmi();
}
#else /* ! CONFIG_KERNEL_MODE_NEON */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 3d848c89604e..6d956ed23bd2 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -225,10 +225,21 @@ static void fpsimd_bind_task_to_cpu(void);
*/
static void get_cpu_fpsimd_context(void)
{
- if (!IS_ENABLED(CONFIG_PREEMPT_RT))
- local_bh_disable();
- else
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
+ /*
+ * The softirq subsystem lacks a true unmask/mask API, and
+ * re-enabling softirq processing using local_bh_enable() will
+ * not only unmask softirqs, it will also result in immediate
+ * delivery of any pending softirqs.
+ * This is undesirable when running with IRQs disabled, but in
+ * that case, there is no need to mask softirqs in the first
+ * place, so only bother doing so when IRQs are enabled.
+ */
+ if (!irqs_disabled())
+ local_bh_disable();
+ } else {
preempt_disable();
+ }
}
/*
@@ -240,10 +251,12 @@ static void get_cpu_fpsimd_context(void)
*/
static void put_cpu_fpsimd_context(void)
{
- if (!IS_ENABLED(CONFIG_PREEMPT_RT))
- local_bh_enable();
- else
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
+ if (!irqs_disabled())
+ local_bh_enable();
+ } else {
preempt_enable();
+ }
}
unsigned int task_get_vl(const struct task_struct *task, enum vec_type type)
--
2.51.0.869.ge66316f041-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v4 resend 5/7] arm64/efi: Drop efi_rt_lock spinlock from EFI arch wrapper
2025-10-15 20:56 [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Ard Biesheuvel
` (3 preceding siblings ...)
2025-10-15 20:56 ` [PATCH v4 resend 4/7] arm64/fpsimd: Permit kernel mode NEON with IRQs off Ard Biesheuvel
@ 2025-10-15 20:56 ` Ard Biesheuvel
2025-10-15 20:56 ` [PATCH v4 resend 6/7] arm64/efi: Move uaccess en/disable out of efi_set_pgd() Ard Biesheuvel
` (3 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2025-10-15 20:56 UTC (permalink / raw)
To: linux-efi
Cc: linux-kernel, linux-arm-kernel, Ard Biesheuvel, Will Deacon,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Catalin Marinas, Mark Brown, Pierre Gondois, Sami Mujawar
From: Ard Biesheuvel <ardb@kernel.org>
Since commit
5894cf571e14 ("acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers")
all EFI runtime calls on arm64 are routed via the EFI runtime wrappers,
which are serialized using the efi_runtime_lock semaphore.
This means the efi_rt_lock spinlock in the arm64 arch wrapper code has
become redundant, and can be dropped. For robustness, replace it with an
assert that the EFI runtime lock is in fact held by 'current'.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/kernel/efi.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 6c371b158b99..0094f5938ba6 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -165,19 +165,16 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f)
return s;
}
-static DEFINE_RAW_SPINLOCK(efi_rt_lock);
-
void arch_efi_call_virt_setup(void)
{
+ efi_runtime_assert_lock_held();
efi_virtmap_load();
- raw_spin_lock(&efi_rt_lock);
__efi_fpsimd_begin();
}
void arch_efi_call_virt_teardown(void)
{
__efi_fpsimd_end();
- raw_spin_unlock(&efi_rt_lock);
efi_virtmap_unload();
}
--
2.51.0.869.ge66316f041-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v4 resend 6/7] arm64/efi: Move uaccess en/disable out of efi_set_pgd()
2025-10-15 20:56 [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Ard Biesheuvel
` (4 preceding siblings ...)
2025-10-15 20:56 ` [PATCH v4 resend 5/7] arm64/efi: Drop efi_rt_lock spinlock from EFI arch wrapper Ard Biesheuvel
@ 2025-10-15 20:56 ` Ard Biesheuvel
2025-10-15 20:56 ` [PATCH v4 resend 7/7] arm64/efi: Call EFI runtime services without disabling preemption Ard Biesheuvel
` (2 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2025-10-15 20:56 UTC (permalink / raw)
To: linux-efi
Cc: linux-kernel, linux-arm-kernel, Ard Biesheuvel, Will Deacon,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Catalin Marinas, Mark Brown, Pierre Gondois, Sami Mujawar
From: Ard Biesheuvel <ardb@kernel.org>
efi_set_pgd() will no longer be called when invoking EFI runtime
services via the efi_rts_wq work queue, but the uaccess en/disable are
still needed when using PAN emulation using TTBR0 switching. So move
these into the callers.
Acked-by: Will Deacon <will@kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/include/asm/efi.h | 13 +++----------
arch/arm64/kernel/efi.c | 18 ++++++++++++++++++
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index bcd5622aa096..aa91165ca140 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -126,21 +126,14 @@ static inline void efi_set_pgd(struct mm_struct *mm)
if (mm != current->active_mm) {
/*
* Update the current thread's saved ttbr0 since it is
- * restored as part of a return from exception. Enable
- * access to the valid TTBR0_EL1 and invoke the errata
- * workaround directly since there is no return from
- * exception when invoking the EFI run-time services.
+ * restored as part of a return from exception.
*/
update_saved_ttbr0(current, mm);
- uaccess_ttbr0_enable();
- post_ttbr_update_workaround();
} else {
/*
- * Defer the switch to the current thread's TTBR0_EL1
- * until uaccess_enable(). Restore the current
- * thread's saved ttbr0 corresponding to its active_mm
+ * Restore the current thread's saved ttbr0
+ * corresponding to its active_mm
*/
- uaccess_ttbr0_disable();
update_saved_ttbr0(current, current->active_mm);
}
}
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 0094f5938ba6..85f65d5c863c 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -169,12 +169,30 @@ void arch_efi_call_virt_setup(void)
{
efi_runtime_assert_lock_held();
efi_virtmap_load();
+
+ /*
+ * Enable access to the valid TTBR0_EL1 and invoke the errata
+ * workaround directly since there is no return from exception when
+ * invoking the EFI run-time services.
+ */
+ uaccess_ttbr0_enable();
+ post_ttbr_update_workaround();
+
__efi_fpsimd_begin();
}
void arch_efi_call_virt_teardown(void)
{
__efi_fpsimd_end();
+
+ /*
+ * Defer the switch to the current thread's TTBR0_EL1 until
+ * uaccess_enable(). Do so before efi_virtmap_unload() updates the
+ * saved TTBR0 value, so the userland page tables are not activated
+ * inadvertently over the back of an exception.
+ */
+ uaccess_ttbr0_disable();
+
efi_virtmap_unload();
}
--
2.51.0.869.ge66316f041-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v4 resend 7/7] arm64/efi: Call EFI runtime services without disabling preemption
2025-10-15 20:56 [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Ard Biesheuvel
` (5 preceding siblings ...)
2025-10-15 20:56 ` [PATCH v4 resend 6/7] arm64/efi: Move uaccess en/disable out of efi_set_pgd() Ard Biesheuvel
@ 2025-10-15 20:56 ` Ard Biesheuvel
2025-11-11 18:45 ` [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Catalin Marinas
2025-11-11 20:16 ` Catalin Marinas
8 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2025-10-15 20:56 UTC (permalink / raw)
To: linux-efi
Cc: linux-kernel, linux-arm-kernel, Ard Biesheuvel, Will Deacon,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Catalin Marinas, Mark Brown, Pierre Gondois, Sami Mujawar
From: Ard Biesheuvel <ardb@kernel.org>
The only remaining reason why EFI runtime services are invoked with
preemption disabled is the fact that the mm is swapped out behind the
back of the context switching code.
The kernel no longer disables preemption in kernel_neon_begin().
Furthermore, the EFI spec is being clarified to explicitly state that
only baseline FP/SIMD is permitted in EFI runtime service
implementations, and so the existing kernel mode NEON context switching
code is sufficient to preserve and restore the execution context of an
in-progress EFI runtime service call.
Most EFI calls are made from the efi_rts_wq, which is serviced by a
kthread. As kthreads never return to user space, they usually don't have
an mm, and so we can use the existing infrastructure to swap in the
efi_mm while the EFI call is in progress. This is visible to the
scheduler, which will therefore reactivate the selected mm when
switching out the kthread and back in again.
Given that the EFI spec explicitly permits runtime services to be called
with interrupts enabled, firmware code is already required to tolerate
interruptions. So rather than disable preemption, disable only migration
so that EFI runtime services are less likely to cause scheduling delays.
To avoid potential issues where runtime services are interrupted while
polling the secure firmware for async completions, keep migration
disabled so that a runtime service invocation does not resume on a
different CPU from the one it was started on.
Note, though, that the firmware executes at the same privilege level as
the kernel, and is therefore able to disable interrupts altogether.
Acked-by: Will Deacon <will@kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/kernel/efi.c | 23 ++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 85f65d5c863c..a81cb4aa4738 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -10,6 +10,7 @@
#include <linux/efi.h>
#include <linux/init.h>
#include <linux/kmemleak.h>
+#include <linux/kthread.h>
#include <linux/screen_info.h>
#include <linux/vmalloc.h>
@@ -168,7 +169,20 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f)
void arch_efi_call_virt_setup(void)
{
efi_runtime_assert_lock_held();
- efi_virtmap_load();
+
+ if (preemptible() && (current->flags & PF_KTHREAD)) {
+ /*
+ * Disable migration to ensure that a preempted EFI runtime
+ * service call will be resumed on the same CPU. This avoids
+ * potential issues with EFI runtime calls that are preempted
+ * while polling for an asynchronous completion of a secure
+ * firmware call, which may not permit the CPU to change.
+ */
+ migrate_disable();
+ kthread_use_mm(&efi_mm);
+ } else {
+ efi_virtmap_load();
+ }
/*
* Enable access to the valid TTBR0_EL1 and invoke the errata
@@ -193,7 +207,12 @@ void arch_efi_call_virt_teardown(void)
*/
uaccess_ttbr0_disable();
- efi_virtmap_unload();
+ if (preemptible() && (current->flags & PF_KTHREAD)) {
+ kthread_unuse_mm(&efi_mm);
+ migrate_enable();
+ } else {
+ efi_virtmap_unload();
+ }
}
asmlinkage u64 *efi_rt_stack_top __ro_after_init;
--
2.51.0.869.ge66316f041-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible
2025-10-15 20:56 [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Ard Biesheuvel
` (6 preceding siblings ...)
2025-10-15 20:56 ` [PATCH v4 resend 7/7] arm64/efi: Call EFI runtime services without disabling preemption Ard Biesheuvel
@ 2025-11-11 18:45 ` Catalin Marinas
2025-11-11 18:50 ` Ard Biesheuvel
2025-11-11 20:16 ` Catalin Marinas
8 siblings, 1 reply; 15+ messages in thread
From: Catalin Marinas @ 2025-11-11 18:45 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-efi, linux-kernel, linux-arm-kernel, Ard Biesheuvel,
Will Deacon, Mark Rutland, Sebastian Andrzej Siewior,
Peter Zijlstra, Mark Brown, Pierre Gondois, Sami Mujawar
On Wed, Oct 15, 2025 at 10:56:35PM +0200, Ard Biesheuvel wrote:
> Ard Biesheuvel (7):
> efi: Add missing static initializer for efi_mm::cpus_allowed_lock
> efi/runtime-wrappers: Keep track of the efi_runtime_lock owner
> arm64/fpsimd: Don't warn when EFI execution context is preemptible
> arm64/fpsimd: Permit kernel mode NEON with IRQs off
> arm64/efi: Drop efi_rt_lock spinlock from EFI arch wrapper
> arm64/efi: Move uaccess en/disable out of efi_set_pgd()
> arm64/efi: Call EFI runtime services without disabling preemption
The series looks fine to me:
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
What do you plan to do with this, merge via the EFI tree? Are there any
dependencies?
--
Catalin
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible
2025-11-11 18:45 ` [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Catalin Marinas
@ 2025-11-11 18:50 ` Ard Biesheuvel
2025-11-11 18:59 ` Catalin Marinas
0 siblings, 1 reply; 15+ messages in thread
From: Ard Biesheuvel @ 2025-11-11 18:50 UTC (permalink / raw)
To: Catalin Marinas
Cc: Ard Biesheuvel, linux-efi, linux-kernel, linux-arm-kernel,
Will Deacon, Mark Rutland, Sebastian Andrzej Siewior,
Peter Zijlstra, Mark Brown, Pierre Gondois, Sami Mujawar
On Tue, 11 Nov 2025 at 19:45, Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> On Wed, Oct 15, 2025 at 10:56:35PM +0200, Ard Biesheuvel wrote:
> > Ard Biesheuvel (7):
> > efi: Add missing static initializer for efi_mm::cpus_allowed_lock
> > efi/runtime-wrappers: Keep track of the efi_runtime_lock owner
> > arm64/fpsimd: Don't warn when EFI execution context is preemptible
> > arm64/fpsimd: Permit kernel mode NEON with IRQs off
> > arm64/efi: Drop efi_rt_lock spinlock from EFI arch wrapper
> > arm64/efi: Move uaccess en/disable out of efi_set_pgd()
> > arm64/efi: Call EFI runtime services without disabling preemption
>
> The series looks fine to me:
>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
>
> What do you plan to do with this, merge via the EFI tree? Are there any
> dependencies?
>
As you prefer - I can take it via the EFI tree, or you can take it.
There are no conflicts with the other kernel mode FP/SIMD related
changes that we are taking via libcrypto, and there are no other
dependencies that I am aware of.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible
2025-11-11 18:50 ` Ard Biesheuvel
@ 2025-11-11 18:59 ` Catalin Marinas
0 siblings, 0 replies; 15+ messages in thread
From: Catalin Marinas @ 2025-11-11 18:59 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Ard Biesheuvel, linux-efi, linux-kernel, linux-arm-kernel,
Will Deacon, Mark Rutland, Sebastian Andrzej Siewior,
Peter Zijlstra, Mark Brown, Pierre Gondois, Sami Mujawar
On Tue, Nov 11, 2025 at 07:50:49PM +0100, Ard Biesheuvel wrote:
> On Tue, 11 Nov 2025 at 19:45, Catalin Marinas <catalin.marinas@arm.com> wrote:
> >
> > On Wed, Oct 15, 2025 at 10:56:35PM +0200, Ard Biesheuvel wrote:
> > > Ard Biesheuvel (7):
> > > efi: Add missing static initializer for efi_mm::cpus_allowed_lock
> > > efi/runtime-wrappers: Keep track of the efi_runtime_lock owner
> > > arm64/fpsimd: Don't warn when EFI execution context is preemptible
> > > arm64/fpsimd: Permit kernel mode NEON with IRQs off
> > > arm64/efi: Drop efi_rt_lock spinlock from EFI arch wrapper
> > > arm64/efi: Move uaccess en/disable out of efi_set_pgd()
> > > arm64/efi: Call EFI runtime services without disabling preemption
> >
> > The series looks fine to me:
> >
> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> >
> > What do you plan to do with this, merge via the EFI tree? Are there any
> > dependencies?
>
> As you prefer - I can take it via the EFI tree, or you can take it.
> There are no conflicts with the other kernel mode FP/SIMD related
> changes that we are taking via libcrypto, and there are no other
> dependencies that I am aware of.
OK, I'll queue them via arm64 shortly.
--
Catalin
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible
2025-10-15 20:56 [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Ard Biesheuvel
` (7 preceding siblings ...)
2025-11-11 18:45 ` [PATCH v4 resend 0/7] arm64: Make EFI calls preemptible Catalin Marinas
@ 2025-11-11 20:16 ` Catalin Marinas
8 siblings, 0 replies; 15+ messages in thread
From: Catalin Marinas @ 2025-11-11 20:16 UTC (permalink / raw)
To: linux-efi, Ard Biesheuvel
Cc: Will Deacon, linux-kernel, linux-arm-kernel, Ard Biesheuvel,
Mark Rutland, Sebastian Andrzej Siewior, Peter Zijlstra,
Mark Brown, Pierre Gondois, Sami Mujawar
On Wed, 15 Oct 2025 22:56:35 +0200, Ard Biesheuvel wrote:
> The arm64 port permits the use of the baseline FP/SIMD register file in
> kernel mode, and no longer requires preemption to be disabled. Now that
> the EFI spec is being clarified to state that EFI runtime services may
> only use baseline FP/SIMD, the fact that EFI may code may use FP/SIMD
> registers (while executing at the same privilege level as the kernel) is
> no longer a reason to disable preemption when invoking them.
>
> [...]
Applied to arm64 (for-next/efi-preempt), thanks!
[1/7] efi: Add missing static initializer for efi_mm::cpus_allowed_lock
https://git.kernel.org/arm64/c/40374d308e4e
[2/7] efi/runtime-wrappers: Keep track of the efi_runtime_lock owner
https://git.kernel.org/arm64/c/a2860501203c
[3/7] arm64/fpsimd: Don't warn when EFI execution context is preemptible
https://git.kernel.org/arm64/c/1d038e801833
[4/7] arm64/fpsimd: Permit kernel mode NEON with IRQs off
https://git.kernel.org/arm64/c/7137a203b251
[5/7] arm64/efi: Drop efi_rt_lock spinlock from EFI arch wrapper
https://git.kernel.org/arm64/c/1068cb52e8ef
[6/7] arm64/efi: Move uaccess en/disable out of efi_set_pgd()
https://git.kernel.org/arm64/c/6b9c98e65755
[7/7] arm64/efi: Call EFI runtime services without disabling preemption
https://git.kernel.org/arm64/c/a5baf582f4c0
--
Catalin
^ permalink raw reply [flat|nested] 15+ messages in thread