[PATCH RFC v9 07/25] arm64: Context-switch POR_EL1
Linu Cherian
linu.cherian at arm.com
Wed Sep 2 22:58:08 PDT 2026
On Tue, Aug 18, 2026 at 03:08:49PM +0100, Kevin Brodsky wrote:
> POR_EL1 is about to be used by the kpkeys framework, modifying it
> for (typically small) sections of code. If an exception occurs
> during that window and scheduling occurs, we must ensure that
> POR_EL1 is context-switched as needed (saving the old value and
> restoring the new one). An ISB is needed to ensure the write takes
> effect, so we skip it if the new value is the same as the old, like
> for POR_EL0.
>
> Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
> ---
> arch/arm64/include/asm/processor.h | 1 +
> arch/arm64/kernel/process.c | 10 ++++++++++
> 2 files changed, 11 insertions(+)
>
> diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
> index c2a627f39314..8d7fa479cd36 100644
> --- a/arch/arm64/include/asm/processor.h
> +++ b/arch/arm64/include/asm/processor.h
> @@ -195,6 +195,7 @@ struct thread_struct {
> u64 svcr;
> u64 tpidr2_el0;
> u64 por_el0;
> + u64 por_el1;
> #ifdef CONFIG_ARM64_GCS
> unsigned int gcs_el0_mode;
> unsigned int gcs_el0_locked;
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 581f80e9b9b7..1dec143decf1 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -51,6 +51,7 @@
> #include <asm/exec.h>
> #include <asm/fpsimd.h>
> #include <asm/gcs.h>
> +#include <asm/kpkeys.h>
> #include <asm/mmu_context.h>
> #include <asm/mpam.h>
> #include <asm/mte.h>
> @@ -431,6 +432,9 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
>
> ptrauth_thread_init_kernel(p);
>
> + if (system_supports_poe())
> + p->thread.por_el1 = POR_EL1_INIT;
> +
> if (likely(!args->fn)) {
> *childregs = *current_pt_regs();
> childregs->regs[0] = 0;
> @@ -681,6 +685,12 @@ static void permission_overlay_switch(struct task_struct *next)
> * of POR_EL0.
> */
> }
> +
> + current->thread.por_el1 = read_sysreg_s(SYS_POR_EL1);
> + if (current->thread.por_el1 != next->thread.por_el1) {
> + write_sysreg_s(next->thread.por_el1, SYS_POR_EL1);
> + isb();
> + }
> }
>
> /*
Reviewed-by: Linu Cherian <linu.cherian at arm.com>
More information about the linux-arm-kernel
mailing list