Enable stage-2 MMU.
diff --git a/src/load.c b/src/load.c
index 39de7d1..1b75008 100644
--- a/src/load.c
+++ b/src/load.c
@@ -111,11 +111,31 @@
{
size_t tmp = (size_t)&load_primary;
tmp = (tmp + 0x80000 - 1) & ~(0x80000 - 1);
- vm_init(&primary_vm, MAX_CPUS);
+ if (!vm_init(&primary_vm, 0, MAX_CPUS)) {
+ dlog("Unable to initialise primary vm\n");
+ return false;
+ }
+
+ /* Map the 1TB of memory. */
+ /* TODO: We should do a whitelist rather than a blacklist. */
+ if (!mm_ptable_map(&primary_vm.ptable, 0,
+ 1024ull * 1024 * 1024 * 1024, 0,
+ MM_MODE_R | MM_MODE_W | MM_MODE_X |
+ MM_MODE_NOINVALIDATE)) {
+ dlog("Unable to initialise memory for primary vm\n");
+ return false;
+ }
+
+ if (!mm_ptable_unmap_hypervisor(&primary_vm.ptable,
+ MM_MODE_NOINVALIDATE)) {
+ dlog("Unable to unmap hypervisor from primary vm\n");
+ return false;
+ }
+
vm_start_vcpu(&primary_vm, 0, tmp, kernel_arg, true);
}
- arch_set_vm_mm(&primary_vm.page_table);
+ vm_set_current(&primary_vm);
return true;
}
@@ -139,6 +159,9 @@
return true;
}
+ /* Round the last address down to the page size. */
+ *mem_end &= ~(PAGE_SIZE - 1);
+
for (count = 0;
memiter_parse_uint(&it, &mem) && memiter_parse_uint(&it, &cpu) &&
memiter_parse_str(&it, &str) && count < MAX_VMS;
@@ -150,6 +173,8 @@
continue;
}
+ /* Round up to page size. */
+ mem = (mem + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
if (mem > *mem_end - mem_begin) {
dlog("Not enough memory for vm %u (%u bytes)\n", count,
mem);
@@ -170,11 +195,37 @@
continue;
}
+ if (!vm_init(secondary_vm + count, count + 1, cpu)) {
+ dlog("Unable to initialise vm %u\n", count);
+ continue;
+ }
+
+ /* TODO: Remove this. */
+ /* Grant VM access to uart. */
+ mm_ptable_map_page(&secondary_vm[count].ptable, PL011_BASE,
+ PL011_BASE,
+ MM_MODE_R | MM_MODE_W | MM_MODE_D |
+ MM_MODE_NOINVALIDATE);
+
+ /* Grant the VM access to the memory. */
+ if (!mm_ptable_map(&secondary_vm[count].ptable, *mem_end,
+ *mem_end + mem, *mem_end,
+ MM_MODE_R | MM_MODE_W | MM_MODE_X |
+ MM_MODE_NOINVALIDATE)) {
+ dlog("Unable to initialise memory for vm %u\n", count);
+ continue;
+ }
+
+ /* Deny the primary VM access to this memory. */
+ if (!mm_ptable_unmap(&primary_vm.ptable, *mem_end,
+ *mem_end + mem, MM_MODE_NOINVALIDATE)) {
+ dlog("Unable to unmap secondary VM from primary VM\n");
+ return false;
+ }
+
dlog("Loaded VM%u with %u vcpus, entry at 0x%x\n", count, cpu,
*mem_end);
- /* TODO: Update page table to reflect the memory range. */
- vm_init(secondary_vm + count, cpu);
vm_start_vcpu(secondary_vm + count, 0, *mem_end, 0, false);
}