Each colored operation has to identify the correct physically colored
address where to map successive virtual addresses according to
contiguous coloring regions (expressed as contiguous bits in the color
bitmask).

Coloring is still disabled since coloring_way_size is not yet
determined.

Signed-off-by: Andrea Bastoni <andrea.bast...@tum.de>
---
 hypervisor/arch/arm64/Kbuild                 |   1 +
 hypervisor/arch/arm64/coloring.c             | 186 +++++++++++++++++++
 hypervisor/arch/arm64/include/asm/coloring.h |  85 +++++++--
 3 files changed, 258 insertions(+), 14 deletions(-)
 create mode 100644 hypervisor/arch/arm64/coloring.c

diff --git a/hypervisor/arch/arm64/Kbuild b/hypervisor/arch/arm64/Kbuild
index 4d328021..a5525811 100644
--- a/hypervisor/arch/arm64/Kbuild
+++ b/hypervisor/arch/arm64/Kbuild
@@ -23,3 +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
diff --git a/hypervisor/arch/arm64/coloring.c b/hypervisor/arch/arm64/coloring.c
new file mode 100644
index 00000000..ea19560c
--- /dev/null
+++ b/hypervisor/arch/arm64/coloring.c
@@ -0,0 +1,186 @@
+/*
+ * 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 <lucmic...@gmail.com>
+ *  Renato Mancuso (BU) <rmanc...@bu.edu>
+ *  Andrea Bastoni <andrea.bast...@tum.de>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See the
+ * COPYING file in the top-level directory.
+ */
+#include <jailhouse/control.h>
+#include <jailhouse/paging.h>
+#include <jailhouse/printk.h>
+#include <jailhouse/string.h>
+#include <jailhouse/unit.h>
+#include <jailhouse/cell.h>
+#include <jailhouse/mmio.h>
+#include <asm/control.h>
+#include <asm/coloring.h>
+
+/**
+ *  Only parameter needed to determine the coloring.
+ */
+u64 coloring_way_size = 0;
+
+static inline int coloring_mem_destroy(struct cell *cell,
+                                      struct jailhouse_memory *mr)
+{
+       int err = 0;
+
+       /* Coloring was not created for subpages */
+       if (JAILHOUSE_MEMORY_IS_SUBPAGE(mr)) {
+               BUG();
+       }
+
+       err = arch_unmap_memory_region(cell, mr);
+       if (err)
+               return err;
+
+       if (!(mr->flags & (JAILHOUSE_MEM_COMM_REGION |
+                                       JAILHOUSE_MEM_ROOTSHARED))) {
+               err = remap_to_root_cell(mr, WARN_ON_ERROR);
+       }
+
+       return err;
+}
+
+static inline int coloring_mem_start(struct jailhouse_memory *mr)
+{
+       if (!(mr->flags & JAILHOUSE_MEM_LOADABLE)) {
+               BUG();
+       }
+
+       /* Match the address specified during load */
+       mr->virt_start += ROOT_MAP_OFFSET;
+
+       return arch_unmap_memory_region(&root_cell, mr);
+}
+
+static inline int coloring_mem_load(struct jailhouse_memory *mr)
+{
+       if (!(mr->flags & JAILHOUSE_MEM_LOADABLE)) {
+               BUG();
+       }
+
+       /* Fix addr to match the driver's IPA ioremap */
+       mr->virt_start += ROOT_MAP_OFFSET;
+
+       /* Create an ad-hoc mapping just to load this image */
+       return arch_map_memory_region(&root_cell, mr);
+}
+
+static int dispatch_op(struct cell *cell, struct jailhouse_memory *mr,
+                             unsigned int op, unsigned int flags)
+{
+       if (op & COL_OP_CREATE) {
+               return arch_map_memory_region(cell, mr);
+       }
+
+       if (op & COL_OP_DESTROY) {
+               return coloring_mem_destroy(cell, mr);
+       }
+
+       if (op & COL_OP_START) {
+               return coloring_mem_start(mr);
+       }
+
+       if (op & COL_OP_LOAD) {
+               return coloring_mem_load(mr);
+       }
+
+       if (op & COL_OP_FLUSH) {
+               arm_dcache_flush_memory_region(mr->phys_start, mr->size, flags);
+               return 0;
+       }
+
+       /* shouldn't get here */
+       BUG();
+
+       /* keep compiler happy */
+       return 0;
+}
+
+/**
+ *  Get range of contiguous bits in a bitmask.
+ *
+ *  The function returns:
+ *  - bitmask without the extracted bit range.
+ *  - low: original bit position of range start.
+ *  - size: size of the range
+ *
+ *  The function assumes bitmask is not 0.
+ */
+static inline void get_bit_range(
+       size_t *bitmask,
+       unsigned int *low,
+       unsigned int *size)
+{
+       unsigned int _range;
+
+       //col_print("mask: 0x%lx ", *bitmask);
+
+       *low = ffsl(*bitmask);
+       _range = *bitmask >> *low;
+       *bitmask = _range & (_range + 1UL);
+
+       _range = _range ^ *bitmask;
+       *size = msbl(_range) + 1;
+
+       //col_print("range: 0x%x, low: %u, size %u\n", _range, *low, *size);
+}
+
+int color_cell_op(struct cell *cell,
+                 const struct jailhouse_memory *col_mem,
+                 unsigned int op, unsigned int flags)
+{
+       size_t colors;
+       u64 phys_start = col_mem->phys_start;
+       u64 virt_start = col_mem->virt_start;
+       struct jailhouse_memory mr;
+       unsigned int start, low, size;
+       unsigned int n;
+       int err = -EINVAL;
+
+       col_print("OP 0x%x: PHYS 0x%08llx -> VIRT 0x%08llx "
+                       "(C: 0x%08lx, F: 0x%x)\n",
+                       op, col_mem->phys_start,
+                       col_mem->virt_start,
+                       col_mem->colors, flags);
+
+       n = 0;
+       mr.flags = col_mem->flags;
+       while (virt_start < col_mem->virt_start + col_mem->size) {
+               start = low = size = 0;
+               colors = col_mem->colors;
+
+               while (colors != 0) {
+                       /* update colors with next color-range */
+                       get_bit_range(&colors, &low, &size);
+                       start += low;
+                       mr.size = size * PAGE_SIZE;
+                       mr.phys_start = phys_start + (start * PAGE_SIZE) +
+                                       (n * coloring_way_size);
+                       mr.virt_start = virt_start;
+                       /* update next round */
+                       virt_start += mr.size;
+                       n++;
+#if 0
+                       col_print("V: 0x%08llx -> P: 0x%08llx (size = 
0x%08llx)\n",
+                                       mr.virt_start, mr.phys_start,
+                                       mr.size);
+#endif
+                       err = dispatch_op(cell, &mr, op, flags);
+                       if (err)
+                               return err;
+               }
+       }
+
+       col_print("Result: %d\n", err);
+       return err;
+}
diff --git a/hypervisor/arch/arm64/include/asm/coloring.h 
b/hypervisor/arch/arm64/include/asm/coloring.h
index 54bfa9dd..44c1ca38 100644
--- a/hypervisor/arch/arm64/include/asm/coloring.h
+++ b/hypervisor/arch/arm64/include/asm/coloring.h
@@ -1,9 +1,13 @@
 /*
  * 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 <lucmic...@gmail.com>
+ *  Renato Mancuso (BU) <rmanc...@bu.edu>
  *  Andrea Bastoni <andrea.bast...@tum.de>
  *
  * This work is licensed under the terms of the GNU GPL, version 2.  See the
@@ -12,13 +16,34 @@
 #ifndef _JAILHOUSE_COLORING_H
 #define _JAILHOUSE_COLORING_H
 
-#include <asm/dcaches.h>
+#include <jailhouse/cell.h>
 
-/* Initial empty stub for coloring functions. */
-static inline void arm_color_init(void)
-{
-       return;
-}
+#define col_print(fmt, ...)                    \
+       printk("[COL] " fmt, ##__VA_ARGS__)
+
+/** Color operations */
+#define COL_OP_CREATE  0x1
+#define COL_OP_DESTROY 0x2
+#define COL_OP_START   0x4
+#define COL_OP_LOAD    0x8
+#define COL_OP_FLUSH   0x10
+
+/**
+ * Only parameter needed to determine the coloring.
+ */
+extern u64 coloring_way_size;
+
+/**
+ * Colored operations on a cell / memory region.
+ *
+ * Encapsulate the loops needed to iterate through a region and identify
+ * the color-compatible phys2virt mappings.
+ */
+extern int color_cell_op(struct cell *cell,
+                        const struct jailhouse_memory *mr,
+                        unsigned int op, unsigned int flags);
+
+/* -------------------- COLORING ARCH API ---------------------------------- */
 
 /* Make sure we catch incorrect calls to these functions for arm */
 static inline void arm_color_dcache_flush_memory_region(
@@ -26,34 +51,66 @@ static inline void arm_color_dcache_flush_memory_region(
                const struct jailhouse_memory *mr,
                enum dcache_flush flush_type)
 {
-       BUG();
+       (void)color_cell_op(cell, mr, COL_OP_FLUSH, flush_type);
+}
+
+/**
+ * Autodetection of coloring_way_size.
+ */
+static inline void arm_color_init(void)
+{
+       return;
 }
 
+/* ------------------------- COLORING API ---------------------------------- */
+
 static inline void arch_color_unmap_memory_region(
                struct cell *cell,
                const struct jailhouse_memory *mr)
 {
-       BUG();
+       int err;
+
+       if (coloring_way_size == 0) {
+               /* TODO: add assert() for debugging jailhouse? */
+               /* must have mapped before */
+               BUG();
+       }
+
+       err = color_cell_op(cell, mr, COL_OP_DESTROY, 0);
+       if (err) {
+               BUG();
+       }
 }
 
 static inline int arch_color_map_memory_region(
                struct cell *cell,
                const struct jailhouse_memory *mr)
 {
-       BUG();
-       return 0;
+       if (coloring_way_size == 0) {
+               return -ENODEV;
+       }
+
+       // assert(!JAILHOUSE_MEMORY_IS_SUBPAGE(mr));
+
+       return color_cell_op(cell, mr, COL_OP_CREATE, 0);
 }
 
 static inline int arch_color_remap_to_root(const struct jailhouse_memory *mr)
 {
-       BUG();
-       return 0;
+       if (coloring_way_size == 0) {
+               return -ENODEV;
+       }
+
+       return color_cell_op(&root_cell, mr, COL_OP_LOAD, 0);
 }
 
 static inline int arch_color_unmap_from_root(const struct jailhouse_memory *mr)
 {
-       BUG();
-       return 0;
+       if (coloring_way_size == 0) {
+               return -ENODEV;
+       }
+
+       return color_cell_op(&root_cell, mr, COL_OP_START, 0);
 }
 
 #endif
-- 
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 jailhouse-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/20210125120044.56794-4-andrea.bastoni%40tum.de.

Reply via email to