Signed-off-by: Andrea Bastoni <[email protected]> --- hypervisor/arch/arm64/Kbuild | 2 +- hypervisor/arch/arm64/cache_layout.c | 148 ++++++++++++++++++ .../arch/arm64/include/asm/cache_layout.h | 19 +++ hypervisor/arch/arm64/include/asm/coloring.h | 3 +- 4 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 hypervisor/arch/arm64/cache_layout.c create mode 100644 hypervisor/arch/arm64/include/asm/cache_layout.h
diff --git a/hypervisor/arch/arm64/Kbuild b/hypervisor/arch/arm64/Kbuild index a5525811..3f5aebcd 100644 --- a/hypervisor/arch/arm64/Kbuild +++ b/hypervisor/arch/arm64/Kbuild @@ -23,4 +23,4 @@ lib-y := $(common-objs-y) lib-y += entry.o setup.o control.o mmio.o paging.o caches.o traps.o lib-y += iommu.o smmu-v3.o ti-pvu.o lib-y += smmu.o -lib-y += coloring.o +lib-y += coloring.o cache_layout.o diff --git a/hypervisor/arch/arm64/cache_layout.c b/hypervisor/arch/arm64/cache_layout.c new file mode 100644 index 00000000..0f28a440 --- /dev/null +++ b/hypervisor/arch/arm64/cache_layout.c @@ -0,0 +1,148 @@ +/* + * Jailhouse Cache Coloring Support + * + * Copyright (C) Università di Modena e Reggio Emilia, 2018 + * Copyright (C) Boston University, 2020 + * Copyright (C) Technical University of Munich, 2020 + * + * Authors: + * Luca Miccio <[email protected]> + * Renato Mancuso (BU) <[email protected]> + * Andrea Bastoni <[email protected]> + * + * Autodetection of the cache geometry. + * + * This work is licensed under the terms of the GNU GPL, version 2. See the + * COPYING file in the top-level directory. + */ + +#include <jailhouse/printk.h> +#include <jailhouse/utils.h> +#include <jailhouse/paging.h> +#include <asm/cache_layout.h> +#include <asm/sysregs.h> + +#define verb_print(fmt, ...) \ + printk("[COL] " fmt, ##__VA_ARGS__) + +#define MAX_CACHE_LEVEL 7 + +#define CLIDR_CTYPE(reg, n) GET_FIELD((reg), 3*(n)+2, 3*(n)) +#define CLIDR_ICB(reg) GET_FIELD((reg), 32, 30) + +enum clidr_ctype { + CLIDR_CTYPE_NOCACHE, + CLIDR_CTYPE_IONLY, + CLIDR_CTYPE_DONLY, + CLIDR_CTYPE_IDSPLIT, + CLIDR_CTYPE_UNIFIED, +}; + +#define CSSELR_LEVEL(reg) SET_FIELD((reg), 3, 1) +#define CSSELR_IND 0x1 + +/* Assume ARM v8.0, v8.1, v8.2 */ +#define CCSIDR_LINE_SIZE(reg) GET_FIELD((reg), 2, 0) +#define CCSIDR_ASSOC(reg) GET_FIELD((reg), 12, 3) +#define CCSIDR_NUM_SETS(reg) GET_FIELD((reg), 27, 13) + +const char * cache_types[] = {"Not present", "Instr. Only", "Data Only", "I+D Split", "Unified"}; + +typedef struct cache { + /* Total size of the cache in bytes */ + u64 size; + /* Size of a single way in bytes */ + u64 line_size; + /* Size of each cache line in bytes */ + u64 way_size; + /* Associativity */ + u32 assoc; + /* Max number of colors supported by this cache */ + u64 colors; + /* Which level is this cache at */ + int level; +} cache_t; + +/** Autodetect cache(s) geometry. + * Return the size of a way or 0 if no cache was detected. + */ +u64 arm_cache_layout_detect(void) +{ + /* First, parse CLIDR_EL1 to understand how many levels are + * present in the system. */ + u64 reg, geom; + unsigned int max_cache_level; + + unsigned int n; + cache_t cache; + u64 type, assoc, ls, sets; + + arm_read_sysreg(clidr_el1, reg); + + max_cache_level = CLIDR_ICB(reg); + if (max_cache_level == 0) { + max_cache_level = MAX_CACHE_LEVEL; + verb_print("\tUsing default max cache levels\n"); + } + verb_print("\tmax cache level = %u\n", max_cache_level); + + cache.way_size = 0; + cache.level = -1; + + for (n = 0; n < max_cache_level; ++n) { + type = CLIDR_CTYPE(reg, n); + verb_print("\tL%d Cache Type: %s\n", n + 1, cache_types[type]); + + if (type == CLIDR_CTYPE_NOCACHE) + continue; + + /* Fetch additional info about this cache level */ + arm_write_sysreg(csselr_el1, CSSELR_LEVEL(n)); + arm_read_sysreg(ccsidr_el1, geom); + + /* Parse info about this level */ + ls = 1 << (4 + CCSIDR_LINE_SIZE(geom)); + assoc = CCSIDR_ASSOC(geom) + 1; + sets = CCSIDR_NUM_SETS(geom) + 1; + + verb_print("\t\tTotal size: %lld\n", ls * assoc * sets); + verb_print("\t\tLine size: %lld\n", ls); + verb_print("\t\tAssoc.: %lld\n", assoc); + verb_print("\t\tNum. sets: %lld\n", sets); + + if (type == CLIDR_CTYPE_IDSPLIT) { + arm_write_sysreg(csselr_el1, (CSSELR_LEVEL(n) | CSSELR_IND)); + arm_read_sysreg(ccsidr_el1, geom); + + ls = 1 << (4 + CCSIDR_LINE_SIZE(geom)); + assoc = CCSIDR_ASSOC(geom) + 1; + sets = CCSIDR_NUM_SETS(geom) + 1; + + verb_print("\t\tTotal size (I): %lld\n", ls * assoc * sets); + verb_print("\t\tLine size (I): %lld\n", ls); + verb_print("\t\tAssoc. (I): %lld\n", assoc); + verb_print("\t\tNum. sets (I): %lld\n", sets); + + } + + /* Perform coloring at the last unified cache level */ + if (type == CLIDR_CTYPE_UNIFIED) { + cache.level = n + 1; + + cache.size = ls * assoc * sets; + cache.line_size = ls; + cache.way_size = ls * sets; + cache.assoc = assoc; + cache.colors = sets / (PAGE_SIZE / ls); + + /* Compute the max. number of colors */ + verb_print("\t\tNum. colors: %lld\n", cache.colors); + } + + } + + verb_print("\tNOTE: L%d Cache selected for coloring.\n", cache.level); + + return cache.way_size; +} + diff --git a/hypervisor/arch/arm64/include/asm/cache_layout.h b/hypervisor/arch/arm64/include/asm/cache_layout.h new file mode 100644 index 00000000..959388f5 --- /dev/null +++ b/hypervisor/arch/arm64/include/asm/cache_layout.h @@ -0,0 +1,19 @@ +/* + * Jailhouse Cache Coloring Support + * + * Copyright (C) Università di Modena e Reggio Emilia, 2018 + * Copyright (C) Boston University, 2020 + * Copyright (C) Technical University of Munich, 2020 + * + * Authors: + * Luca Miccio <[email protected]> + * Renato Mancuso (BU) <[email protected]> + * Andrea Bastoni <[email protected]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See the + * COPYING file in the top-level directory. + */ +/** Autodetect cache(s) geometry. + * Return the size of a way or 0 if no cache was detected. + */ +extern u64 arm_cache_layout_detect(void); diff --git a/hypervisor/arch/arm64/include/asm/coloring.h b/hypervisor/arch/arm64/include/asm/coloring.h index 44c1ca38..61def877 100644 --- a/hypervisor/arch/arm64/include/asm/coloring.h +++ b/hypervisor/arch/arm64/include/asm/coloring.h @@ -17,6 +17,7 @@ #define _JAILHOUSE_COLORING_H #include <jailhouse/cell.h> +#include <asm/cache_layout.h> #define col_print(fmt, ...) \ printk("[COL] " fmt, ##__VA_ARGS__) @@ -59,7 +60,7 @@ static inline void arm_color_dcache_flush_memory_region( */ static inline void arm_color_init(void) { - return; + coloring_way_size = arm_cache_layout_detect(); } /* ------------------------- COLORING API ---------------------------------- */ -- 2.29.2 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/jailhouse-dev/20201123204613.252563-5-andrea.bastoni%40tum.de.
