xen/arm: Sanitize CTR_EL0
authorBertrand Marquis <bertrand.marquis@arm.com>
Thu, 16 Sep 2021 06:25:40 +0000 (07:25 +0100)
committerStefano Stabellini <stefano.stabellini@xilinx.com>
Thu, 16 Sep 2021 21:15:52 +0000 (14:15 -0700)
Sanitize CTR_EL0 value between cores and taint Xen if incompatible
values are found.

In the case of different i-cache types, the sanitize ctr_el0 will have a
sanitize value but this is currently not used or exposed to guest which
are seeing the original ctr_el0 value.

Use the opportunity to rename CTR_L1Ip to use an upper case name like
Linux does.
The patch is also defining ICACHE_POLICY_xxx instead of only having
CTR_L1IP_xxx to sync the definitions with Linux and is updating the code
using those accordingly (arm32 setup).

On platforms with only the same type of cores, this patch should not
modify the current Xen behaviour.

Signed-off-by: Bertrand Marquis <bertrand.marquis@arm.com>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/arm64/cpufeature.c
xen/arch/arm/cpufeature.c
xen/arch/arm/setup.c
xen/include/asm-arm/cpufeature.h
xen/include/asm-arm/processor.h

index d4679f5df304bc275eb802584b8c1b1da60d4cfb..6e5d30dc7b52501e5fa78812383d9dd3c1290377 100644 (file)
@@ -275,9 +275,6 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
        ARM64_FTR_END,
 };
 
-#if 0
-/* TODO: use this to sanitize the cache line size among cores */
-
 static const struct arm64_ftr_bits ftr_ctr[] = {
        ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RES1 */
        ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, CTR_DIC_SHIFT, 1, 1),
@@ -294,7 +291,6 @@ static const struct arm64_ftr_bits ftr_ctr[] = {
        ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, CTR_IMINLINE_SHIFT, 4, 0),
        ARM64_FTR_END,
 };
-#endif
 
 static const struct arm64_ftr_bits ftr_id_mmfr0[] = {
        S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR0_INNERSHR_SHIFT, 4, 0xf),
@@ -606,6 +602,8 @@ void update_system_features(const struct cpuinfo_arm *new)
         */
        SANITIZE_REG(dczid, 0, dczid);
 
+       SANITIZE_REG(ctr, 0, ctr);
+
        if ( cpu_feature64_has_el0_32(&system_cpuinfo) )
        {
                SANITIZE_ID_REG(pfr32, 0, pfr0);
index 113f20f601a8f0211d9876821240433fc3bc7e67..6e51f530a80e6677b598d74de820b5e491247e23 100644 (file)
@@ -127,6 +127,8 @@ void identify_cpu(struct cpuinfo_arm *c)
 
     c->dczid.bits[0] = READ_SYSREG(DCZID_EL0);
 
+    c->ctr.bits[0] = READ_SYSREG(CTR_EL0);
+
     aarch32_el0 = cpu_feature64_has_el0_32(c);
 #endif
 
index 4ab13d0fbe3f5021bed128bc2db4b3c65332d587..49dc90d198a7260395a6d22858ed8b8691ff429c 100644 (file)
@@ -650,7 +650,7 @@ static void __init setup_mm(void)
         panic("No memory bank\n");
 
     /* We only supports instruction caches implementing the IVIPT extension. */
-    if ( ((ctr >> CTR_L1Ip_SHIFT) & CTR_L1Ip_MASK) == CTR_L1Ip_AIVIVT )
+    if ( ((ctr >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK) == ICACHE_POLICY_AIVIVT )
         panic("AIVIVT instruction cache not supported\n");
 
     init_pdx();
index 5219fd3bab346fe3a61c94eb419be982efd1d859..5ca09b0bff735a03d87a9ea61938f09f1653d79a 100644 (file)
@@ -267,6 +267,14 @@ struct cpuinfo_arm {
         register_t bits[1];
     } dczid;
 
+    /*
+     * CTR is only used to check for different cache types or policies and
+     * taint Xen in this case
+     */
+    struct {
+        register_t bits[1];
+    } ctr;
+
 #endif
 
     /*
index 2058b694472851b3d41fb8ddd78c823dc9d04839..8ab2940f688e19b9fb60979591223e3ddcecc1b5 100644 (file)
@@ -7,9 +7,21 @@
 #include <public/arch-arm.h>
 
 /* CTR Cache Type Register */
-#define CTR_L1Ip_MASK       0x3
-#define CTR_L1Ip_SHIFT      14
-#define CTR_L1Ip_AIVIVT     0x1
+#define CTR_L1IP_MASK       0x3
+#define CTR_L1IP_SHIFT      14
+#define CTR_DMINLINE_SHIFT  16
+#define CTR_IMINLINE_SHIFT  0
+#define CTR_IMINLINE_MASK   0xf
+#define CTR_ERG_SHIFT       20
+#define CTR_CWG_SHIFT       24
+#define CTR_CWG_MASK        15
+#define CTR_IDC_SHIFT       28
+#define CTR_DIC_SHIFT       29
+
+#define ICACHE_POLICY_VPIPT  0
+#define ICACHE_POLICY_AIVIVT 1
+#define ICACHE_POLICY_VIPT   2
+#define ICACHE_POLICY_PIPT   3
 
 /* MIDR Main ID Register */
 #define MIDR_REVISION_MASK      0xf