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.

Reply via email to