From: Luca Miccio <206497@studenti.unimore.it> Date: Wed, 21 Aug 2019 13:55:52 +0000 (+0200) Subject: xen/arm: compute LLC way size by hardware inspection X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=604922e48ee0cd5880ac73ebfd59afd41cf6d99c;p=people%2Fsstabellini%2Fxen-unstable.git%2F.git xen/arm: compute LLC way size by hardware inspection 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 --- diff --git a/xen/arch/arm/coloring.c b/xen/arch/arm/coloring.c index c7a98f8552..ae1f370703 100644 --- a/xen/arch/arm/coloring.c +++ b/xen/arch/arm/coloring.c @@ -25,6 +25,9 @@ #include #include +#include +#include + /* 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 */