[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 7/9] 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. Accesses to the *_EL1 registers from EL0 are trapped to EL1 by the hardware, so add a BUG_ON. Likewise accesses from 32-bit EL1 cannot happen. PMUSERENR_EL0 and MDCCSR_EL0 are R/O to EL0. 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> --- xen/arch/arm/traps.c | 54 +++++++++++++++++++++++++++++++---------- xen/include/asm-arm/sysregs.h | 1 + 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 01cc3c0..be02c68 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1726,11 +1726,40 @@ static void do_sysreg(struct cpu_user_regs *regs, switch ( hsr.bits & HSR_SYSREG_REGS_MASK ) { /* RAZ/WI registers: */ + /* - Debug */ case HSR_SYSREG_MDSCR_EL1: /* - Perf monitors */ case HSR_SYSREG_PMINTENSET_EL1: case HSR_SYSREG_PMINTENCLR_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: + /* EL1 only */ + BUG_ON(psr_mode_is_user(regs)); + goto sysreg_raz_wi; + + 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_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; case HSR_SYSREG_PMCR_EL0: case HSR_SYSREG_PMCNTENSET_EL0: case HSR_SYSREG_PMCNTENCLR_EL0: @@ -1742,16 +1771,16 @@ 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; + /* Fall thru */ + + sysreg_raz_wi: if ( hsr.sysreg.read ) *x = 0; /* else: write ignored */ @@ -1759,8 +1788,9 @@ static void do_sysreg(struct cpu_user_regs *regs, /* Write only, Write ignore registers: */ case HSR_SYSREG_OSLAR_EL1: + BUG_ON(psr_mode_is_user(regs)); if ( hsr.sysreg.read ) - goto bad_sysreg; + goto undef_sysreg; /* else: write ignored */ break; case HSR_SYSREG_CNTP_CTL_EL0: @@ -1768,7 +1798,6 @@ static void do_sysreg(struct cpu_user_regs *regs, case HSR_SYSREG_CNTPCT_EL0: goto undef_sysreg; default: - bad_sysreg: { #ifndef NDEBUG struct hsr_sysreg sysreg = hsr.sysreg; @@ -1999,8 +2028,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)); do_sysreg(regs, hsr); break; #endif diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h index b00871c..0e8c497 100644 --- a/xen/include/asm-arm/sysregs.h +++ b/xen/include/asm-arm/sysregs.h @@ -43,6 +43,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 |