diff options
Diffstat (limited to 'arch/arm64/kernel/traps.c')
-rw-r--r-- | arch/arm64/kernel/traps.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 6543cd7bcb93..a5fb6f0428a2 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -409,6 +409,25 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) arm64_notify_die("Oops - undefined instruction", regs, &info, 0); } +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; + + if (rt != 31) + regs->regs[rt] = arch_counter_get_cntvct(); + regs->pc += 4; +} + +asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs) +{ + if ((esr & ESR_ELx_SYS64_ISS_SYS_OP_MASK) == ESR_ELx_SYS64_ISS_SYS_CNTVCT) { + cntvct_read_handler(esr, regs); + return; + } + + do_undefinstr(regs); +} + long compat_arm_syscall(struct pt_regs *regs); asmlinkage long do_ni_syscall(struct pt_regs *regs) |