And provide wrappers for operations used in get_bit_range() Signed-off-by: Andrea Bastoni <andrea.bast...@tum.de> --- 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 jailhouse-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/jailhouse-dev/20210322194411.82520-5-andrea.bastoni%40tum.de.