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