[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 06/19] xen: arm: add minimum exception level argument to trap handler helpers
Removes a load of boiler plate. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- v2: Move last parameter of a call to handle_ro_raz here where it belongs. Added asserts for valid min_el values --- xen/arch/arm/traps.c | 73 +++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index b54aef6..7110c66 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1578,8 +1578,14 @@ static void advance_pc(struct cpu_user_regs *regs, const union hsr hsr) static void handle_raz_wi(struct cpu_user_regs *regs, register_t *reg, bool_t read, - const union hsr hsr) + const union hsr hsr, + int min_el) { + ASSERT((min_el == 0) || (min_el == 1)); + + if ( min_el > 0 && psr_mode_is_user(regs) ) + return inject_undef_exception(regs, hsr); + if ( read ) *reg = 0; /* else: write ignored */ @@ -1591,8 +1597,14 @@ static void handle_raz_wi(struct cpu_user_regs *regs, static void handle_wo_wi(struct cpu_user_regs *regs, register_t *reg, bool_t read, - const union hsr hsr) + const union hsr hsr, + int min_el) { + ASSERT((min_el == 0) || (min_el == 1)); + + if ( min_el > 0 && psr_mode_is_user(regs) ) + return inject_undef_exception(regs, hsr); + if ( read ) return inject_undef_exception(regs, hsr); /* else: ignore */ @@ -1604,8 +1616,14 @@ static void handle_wo_wi(struct cpu_user_regs *regs, static void handle_ro_raz(struct cpu_user_regs *regs, register_t *reg, bool_t read, - const union hsr hsr) + const union hsr hsr, + int min_el) { + ASSERT((min_el == 0) || (min_el == 1)); + + if ( min_el > 0 && psr_mode_is_user(regs) ) + return inject_undef_exception(regs, hsr); + if ( !read ) return inject_undef_exception(regs, hsr); /* else: raz */ @@ -1652,16 +1670,15 @@ static void do_cp15_32(struct cpu_user_regs *regs, */ case HSR_CPREG32(PMUSERENR): /* RO at EL0. RAZ/WI at EL1 */ - if ( psr_mode_is_user(regs) && !hsr.cp32.read ) - return inject_undef_exception(regs, hsr); - return handle_raz_wi(regs, r, cp32.read, hsr); + if ( psr_mode_is_user(regs) ) + return handle_ro_raz(regs, r, cp32.read, hsr, 0); + else + return handle_raz_wi(regs, r, cp32.read, hsr, 1); case HSR_CPREG32(PMINTENSET): case HSR_CPREG32(PMINTENCLR): /* EL1 only, however MDCR_EL2.TPM==1 means EL0 may trap here also. */ - if ( psr_mode_is_user(regs) ) - return inject_undef_exception(regs, hsr); - return handle_raz_wi(regs, r, cp32.read, hsr); + return handle_raz_wi(regs, r, cp32.read, hsr, 1); case HSR_CPREG32(PMCR): case HSR_CPREG32(PMCNTENSET): case HSR_CPREG32(PMCNTENCLR): @@ -1678,9 +1695,7 @@ static void do_cp15_32(struct cpu_user_regs *regs, * Accessible at EL0 only if PMUSERENR_EL0.EN is set. We * emulate that register as 0 above. */ - if ( psr_mode_is_user(regs) ) - return inject_undef_exception(regs, hsr); - return handle_raz_wi(regs, r, cp32.read, hsr); + return handle_raz_wi(regs, r, cp32.read, hsr, 1); default: gdprintk(XENLOG_ERR, @@ -1765,17 +1780,14 @@ static void do_cp14_32(struct cpu_user_regs *regs, const union hsr hsr) * Read-only register. Accessible by EL0 if DBGDSCRext.UDCCdis * is set to 0, which we emulated below. */ - return handle_ro_raz(regs, r, cp32.read, hsr); + return handle_ro_raz(regs, r, cp32.read, hsr, 1); case HSR_CPREG32(DBGDSCREXT): - if ( usr_mode(regs) ) - return inject_undef_exception(regs, hsr); - /* * Implement debug status and control register as RAZ/WI. * The OS won't use Hardware debug if MDBGen not set. */ - return handle_raz_wi(regs, r, cp32.read, hsr); + return handle_raz_wi(regs, r, cp32.read, hsr, 1); case HSR_CPREG32(DBGVCR): case HSR_CPREG32(DBGBVR0): @@ -1785,14 +1797,10 @@ static void do_cp14_32(struct cpu_user_regs *regs, const union hsr hsr) case HSR_CPREG32(DBGBVR1): case HSR_CPREG32(DBGBCR1): case HSR_CPREG32(DBGOSDLR): - if ( usr_mode(regs) ) - return inject_undef_exception(regs, hsr); - return handle_raz_wi(regs, r, cp32.read, hsr); + return handle_raz_wi(regs, r, cp32.read, hsr, 1); case HSR_CPREG32(DBGOSLAR): - if ( usr_mode(regs) ) - return inject_undef_exception(regs, hsr); - return handle_wo_wi(regs, r, cp32.read, hsr); + return handle_wo_wi(regs, r, cp32.read, hsr, 1); default: gdprintk(XENLOG_ERR, "%s p14, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n", @@ -1868,23 +1876,22 @@ static void do_sysreg(struct cpu_user_regs *regs, * Accessible from EL1 only, but if EL0 trap happens handle as * undef. */ - if ( psr_mode_is_user(regs) ) - return inject_undef_exception(regs, hsr); - return handle_raz_wi(regs, x, hsr.sysreg.read, hsr); + return handle_raz_wi(regs, x, hsr.sysreg.read, hsr, 1); 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. */ - return handle_ro_raz(regs, x, hsr.sysreg.read, hsr); + return handle_ro_raz(regs, x, hsr.sysreg.read, hsr, 0); /* - Perf monitors */ case HSR_SYSREG_PMUSERENR_EL0: /* RO at EL0. RAZ/WI at EL1 */ - if ( psr_mode_is_user(regs) && !hsr.sysreg.read ) - return inject_undef_exception(regs, hsr); - return handle_raz_wi(regs, x, hsr.sysreg.read, hsr); + if ( psr_mode_is_user(regs) ) + return handle_ro_raz(regs, x, hsr.sysreg.read, hsr, 0); + else + return handle_raz_wi(regs, x, hsr.sysreg.read, hsr, 1); case HSR_SYSREG_PMCR_EL0: case HSR_SYSREG_PMCNTENSET_EL0: case HSR_SYSREG_PMCNTENCLR_EL0: @@ -1901,13 +1908,11 @@ static void do_sysreg(struct cpu_user_regs *regs, * Accessible at EL0 only if PMUSERENR_EL0.EN is set. We * emulate that register as 0 above. */ - if ( psr_mode_is_user(regs) ) - return inject_undef_exception(regs, hsr); - return handle_raz_wi(regs, x, hsr.sysreg.read, hsr); + return handle_raz_wi(regs, x, hsr.sysreg.read, hsr, 1); /* Write only, Write ignore registers: */ case HSR_SYSREG_OSLAR_EL1: - return handle_wo_wi(regs, x, hsr.sysreg.read, hsr); + return handle_wo_wi(regs, x, hsr.sysreg.read, hsr, 1); case HSR_SYSREG_CNTP_CTL_EL0: case HSR_SYSREG_CNTP_TVAL_EL0: -- 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 |