[prev in list] [next in list] [prev in thread] [next in thread] 

List:       oss-security
Subject:    [oss-security] Xen Security Advisory 93 (CVE-2014-2915) - Hardware features unintentionally exposed 
From:       Xen.org security team <security () xen ! org>
Date:       2014-04-23 10:20:38
Message-ID: E1WcuIA-00083c-CY () xenbits ! xen ! org
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

             Xen Security Advisory CVE-2014-2915 / XSA-93
                              version 2

      Hardware features unintentionally exposed to guests on ARM

UPDATES IN VERSION 2
====================

This issue has been assigned CVE-2014-2915.

ISSUE DESCRIPTION
=================

When running on an ARM platform Xen was not correctly configuring the
hardware virtualisation platform and therefore did not prevent guests
from accessing various hardware features including cache control,
coprocessors, debug registers and various processor specific
registers.

IMPACT
======

By accessing these hardware facilities a malicious or buggy guest may
be able to cause various issues, including crashing the host, crashing
other guests (including control domains) and data corruption.

Privilege escalation is not thought to be possible but has not been
ruled out.

VULNERABLE SYSTEMS
==================

Both 32- and 64-bit ARM systems are vulnerable from Xen 4.4 onwards.

x86 systems are not vulnerable.

MITIGATION
==========

None.

NOTE REGARDING LACK OF EMBARGO
==============================

This bug was publicly reported on xen-devel, before it was appreciated
that there was a security problem.  The public mailing list thread
contains information strongly suggestive of a security bug and
included example code which can crash the host.

CREDITS
=======

The initial bug was discovered by Thomas Leonard and further followup
issues were discovered by Julien Grall.

RESOLUTION
==========

Applying the attached patches resolves this issue.

xsa93-unstable-{01..06}.patch        xen-unstable
xsa93-4.4-{01..06}.patch             Xen 4.4.x

$ sha256sum xsa93*.patch
9a01ed1c7d33d2381594af3b0985df50f3aa7f13f5a9989595427407c5a5eb06  xsa93-4.4-01.patch
68ec2bdb48dd232dbabefbe7c971546b52d7001a128471226a41f36e27a806f2  xsa93-4.4-02.patch
541d2d57ee85a9603ae4bf00bb321f6f491354df9e15eb09ddb5ccba68333ecc  xsa93-4.4-03.patch
6a3736e5dea1d45df6b979f02e06e058d8dffdbcf128d2d0984db404a87ebb62  xsa93-4.4-04.patch
282e2cf82ad4345573d21351c242684cd09f384bcd76c262740f9e33f8b04c9c  xsa93-4.4-05.patch
e212ad288eaeccf6a33cab27ecc6515a889365b0c56b5010e91a603ce239a38b  xsa93-4.4-06.patch
9a01ed1c7d33d2381594af3b0985df50f3aa7f13f5a9989595427407c5a5eb06  xsa93-unstable-01.patch
9b472975087dee1d22db8e5f3e55b1589910d84de86b2cad218bfd540fbbd92e  xsa93-unstable-02.patch
f921ba7c1b216dd425035f94ac9eef9374ae5eba4af4cb5a3b7aa3f958a0a767  xsa93-unstable-03.patch
45b7e6b226a4449370c4dbe21aa71c398955e4ed2bc7cf9e4426f29583af14be  xsa93-unstable-04.patch
282e2cf82ad4345573d21351c242684cd09f384bcd76c262740f9e33f8b04c9c  xsa93-unstable-05.patch
e2668f0ecf1e79aa30928791b92a15c15821c8bce7958a5c3fee7563cf81960b  xsa93-unstable-06.patch
$

NOTE: These patches unconditionally deny access by all guests
(including control domains) to various hardware features in order to
close the vulnerability. Specifically guests are prevented from
accessing:

  * coprocessors 0..9, 12 and 13;
  * coprocessor 14 (trace registers);
  * coprocessor 15 encodings:
      CRn==c9, opc1=={0-7}, CRm=={c0-c2, c5-c8}, opc2=={0-7},
      CRn==c10, opc1=={0-7}, CRm=={c0, c1, c4, c8}, opc2=={0-7}
      CRn==c11, opc1=={0-7}, CRm=={c0-c8, c15}, opc2=={0-7}
    (IMPLEMENTATION DEFINED cache, TCM, branch predictor, memory
     remapping, and TLB control registers);
  * cp15 c15 (IMPLEMENTATION DEFINED);
  * Debug and Performance monitor registers.

We have checked common Operating Systems which are known to run on Xen
on ARM and not found any default uses of these registers. However it
is expected that tools such as the Linux perf tool which make use of
debug and performance registers will no longer function correctly in
guest context. In addition if your use case requires access to
specific coprocessors by one or more guest domains then additional
local patches may be required to enable this.

Where feasible we hope to reenable these use cases in the future. If
this affects you then please contact the xen-devel mailing list
http://lists.xen.org/mailman/listinfo/xen-devel.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)

iQEcBAEBAgAGBQJTV5O6AAoJEIP+FMlX6CvZt7MH+wYxthL+nxagERvLrXQdXlF6
XYctN9gb5iEGwKLI4MLuVYdMqXIa2NfTvTEHfwNyWEp6sS/+nc2V0h8qAqDdhdtO
cNuxV2zK7Ab328SkNVy17y6j0Jgyen0QrOGBwTaNb5CXUHkg3J+YppObvGlTqjDi
HoXeX7Whv4CSqOjgua189e9uNzKtBNsZZepqerli1/tIazWSuOT8KIHp92NKAbLv
hwm9HUS7gN2JmR8wU3DD3DxJp+bfTDXBCKOvGmYILxN+X0pzAtfDgK+RMOBwSD05
iJ3rcs83VR6ITRqdI+hRifesSiS6Yi7OFi3xB2vAdSm6IjsA06pARYPCIPGCQh0=
=Nnq0
-----END PGP SIGNATURE-----

