arm64/cpufeatures: Emulate MRS instructions by parsing ESR_ELx.ISS
Armv8.4-A extension enables MRS instruction encodings inside ESR_ELx.ISS during exception class ESR_ELx_EC_SYS64 (0x18). This encoding can be used to emulate MRS instructions which can avoid fetch/decode from user space thus improving performance. This adds a new sys64_hook structure element with applicable ESR mask/value pair for MRS instructions on various system registers but constrained by sysreg encodings which is currently allowed to be emulated. Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
Родитель
520ad98871
Коммит
21f8479617
|
@ -208,6 +208,18 @@
|
|||
#define ESR_ELx_SYS64_ISS_EL0_CACHE_OP_VAL \
|
||||
(ESR_ELx_SYS64_ISS_SYS_VAL(1, 3, 1, 7, 0) | \
|
||||
ESR_ELx_SYS64_ISS_DIR_WRITE)
|
||||
/*
|
||||
* User space MRS operations which are supported for emulation
|
||||
* have the following sysreg encoding in System instructions.
|
||||
* op0 = 3, op1= 0, crn = 0, {crm = 0, 4-7}, READ (L = 1)
|
||||
*/
|
||||
#define ESR_ELx_SYS64_ISS_SYS_MRS_OP_MASK (ESR_ELx_SYS64_ISS_OP0_MASK | \
|
||||
ESR_ELx_SYS64_ISS_OP1_MASK | \
|
||||
ESR_ELx_SYS64_ISS_CRN_MASK | \
|
||||
ESR_ELx_SYS64_ISS_DIR_MASK)
|
||||
#define ESR_ELx_SYS64_ISS_SYS_MRS_OP_VAL \
|
||||
(ESR_ELx_SYS64_ISS_SYS_VAL(3, 0, 0, 0, 0) | \
|
||||
ESR_ELx_SYS64_ISS_DIR_READ)
|
||||
|
||||
#define ESR_ELx_SYS64_ISS_SYS_CTR ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 1, 0, 0)
|
||||
#define ESR_ELx_SYS64_ISS_SYS_CTR_READ (ESR_ELx_SYS64_ISS_SYS_CTR | \
|
||||
|
|
|
@ -497,6 +497,17 @@ static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs)
|
|||
arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE);
|
||||
}
|
||||
|
||||
static void mrs_handler(unsigned int esr, struct pt_regs *regs)
|
||||
{
|
||||
u32 sysreg, rt;
|
||||
|
||||
rt = ESR_ELx_SYS64_ISS_RT(esr);
|
||||
sysreg = esr_sys64_to_sysreg(esr);
|
||||
|
||||
if (do_emulate_mrs(regs, sysreg, rt) != 0)
|
||||
force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc);
|
||||
}
|
||||
|
||||
struct sys64_hook {
|
||||
unsigned int esr_mask;
|
||||
unsigned int esr_val;
|
||||
|
@ -527,6 +538,12 @@ static struct sys64_hook sys64_hooks[] = {
|
|||
.esr_val = ESR_ELx_SYS64_ISS_SYS_CNTFRQ,
|
||||
.handler = cntfrq_read_handler,
|
||||
},
|
||||
{
|
||||
/* Trap read access to CPUID registers */
|
||||
.esr_mask = ESR_ELx_SYS64_ISS_SYS_MRS_OP_MASK,
|
||||
.esr_val = ESR_ELx_SYS64_ISS_SYS_MRS_OP_VAL,
|
||||
.handler = mrs_handler,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче