BACKPORT: arm64: Add CNTVCT_EL0 trap handler
Since people seem to make a point in breaking the userspace visible counter, we have no choice but to trap the access. Add the required handler. Acked-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> (cherry picked from commit 6126ce0588eb5a0752d5c8b5796a7fca324fd887) Change-Id: I0705f47c85a78040df38df18f51a4a22500b904d Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
64afad041d
commit
bd3c67ac4f
3 changed files with 67 additions and 1 deletions
|
@ -109,6 +109,43 @@
|
|||
((ESR_ELx_EC_BRK64 << ESR_ELx_EC_SHIFT) | ESR_ELx_IL | \
|
||||
((imm) & 0xffff))
|
||||
|
||||
/* ISS field definitions for System instruction traps */
|
||||
#define ESR_ELx_SYS64_ISS_RES0_SHIFT 22
|
||||
#define ESR_ELx_SYS64_ISS_RES0_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_RES0_SHIFT)
|
||||
#define ESR_ELx_SYS64_ISS_DIR_MASK 0x1
|
||||
#define ESR_ELx_SYS64_ISS_DIR_READ 0x1
|
||||
#define ESR_ELx_SYS64_ISS_DIR_WRITE 0x0
|
||||
|
||||
#define ESR_ELx_SYS64_ISS_RT_SHIFT 5
|
||||
#define ESR_ELx_SYS64_ISS_RT_MASK (UL(0x1f) << ESR_ELx_SYS64_ISS_RT_SHIFT)
|
||||
#define ESR_ELx_SYS64_ISS_CRM_SHIFT 1
|
||||
#define ESR_ELx_SYS64_ISS_CRM_MASK (UL(0xf) << ESR_ELx_SYS64_ISS_CRM_SHIFT)
|
||||
#define ESR_ELx_SYS64_ISS_CRN_SHIFT 10
|
||||
#define ESR_ELx_SYS64_ISS_CRN_MASK (UL(0xf) << ESR_ELx_SYS64_ISS_CRN_SHIFT)
|
||||
#define ESR_ELx_SYS64_ISS_OP1_SHIFT 14
|
||||
#define ESR_ELx_SYS64_ISS_OP1_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_OP1_SHIFT)
|
||||
#define ESR_ELx_SYS64_ISS_OP2_SHIFT 17
|
||||
#define ESR_ELx_SYS64_ISS_OP2_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_OP2_SHIFT)
|
||||
#define ESR_ELx_SYS64_ISS_OP0_SHIFT 20
|
||||
#define ESR_ELx_SYS64_ISS_OP0_MASK (UL(0x3) << ESR_ELx_SYS64_ISS_OP0_SHIFT)
|
||||
#define ESR_ELx_SYS64_ISS_SYS_MASK (ESR_ELx_SYS64_ISS_OP0_MASK | \
|
||||
ESR_ELx_SYS64_ISS_OP1_MASK | \
|
||||
ESR_ELx_SYS64_ISS_OP2_MASK | \
|
||||
ESR_ELx_SYS64_ISS_CRN_MASK | \
|
||||
ESR_ELx_SYS64_ISS_CRM_MASK)
|
||||
#define ESR_ELx_SYS64_ISS_SYS_VAL(op0, op1, op2, crn, crm) \
|
||||
(((op0) << ESR_ELx_SYS64_ISS_OP0_SHIFT) | \
|
||||
((op1) << ESR_ELx_SYS64_ISS_OP1_SHIFT) | \
|
||||
((op2) << ESR_ELx_SYS64_ISS_OP2_SHIFT) | \
|
||||
((crn) << ESR_ELx_SYS64_ISS_CRN_SHIFT) | \
|
||||
((crm) << ESR_ELx_SYS64_ISS_CRM_SHIFT))
|
||||
|
||||
#define ESR_ELx_SYS64_ISS_SYS_OP_MASK (ESR_ELx_SYS64_ISS_SYS_MASK | \
|
||||
ESR_ELx_SYS64_ISS_DIR_MASK)
|
||||
|
||||
#define ESR_ELx_SYS64_ISS_SYS_CNTVCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \
|
||||
ESR_ELx_SYS64_ISS_DIR_READ)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/types.h>
|
||||
|
||||
|
|
|
@ -604,7 +604,7 @@ el0_sync:
|
|||
cmp x24, #ESR_ELx_EC_FP_EXC64 // FP/ASIMD exception
|
||||
b.eq el0_fpsimd_exc
|
||||
cmp x24, #ESR_ELx_EC_SYS64 // configurable trap
|
||||
b.eq el0_undef
|
||||
b.eq el0_sys
|
||||
cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception
|
||||
b.eq el0_sp_pc
|
||||
cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception
|
||||
|
@ -732,6 +732,16 @@ el0_undef:
|
|||
mov x0, sp
|
||||
bl do_undefinstr
|
||||
b ret_to_user
|
||||
el0_sys:
|
||||
/*
|
||||
* System instructions, for trapped cache maintenance instructions
|
||||
*/
|
||||
enable_dbg_and_irq
|
||||
ct_user_exit
|
||||
mov x0, x25
|
||||
mov x1, sp
|
||||
bl do_sysinstr
|
||||
b ret_to_user
|
||||
el0_dbg:
|
||||
/*
|
||||
* Debug exception handling
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue