ACK: [PATCH][SRU Zesty] arm64: Add CNTFRQ_EL0 trap handler

Colin Ian King colin.king at canonical.com
Tue May 9 21:54:27 UTC 2017


On 08/05/17 18:02, dann frazier wrote:
> From: Marc Zyngier <marc.zyngier at arm.com>
> 
> BugLink http://bugs.launchpad.net/bugs/1688164
> 
> We now trap accesses to CNTVCT_EL0 when the counter is broken
> enough to require the kernel to mediate the access. But it
> turns out that some existing userspace (such as OpenMPI) do
> probe for the counter frequency, leading to an UNDEF exception
> as CNTVCT_EL0 and CNTFRQ_EL0 share the same control bit.
> 
> The fix is to handle the exception the same way we do for CNTVCT_EL0.
> 
> Fixes: a86bd139f2ae ("arm64: arch_timer: Enable CNTVCT_EL0 trap if workaround is enabled")
> Reported-by: Hanjun Guo <guohanjun at huawei.com>
> Tested-by: Hanjun Guo <guohanjun at huawei.com>
> Reviewed-by: Hanjun Guo <guohanjun at huawei.com>
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> (cherry picked from commit 9842119a238bfb92cbab63258dabb54f0e7b111b)
> Signed-off-by: dann frazier <dann.frazier at canonical.com>
> ---
>  arch/arm64/include/asm/esr.h |  4 ++++
>  arch/arm64/kernel/traps.c    | 14 ++++++++++++++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index ad42e79a5d4d..85997c0e5443 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -177,6 +177,10 @@
>  
>  #define ESR_ELx_SYS64_ISS_SYS_CNTVCT	(ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \
>  					 ESR_ELx_SYS64_ISS_DIR_READ)
> +
> +#define ESR_ELx_SYS64_ISS_SYS_CNTFRQ	(ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 0, 14, 0) | \
> +					 ESR_ELx_SYS64_ISS_DIR_READ)
> +
>  #ifndef __ASSEMBLY__
>  #include <asm/types.h>
>  
> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> index cca9ae4b367a..27a74311f2a5 100644
> --- a/arch/arm64/kernel/traps.c
> +++ b/arch/arm64/kernel/traps.c
> @@ -508,6 +508,14 @@ static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
>  	regs->pc += 4;
>  }
>  
> +static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs)
> +{
> +	int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
> +
> +	pt_regs_write_reg(regs, rt, read_sysreg(cntfrq_el0));
> +	regs->pc += 4;
> +}
> +
>  struct sys64_hook {
>  	unsigned int esr_mask;
>  	unsigned int esr_val;
> @@ -532,6 +540,12 @@ static struct sys64_hook sys64_hooks[] = {
>  		.esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCT,
>  		.handler = cntvct_read_handler,
>  	},
> +	{
> +		/* Trap read access to CNTFRQ_EL0 */
> +		.esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK,
> +		.esr_val = ESR_ELx_SYS64_ISS_SYS_CNTFRQ,
> +		.handler = cntfrq_read_handler,
> +	},
>  	{},
>  };
>  
> 

Thanks Dann,

Testing shows this fixes the issue and this is a clean cherry pick that
fixes the this issue.

Acked-by: Colin Ian King <colin.king at canonical.com>




More information about the kernel-team mailing list