["xsa93-4.4-01.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Mon, 14 Apr 2014 19:01:20 +0100
Subject: xen/arm: Inject an undefined instruction when the
 coproc/sysreg is not handled

Currently Xen panics if it's unable to handle a coprocessor/sysreg instruction.
Replace this behavior by inject an undefined instruction to the faulty guest
and log if Xen is in debug mode.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c |   61 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 20 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index a7edc4e..92b7910 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1351,10 +1351,16 @@ static void do_cp15_32(struct cpu_user_regs *regs,
            *r = v->arch.actlr;
         break;
     default:
-        printk("%s p15, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
-               cp32.read ? "mrc" : "mcr",
-               cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
-        panic("unhandled 32-bit CP15 access %#x", hsr.bits & HSR_CP32_REGS_MASK);
+#ifndef NDEBUG
+        gdprintk(XENLOG_ERR,
+                 "%s p15, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
+                 cp32.read ? "mrc" : "mcr",
+                 cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
+        gdprintk(XENLOG_ERR, "unhandled 32-bit CP15 access %#x",
+                 hsr.bits & HSR_CP32_REGS_MASK);
+#endif
+        inject_undef32_exception(regs);
+        return;
     }
     advance_pc(regs, hsr);
 }
@@ -1362,8 +1368,6 @@ static void do_cp15_32(struct cpu_user_regs *regs,
 static void do_cp15_64(struct cpu_user_regs *regs,
                        union hsr hsr)
 {
-    struct hsr_cp64 cp64 = hsr.cp64;
-
     if ( !check_conditional_instr(regs, hsr) )
     {
         advance_pc(regs, hsr);
@@ -1381,10 +1385,20 @@ static void do_cp15_64(struct cpu_user_regs *regs,
         }
         break;
     default:
-        printk("%s p15, %d, r%d, r%d, cr%d @ 0x%"PRIregister"\n",
-               cp64.read ? "mrrc" : "mcrr",
-               cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
-        panic("unhandled 64-bit CP15 access %#x", hsr.bits & HSR_CP64_REGS_MASK);
+        {
+#ifndef NDEBUG
+            struct hsr_cp64 cp64 = hsr.cp64;
+
+            gdprintk(XENLOG_ERR,
+                     "%s p15, %d, r%d, r%d, cr%d @ 0x%"PRIregister"\n",
+                     cp64.read ? "mrrc" : "mcrr",
+                     cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
+            gdprintk(XENLOG_ERR, "unhandled 64-bit CP15 access %#x",
+                     hsr.bits & HSR_CP64_REGS_MASK);
+#endif
+            inject_undef32_exception(regs);
+            return;
+        }
     }
     advance_pc(regs, hsr);
 }
@@ -1393,7 +1407,6 @@ static void do_cp15_64(struct cpu_user_regs *regs,
 static void do_sysreg(struct cpu_user_regs *regs,
                       union hsr hsr)
 {
-    struct hsr_sysreg sysreg = hsr.sysreg;
 
     switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
     {
@@ -1407,15 +1420,23 @@ static void do_sysreg(struct cpu_user_regs *regs,
         }
         break;
     default:
-        printk("%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
-               sysreg.read ? "mrs" : "msr",
-               sysreg.op0, sysreg.op1,
-               sysreg.crn, sysreg.crm,
-               sysreg.op2,
-               sysreg.read ? "=>" : "<=",
-               sysreg.reg, regs->pc);
-        panic("unhandled 64-bit sysreg access %#x",
-              hsr.bits & HSR_SYSREG_REGS_MASK);
+        {
+            struct hsr_sysreg sysreg = hsr.sysreg;
+#ifndef NDEBUG
+
+            gdprintk(XENLOG_ERR,
+                     "%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
+                     sysreg.read ? "mrs" : "msr",
+                     sysreg.op0, sysreg.op1,
+                     sysreg.crn, sysreg.crm,
+                     sysreg.op2,
+                     sysreg.read ? "=>" : "<=",
+                     sysreg.reg, regs->pc);
+            gdprintk(XENLOG_ERR, "unhandled 64-bit sysreg access %#x",
+                     hsr.bits & HSR_SYSREG_REGS_MASK);
+#endif
+            inject_undef64_exception(regs, sysreg.len);
+        }
     }
 
     regs->pc += 4;
-- 
1.7.10.4


["xsa93-4.4-02.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Mon, 14 Apr 2014 20:37:16 +0100
Subject: xen/arm: Don't let the guest access the coprocessors
 registers

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 <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 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


["xsa93-4.4-03.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Mon, 14 Apr 2014 20:46:43 +0100
Subject: xen/arm: Upgrade DCISW into DCCISW

A guest is allowed to use invalidate cache by set/way instruction (i.e DCISW)
without any restriction. As the cache is shared with Xen, the guest invalidate
an address being in used by Xen. This may lead a Xen crash because the memory
state is invalid.
Set the bit HCR.SWIO to upgrade invalidate cache by set/way instruction to an
invalidate and clean.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Reported-by: Thomas Leonard <tal36@cam.ac.uk>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 97ab286..17ac8d8 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -82,7 +82,7 @@ void __cpuinit init_traps(void)
 
     /* Setup hypervisor traps */
     WRITE_SYSREG(HCR_PTW|HCR_BSU_OUTER|HCR_AMO|HCR_IMO|HCR_VM|HCR_TWI|HCR_TSC|
-                 HCR_TAC, HCR_EL2);
+                 HCR_TAC|HCR_SWIO, HCR_EL2);
     isb();
 }
 
-- 
1.7.10.4


["xsa93-4.4-04.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Mon, 14 Apr 2014 20:00:14 +0100
Subject: xen/arm: Trap cache and TCM lockdown registers

Some cp15 c9/c10/c11 encodings are used for:
     - cache control
     - TCM control
     - branch predictor control

All of them are implementation defined. For now inject an undefined exception
if the guest wants try to access it.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 17ac8d8..b77e623 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -82,7 +82,7 @@ void __cpuinit init_traps(void)
 
     /* Setup hypervisor traps */
     WRITE_SYSREG(HCR_PTW|HCR_BSU_OUTER|HCR_AMO|HCR_IMO|HCR_VM|HCR_TWI|HCR_TSC|
-                 HCR_TAC|HCR_SWIO, HCR_EL2);
+                 HCR_TAC|HCR_SWIO|HCR_TIDCP, HCR_EL2);
     isb();
 }
 
-- 
1.7.10.4


["xsa93-4.4-05.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Tue, 15 Apr 2014 12:45:28 +0100
Subject: xen/arm: Don't expose implementation defined registers
 (Cp15 c15) to the guest

On Cortex-A15, CP15 c15 contains registers to retrieve data from L1/L2 RAM.

Exposing this registers to guest may result to leak data from Xen and/or
another guest.

By default trap every registers and inject an undefined instruction.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c            |    3 +++
 xen/include/asm-arm/cpregs.h    |    2 ++
 xen/include/asm-arm/processor.h |    3 +++
 3 files changed, 8 insertions(+)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index b77e623..710e5cc 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -74,6 +74,9 @@ void __cpuinit init_traps(void)
     /* Setup Hyp vector base */
     WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2);
 
+    /* Trap CP15 c15 used for implementation defined registers */
+    WRITE_SYSREG(HSTR_T(15), HSTR_EL2);
+
     /* Trap all coprocessor registers (0-13) except cp10 and cp11 for VFP
      * /!\ All processors except cp10 and cp11 cannot be used in Xen
      */
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index 2b411af..e9a8094 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -116,6 +116,7 @@
 #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 */
+#define HSTR            p15,4,c1,c1,3   /* Hyp. System Trap Register */
 
 /* CP15 CR2: Translation Table Base and Control Registers */
 #define TTBCR           p15,0,c2,c0,2   /* Translatation Table Base Control Register */
@@ -270,6 +271,7 @@
 #define FAR_EL2                 HIFAR
 #define HCR_EL2                 HCR
 #define HPFAR_EL2               HPFAR
+#define HSTR_EL2                HSTR
 #define ID_AFR0_EL1             ID_AFR0
 #define ID_DFR0_EL1             ID_DFR0
 #define ID_ISAR0_EL1            ID_ISAR0
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 02cefe9..750864a 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -89,6 +89,9 @@
 #define HCPTR_CP(x)     ((_AC(1,U)<<(x)))       /* Trap Coprocessor x */
 #define HCPTR_CP_MASK   ((_AC(1,U)<<14)-1)
 
+/* HSTR Hyp. System Trap Register */
+#define HSTR_T(x)       ((_AC(1,U)<<(x)))       /* Trap Cp15 c<x> */
+
 #define HSR_EC_UNKNOWN              0x00
 #define HSR_EC_WFI_WFE              0x01
 #define HSR_EC_CP15_32              0x03
-- 
1.7.10.4


["xsa93-4.4-06.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Tue, 15 Apr 2014 14:06:42 +0100
Subject: xen/arm: Don't let guess access to Debug and Performance
 Monitor registers

Debug and performance registers are not properly switched by Xen.

Trap them and inject an undefined instruction, except for those registers
which might be unconditionally accessed which we implement as RAZ/WI.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c            |   59 +++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/cpregs.h    |    2 ++
 xen/include/asm-arm/processor.h |   11 ++++++--
 xen/include/asm-arm/sysregs.h   |   43 ++++++++++++++++++++++++++++
 4 files changed, 113 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 710e5cc..39c2468 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -74,6 +74,10 @@ void __cpuinit init_traps(void)
     /* Setup Hyp vector base */
     WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2);
 
+    /* Trap Debug and Performance Monitor accesses */
+    WRITE_SYSREG(HDCR_TDRA|HDCR_TDOSA|HDCR_TDA|HDCR_TPM|HDCR_TPMCR,
+                 MDCR_EL2);
+
     /* Trap CP15 c15 used for implementation defined registers */
     WRITE_SYSREG(HSTR_T(15), HSTR_EL2);
 
@@ -1412,6 +1416,17 @@ static void do_cp15_64(struct cpu_user_regs *regs,
     advance_pc(regs, hsr);
 }
 
+static void do_cp14(struct cpu_user_regs *regs, union hsr hsr)
+{
+    if ( !check_conditional_instr(regs, hsr) )
+    {
+        advance_pc(regs, hsr);
+        return;
+    }
+
+    inject_undef32_exception(regs);
+}
+
 static void do_cp(struct cpu_user_regs *regs, union hsr hsr)
 {
     if ( !check_conditional_instr(regs, hsr) )
@@ -1427,9 +1442,46 @@ 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);
 
     switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
     {
+    /* RAZ/WI registers: */
+    /*  - Debug */
+    case HSR_SYSREG_MDSCR_EL1:
+    /*  - Perf monitors */
+    case HSR_SYSREG_PMINTENSET_EL1:
+    case HSR_SYSREG_PMINTENCLR_EL1:
+    case HSR_SYSREG_PMCR_EL0:
+    case HSR_SYSREG_PMCNTENSET_EL0:
+    case HSR_SYSREG_PMCNTENCLR_EL0:
+    case HSR_SYSREG_PMOVSCLR_EL0:
+    case HSR_SYSREG_PMSWINC_EL0:
+    case HSR_SYSREG_PMSELR_EL0:
+    case HSR_SYSREG_PMCEID0_EL0:
+    case HSR_SYSREG_PMCEID1_EL0:
+    case HSR_SYSREG_PMCCNTR_EL0:
+    case HSR_SYSREG_PMXEVTYPER_EL0:
+    case HSR_SYSREG_PMXEVCNTR_EL0:
+    case HSR_SYSREG_PMUSERENR_EL0:
+    case HSR_SYSREG_PMOVSSET_EL0:
+    /* - Breakpoints */
+    HSR_SYSREG_DBG_CASES(DBGBVR):
+    HSR_SYSREG_DBG_CASES(DBGBCR):
+    /* -  Watchpoints */
+    HSR_SYSREG_DBG_CASES(DBGWVR):
+    HSR_SYSREG_DBG_CASES(DBGWCR):
+        if ( hsr.sysreg.read )
+            *x = 0;
+        /* else: write ignored */
+        break;
+
+    /* Write only, Write ignore registers: */
+    case HSR_SYSREG_OSLAR_EL1:
+        if ( hsr.sysreg.read )
+            goto bad_sysreg;
+        /* else: write ignored */
+        break;
     case HSR_SYSREG_CNTP_CTL_EL0:
     case HSR_SYSREG_CNTP_TVAL_EL0:
         if ( !vtimer_emulate(regs, hsr) )
@@ -1440,6 +1492,7 @@ static void do_sysreg(struct cpu_user_regs *regs,
         }
         break;
     default:
+ bad_sysreg:
         {
             struct hsr_sysreg sysreg = hsr.sysreg;
 #ifndef NDEBUG
@@ -1614,6 +1667,12 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs)
             goto bad_trap;
         do_cp15_64(regs, hsr);
         break;
+    case HSR_EC_CP14_32:
+    case HSR_EC_CP14_DBG:
+        if ( !is_pv32_domain(current->domain) )
+            goto bad_trap;
+        do_cp14(regs, hsr);
+        break;
     case HSR_EC_CP:
         if ( !is_pv32_domain(current->domain) )
             goto bad_trap;
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index e9a8094..bf8133e 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 HDCR            p15,4,c1,c1,1   /* Hyp. Debug Configuration Register */
 #define HCPTR           p15,4,c1,c1,2   /* Hyp. Coprocessor Trap Register */
 #define HSTR            p15,4,c1,c1,3   /* Hyp. System Trap Register */
 
@@ -287,6 +288,7 @@
 #define ID_PFR0_EL1             ID_PFR0
 #define ID_PFR1_EL1             ID_PFR1
 #define IFSR32_EL2              IFSR
+#define MDCR_EL2                HDCR
 #define MIDR_EL1                MIDR
 #define MPIDR_EL1               MPIDR
 #define PAR_EL1                 PAR
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 750864a..9267c1b 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -92,12 +92,19 @@
 /* HSTR Hyp. System Trap Register */
 #define HSTR_T(x)       ((_AC(1,U)<<(x)))       /* Trap Cp15 c<x> */
 
+/* HDCR Hyp. Debug Configuration Register */
+#define HDCR_TDRA       (_AC(1,U)<<11)          /* Trap Debug ROM access */
+#define HDCR_TDOSA      (_AC(1,U)<<10)          /* Trap Debug-OS-related register access */
+#define HDCR_TDA        (_AC(1,U)<<9)           /* Trap Debug Access */
+#define HDCR_TPM        (_AC(1,U)<<6)           /* Trap Performance Monitors accesses */
+#define HDCR_TPMCR      (_AC(1,U)<<5)           /* Trap PMCR accesses */
+
 #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_CP14_32              0x05        /* Trapped MCR or MRC access to CP14 */
+#define HSR_EC_CP14_DBG             0x06        /* Trapped LDC/STC access to CP14 (only for debug registers) */
 #define HSR_EC_CP                   0x07        /* HCPTR-trapped access to CP0-CP13 */
 #define HSR_EC_CP10                 0x08
 #define HSR_EC_JAZELLE              0x09
diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h
index 0cee0e9..4a4de34 100644
--- a/xen/include/asm-arm/sysregs.h
+++ b/xen/include/asm-arm/sysregs.h
@@ -40,6 +40,31 @@
     ((__HSR_SYSREG_##crm) << HSR_SYSREG_CRM_SHIFT) | \
     ((__HSR_SYSREG_##op2) << HSR_SYSREG_OP2_SHIFT)
 
+#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_DBGBVRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,4)
+#define HSR_SYSREG_DBGBCRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,5)
+#define HSR_SYSREG_DBGWVRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,6)
+#define HSR_SYSREG_DBGWCRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,7)
+
+#define HSR_SYSREG_DBG_CASES(REG) case HSR_SYSREG_##REG##n_EL1(0):  \
+                                  case HSR_SYSREG_##REG##n_EL1(1):  \
+                                  case HSR_SYSREG_##REG##n_EL1(2):  \
+                                  case HSR_SYSREG_##REG##n_EL1(3):  \
+                                  case HSR_SYSREG_##REG##n_EL1(4):  \
+                                  case HSR_SYSREG_##REG##n_EL1(5):  \
+                                  case HSR_SYSREG_##REG##n_EL1(6):  \
+                                  case HSR_SYSREG_##REG##n_EL1(7):  \
+                                  case HSR_SYSREG_##REG##n_EL1(8):  \
+                                  case HSR_SYSREG_##REG##n_EL1(9):  \
+                                  case HSR_SYSREG_##REG##n_EL1(10): \
+                                  case HSR_SYSREG_##REG##n_EL1(11): \
+                                  case HSR_SYSREG_##REG##n_EL1(12): \
+                                  case HSR_SYSREG_##REG##n_EL1(13): \
+                                  case HSR_SYSREG_##REG##n_EL1(14): \
+                                  case HSR_SYSREG_##REG##n_EL1(15)
+
 #define HSR_SYSREG_SCTLR_EL1      HSR_SYSREG(3,0,c1, c0,0)
 #define HSR_SYSREG_TTBR0_EL1      HSR_SYSREG(3,0,c2, c0,0)
 #define HSR_SYSREG_TTBR1_EL1      HSR_SYSREG(3,0,c2, c0,1)
@@ -48,10 +73,28 @@
 #define HSR_SYSREG_AFSR1_EL1      HSR_SYSREG(3,0,c5, c1,1)
 #define HSR_SYSREG_ESR_EL1        HSR_SYSREG(3,0,c5, c2,0)
 #define HSR_SYSREG_FAR_EL1        HSR_SYSREG(3,0,c6, c0,0)
+#define HSR_SYSREG_PMINTENSET_EL1 HSR_SYSREG(3,0,c9,c14,1)
+#define HSR_SYSREG_PMINTENCLR_EL1 HSR_SYSREG(3,0,c9,c14,2)
 #define HSR_SYSREG_MAIR_EL1       HSR_SYSREG(3,0,c10,c2,0)
 #define HSR_SYSREG_AMAIR_EL1      HSR_SYSREG(3,0,c10,c3,0)
 #define HSR_SYSREG_CONTEXTIDR_EL1 HSR_SYSREG(3,0,c13,c0,1)
 
+#define HSR_SYSREG_PMCR_EL0       HSR_SYSREG(3,3,c9,c12,0)
+#define HSR_SYSREG_PMCNTENSET_EL0 HSR_SYSREG(3,3,c9,c12,1)
+#define HSR_SYSREG_PMCNTENCLR_EL0 HSR_SYSREG(3,3,c9,c12,2)
+#define HSR_SYSREG_PMOVSCLR_EL0   HSR_SYSREG(3,3,c9,c12,3)
+#define HSR_SYSREG_PMSWINC_EL0    HSR_SYSREG(3,3,c9,c12,4)
+#define HSR_SYSREG_PMSELR_EL0     HSR_SYSREG(3,3,c9,c12,5)
+#define HSR_SYSREG_PMCEID0_EL0    HSR_SYSREG(3,3,c9,c12,6)
+#define HSR_SYSREG_PMCEID1_EL0    HSR_SYSREG(3,3,c9,c12,7)
+
+#define HSR_SYSREG_PMCCNTR_EL0    HSR_SYSREG(3,3,c9,c13,0)
+#define HSR_SYSREG_PMXEVTYPER_EL0 HSR_SYSREG(3,3,c9,c13,1)
+#define HSR_SYSREG_PMXEVCNTR_EL0  HSR_SYSREG(3,3,c9,c13,2)
+
+#define HSR_SYSREG_PMUSERENR_EL0  HSR_SYSREG(3,3,c9,c14,0)
+#define HSR_SYSREG_PMOVSSET_EL0   HSR_SYSREG(3,3,c9,c14,3)
+
 #define HSR_SYSREG_CNTPCT_EL0     HSR_SYSREG(3,3,c14,c0,0)
 #define HSR_SYSREG_CNTP_CTL_EL0   HSR_SYSREG(3,3,c14,c2,1)
 #define HSR_SYSREG_CNTP_TVAL_EL0  HSR_SYSREG(3,3,c14,c2,0)
-- 
1.7.10.4


["xsa93-unstable-01.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Mon, 14 Apr 2014 19:01:20 +0100
Subject: xen/arm: Inject an undefined instruction when the
 coproc/sysreg is not handled

Currently Xen panics if it's unable to handle a coprocessor/sysreg instruction.
Replace this behavior by inject an undefined instruction to the faulty guest
and log if Xen is in debug mode.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c |   61 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 20 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index a7edc4e..92b7910 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1351,10 +1351,16 @@ static void do_cp15_32(struct cpu_user_regs *regs,
            *r = v->arch.actlr;
         break;
     default:
-        printk("%s p15, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
-               cp32.read ? "mrc" : "mcr",
-               cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
-        panic("unhandled 32-bit CP15 access %#x", hsr.bits & HSR_CP32_REGS_MASK);
+#ifndef NDEBUG
+        gdprintk(XENLOG_ERR,
+                 "%s p15, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
+                 cp32.read ? "mrc" : "mcr",
+                 cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
+        gdprintk(XENLOG_ERR, "unhandled 32-bit CP15 access %#x",
+                 hsr.bits & HSR_CP32_REGS_MASK);
+#endif
+        inject_undef32_exception(regs);
+        return;
     }
     advance_pc(regs, hsr);
 }
@@ -1362,8 +1368,6 @@ static void do_cp15_32(struct cpu_user_regs *regs,
 static void do_cp15_64(struct cpu_user_regs *regs,
                        union hsr hsr)
 {
-    struct hsr_cp64 cp64 = hsr.cp64;
-
     if ( !check_conditional_instr(regs, hsr) )
     {
         advance_pc(regs, hsr);
@@ -1381,10 +1385,20 @@ static void do_cp15_64(struct cpu_user_regs *regs,
         }
         break;
     default:
-        printk("%s p15, %d, r%d, r%d, cr%d @ 0x%"PRIregister"\n",
-               cp64.read ? "mrrc" : "mcrr",
-               cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
-        panic("unhandled 64-bit CP15 access %#x", hsr.bits & HSR_CP64_REGS_MASK);
+        {
+#ifndef NDEBUG
+            struct hsr_cp64 cp64 = hsr.cp64;
+
+            gdprintk(XENLOG_ERR,
+                     "%s p15, %d, r%d, r%d, cr%d @ 0x%"PRIregister"\n",
+                     cp64.read ? "mrrc" : "mcrr",
+                     cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
+            gdprintk(XENLOG_ERR, "unhandled 64-bit CP15 access %#x",
+                     hsr.bits & HSR_CP64_REGS_MASK);
+#endif
+            inject_undef32_exception(regs);
+            return;
+        }
     }
     advance_pc(regs, hsr);
 }
@@ -1393,7 +1407,6 @@ static void do_cp15_64(struct cpu_user_regs *regs,
 static void do_sysreg(struct cpu_user_regs *regs,
                       union hsr hsr)
 {
-    struct hsr_sysreg sysreg = hsr.sysreg;
 
     switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
     {
@@ -1407,15 +1420,23 @@ static void do_sysreg(struct cpu_user_regs *regs,
         }
         break;
     default:
-        printk("%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
-               sysreg.read ? "mrs" : "msr",
-               sysreg.op0, sysreg.op1,
-               sysreg.crn, sysreg.crm,
-               sysreg.op2,
-               sysreg.read ? "=>" : "<=",
-               sysreg.reg, regs->pc);
-        panic("unhandled 64-bit sysreg access %#x",
-              hsr.bits & HSR_SYSREG_REGS_MASK);
+        {
+            struct hsr_sysreg sysreg = hsr.sysreg;
+#ifndef NDEBUG
+
+            gdprintk(XENLOG_ERR,
+                     "%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
+                     sysreg.read ? "mrs" : "msr",
+                     sysreg.op0, sysreg.op1,
+                     sysreg.crn, sysreg.crm,
+                     sysreg.op2,
+                     sysreg.read ? "=>" : "<=",
+                     sysreg.reg, regs->pc);
+            gdprintk(XENLOG_ERR, "unhandled 64-bit sysreg access %#x",
+                     hsr.bits & HSR_SYSREG_REGS_MASK);
+#endif
+            inject_undef64_exception(regs, sysreg.len);
+        }
     }
 
     regs->pc += 4;
-- 
1.7.10.4


["xsa93-unstable-02.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Mon, 14 Apr 2014 20:37:16 +0100
Subject: xen/arm: Don't let the guest access the coprocessors
 registers

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 <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 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_INNER|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_32bit_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


["xsa93-unstable-03.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Mon, 14 Apr 2014 20:46:43 +0100
Subject: xen/arm: Upgrade DCISW into DCCISW

A guest is allowed to use invalidate cache by set/way instruction (i.e DCISW)
without any restriction. As the cache is shared with Xen, the guest invalidate
an address being in used by Xen. This may lead a Xen crash because the memory
state is invalid.
Set the bit HCR.SWIO to upgrade invalidate cache by set/way instruction to an
invalidate and clean.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Reported-by: Thomas Leonard <tal36@cam.ac.uk>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 97ab286..17ac8d8 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -82,7 +82,7 @@ void __cpuinit init_traps(void)
 
     /* Setup hypervisor traps */
     WRITE_SYSREG(HCR_PTW|HCR_BSU_INNER|HCR_AMO|HCR_IMO|HCR_VM|HCR_TWI|HCR_TSC|
-                 HCR_TAC, HCR_EL2);
+                 HCR_TAC|HCR_SWIO, HCR_EL2);
     isb();
 }
 
-- 
1.7.10.4


["xsa93-unstable-04.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Mon, 14 Apr 2014 20:00:14 +0100
Subject: xen/arm: Trap cache and TCM lockdown registers

Some cp15 c9/c10/c11 encodings are used for:
     - cache control
     - TCM control
     - branch predictor control

All of them are implementation defined. For now inject an undefined exception
if the guest wants try to access it.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 17ac8d8..b77e623 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -82,7 +82,7 @@ void __cpuinit init_traps(void)
 
     /* Setup hypervisor traps */
     WRITE_SYSREG(HCR_PTW|HCR_BSU_INNER|HCR_AMO|HCR_IMO|HCR_VM|HCR_TWI|HCR_TSC|
-                 HCR_TAC|HCR_SWIO, HCR_EL2);
+                 HCR_TAC|HCR_SWIO|HCR_TIDCP, HCR_EL2);
     isb();
 }
 
-- 
1.7.10.4


["xsa93-unstable-05.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Tue, 15 Apr 2014 12:45:28 +0100
Subject: xen/arm: Don't expose implementation defined registers
 (Cp15 c15) to the guest

On Cortex-A15, CP15 c15 contains registers to retrieve data from L1/L2 RAM.

Exposing this registers to guest may result to leak data from Xen and/or
another guest.

By default trap every registers and inject an undefined instruction.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c            |    3 +++
 xen/include/asm-arm/cpregs.h    |    2 ++
 xen/include/asm-arm/processor.h |    3 +++
 3 files changed, 8 insertions(+)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index b77e623..710e5cc 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -74,6 +74,9 @@ void __cpuinit init_traps(void)
     /* Setup Hyp vector base */
     WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2);
 
+    /* Trap CP15 c15 used for implementation defined registers */
+    WRITE_SYSREG(HSTR_T(15), HSTR_EL2);
+
     /* Trap all coprocessor registers (0-13) except cp10 and cp11 for VFP
      * /!\ All processors except cp10 and cp11 cannot be used in Xen
      */
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index 2b411af..e9a8094 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -116,6 +116,7 @@
 #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 */
+#define HSTR            p15,4,c1,c1,3   /* Hyp. System Trap Register */
 
 /* CP15 CR2: Translation Table Base and Control Registers */
 #define TTBCR           p15,0,c2,c0,2   /* Translatation Table Base Control Register */
@@ -270,6 +271,7 @@
 #define FAR_EL2                 HIFAR
 #define HCR_EL2                 HCR
 #define HPFAR_EL2               HPFAR
+#define HSTR_EL2                HSTR
 #define ID_AFR0_EL1             ID_AFR0
 #define ID_DFR0_EL1             ID_DFR0
 #define ID_ISAR0_EL1            ID_ISAR0
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 02cefe9..750864a 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -89,6 +89,9 @@
 #define HCPTR_CP(x)     ((_AC(1,U)<<(x)))       /* Trap Coprocessor x */
 #define HCPTR_CP_MASK   ((_AC(1,U)<<14)-1)
 
+/* HSTR Hyp. System Trap Register */
+#define HSTR_T(x)       ((_AC(1,U)<<(x)))       /* Trap Cp15 c<x> */
+
 #define HSR_EC_UNKNOWN              0x00
 #define HSR_EC_WFI_WFE              0x01
 #define HSR_EC_CP15_32              0x03
-- 
1.7.10.4


["xsa93-unstable-06.patch" (application/octet-stream)]

From: Julien Grall <julien.grall@linaro.org>
Date: Tue, 15 Apr 2014 14:06:42 +0100
Subject: xen/arm: Don't let guess access to Debug and Performance
 Monitor registers

Debug and performance registers are not properly switched by Xen.

Trap them and inject an undefined instruction, except for those registers
which might be unconditionally accessed which we implement as RAZ/WI.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c            |   59 +++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/cpregs.h    |    2 ++
 xen/include/asm-arm/processor.h |   11 ++++++--
 xen/include/asm-arm/sysregs.h   |   43 ++++++++++++++++++++++++++++
 4 files changed, 113 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 710e5cc..39c2468 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -74,6 +74,10 @@ void __cpuinit init_traps(void)
     /* Setup Hyp vector base */
     WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2);
 
+    /* Trap Debug and Performance Monitor accesses */
+    WRITE_SYSREG(HDCR_TDRA|HDCR_TDOSA|HDCR_TDA|HDCR_TPM|HDCR_TPMCR,
+                 MDCR_EL2);
+
     /* Trap CP15 c15 used for implementation defined registers */
     WRITE_SYSREG(HSTR_T(15), HSTR_EL2);
 
@@ -1412,6 +1416,17 @@ static void do_cp15_64(struct cpu_user_regs *regs,
     advance_pc(regs, hsr);
 }
 
+static void do_cp14(struct cpu_user_regs *regs, union hsr hsr)
+{
+    if ( !check_conditional_instr(regs, hsr) )
+    {
+        advance_pc(regs, hsr);
+        return;
+    }
+
+    inject_undef32_exception(regs);
+}
+
 static void do_cp(struct cpu_user_regs *regs, union hsr hsr)
 {
     if ( !check_conditional_instr(regs, hsr) )
@@ -1427,9 +1442,46 @@ 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);
 
     switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
     {
+    /* RAZ/WI registers: */
+    /*  - Debug */
+    case HSR_SYSREG_MDSCR_EL1:
+    /*  - Perf monitors */
+    case HSR_SYSREG_PMINTENSET_EL1:
+    case HSR_SYSREG_PMINTENCLR_EL1:
+    case HSR_SYSREG_PMCR_EL0:
+    case HSR_SYSREG_PMCNTENSET_EL0:
+    case HSR_SYSREG_PMCNTENCLR_EL0:
+    case HSR_SYSREG_PMOVSCLR_EL0:
+    case HSR_SYSREG_PMSWINC_EL0:
+    case HSR_SYSREG_PMSELR_EL0:
+    case HSR_SYSREG_PMCEID0_EL0:
+    case HSR_SYSREG_PMCEID1_EL0:
+    case HSR_SYSREG_PMCCNTR_EL0:
+    case HSR_SYSREG_PMXEVTYPER_EL0:
+    case HSR_SYSREG_PMXEVCNTR_EL0:
+    case HSR_SYSREG_PMUSERENR_EL0:
+    case HSR_SYSREG_PMOVSSET_EL0:
+    /* - Breakpoints */
+    HSR_SYSREG_DBG_CASES(DBGBVR):
+    HSR_SYSREG_DBG_CASES(DBGBCR):
+    /* -  Watchpoints */
+    HSR_SYSREG_DBG_CASES(DBGWVR):
+    HSR_SYSREG_DBG_CASES(DBGWCR):
+        if ( hsr.sysreg.read )
+            *x = 0;
+        /* else: write ignored */
+        break;
+
+    /* Write only, Write ignore registers: */
+    case HSR_SYSREG_OSLAR_EL1:
+        if ( hsr.sysreg.read )
+            goto bad_sysreg;
+        /* else: write ignored */
+        break;
     case HSR_SYSREG_CNTP_CTL_EL0:
     case HSR_SYSREG_CNTP_TVAL_EL0:
         if ( !vtimer_emulate(regs, hsr) )
@@ -1440,6 +1492,7 @@ static void do_sysreg(struct cpu_user_regs *regs,
         }
         break;
     default:
+ bad_sysreg:
         {
             struct hsr_sysreg sysreg = hsr.sysreg;
 #ifndef NDEBUG
@@ -1614,6 +1667,12 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs)
             goto bad_trap;
         do_cp15_64(regs, hsr);
         break;
+    case HSR_EC_CP14_32:
+    case HSR_EC_CP14_DBG:
+        if ( !is_32bit_domain(current->domain) )
+            goto bad_trap;
+        do_cp14(regs, hsr);
+        break;
     case HSR_EC_CP:
         if ( !is_32bit_domain(current->domain) )
             goto bad_trap;
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index e9a8094..bf8133e 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 HDCR            p15,4,c1,c1,1   /* Hyp. Debug Configuration Register */
 #define HCPTR           p15,4,c1,c1,2   /* Hyp. Coprocessor Trap Register */
 #define HSTR            p15,4,c1,c1,3   /* Hyp. System Trap Register */
 
@@ -287,6 +288,7 @@
 #define ID_PFR0_EL1             ID_PFR0
 #define ID_PFR1_EL1             ID_PFR1
 #define IFSR32_EL2              IFSR
+#define MDCR_EL2                HDCR
 #define MIDR_EL1                MIDR
 #define MPIDR_EL1               MPIDR
 #define PAR_EL1                 PAR
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 750864a..9267c1b 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -92,12 +92,19 @@
 /* HSTR Hyp. System Trap Register */
 #define HSTR_T(x)       ((_AC(1,U)<<(x)))       /* Trap Cp15 c<x> */
 
+/* HDCR Hyp. Debug Configuration Register */
+#define HDCR_TDRA       (_AC(1,U)<<11)          /* Trap Debug ROM access */
+#define HDCR_TDOSA      (_AC(1,U)<<10)          /* Trap Debug-OS-related register access */
+#define HDCR_TDA        (_AC(1,U)<<9)           /* Trap Debug Access */
+#define HDCR_TPM        (_AC(1,U)<<6)           /* Trap Performance Monitors accesses */
+#define HDCR_TPMCR      (_AC(1,U)<<5)           /* Trap PMCR accesses */
+
 #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_CP14_32              0x05        /* Trapped MCR or MRC access to CP14 */
+#define HSR_EC_CP14_DBG             0x06        /* Trapped LDC/STC access to CP14 (only for debug registers) */
 #define HSR_EC_CP                   0x07        /* HCPTR-trapped access to CP0-CP13 */
 #define HSR_EC_CP10                 0x08
 #define HSR_EC_JAZELLE              0x09
diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h
index 0cee0e9..4a4de34 100644
--- a/xen/include/asm-arm/sysregs.h
+++ b/xen/include/asm-arm/sysregs.h
@@ -40,6 +40,31 @@
     ((__HSR_SYSREG_##crm) << HSR_SYSREG_CRM_SHIFT) | \
     ((__HSR_SYSREG_##op2) << HSR_SYSREG_OP2_SHIFT)
 
+#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_DBGBVRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,4)
+#define HSR_SYSREG_DBGBCRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,5)
+#define HSR_SYSREG_DBGWVRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,6)
+#define HSR_SYSREG_DBGWCRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,7)
+
+#define HSR_SYSREG_DBG_CASES(REG) case HSR_SYSREG_##REG##n_EL1(0):  \
+                                  case HSR_SYSREG_##REG##n_EL1(1):  \
+                                  case HSR_SYSREG_##REG##n_EL1(2):  \
+                                  case HSR_SYSREG_##REG##n_EL1(3):  \
+                                  case HSR_SYSREG_##REG##n_EL1(4):  \
+                                  case HSR_SYSREG_##REG##n_EL1(5):  \
+                                  case HSR_SYSREG_##REG##n_EL1(6):  \
+                                  case HSR_SYSREG_##REG##n_EL1(7):  \
+                                  case HSR_SYSREG_##REG##n_EL1(8):  \
+                                  case HSR_SYSREG_##REG##n_EL1(9):  \
+                                  case HSR_SYSREG_##REG##n_EL1(10): \
+                                  case HSR_SYSREG_##REG##n_EL1(11): \
+                                  case HSR_SYSREG_##REG##n_EL1(12): \
+                                  case HSR_SYSREG_##REG##n_EL1(13): \
+                                  case HSR_SYSREG_##REG##n_EL1(14): \
+                                  case HSR_SYSREG_##REG##n_EL1(15)
+
 #define HSR_SYSREG_SCTLR_EL1      HSR_SYSREG(3,0,c1, c0,0)
 #define HSR_SYSREG_TTBR0_EL1      HSR_SYSREG(3,0,c2, c0,0)
 #define HSR_SYSREG_TTBR1_EL1      HSR_SYSREG(3,0,c2, c0,1)
@@ -48,10 +73,28 @@
 #define HSR_SYSREG_AFSR1_EL1      HSR_SYSREG(3,0,c5, c1,1)
 #define HSR_SYSREG_ESR_EL1        HSR_SYSREG(3,0,c5, c2,0)
 #define HSR_SYSREG_FAR_EL1        HSR_SYSREG(3,0,c6, c0,0)
+#define HSR_SYSREG_PMINTENSET_EL1 HSR_SYSREG(3,0,c9,c14,1)
+#define HSR_SYSREG_PMINTENCLR_EL1 HSR_SYSREG(3,0,c9,c14,2)
 #define HSR_SYSREG_MAIR_EL1       HSR_SYSREG(3,0,c10,c2,0)
 #define HSR_SYSREG_AMAIR_EL1      HSR_SYSREG(3,0,c10,c3,0)
 #define HSR_SYSREG_CONTEXTIDR_EL1 HSR_SYSREG(3,0,c13,c0,1)
 
+#define HSR_SYSREG_PMCR_EL0       HSR_SYSREG(3,3,c9,c12,0)
+#define HSR_SYSREG_PMCNTENSET_EL0 HSR_SYSREG(3,3,c9,c12,1)
+#define HSR_SYSREG_PMCNTENCLR_EL0 HSR_SYSREG(3,3,c9,c12,2)
+#define HSR_SYSREG_PMOVSCLR_EL0   HSR_SYSREG(3,3,c9,c12,3)
+#define HSR_SYSREG_PMSWINC_EL0    HSR_SYSREG(3,3,c9,c12,4)
+#define HSR_SYSREG_PMSELR_EL0     HSR_SYSREG(3,3,c9,c12,5)
+#define HSR_SYSREG_PMCEID0_EL0    HSR_SYSREG(3,3,c9,c12,6)
+#define HSR_SYSREG_PMCEID1_EL0    HSR_SYSREG(3,3,c9,c12,7)
+
+#define HSR_SYSREG_PMCCNTR_EL0    HSR_SYSREG(3,3,c9,c13,0)
+#define HSR_SYSREG_PMXEVTYPER_EL0 HSR_SYSREG(3,3,c9,c13,1)
+#define HSR_SYSREG_PMXEVCNTR_EL0  HSR_SYSREG(3,3,c9,c13,2)
+
+#define HSR_SYSREG_PMUSERENR_EL0  HSR_SYSREG(3,3,c9,c14,0)
+#define HSR_SYSREG_PMOVSSET_EL0   HSR_SYSREG(3,3,c9,c14,3)
+
 #define HSR_SYSREG_CNTPCT_EL0     HSR_SYSREG(3,3,c14,c0,0)
 #define HSR_SYSREG_CNTP_CTL_EL0   HSR_SYSREG(3,3,c14,c2,1)
 #define HSR_SYSREG_CNTP_TVAL_EL0  HSR_SYSREG(3,3,c14,c2,0)
-- 
1.7.10.4



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic