The colored ioremapping uses the same logic as main hypervisor coloring.
Signed-off-by: Andrea Bastoni <[email protected]>
---
driver/cell.c | 22 ++++++++-------
driver/main.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++-
driver/main.h | 4 +++
3 files changed, 91 insertions(+), 10 deletions(-)
diff --git a/driver/cell.c b/driver/cell.c
index 8a9fccb4..af78f564 100644
--- a/driver/cell.c
+++ b/driver/cell.c
@@ -333,18 +333,18 @@ static int load_image(struct cell *cell,
if (regions == 0)
return -EINVAL;
+ phys_start = (mem->phys_start + image_offset) & PAGE_MASK;
+ page_offs = offset_in_page(image_offset);
if (mem->flags & JAILHOUSE_MEM_COLORED) {
- /* Tweak the base address to request remapping of
- * a reserved, high memory region.
- */
- phys_start = (mem->virt_start + image_offset +
- root_cell->color_root_map_offset) & PAGE_MASK;
+ image_mem = jailhouse_ioremap_col(mem->phys_start,
+ PAGE_ALIGN(image.size + image_offset +
+ page_offs),
+ mem->colors);
} else {
- phys_start = (mem->phys_start + image_offset) & PAGE_MASK;
+ image_mem = jailhouse_ioremap(phys_start, 0,
+ PAGE_ALIGN(image.size + page_offs));
}
- page_offs = offset_in_page(image_offset);
- 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",
@@ -352,6 +352,10 @@ static int load_image(struct cell *cell,
return -EBUSY;
}
+ if (mem->flags & JAILHOUSE_MEM_COLORED) {
+ image_mem += image_offset;
+ }
+
if (copy_from_user(image_mem + page_offs,
(void __user *)(unsigned long)image.source_address,
image.size))
diff --git a/driver/main.c b/driver/main.c
index 56955e73..5351dd2c 100644
--- a/driver/main.c
+++ b/driver/main.c
@@ -33,6 +33,7 @@
#include <linux/vmalloc.h>
#include <linux/io.h>
#include <linux/ioport.h>
+#include <linux/bitops.h>
#include <asm/barrier.h>
#include <asm/smp.h>
#include <asm/cacheflush.h>
@@ -53,6 +54,7 @@
#include <jailhouse/header.h>
#include <jailhouse/hypercall.h>
+#include <jailhouse/coloring.h>
#include <generated/version.h>
#ifdef CONFIG_X86_32
@@ -104,6 +106,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 +235,74 @@ 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;
+ unsigned long virt;
+ /* 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;
+ vma->phys_addr = phys_start;
+ virt = (unsigned long) vma->addr;
+
+ pr_err("IOREMAP PHYS 0x%08llx -> VIRT 0x%08lx "
+ "(size = 0x%lx, C: 0x%08llx)\n",
+ phys_start, virt, tot_size, color_mask);
+
+ bphys = bvirt = bsize = 0;
+ /* ioremap the VAs to colored PAs blocks according to the color mask */
+ n = 0;
+ while (virt < (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;
+ bsize = bw * PAGE_SIZE;
+ bphys = phys_start + (bs * PAGE_SIZE) +
+ (n * coloring_way_size);
+ bvirt = virt;
+ /* update next round */
+ virt += bsize;
+#if 0
+ pr_err("V: 0x%08lx -> P: 0x%08lx (size = 0x%08lx, end =
0x%lx)\n",
+ bvirt, bphys, bsize, (unsigned
long)vma->addr + tot_size);
+#endif
+ if (ioremap_page_range_sym(bvirt, bvirt + bsize, bphys,
+ PAGE_KERNEL_EXEC)) {
+ vunmap(vma->addr);
+ return NULL;
+ }
+ }
+ n++;
+ }
+ pr_err("V: 0x%08lx -> P: 0x%08lx (size = 0x%08lx, end = 0x%lx)\n",
+ bvirt, bphys, bsize, (unsigned long)vma->addr +
tot_size);
+
+ 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,7 +650,9 @@ static int jailhouse_cmd_enable(struct jailhouse_system
__user *arg)
if (err)
goto error_unmap;
- jailhouse_init_color_params(config, root_cell);
+ /* If present, initialize coloring parameter */
+ coloring_way_size = config->platform_info.color.way_size;
+ pr_err("coloring_size %llu", coloring_way_size);
error_code = 0;
diff --git a/driver/main.h b/driver/main.h
index 7c9f661c..4df22e11 100644
--- a/driver/main.h
+++ b/driver/main.h
@@ -23,6 +23,10 @@ extern void *hypervisor_mem;
void *jailhouse_ioremap(phys_addr_t phys, unsigned long virt,
unsigned long size);
+/** ioremap an address range considering colors as specified in color_mask */
+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);
--
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/20210125120044.56794-23-andrea.bastoni%40tum.de.