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.

Reply via email to