[PATCH] arm64: entry: consolidate Cortex-A76 erratum 1463225 workaround

Will Deacon will at kernel.org
Fri Jan 22 14:17:48 EST 2021


On Fri, Jan 22, 2021 at 11:52:03AM +0000, Mark Rutland wrote:
> The workaround for Cortex-A76 erratum 1463225 is split across the
> syscall and debug handlers in separate files. This structure currently
> forces us to do some redundant work for debug exceptions from EL0, is a
> little difficult to follow, and gets in the way of some future rework of
> the exception entry code as it requires exceptions to be unmasked late
> in the syscall handling path.
> 
> To simplify things, and as a preparatory step for future rework of
> exception entry, this patch moves all the workaround logic into
> entry-common.c. As the debug handler only needs to run for EL1 debug
> exceptions, we no longer call it for EL0 debug exceptions, and no longer
> need to check user_mode(regs) as this is always false. For clarity
> cortex_a76_erratum_1463225_debug_handler() is changed to return bool.
> 
> In the SVC path, the workaround is applied earlier, but this should have
> no functional impact as exceptions are still masked. In the debug path
> we run the fixup before explicitly disabling preemption, but we will not
> attempt to preempt before returning from the exception.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: James Morse <james.morse at arm.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/kernel/cpu_errata.c   |  2 --
>  arch/arm64/kernel/entry-common.c | 54 +++++++++++++++++++++++++++++++++++++++-
>  arch/arm64/kernel/syscall.c      | 30 ----------------------
>  arch/arm64/mm/fault.c            | 32 ------------------------
>  4 files changed, 53 insertions(+), 65 deletions(-)
> 
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index a63428301f42..506a1cd37973 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -107,8 +107,6 @@ cpu_enable_trap_ctr_access(const struct arm64_cpu_capabilities *cap)
>  }
>  
>  #ifdef CONFIG_ARM64_ERRATUM_1463225
> -DEFINE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
> -
>  static bool
>  has_cortex_a76_erratum_1463225(const struct arm64_cpu_capabilities *entry,
>  			       int scope)
> diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
> index 5346953e4382..46a9f9479af9 100644
> --- a/arch/arm64/kernel/entry-common.c
> +++ b/arch/arm64/kernel/entry-common.c
> @@ -109,6 +109,55 @@ asmlinkage void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs)
>  		exit_to_kernel_mode(regs);
>  }
>  
> +#ifdef CONFIG_ARM64_ERRATUM_1463225
> +static DEFINE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
> +
> +static void cortex_a76_erratum_1463225_svc_handler(void)
> +{
> +	u32 reg, val;
> +
> +	if (!unlikely(test_thread_flag(TIF_SINGLESTEP)))
> +		return;
> +
> +	if (!unlikely(this_cpu_has_cap(ARM64_WORKAROUND_1463225)))
> +		return;
> +
> +	__this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 1);
> +	reg = read_sysreg(mdscr_el1);
> +	val = reg | DBG_MDSCR_SS | DBG_MDSCR_KDE;
> +	write_sysreg(val, mdscr_el1);
> +	asm volatile("msr daifclr, #8");
> +	isb();
> +
> +	/* We will have taken a single-step exception by this point */
> +
> +	write_sysreg(reg, mdscr_el1);
> +	__this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 0);
> +}
> +
> +static bool cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
> +{
> +	if (!__this_cpu_read(__in_cortex_a76_erratum_1463225_wa))
> +		return false;
> +
> +	/*
> +	 * We've taken a dummy step exception from the kernel to ensure
> +	 * that interrupts are re-enabled on the syscall path. Return back
> +	 * to cortex_a76_erratum_1463225_svc_handler() with debug exceptions
> +	 * masked so that we can safely restore the mdscr and get on with
> +	 * handling the syscall.
> +	 */
> +	regs->pstate |= PSR_D_BIT;
> +	return true;
> +}
> +#else /* CONFIG_ARM64_ERRATUM_1463225 */
> +static void cortex_a76_erratum_1463225_svc_handler(void) { }
> +static int cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)

This      ^^^ should be bool.

Will



More information about the linux-arm-kernel mailing list