And provide wrappers for operations used in get_bit_range()
Signed-off-by: Andrea Bastoni <[email protected]>
---
driver/cell.c | 11 +++++-
driver/main.c | 75 ++++++++++++++++++++++++++++++++++++
driver/main.h | 3 ++
include/jailhouse/coloring.h | 6 +++
4 files changed, 93 insertions(+), 2 deletions(-)
diff --git a/driver/cell.c b/driver/cell.c
index ade61edb..cab3a08a 100644
--- a/driver/cell.c
+++ b/driver/cell.c
@@ -335,8 +335,15 @@ static int load_image(struct cell *cell,
phys_start = (mem->phys_start + image_offset) & PAGE_MASK;
page_offs = offset_in_page(image_offset);
- image_mem = jailhouse_ioremap(phys_start, 0,
- PAGE_ALIGN(image.size + page_offs));
+ if (mem->flags & JAILHOUSE_MEM_COLORED) {
+ image_mem = jailhouse_ioremap_col(phys_start,
+ PAGE_ALIGN(image.size + page_offs),
+ mem->colors);
+ } else {
+ image_mem = jailhouse_ioremap(phys_start, 0,
+ PAGE_ALIGN(image.size + page_offs));
+ }
+
if (!image_mem) {
pr_err("jailhouse: Unable to map cell RAM at %08llx "
"for image loading\n",
diff --git a/driver/main.c b/driver/main.c
index 64e2b9a4..7786dc25 100644
--- a/driver/main.c
+++ b/driver/main.c
@@ -53,6 +53,7 @@
#include <jailhouse/header.h>
#include <jailhouse/hypercall.h>
+#include <jailhouse/coloring.h>
#include <generated/version.h>
#ifdef CONFIG_X86_32
@@ -104,6 +105,7 @@ static int error_code;
static struct jailhouse_virt_console* volatile console_page;
static bool console_available;
static struct resource *hypervisor_mem_res;
+static u64 coloring_way_size;
static typeof(ioremap_page_range) *ioremap_page_range_sym;
#ifdef CONFIG_X86
@@ -232,6 +234,75 @@ void *jailhouse_ioremap(phys_addr_t phys, unsigned long
virt,
return vma->addr;
}
+void *jailhouse_ioremap_col(phys_addr_t phys_start,
+ unsigned long tot_size,
+ u64 color_mask)
+{
+ struct vm_struct *vma;
+ /* ioremapping-colored-block params */
+ unsigned long bphys, bvirt, bsize;
+ /* bit: start, low, contiguous bit range width */
+ unsigned int bs, bl, bw;
+ unsigned int n;
+ u64 colors;
+
+ if (coloring_way_size == 0) {
+ pr_err("jailhouse: colored ioremap, but way_size = 0\n");
+ return NULL;
+ }
+
+ /* NOTE: the ioremapped size may not match the size reserved
+ * into the configuration: the size of the image-to-be-loaded
+ * can be smaller than the reserved area.
+ */
+ tot_size = PAGE_ALIGN(tot_size);
+ vma = __get_vm_area(tot_size, VM_IOREMAP, VMALLOC_START, VMALLOC_END);
+ if (!vma)
+ return NULL;
+ bvirt = (unsigned long) vma->addr;
+
+ pr_err("IOREMAP P: 0x%08llx V: 0x%08lx "
+ "(S: 0x%lx C: 0x%08llx E: 0x%lx)\n",
+ phys_start, bvirt, tot_size, color_mask,
+ bvirt + tot_size);
+
+ bphys = bsize = 0;
+ /* ioremap the VAs to colored PAs blocks according to the color mask */
+ n = 0;
+ while (bvirt < (unsigned long)vma->addr + tot_size) {
+ bs = bl = bw = 0;
+ colors = color_mask;
+
+ while (colors != 0) {
+ /* update colors with next color-range */
+ get_bit_range(&colors, &bl, &bw);
+ bs += bl;
+ bphys = phys_start + (bs * PAGE_SIZE) +
+ (n * coloring_way_size);
+ /* depending on the color, the initial vma->phys_addr
+ * might not be phys_addr
+ */
+ if (bsize == 0)
+ vma->phys_addr = bphys;
+ bsize = bw * PAGE_SIZE;
+
+ if (ioremap_page_range_sym(bvirt, bvirt + bsize, bphys,
+ PAGE_KERNEL_EXEC)) {
+ vunmap(vma->addr);
+ return NULL;
+ }
+
+ /* update next round */
+ bvirt += bsize;
+ }
+ n++;
+ }
+ pr_err("end P: 0x%08lx 1P: 0x%llx V: 0x%08lx (bsize = 0x%08lx)\n",
+ bphys, vma->phys_addr, bvirt - bsize, bsize);
+
+ return vma->addr;
+}
+
/*
* Called for each cpu by the JAILHOUSE_ENABLE ioctl.
* It jumps to the entry point set in the header, reports the result and
@@ -579,6 +650,10 @@ static int jailhouse_cmd_enable(struct jailhouse_system
__user *arg)
if (err)
goto error_unmap;
+ /* If present, initialize coloring parameter */
+ coloring_way_size = config->platform_info.color.way_size;
+ pr_info("coloring_size %llu", coloring_way_size);
+
error_code = 0;
preempt_disable();
diff --git a/driver/main.h b/driver/main.h
index 7c9f661c..a2069a76 100644
--- a/driver/main.h
+++ b/driver/main.h
@@ -23,6 +23,9 @@ extern void *hypervisor_mem;
void *jailhouse_ioremap(phys_addr_t phys, unsigned long virt,
unsigned long size);
+void *jailhouse_ioremap_col(phys_addr_t phys_start,
+ unsigned long tot_size,
+ u64 color_mask);
int jailhouse_console_dump_delta(char *dst, unsigned int head,
unsigned int *miss);
diff --git a/include/jailhouse/coloring.h b/include/jailhouse/coloring.h
index bf025dff..1b109c67 100644
--- a/include/jailhouse/coloring.h
+++ b/include/jailhouse/coloring.h
@@ -10,8 +10,14 @@
* COPYING file in the top-level directory.
*/
/** MSB/LSB function names differs between Jailhouse and Linux */
+#ifdef LINUX_VERSION_CODE
+/* NOTE: use [0-63] variants */
+#define _lsb(x) __ffs(x)
+#define _msb(x) __fls(x)
+#else
#define _lsb(x) ffsl(x)
#define _msb(x) msbl(x)
+#endif
/**
* Get range of contiguous bits in a bitmask.
--
2.30.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/20210322194411.82520-5-andrea.bastoni%40tum.de.