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.

Reply via email to