Loading arch/arm64/include/asm/esr.h +6 −0 Original line number Diff line number Diff line Loading @@ -175,6 +175,12 @@ #define ESR_ELx_SYS64_ISS_SYS_CTR_READ (ESR_ELx_SYS64_ISS_SYS_CTR | \ ESR_ELx_SYS64_ISS_DIR_READ) #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> Loading arch/arm64/kernel/traps.c +32 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <linux/syscalls.h> #include <asm/atomic.h> #include <asm/barrier.h> #include <asm/bug.h> #include <asm/debug-monitors.h> #include <asm/esr.h> Loading Loading @@ -540,6 +541,25 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs) regs->pc += 4; } static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs) { int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; isb(); if (rt != 31) regs->regs[rt] = arch_counter_get_cntvct(); 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; if (rt != 31) regs->regs[rt] = read_sysreg(cntfrq_el0); regs->pc += 4; } struct sys64_hook { unsigned int esr_mask; unsigned int esr_val; Loading @@ -558,6 +578,18 @@ static struct sys64_hook sys64_hooks[] = { .esr_val = ESR_ELx_SYS64_ISS_SYS_CTR_READ, .handler = ctr_read_handler, }, { /* Trap read access to CNTVCT_EL0 */ .esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK, .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, }, {}, }; Loading drivers/clocksource/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -315,6 +315,14 @@ config FSL_ERRATUM_A008585 value"). The workaround will only be active if the fsl,erratum-a008585 property is found in the timer node. config ARM_ARCH_TIMER_VCT_ACCESS bool "Support for ARM architected timer virtual counter access in userspace" default !ARM64 depends on ARM_ARCH_TIMER help This option enables support for reading the ARM architected timer's virtual counter in userspace. config ARM_GLOBAL_TIMER bool "Support for the ARM global timer" if COMPILE_TEST select CLKSRC_OF if OF Loading drivers/clocksource/arm_arch_timer.c +7 −2 Original line number Diff line number Diff line Loading @@ -449,8 +449,13 @@ static void arch_counter_set_user_access(void) | ARCH_TIMER_USR_VT_ACCESS_EN | ARCH_TIMER_VIRT_EVT_EN); /* Enable user access to the virtual and physical counters */ cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN | ARCH_TIMER_USR_PCT_ACCESS_EN; cntkctl |= ARCH_TIMER_USR_PCT_ACCESS_EN; /* Enable user access to the virtual counter */ if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS)) cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; else cntkctl &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; arch_timer_set_cntkctl(cntkctl); } Loading Loading
arch/arm64/include/asm/esr.h +6 −0 Original line number Diff line number Diff line Loading @@ -175,6 +175,12 @@ #define ESR_ELx_SYS64_ISS_SYS_CTR_READ (ESR_ELx_SYS64_ISS_SYS_CTR | \ ESR_ELx_SYS64_ISS_DIR_READ) #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> Loading
arch/arm64/kernel/traps.c +32 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <linux/syscalls.h> #include <asm/atomic.h> #include <asm/barrier.h> #include <asm/bug.h> #include <asm/debug-monitors.h> #include <asm/esr.h> Loading Loading @@ -540,6 +541,25 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs) regs->pc += 4; } static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs) { int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; isb(); if (rt != 31) regs->regs[rt] = arch_counter_get_cntvct(); 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; if (rt != 31) regs->regs[rt] = read_sysreg(cntfrq_el0); regs->pc += 4; } struct sys64_hook { unsigned int esr_mask; unsigned int esr_val; Loading @@ -558,6 +578,18 @@ static struct sys64_hook sys64_hooks[] = { .esr_val = ESR_ELx_SYS64_ISS_SYS_CTR_READ, .handler = ctr_read_handler, }, { /* Trap read access to CNTVCT_EL0 */ .esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK, .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, }, {}, }; Loading
drivers/clocksource/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -315,6 +315,14 @@ config FSL_ERRATUM_A008585 value"). The workaround will only be active if the fsl,erratum-a008585 property is found in the timer node. config ARM_ARCH_TIMER_VCT_ACCESS bool "Support for ARM architected timer virtual counter access in userspace" default !ARM64 depends on ARM_ARCH_TIMER help This option enables support for reading the ARM architected timer's virtual counter in userspace. config ARM_GLOBAL_TIMER bool "Support for the ARM global timer" if COMPILE_TEST select CLKSRC_OF if OF Loading
drivers/clocksource/arm_arch_timer.c +7 −2 Original line number Diff line number Diff line Loading @@ -449,8 +449,13 @@ static void arch_counter_set_user_access(void) | ARCH_TIMER_USR_VT_ACCESS_EN | ARCH_TIMER_VIRT_EVT_EN); /* Enable user access to the virtual and physical counters */ cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN | ARCH_TIMER_USR_PCT_ACCESS_EN; cntkctl |= ARCH_TIMER_USR_PCT_ACCESS_EN; /* Enable user access to the virtual counter */ if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS)) cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; else cntkctl &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; arch_timer_set_cntkctl(cntkctl); } Loading