|
[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 |