I've gotten rid of the uint8_t kernel[] and am using mmap to back the image.
The image starts and runs UNTIL it tries to load its own cr3 and run from that. Then it dies: Map 0x1000000 for 20426752 bytes p512 0x100000049000 p512[0] is 0x10000004a003 p1 0x10000004a000 p1[0] is 0x4b003 Don't know how to handle exit 2 RIP 0xffffffff81000147, shutdown 0x2 vmm: handle_vmexit returned false Note: this may be a kernel module, not the kernel RIP was 0xffffffff81000147: 01000147: b8 01 00 00 80 0f a2 89 d7 b9 80 00 00 c0 0f 32 ...............2 02008000: 63 90 00 02 00 00 00 00 63 90 00 02 00 00 00 00 c.......c....... 02008010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ... 02008ff0: 00 00 00 00 00 00 00 00 67 e0 e0 01 00 00 00 00 ........g....... 01e0e000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ... Shutdown: core 0, exit due to TRIPLE_FAULT(0x2); ret code 0x2 gva 0xffffffff81000147 gpa (nil) cr3 0x2008000 rax 0xffffffff81000147 rbx 0x000000000200a000 rcx 0x00000000000000a0 rdx 0x000000000200a063 rbp 0x0000000000000000 rsi 0x00000000000e4000 rdi 0x0000000001e10000 r8 0x0000000001e10000 r9 0x0000000000000000 r10 0x0000000000000000 r11 0x0000000000000000 r12 0x0000000000000000 r13 0x0000000000000000 r14 0x0000000000000000 r15 0x0000000000000000 So, note the cr3 is 2008000, and the last 64-bit word in that page (ff8) points to 01e0e000. This all makes sense, save that page table is all zeros. Damn. I think I had this problem earlier and it's why I went to the pre-allocated part-of-.date kernel[] array, but it's time we fixed this. Change-Id: I90a90cf7ffe6abcb5666e1648ecf1d41ceb17fc9 Signed-off-by: Ronald G. Minnich <[email protected]> --- tests/vmm/vmrunkernel.c | 76 +++++++++++++++++++++++++------------------------ user/vmm/sched.c | 2 ++ 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/tests/vmm/vmrunkernel.c b/tests/vmm/vmrunkernel.c index 5f2787f..04082c6 100644 --- a/tests/vmm/vmrunkernel.c +++ b/tests/vmm/vmrunkernel.c @@ -14,7 +14,6 @@ #include <string.h> #include <ros/syscall.h> #include <sys/mman.h> -#include <vmm/coreboot_tables.h> #include <vmm/vmm.h> #include <vmm/acpi/acpi.h> #include <vmm/acpi/vmm_simple_dsdt.h> @@ -38,8 +37,8 @@ #include <sys/eventfd.h> #include <sys/uio.h> -#define DBG(format, ...) if (debug)\ - fprintf(stderr, format, __VA_ARGS__) +#define DBG(args...) if (debug) \ + fprintf(stderr, args) struct virtual_machine local_vm, *vm = &local_vm; @@ -136,9 +135,6 @@ unsigned int maxresume = (unsigned int) -1; #define MiB 0x100000ull #define GiB (1ull << 30) -#define GKERNBASE (16*MiB) -#define KERNSIZE (1024 * MiB + GKERNBASE) -uint8_t _kernel[KERNSIZE]; unsigned long long *p512, *p1, *p2m; @@ -176,7 +172,7 @@ void timer_thread(void *arg) vmm_interrupt_guest(vm, 0, vector); uthread_usleep(100000); } - fprintf(stderr, "SENDING TIMER\n"); + DBG("SENDING TIMER\n"); } @@ -300,7 +296,7 @@ static uint8_t acpi_tb_checksum(uint8_t *buffer, uint32_t length) DBG("tbchecksum %p for %d", buffer, length); while (buffer < end) { if (0 && end - buffer < 2) - fprintf(stderr, "%02x\n", sum); + DBG( "%02x\n", sum); sum = (uint8_t)(sum + *(buffer++)); } DBG(" is %02x\n", sum); @@ -338,6 +334,7 @@ load_kernel(char *filename, uintptr_t *kernstart, uintptr_t *kernend) size_t phnum = 0; Elf64_Phdr *hdrs; int fd; + uint64_t align, start, end, size; elf_version(EV_CURRENT); fd = open(filename, O_RDONLY); @@ -359,14 +356,14 @@ load_kernel(char *filename, uintptr_t *kernstart, uintptr_t *kernend) __func__, filename); goto fail; } - fprintf(stderr, "%s ELF entry point is %p\n", filename, ehdr->e_entry); + DBG( "%s ELF entry point is %p\n", filename, ehdr->e_entry); if (elf_getphdrnum(elf, &phnum) < 0) { fprintf(stderr, "%s: cannot get program header num of %s.\n", __func__, filename); goto fail; } - fprintf(stderr, "%s has %d program headers\n", filename, phnum); + DBG( "%s has %d program headers\n", filename, phnum); hdrs = elf64_getphdr(elf); if (hdrs == NULL) { @@ -380,7 +377,7 @@ load_kernel(char *filename, uintptr_t *kernstart, uintptr_t *kernend) Elf64_Phdr *h = &hdrs[i]; uintptr_t pa; - fprintf(stderr, + DBG( "%d: type 0x%lx flags 0x%lx offset 0x%lx vaddr 0x%lx paddr 0x%lx size 0x%lx memsz 0x%lx align 0x%lx\n", i, h->p_type, /* Segment type */ @@ -396,16 +393,37 @@ load_kernel(char *filename, uintptr_t *kernstart, uintptr_t *kernend) if ((h->p_flags & (PF_R|PF_W|PF_X)) == 0) continue; - /* we do the memset purely to ensure everything gets paged in. */ + /* compute the end with the unaligned address and size. + * Figure out the alignment for the start. + * The size is the computed end minus the aligned start. */ + end = h->p_paddr + h->p_memsz; + align = h->p_align; + start = h->p_paddr & ~(align-1); + size = end - start; + /* compute the offset from the desired address. */ /* this ONLY works now if kernaddr > h->p_paddr */ + pa = (uintptr_t)mmap((uint8_t *)start, size, + PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_ANONYMOUS|MAP_POPULATE|MAP_FIXED, -1, 0); + if (-1 == (int64_t) pa) { + fprintf(stderr, "Can't mmap(%p, %d, 0x%x, 0x%x, -1, 0): %r\n", + start, size, + PROT_READ|PROT_WRITE|PROT_EXEC); + goto fail; + } + + /* we do the memset purely to ensure everything gets paged in, + * i.e. we don't want to assume MAP_POPULATE always works. + * If it does the memset is superfluous but cheap. */ pa = h->p_paddr; memset((void *)pa, 0, h->p_memsz); + DBG("memset(%p, 0, %d)\n", (void *)pa, h->p_memsz); if (*kernstart > pa) *kernstart = pa; if (*kernend < pa+h->p_memsz) *kernend = pa+h->p_memsz; - fprintf(stderr, + DBG( "Read header %d @offset %p to %p (elf PA is %p) %d bytes:", i, h->p_offset, pa, h->p_paddr, h->p_filesz); tot = 0; @@ -416,7 +434,7 @@ load_kernel(char *filename, uintptr_t *kernstart, uintptr_t *kernend) break; tot += amt; } - fprintf(stderr, "read a total of %d bytes\n", tot); + DBG( "read a total of %d bytes\n", tot); if (tot < h->p_filesz) { fprintf(stderr, "%s: got %d bytes, wanted %d bytes\n", filename, tot, h->p_filesz); @@ -455,7 +473,6 @@ int main(int argc, char **argv) static char cmd[512]; int i; uint8_t csum; - void *coreboot_tables = (void *) 0x1165000; void *a_page; struct vm_trapframe *vm_tf; uint64_t tsc_freq_khz; @@ -481,16 +498,9 @@ int main(int argc, char **argv) {0, 0, 0, 0} }; - fprintf(stderr, "%p %p %p %p\n", PGSIZE, PGSHIFT, PML1_SHIFT, + DBG( "%p %p %p %p\n", PGSIZE, PGSHIFT, PML1_SHIFT, PML1_PTE_REACH); - - // mmap is not working for us at present. - if ((uint64_t)_kernel > GKERNBASE) { - fprintf(stderr, "kernel array @%p is above , GKERNBASE@%p sucks\n", _kernel, GKERNBASE); - exit(1); - } - memset(_kernel, 0, sizeof(_kernel)); vm->low4k = malloc(PGSIZE); memset(vm->low4k, 0xff, PGSIZE); vm->low4k[0x40e] = 0; @@ -499,7 +509,7 @@ int main(int argc, char **argv) //Place mmap(Gan) a_page = mmap((void *)0xfee00000, PGSIZE, PROT_READ | PROT_WRITE, MAP_POPULATE | MAP_ANONYMOUS, -1, 0); - fprintf(stderr, "a_page mmap pointer %p\n", a_page); + DBG( "a_page mmap pointer %p\n", a_page); if (a_page == (void *) -1) { perror("Could not mmap APIC"); @@ -585,13 +595,10 @@ int main(int argc, char **argv) argc -= optind; argv += optind; if (argc < 1) { - fprintf(stderr, "Usage: %s vmimage [-n (no vmcall printf)] [coreboot_tables [loadaddress [entrypoint]]]\n", argv[0]); + fprintf(stderr, "Usage: %s vmimage [-n (no vmcall printf)] \n", argv[0]); exit(1); } - if (argc > 1) - coreboot_tables = (void *) strtoull(argv[1], 0, 0); - entry = load_kernel(argv[0], &kernstart, &kernend); if (entry == 0) { fprintf(stderr, "Unable to load kernel %s\n", argv[0]); @@ -683,7 +690,7 @@ int main(int argc, char **argv) exit(1); } - fprintf(stderr, "allchecksums ok\n"); + DBG( "allchecksums ok\n"); if (debug) { fprintf(stderr, "ACPI tables:\n"); @@ -832,7 +839,7 @@ int main(int argc, char **argv) p2m = &p512[2 * NPTENTRIES]; size = kernend - kernstart; - fprintf(stderr, "Map %p for %zu bytes\n", kernstart, size); + DBG( "Map %p for %zu bytes\n", kernstart, size); p512[PML4(kernstart)] = (uint64_t)p1 | PTE_KERN_RW; p1[PML3(kernstart)] = (uint64_t)p2m | PTE_KERN_RW; for (uintptr_t i = 0; i < size; i += PML2_PTE_REACH) { @@ -840,13 +847,7 @@ int main(int argc, char **argv) (uint64_t)(kernstart + i) | PTE_KERN_RW | PTE_PS; } - uint8_t *kernel = (void *)GKERNBASE; - //write_coreboot_table(coreboot_tables, ((void *)VIRTIOBASE) /*kernel*/, KERNSIZE + 1048576); - if (debug) { - fprintf(stderr, "Coreboot tables\n"); - hexdump(stderr, coreboot_tables, 512); - } - fprintf(stderr, "p512 %p p512[0] is 0x%lx p1 %p p1[0] is 0x%x\n", p512, p512[0], p1, p1[0]); + DBG( "p512 %p p512[0] is 0x%lx p1 %p p1[0] is 0x%x\n", p512, p512[0], p1, p1[0]); vmm_run_task(vm, timer_thread, 0); @@ -858,5 +859,6 @@ int main(int argc, char **argv) start_guest_thread(vm->gths[0]); uthread_sleep_forever(); +printf("hit the any key to continue\n"); (void)getchar(); return 0; } diff --git a/user/vmm/sched.c b/user/vmm/sched.c index 5286796..dba4217 100644 --- a/user/vmm/sched.c +++ b/user/vmm/sched.c @@ -343,6 +343,8 @@ static void __ctlr_entry(void) * enough. */ hexdump(stderr, (void *)(vm_tf->tf_rip & 0x3fffffff), 16); + hexdump(stderr, (void *)(vm_tf->tf_cr3), 4096); + hexdump(stderr, (void *)(0x01e0e000), 4096); showstatus(stderr, cth->buddy); exit(0); } -- 2.8.0.rc3.226.g39d4020 -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
