[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v4 08/15] xen: arm: don't pretend to handle cache maintenance by set/way



We set HCR_EL2.TSW but only (sort of) handle 32-bit access to DCCISW
but not the other two registers, nor any 64-bit access. Add handlers
for all of these.

The existing handling of DCCISW was to simply propagate the action to
the host level. This can't really work on an SMP system (due to
speculation from other cores) and is even worse under virtualisation
(imagine a VCPU changing PCPU half way through a set/way loop).

Since set/way operations are not really usable under any hypervisor
don't even try, instead for writes log a guest debug message and
inject an under exception.

These registers are all WO, so continue to kill the guest on read from
EL1.

For accesses from EL0 just silently inject undef.

In do_sysreg promote the sysreg variable to the top level and use
throughout.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
v4: New patch
---
 xen/arch/arm/traps.c          |   57 +++++++++++++++++++++++++++++++++--------
 xen/include/asm-arm/sysregs.h |    4 +++
 xen/include/public/arch-arm.h |    5 ++++
 3 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index f35b7c3..10eb3e6 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1564,19 +1564,28 @@ static void do_cp15_32(struct cpu_user_regs *regs,
 
     switch ( hsr.bits & HSR_CP32_REGS_MASK )
     {
+    case HSR_CPREG32(DCISW):
+    case HSR_CPREG32(DCCSW):
     case HSR_CPREG32(DCCISW):
+        if ( psr_mode_is_user(regs) )
+            goto undef_cp15_32;
+
+        gdprintk(XENLOG_ERR,
+                 "Unhandled set/way operation "
+                 "p15, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister", "
+                 "rn = %"PRIx32"\n",
+                 cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2,
+                 regs->pc, *r);
+
         if ( cp32.read )
         {
             dprintk(XENLOG_ERR,
-                    "attempt to read from write-only register DCCISW\n");
+                    "attempt to read from write-only register\n");
             domain_crash_synchronous();
         }
-#ifdef CONFIG_ARM_32
-        WRITE_CP32(*r, DCCISW);
-#else
-        asm volatile("dc cisw, %0;" : : "r" (*r) : "memory");
-#endif
-        break;
+
+        goto undef_cp15_32;
+
     case HSR_CPREG32(CNTP_CTL):
     case HSR_CPREG32(CNTP_TVAL):
         if ( !vtimer_emulate(regs, hsr) )
@@ -1781,10 +1790,37 @@ static void do_cp(struct cpu_user_regs *regs, union hsr 
hsr)
 static void do_sysreg(struct cpu_user_regs *regs,
                       union hsr hsr)
 {
-    register_t *x = select_user_reg(regs, hsr.sysreg.reg);
+    struct hsr_sysreg sysreg = hsr.sysreg;
+    register_t *x = select_user_reg(regs, sysreg.reg);
 
     switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
     {
+
+    /* Set/way registers */
+    case HSR_SYSREG_DCISW:
+    case HSR_SYSREG_DCCSW:
+    case HSR_SYSREG_DCCISW:
+        if ( psr_mode_is_user(regs) )
+            goto undef_sysreg;
+
+        gdprintk(XENLOG_ERR,
+                 "Unhandled set/way operation "
+                 "%d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister", "
+                 "xn = %"PRIx64"\n",
+                 sysreg.op0, sysreg.op1,
+                 sysreg.crn, sysreg.crm,
+                 sysreg.op2,
+                 sysreg.read ? "=>" : "<=",
+                 sysreg.reg, regs->pc, *x);
+        if ( sysreg.read )
+        {
+            dprintk(XENLOG_ERR,
+                    "attempt to read from write-only register\n");
+            domain_crash_synchronous();
+        }
+
+        goto undef_sysreg;
+
     /* RAZ/WI registers: */
     /*  - Debug */
     case HSR_SYSREG_MDSCR_EL1:
@@ -1812,14 +1848,14 @@ static void do_sysreg(struct cpu_user_regs *regs,
     HSR_SYSREG_DBG_CASES(DBGWCR):
     /* - Double Lock Register */
     case HSR_SYSREG_OSDLR_EL1:
-        if ( hsr.sysreg.read )
+        if ( sysreg.read )
             *x = 0;
         /* else: write ignored */
         break;
 
     /* Write only, Write ignore registers: */
     case HSR_SYSREG_OSLAR_EL1:
-        if ( hsr.sysreg.read )
+        if ( sysreg.read )
             goto bad_sysreg;
         /* else: write ignored */
         break;
@@ -1847,7 +1883,6 @@ static void do_sysreg(struct cpu_user_regs *regs,
  bad_sysreg:
         {
 #ifndef NDEBUG
-            struct hsr_sysreg sysreg = hsr.sysreg;
 
             gdprintk(XENLOG_ERR,
                      "%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h
index df8e070..2e256cc 100644
--- a/xen/include/asm-arm/sysregs.h
+++ b/xen/include/asm-arm/sysregs.h
@@ -40,6 +40,10 @@
     ((__HSR_SYSREG_##crm) << HSR_SYSREG_CRM_SHIFT) | \
     ((__HSR_SYSREG_##op2) << HSR_SYSREG_OP2_SHIFT)
 
+#define HSR_SYSREG_DCISW          HSR_SYSREG(1,0,c7,c6,2)
+#define HSR_SYSREG_DCCSW          HSR_SYSREG(1,0,c7,c10,2)
+#define HSR_SYSREG_DCCISW         HSR_SYSREG(1,0,c7,c14,2)
+
 #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)
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index c2dcb66..cf3d6cc 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -161,6 +161,11 @@
  *
  * - The device tree Xen compatible node is fully described under Linux
  *   at Documentation/devicetree/bindings/arm/xen.txt.
+ *
+ * - Cache maintenaince operations by set/way ("dc isw|cisw|csw" and
+ *   the equivalent cp15 registers) are not available when running
+ *   under Xen and will result in an undefined instruction exception
+ *   delivered to the guest.
  */
 
 #define XEN_HYPERCALL_TAG   0XEA1
-- 
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®.