Removes a load of boiler plate. Signed-off-by: Ian Campbell <ian.campb...@citrix.com> --- xen/arch/arm/traps.c | 65 +++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 33 deletions(-)
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index ebc09f9..c9c98d3 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1578,8 +1578,12 @@ 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) { + if ( min_el > 0 && psr_mode_is_user(regs) ) + return inject_undef_exception(regs, hsr); + if ( read ) *reg = 0; /* else: write ignored */ @@ -1591,8 +1595,12 @@ 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) { + 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 +1612,12 @@ 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) { + 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 +1664,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 +1689,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, @@ -1768,14 +1777,11 @@ static void do_cp14_32(struct cpu_user_regs *regs, const union hsr 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 +1791,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 +1870,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 +1902,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@lists.xen.org http://lists.xen.org/xen-devel