Subject: xen/arm: Don't let the guest access the coprocessors registers
From: Julien Grall <[email-masked]>
Date: Mon, 14 Apr 2014 20:37:16 +0100

In Xen we only handle save/restore for coprocessor 10 and 11 (NEON). Other
coprocessors (0-9, 12-13) are currently exposed to the guest and may lead
to data shared between guest.

Disable access to all coprocessor except 10 and 11 by setting correctly
HCTPR.

Signed-off-by: Julien Grall <[email-masked]>
Acked-by: Ian Campbell <[email-masked]>
---
 xen/arch/arm/traps.c            |   22 ++++++++++++++++++++++
 xen/include/asm-arm/cpregs.h    |    2 ++
 xen/include/asm-arm/processor.h |    7 ++++++-
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 92b7910..97ab286 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -74,6 +74,12 @@ void __cpuinit init_traps(void)
     /* Setup Hyp vector base */
     WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2);
 
+    /* Trap all coprocessor registers (0-13) except cp10 and cp11 for VFP
+     * /!\ All processors except cp10 and cp11 cannot be used in Xen
+     */
+    WRITE_SYSREG((HCPTR_CP_MASK & ~(HCPTR_CP(10) | HCPTR_CP(11))) | HCPTR_TTA,
+                 CPTR_EL2);
+
     /* Setup hypervisor traps */
     WRITE_SYSREG(HCR_PTW|HCR_BSU_OUTER|HCR_AMO|HCR_IMO|HCR_VM|HCR_TWI|HCR_TSC|
                  HCR_TAC, HCR_EL2);
@@ -1403,6 +1409,17 @@ static void do_cp15_64(struct cpu_user_regs *regs,
     advance_pc(regs, hsr);
 }
 
+static void do_cp(struct cpu_user_regs *regs, union hsr hsr)
+{
+    if ( !check_conditional_instr(regs, hsr) )
+    {
+        advance_pc(regs, hsr);
+        return;
+    }
+
+    inject_undef32_exception(regs);
+}
+
 #ifdef CONFIG_ARM_64
 static void do_sysreg(struct cpu_user_regs *regs,
                       union hsr hsr)
@@ -1594,6 +1611,11 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs)
             goto bad_trap;
         do_cp15_64(regs, hsr);
         break;
+    case HSR_EC_CP:
+        if ( !is_pv32_domain(current->domain) )
+            goto bad_trap;
+        do_cp(regs, hsr);
+        break;
     case HSR_EC_SMC32:
         inject_undef32_exception(regs);
         break;
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index 508467a..2b411af 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -115,6 +115,7 @@
 #define NSACR           p15,0,c1,c1,2   /* Non-Secure Access Control Register */
 #define HSCTLR          p15,4,c1,c0,0   /* Hyp. System Control Register */
 #define HCR             p15,4,c1,c1,0   /* Hyp. Configuration Register */
+#define HCPTR           p15,4,c1,c1,2   /* Hyp. Coprocessor Trap Register */
 
 /* CP15 CR2: Translation Table Base and Control Registers */
 #define TTBCR           p15,0,c2,c0,2   /* Translatation Table Base Control Register */
@@ -260,6 +261,7 @@
 #define CNTV_CVAL_EL0           CNTV_CVAL
 #define CONTEXTIDR_EL1          CONTEXTIDR
 #define CPACR_EL1               CPACR
+#define CPTR_EL2                HCPTR
 #define CSSELR_EL1              CSSELR
 #define DACR32_EL2              DACR
 #define ESR_EL1                 DFSR
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 06e638f..02cefe9 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -84,13 +84,18 @@
 #define HCR_SWIO        (_AC(1,UL)<<1) /* Set/Way Invalidation Override */
 #define HCR_VM          (_AC(1,UL)<<0) /* Virtual MMU Enable */
 
+/* HCPTR Hyp. Coprocessor Trap Register */
+#define HCPTR_TTA       ((_AC(1,U)<<20))        /* Trap trace registers */
+#define HCPTR_CP(x)     ((_AC(1,U)<<(x)))       /* Trap Coprocessor x */
+#define HCPTR_CP_MASK   ((_AC(1,U)<<14)-1)
+
 #define HSR_EC_UNKNOWN              0x00
 #define HSR_EC_WFI_WFE              0x01
 #define HSR_EC_CP15_32              0x03
 #define HSR_EC_CP15_64              0x04
 #define HSR_EC_CP14_32              0x05
 #define HSR_EC_CP14_DBG             0x06
-#define HSR_EC_CP                   0x07
+#define HSR_EC_CP                   0x07        /* HCPTR-trapped access to CP0-CP13 */
 #define HSR_EC_CP10                 0x08
 #define HSR_EC_JAZELLE              0x09
 #define HSR_EC_BXJ                  0x0a
-- 
1.7.10.4