[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.