[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v5 11/15] xen: arm: correctly handle sysreg accesses from userspace
Previously we implemented all registers as RAZ/WI even if they shouldn't be accessible to userspace. It is not entirely clear whether attempts to access *_EL1 registers from EL0 will trap to EL1 or EL2, be conservative and treat as an undef injection. PMUSERENR_EL0 and MDCCSR_EL0 are R/O to EL0. MDCCSR_EL0 was previously not handled at all. Other PM*_EL0 registers are accessible at EL0 only if PMUSERENR_EL0.EN is set, since we emulate that as RAZ/WI we know that bit cannot be set. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Reviewed-by: Julien Grall <julien.grall@xxxxxxxxxx> --- v4: - Handle the possibility of EL1 trapping from EL0 as well, by injecting an undef, since the docs are not completely unambiguous about this possibility. --- xen/arch/arm/traps.c | 55 +++++++++++++++++++++++++++++++---------- xen/include/asm-arm/sysregs.h | 1 + 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 0c33191..2535512 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1806,9 +1806,42 @@ static void do_sysreg(struct cpu_user_regs *regs, /* RAZ/WI registers: */ /* - Debug */ case HSR_SYSREG_MDSCR_EL1: + /* - Breakpoints */ + HSR_SYSREG_DBG_CASES(DBGBVR): + HSR_SYSREG_DBG_CASES(DBGBCR): + /* - Watchpoints */ + HSR_SYSREG_DBG_CASES(DBGWVR): + HSR_SYSREG_DBG_CASES(DBGWCR): + /* - Double Lock Register */ + case HSR_SYSREG_OSDLR_EL1: /* - Perf monitors */ case HSR_SYSREG_PMINTENSET_EL1: case HSR_SYSREG_PMINTENCLR_EL1: + /* + * Accessible from EL1 only, but if EL0 trap happens handle as + * undef. + */ + if ( psr_mode_is_user(regs) ) + goto undef_sysreg; + goto sysreg_raz_wi; + + case HSR_SYSREG_MDCCSR_EL0: + /* + * Accessible at EL0 only if MDSCR_EL1.TDCC is set to 0. We emulate that + * register as RAZ/WI above. So RO at both EL0 and EL1. + */ + if ( !hsr.sysreg.read ) + goto undef_sysreg; + + *x = 0; + break; + + /* - Perf monitors */ + case HSR_SYSREG_PMUSERENR_EL0: + /* RO at EL0. RAZ/WI at EL1 */ + if ( psr_mode_is_user(regs) && !hsr.sysreg.read ) + goto undef_sysreg; + goto sysreg_raz_wi; case HSR_SYSREG_PMCR_EL0: case HSR_SYSREG_PMCNTENSET_EL0: case HSR_SYSREG_PMCNTENCLR_EL0: @@ -1820,16 +1853,14 @@ static void do_sysreg(struct cpu_user_regs *regs, case HSR_SYSREG_PMCCNTR_EL0: case HSR_SYSREG_PMXEVTYPER_EL0: case HSR_SYSREG_PMXEVCNTR_EL0: - case HSR_SYSREG_PMUSERENR_EL0: case HSR_SYSREG_PMOVSSET_EL0: - /* - Breakpoints */ - HSR_SYSREG_DBG_CASES(DBGBVR): - HSR_SYSREG_DBG_CASES(DBGBCR): - /* - Watchpoints */ - HSR_SYSREG_DBG_CASES(DBGWVR): - HSR_SYSREG_DBG_CASES(DBGWCR): - /* - Double Lock Register */ - case HSR_SYSREG_OSDLR_EL1: + /* + * Accessible at EL0 only if PMUSERENR_EL0.EN is set. We + * emulate that register as 0 above. + */ + if ( psr_mode_is_user(regs) ) + goto undef_sysreg; + sysreg_raz_wi: if ( hsr.sysreg.read ) *x = 0; /* else: write ignored */ @@ -1838,7 +1869,7 @@ static void do_sysreg(struct cpu_user_regs *regs, /* Write only, Write ignore registers: */ case HSR_SYSREG_OSLAR_EL1: if ( hsr.sysreg.read ) - goto bad_sysreg; + goto undef_sysreg; /* else: write ignored */ break; case HSR_SYSREG_CNTP_CTL_EL0: @@ -1862,7 +1893,6 @@ static void do_sysreg(struct cpu_user_regs *regs, "Emulation of sysreg ICC_SGI0R_EL1/ASGI1R_EL1 not supported\n"); inject_undef64_exception(regs, hsr.len); default: - bad_sysreg: { struct hsr_sysreg sysreg = hsr.sysreg; @@ -2103,8 +2133,7 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs) inject_undef64_exception(regs, hsr.len); break; case HSR_EC_SYSREG: - if ( is_32bit_domain(current->domain) ) - goto bad_trap; + BUG_ON(psr_mode_is_32bit(regs->cpsr)); perfc_incr(trap_sysreg); do_sysreg(regs, hsr); break; diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h index 2e256cc..2284fd7 100644 --- a/xen/include/asm-arm/sysregs.h +++ b/xen/include/asm-arm/sysregs.h @@ -47,6 +47,7 @@ #define HSR_SYSREG_MDSCR_EL1 HSR_SYSREG(2,0,c0,c2,2) #define HSR_SYSREG_OSLAR_EL1 HSR_SYSREG(2,0,c1,c0,4) #define HSR_SYSREG_OSDLR_EL1 HSR_SYSREG(2,0,c1,c3,4) +#define HSR_SYSREG_MDCCSR_EL0 HSR_SYSREG(2,3,c0,c1,0) #define HSR_SYSREG_DBGBVRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,4) #define HSR_SYSREG_DBGBCRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,5) -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |