[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