]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
xen/arm: compute LLC way size by hardware inspection
authorLuca Miccio <206497@studenti.unimore.it>
Wed, 21 Aug 2019 13:55:52 +0000 (15:55 +0200)
committerLuca Miccio <206497@studenti.unimore.it>
Mon, 6 Jan 2020 13:46:31 +0000 (14:46 +0100)
The size of the LLC way is a crucial parameter for the cache coloring
support, since it determines the maximum number of available colors on
the the platform.  This parameter can currently be retrieved only from
the way_size bootarg and it is prone to misconfiguration nullifying the
coloring mechanism and breaking cache isolation.

Add an alternative and more safe method to retrieve the way size by
directly asking the hardware, namely using CCSIDR_EL1 and CSSELR_EL1
registers.

This method has to check also if at least L2 is implemented in the
hardware since there are scenarios where only L1 cache is availble, e.g,
QEMU.

Signed-off-by: Luca Miccio <206497@studenti.unimore.it>
Signed-off-by: Marco Solieri <marco.solieri@unimore.it>
xen/arch/arm/coloring.c

index c7a98f8552641b33857fd174859fa59ac8eb8da6..ae1f37070348d00731851914fb432206724435d5 100644 (file)
@@ -25,6 +25,9 @@
 #include <xen/lib.h>
 #include <xen/errno.h>
 
+#include <asm/coloring.h>
+#include <asm/io.h>
+
 /* Number of color(s) assigned to Xen */
 static uint64_t xen_col_num;
 /* Coloring configuration of Xen as bitmask */
@@ -37,6 +40,79 @@ static uint64_t dom0_colors_mask;
 
 static uint64_t way_size;
 
+#define CTR_LINESIZE_MASK 0x7
+#define CTR_SIZE_SHIFT 13
+#define CTR_SIZE_MASK 0x3FFF
+#define CTR_SELECT_L2 1 << 1
+#define CTR_SELECT_L3 1 << 2
+#define CTR_CTYPEn_MASK 0x7
+#define CTR_CTYPE2_SHIFT 3
+#define CTR_CTYPE3_SHIFT 6
+#define CTR_LLC_ON 1 << 2
+#define CTR_LOC_SHIFT 24
+#define CTR_LOC_MASK 0x7
+#define CTR_LOC_L2 1 << 1
+#define CTR_LOC_NOT_IMPLEMENTED 1 << 0
+
+
+/* Return the way size of last level cache by asking the hardware */
+static uint64_t get_llc_way_size(void)
+{
+    uint32_t cache_sel = READ_SYSREG64(CSSELR_EL1);
+    uint32_t cache_global_info = READ_SYSREG64(CLIDR_EL1);
+    uint32_t cache_info;
+    uint32_t cache_line_size;
+    uint32_t cache_set_num;
+    uint32_t cache_sel_tmp;
+
+    C_DEBUG("Get information on LLC\n");
+    C_DEBUG("Cache CLIDR_EL1: 0x%x\n", cache_global_info);
+
+    /* Check if at least L2 is implemented */
+    if ( ((cache_global_info >> CTR_LOC_SHIFT) & CTR_LOC_MASK)
+        == CTR_LOC_NOT_IMPLEMENTED )
+    {
+        C_DEBUG("ERROR: L2 Cache not implemented\n");
+        return 0;
+    }
+
+    /* Save old value of CSSELR_EL1 */
+    cache_sel_tmp = cache_sel;
+
+    /* Get LLC index */
+    if ( ((cache_global_info >> CTR_CTYPE2_SHIFT) & CTR_CTYPEn_MASK)
+        == CTR_LLC_ON )
+        cache_sel = CTR_SELECT_L2;
+    else
+        cache_sel = CTR_SELECT_L3;
+
+    C_DEBUG("LLC selection: %u\n", cache_sel);
+    /* Select the correct LLC in CSSELR_EL1 */
+    WRITE_SYSREG64(cache_sel, CSSELR_EL1);
+
+    /* Ensure write */
+    isb();
+
+    /* Get info about the LLC */
+    cache_info = READ_SYSREG64(CCSIDR_EL1);
+
+    /* ARM TRM: (Log2(Number of bytes in cache line)) - 4. */
+    cache_line_size = 1 << ((cache_info & CTR_LINESIZE_MASK) + 4);
+    /* ARM TRM: (Number of sets in cache) - 1 */
+    cache_set_num = ((cache_info >> CTR_SIZE_SHIFT) & CTR_SIZE_MASK) + 1;
+
+    C_DEBUG("Cache line size: %u bytes\n", cache_line_size);
+    C_DEBUG("Cache sets num: %u\n", cache_set_num);
+
+    /* Restore value in CSSELR_EL1 */
+    WRITE_SYSREG64(cache_sel_tmp, CSSELR_EL1);
+
+    /* Ensure write */
+    isb();
+
+    return (cache_line_size * cache_set_num);
+}
+
 /*************************
  * PARSING COLORING BOOTARGS
  */