User library changes to take a guest_thread instead of a vmctl.
authorGanShun <ganshun@gmail.com>
Tue, 22 Mar 2016 00:15:21 +0000 (17:15 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 22 Mar 2016 20:21:44 +0000 (16:21 -0400)
Removed vmctls from user/. user libraries just use a guest_thread now.

Signed-off-by: GanShun <ganshun@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
tests/vmm/vmrunkernel.c
user/vmm/apic.c
user/vmm/decode.c
user/vmm/include/vmm/sched.h [new file with mode: 0644]
user/vmm/include/vmm/virtio_mmio.h
user/vmm/include/vmm/vmm.h
user/vmm/io.c
user/vmm/ioapic.c
user/vmm/virtio-mmio.c
user/vmm/vmx.c
user/vmm/vmxmsr.c

index a3b65c4..011aaa4 100644 (file)
 #include <vmm/virtio_mmio.h>
 #include <vmm/virtio_ids.h>
 #include <vmm/virtio_config.h>
-
-
-
-void showstatus(FILE *f, struct vmctl *v);
-
-int msrio(struct vmctl *vcpu, uint32_t opcode);
+#include <vmm/sched.h>
 
 struct vmctl vmctl;
 struct vmm_gpcore_init gpci;
@@ -37,6 +32,7 @@ struct vmm_gpcore_init gpci;
  * on its behalf. */
 uth_mutex_t the_ball;
 pthread_t vm_thread;
+
 void (*old_thread_refl)(struct uthread *uth, struct user_context *ctx);
 
 static void copy_vmtf_to_vmctl(struct vm_trapframe *vm_tf, struct vmctl *vmctl)
@@ -588,6 +584,7 @@ int main(int argc, char **argv)
        uint8_t csum;
        void *coreboot_tables = (void *) 0x1165000;
        void *a_page;
+       struct vm_trapframe *vm_tf;
 
        the_ball = uth_mutex_alloc();
        uth_mutex_lock(the_ball);
@@ -903,18 +900,21 @@ int main(int argc, char **argv)
                }
        }
 
+       vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
+
        while (1) {
 
                int c;
                uint8_t byte;
-               vmctl.command = REG_RIP;
+               //vmctl.command = REG_RIP;
                if (maxresume-- == 0) {
                        debug = 1;
                        resumeprompt = 1;
                }
                if (debug) {
-                       fprintf(stderr, "RIP %p, shutdown 0x%x\n", vmctl.regs.tf_rip, vmctl.shutdown);
-                       showstatus(stderr, &vmctl);
+                       fprintf(stderr, "RIP %p, exit reason 0x%x\n", vm_tf->tf_rip,
+                               vm_tf->tf_exit_reason);
+                       showstatus(stderr, (struct guest_thread*)&vm_thread);
                }
                if (resumeprompt) {
                        fprintf(stderr, "RESUME?\n");
@@ -922,14 +922,16 @@ int main(int argc, char **argv)
                        if (c == 'q')
                                break;
                }
-               if (vmctl.shutdown == SHUTDOWN_EPT_VIOLATION) {
+               if (vm_tf->tf_exit_reason == EXIT_REASON_EPT_VIOLATION) {
                        uint64_t gpa, *regp, val;
                        uint8_t regx;
                        int store, size;
                        int advance;
-                       if (decode(&vmctl, &gpa, &regx, &regp, &store, &size, &advance)) {
-                               fprintf(stderr, "RIP %p, shutdown 0x%x\n", vmctl.regs.tf_rip, vmctl.shutdown);
-                               showstatus(stderr, &vmctl);
+                       if (decode((struct guest_thread *) vm_thread, &gpa, &regx, &regp,
+                                  &store, &size, &advance)) {
+                               fprintf(stderr, "RIP %p, shutdown 0x%x\n", vm_tf->tf_rip,
+                                       vm_tf->tf_exit_reason);
+                               showstatus(stderr, (struct guest_thread*)&vm_thread);
                                quit = 1;
                                break;
                        }
@@ -937,7 +939,8 @@ int main(int argc, char **argv)
                        if ((gpa & ~0xfffULL) == virtiobase) {
                                if (debug) fprintf(stderr, "DO SOME VIRTIO\n");
                                // Lucky for us the various virtio ops are well-defined.
-                               virtio_mmio(&vmctl, gpa, regx, regp, store);
+                               virtio_mmio((struct guest_thread *)vm_thread, gpa, regx, regp,
+                                           store);
                                if (debug) fprintf(stderr, "store is %d:\n", store);
                                if (debug) fprintf(stderr, "REGP IS %16x:\n", *regp);
                        } else if ((gpa & 0xfee00000) == 0xfee00000) {
@@ -946,78 +949,85 @@ int main(int argc, char **argv)
                                //apic(&vmctl, gpa, regx, regp, store);
                        } else if ((gpa & 0xfec00000) == 0xfec00000) {
                                // until we fix our include mess, just put the proto here.
-                               int do_ioapic(struct vmctl *v, uint64_t gpa, int destreg, uint64_t *regp, int store);
-                               do_ioapic(&vmctl, gpa, regx, regp, store);
+                               do_ioapic((struct guest_thread *)vm_thread, gpa, regx, regp,
+                                         store);
                        } else if (gpa < 4096) {
                                uint64_t val = 0;
                                memmove(&val, &low4k[gpa], size);
                                hexdump(stdout, &low4k[gpa], size);
-                               fprintf(stderr, "Low 1m, code %p read @ %p, size %d, val %p\n", vmctl.regs.tf_rip, gpa, size, val);
+                               fprintf(stderr, "Low 1m, code %p read @ %p, size %d, val %p\n",
+                                       vm_tf->tf_rip, gpa, size, val);
                                memmove(regp, &low4k[gpa], size);
                                hexdump(stdout, regp, size);
                        } else {
                                fprintf(stderr, "EPT violation: can't handle %p\n", gpa);
-                               fprintf(stderr, "RIP %p, shutdown 0x%x\n", vmctl.regs.tf_rip, vmctl.shutdown);
+                               fprintf(stderr, "RIP %p, exit reason 0x%x\n", vm_tf->tf_rip,
+                                       vm_tf->tf_exit_reason);
                                fprintf(stderr, "Returning 0xffffffff\n");
-                               showstatus(stderr, &vmctl);
+                               showstatus(stderr, (struct guest_thread*)&vm_thread);
                                // Just fill the whole register for now.
                                *regp = (uint64_t) -1;
                        }
-                       vmctl.regs.tf_rip += advance;
-                       if (debug) fprintf(stderr, "Advance rip by %d bytes to %p\n", advance, vmctl.regs.tf_rip);
-                       vmctl.shutdown = 0;
-                       vmctl.gpa = 0;
-                       vmctl.command = REG_ALL;
-               } else if (vmctl.shutdown == SHUTDOWN_UNHANDLED_EXIT_REASON) {
-                       switch(vmctl.ret_code){
+                       vm_tf->tf_rip += advance;
+                       if (debug)
+                               fprintf(stderr, "Advance rip by %d bytes to %p\n",
+                                       advance, vm_tf->tf_rip);
+                       //vmctl.shutdown = 0;
+                       //vmctl.gpa = 0;
+                       //vmctl.command = REG_ALL;
+               } else {
+                       switch (vm_tf->tf_exit_reason) {
                        case  EXIT_REASON_VMCALL:
-                               byte = vmctl.regs.tf_rdi;
+                               byte = vm_tf->tf_rdi;
                                printf("%c", byte);
                                if (byte == '\n') printf("%c", '%');
-                               vmctl.regs.tf_rip += 3;
+                               vm_tf->tf_rip += 3;
                                break;
                        case EXIT_REASON_EXTERNAL_INTERRUPT:
                                //debug = 1;
-                               if (debug) fprintf(stderr, "XINT 0x%x 0x%x\n", vmctl.intrinfo1, vmctl.intrinfo2);
+                               if (debug)
+                                       fprintf(stderr, "XINT 0x%x 0x%x\n",
+                                               vm_tf->tf_intrinfo1, vm_tf->tf_intrinfo2);
                                if (debug) pir_dump();
-                               vmctl.command = RESUME;
+                               //vmctl.command = RESUME;
                                break;
                        case EXIT_REASON_IO_INSTRUCTION:
-                               fprintf(stderr, "IO @ %p\n", vmctl.regs.tf_rip);
-                               io(&vmctl);
-                               vmctl.shutdown = 0;
-                               vmctl.gpa = 0;
-                               vmctl.command = REG_ALL;
+                               fprintf(stderr, "IO @ %p\n", vm_tf->tf_rip);
+                               io((struct guest_thread *)vm_thread);
+                               //vmctl.shutdown = 0;
+                               //vmctl.gpa = 0;
+                               //vmctl.command = REG_ALL;
                                break;
                        case EXIT_REASON_INTERRUPT_WINDOW:
                                if (consdata) {
                                        if (debug) fprintf(stderr, "inject an interrupt\n");
                                        virtio_mmio_set_vring_irq();
-                                       vmctl.interrupt = 0x80000000 | virtioirq;
-                                       vmctl.command = RESUME;
+                                       vm_tf->tf_trap_inject = 0x80000000 | virtioirq;
+                                       //vmctl.command = RESUME;
                                        consdata = 0;
                                }
                                break;
                        case EXIT_REASON_MSR_WRITE:
                        case EXIT_REASON_MSR_READ:
                                fprintf(stderr, "Do an msr\n");
-                               if (msrio(&vmctl, vmctl.ret_code)) {
+                               if (msrio((struct guest_thread *)vm_thread,
+                                         vm_tf->tf_exit_reason)) {
                                        // uh-oh, msrio failed
                                        // well, hand back a GP fault which is what Intel does
-                                       fprintf(stderr, "MSR FAILED: RIP %p, shutdown 0x%x\n", vmctl.regs.tf_rip, vmctl.shutdown);
-                                       showstatus(stderr, &vmctl);
+                                       fprintf(stderr, "MSR FAILED: RIP %p, shutdown 0x%x\n",
+                                               vm_tf->tf_rip, vm_tf->tf_exit_reason);
+                                       showstatus(stderr, (struct guest_thread*)&vm_thread);
 
                                        // Use event injection through vmctl to send
                                        // a general protection fault
                                        // vmctl.interrupt gets written to the VM-Entry
                                        // Interruption-Information Field by vmx
-                                       vmctl.interrupt = (1 << 31) // "Valid" bit
-                                                       | (0 << 12) // Reserved by Intel
-                                                       | (1 << 11) // Deliver-error-code bit (set if event pushes error code to stack)
-                                                       | (3 << 8)  // Event type (3 is "hardware exception")
-                                                       | 13;       // Interrupt/exception vector (13 is "general protection fault")
+                                       vm_tf->tf_trap_inject = VM_TRAP_VALID
+                                                             | VM_TRAP_ERROR_CODE
+                                                             | VM_TRAP_HARDWARE
+                                                             | 13; // GPF
                                } else {
-                                       vmctl.regs.tf_rip += 2;
+                                       vm_tf->tf_rip += 2;
                                }
                                break;
                        case EXIT_REASON_MWAIT_INSTRUCTION:
@@ -1030,9 +1040,9 @@ int main(int argc, char **argv)
                                if (debug)
                                        vapic_status_dump(stderr, gpci.vapic_addr);
                                if (debug)fprintf(stderr, "Resume with consdata ...\n");
-                               vmctl.regs.tf_rip += 3;
+                               vm_tf->tf_rip += 3;
                                //fprintf(stderr, "RIP %p, shutdown 0x%x\n", vmctl.regs.tf_rip, vmctl.shutdown);
-                               //showstatus(stderr, &vmctl);
+                               //showstatus(stderr, (struct guest_thread*)&vm_thread);
                                break;
                        case EXIT_REASON_HLT:
                                fflush(stdout);
@@ -1042,9 +1052,9 @@ int main(int argc, char **argv)
                                        ;
                                //debug = 1;
                                if (debug)fprintf(stderr, "Resume with consdata ...\n");
-                               vmctl.regs.tf_rip += 1;
+                               vm_tf->tf_rip += 1;
                                //fprintf(stderr, "RIP %p, shutdown 0x%x\n", vmctl.regs.tf_rip, vmctl.shutdown);
-                               //showstatus(stderr, &vmctl);
+                               //showstatus(stderr, (struct guest_thread*)&vm_thread);
                                break;
                        case EXIT_REASON_APIC_ACCESS:
                                if (1 || debug)fprintf(stderr, "APIC READ EXIT\n");
@@ -1053,28 +1063,35 @@ int main(int argc, char **argv)
                                uint8_t regx;
                                int store, size;
                                int advance;
-                               if (decode(&vmctl, &gpa, &regx, &regp, &store, &size, &advance)) {
-                                       fprintf(stderr, "RIP %p, shutdown 0x%x\n", vmctl.regs.tf_rip, vmctl.shutdown);
-                                       showstatus(stderr, &vmctl);
+                               if (decode((struct guest_thread *)vm_thread, &gpa, &regx,
+                                          &regp, &store, &size, &advance)) {
+                                       fprintf(stderr, "RIP %p, shutdown 0x%x\n", vm_tf->tf_rip,
+                                               vm_tf->tf_exit_reason);
+                                       showstatus(stderr, (struct guest_thread*)&vm_thread);
                                        quit = 1;
                                        break;
                                }
 
-                               int apic(struct vmctl *v, uint64_t gpa, int destreg, uint64_t *regp, int store);
-                               apic(&vmctl, gpa, regx, regp, store);
-                               vmctl.regs.tf_rip += advance;
-                               if (debug) fprintf(stderr, "Advance rip by %d bytes to %p\n", advance, vmctl.regs.tf_rip);
-                               vmctl.shutdown = 0;
-                               vmctl.gpa = 0;
-                               vmctl.command = REG_ALL;
+                               int apic(struct guest_thread *vm_thread, uint64_t gpa,
+                                        int destreg, uint64_t *regp, int store);
+                               apic((struct guest_thread *)vm_thread, gpa, regx, regp, store);
+                               vm_tf->tf_rip += advance;
+                               if (debug)
+                                       fprintf(stderr, "Advance rip by %d bytes to %p\n",
+                                               advance, vm_tf->tf_rip);
+                               //vmctl.shutdown = 0;
+                               //vmctl.gpa = 0;
+                               //vmctl.command = REG_ALL;
                                break;
                        case EXIT_REASON_APIC_WRITE:
                                if (1 || debug)fprintf(stderr, "APIC WRITE EXIT\n");
                                break;
                        default:
-                               fprintf(stderr, "Don't know how to handle exit %d\n", vmctl.ret_code);
-                               fprintf(stderr, "RIP %p, shutdown 0x%x\n", vmctl.regs.tf_rip, vmctl.shutdown);
-                               showstatus(stderr, &vmctl);
+                               fprintf(stderr, "Don't know how to handle exit %d\n",
+                                       vm_tf->tf_exit_reason);
+                               fprintf(stderr, "RIP %p, shutdown 0x%x\n", vm_tf->tf_rip,
+                                       vm_tf->tf_exit_reason);
+                               showstatus(stderr, (struct guest_thread*)&vm_thread);
                                quit = 1;
                                break;
                        }
@@ -1084,15 +1101,19 @@ int main(int argc, char **argv)
                        break;
                if (consdata) {
                        if (debug) fprintf(stderr, "inject an interrupt\n");
-                       if (debug) fprintf(stderr, "XINT 0x%x 0x%x\n", vmctl.intrinfo1, vmctl.intrinfo2);
-                       vmctl.interrupt = 0x80000000 | virtioirq;
+                       if (debug)
+                               fprintf(stderr, "XINT 0x%x 0x%x\n", vm_tf->tf_intrinfo1,
+                                       vm_tf->tf_intrinfo2);
+                       vm_tf->tf_trap_inject = 0x80000000 | virtioirq;
                        virtio_mmio_set_vring_irq();
                        consdata = 0;
                        //debug = 1;
-                       vmctl.command = RESUME;
+                       //vmctl.command = RESUME;
                }
                if (debug) fprintf(stderr, "NOW DO A RESUME\n");
+               copy_vmtf_to_vmctl(vm_tf, &vmctl);
                run_vmthread(&vmctl);
+               copy_vmctl_to_vmtf(&vmctl, vm_tf);
        }
 
        /* later.
index d189dc3..e50d71b 100644 (file)
@@ -26,6 +26,7 @@
 #include <vmm/virtio_mmio.h>
 #include <vmm/virtio_ids.h>
 #include <vmm/virtio_config.h>
+#include <vmm/sched.h>
 
 
 #define APIC_CONFIG 0x100
@@ -163,7 +164,8 @@ static void apic_write(uint64_t offset, uint32_t value)
 
 }
 
-int apic(struct vmctl *v, uint64_t gpa, int destreg, uint64_t *regp, int store)
+int apic(struct guest_thread *vm_thread, uint64_t gpa, int destreg,
+         uint64_t *regp, int store)
 {
        uint32_t offset = gpa & 0xfffff;
        /* basic sanity tests. */
index afcefb6..ede64cd 100644 (file)
@@ -36,6 +36,7 @@
 #include <vmm/virtio_mmio.h>
 #include <vmm/virtio_ids.h>
 #include <vmm/virtio_config.h>
+#include <ros/arch/trapframe.h>
 
 int debug_decode = 0;
 #define DPRINTF(fmt, ...) \
@@ -178,10 +179,12 @@ static int insize(void *rip)
 // int is the reg index which we can use for printing info.
 // regp points to the register in hw_trapframe from which
 // to load or store a result.
-int decode(struct vmctl *v, uint64_t *gpa, uint8_t *destreg, uint64_t **regp, int *store, int *size, int *advance)
+int decode(struct guest_thread *vm_thread, uint64_t *gpa, uint8_t *destreg,
+           uint64_t **regp, int *store, int *size, int *advance)
 {
+       struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
 
-       DPRINTF("v is %p\n", v);
+       DPRINTF("v is %p\n", vm_tf);
 
        // Duh, which way did he go George? Which way did he go? 
        // First hit on Google gets you there!
@@ -190,7 +193,7 @@ int decode(struct vmctl *v, uint64_t *gpa, uint8_t *destreg, uint64_t **regp, in
        // instruction decode, knowing this gpa reduces our work:
        // we don't have to find the source address in registers,
        // only the register holding or receiving the value.
-       *gpa = v->gpa;
+       *gpa = vm_tf->tf_guest_pa;
        DPRINTF("gpa is %p\n", *gpa);
 
        // To find out what to do, we have to look at
@@ -199,7 +202,7 @@ int decode(struct vmctl *v, uint64_t *gpa, uint8_t *destreg, uint64_t **regp, in
        // we take a shortcut for now: read the low 30 bits and use
        // that as the kernel PA, or our VA, and see what's
        // there. Hokey. Works.
-       uint8_t *kva = (void *)(v->regs.tf_rip & 0x3fffffff);
+       uint8_t *kva = (void *)(vm_tf->tf_rip & 0x3fffffff);
        DPRINTF("kva is %p\n", kva);
 
        // fail fast. If we can't get the size we're done.
@@ -220,52 +223,52 @@ int decode(struct vmctl *v, uint64_t *gpa, uint8_t *destreg, uint64_t **regp, in
        // All we need to know is which destination or source register it is.
        switch (*destreg) {
        case 0:
-               *regp = &v->regs.tf_rax;
+               *regp = &vm_tf->tf_rax;
                break;
        case 1:
-               *regp = &v->regs.tf_rcx;
+               *regp = &vm_tf->tf_rcx;
                break;
        case 2:
-               *regp = &v->regs.tf_rdx;
+               *regp = &vm_tf->tf_rdx;
                break;
        case 3:
-               *regp = &v->regs.tf_rbx;
+               *regp = &vm_tf->tf_rbx;
                break;
        case 4:
-               *regp = &v->regs.tf_rsp; // uh, right.
+               *regp = &vm_tf->tf_rsp; // uh, right.
                break;
        case 5:
-               *regp = &v->regs.tf_rbp;
+               *regp = &vm_tf->tf_rbp;
                break;
        case 6:
-               *regp = &v->regs.tf_rsi;
+               *regp = &vm_tf->tf_rsi;
                break;
        case 7:
-               *regp = &v->regs.tf_rdi;
+               *regp = &vm_tf->tf_rdi;
                break;
        case 8:
-               *regp = &v->regs.tf_r8;
+               *regp = &vm_tf->tf_r8;
                break;
        case 9:
-               *regp = &v->regs.tf_r9;
+               *regp = &vm_tf->tf_r9;
                break;
        case 10:
-               *regp = &v->regs.tf_r10;
+               *regp = &vm_tf->tf_r10;
                break;
        case 11:
-               *regp = &v->regs.tf_r11;
+               *regp = &vm_tf->tf_r11;
                break;
        case 12:
-               *regp = &v->regs.tf_r12;
+               *regp = &vm_tf->tf_r12;
                break;
        case 13:
-               *regp = &v->regs.tf_r13;
+               *regp = &vm_tf->tf_r13;
                break;
        case 14:
-               *regp = &v->regs.tf_r14;
+               *regp = &vm_tf->tf_r14;
                break;
        case 15:
-               *regp = &v->regs.tf_r15;
+               *regp = &vm_tf->tf_r15;
                break;
        }
        return 0;
diff --git a/user/vmm/include/vmm/sched.h b/user/vmm/include/vmm/sched.h
new file mode 100644 (file)
index 0000000..484407c
--- /dev/null
@@ -0,0 +1,15 @@
+/* Copyright (c) 2016 Google Inc.
+ * Barret Rhoden <brho@cs.berkeley.edu>
+ * See LICENSE for details. */
+
+#pragma once
+
+#include <parlib/uthread.h>
+
+__BEGIN_DECLS
+
+struct guest_thread {
+       struct uthread                          uthread;
+};
+
+__END_DECLS
index 5f85ef4..162baef 100644 (file)
@@ -34,6 +34,7 @@
 
 #pragma once
 
+#include <vmm/sched.h>
 /*
  * Control registers
  */
@@ -179,5 +180,6 @@ struct virtio_threadarg {
 
 void dumpvirtio_mmio(FILE *f, uint64_t gpa);
 void register_virtio_mmio(struct vqdev *v, uint64_t virtio_base);
-int virtio_mmio(struct vmctl *v, uint64_t gpa, int destreg, uint64_t *regp, int store);
+int virtio_mmio(struct guest_thread *vm_thread, uint64_t gpa, int destreg,
+                uint64_t *regp, int store);
 void virtio_mmio_set_vring_irq(void);
index 7ff8580..141b775 100644 (file)
@@ -7,8 +7,21 @@
 #pragma once
 
 #include <ros/vmm.h>
+#include <vmm/sched.h>
 
 char *regname(uint8_t reg);
-int decode(struct vmctl *v, uint64_t *gpa, uint8_t *destreg, uint64_t **regp,
-           int *store, int *size, int *advance);
-int io(struct vmctl *v);
+int decode(struct guest_thread *vm_thread, uint64_t *gpa, uint8_t *destreg,
+           uint64_t **regp, int *store, int *size, int *advance);
+int io(struct guest_thread *vm_thread);
+void showstatus(FILE *f, struct guest_thread *vm_thread);
+int msrio(struct guest_thread *vm_thread, uint32_t opcode);
+int do_ioapic(struct guest_thread *vm_thread, uint64_t gpa,
+              int destreg, uint64_t *regp, int store);
+
+
+
+/* Intel VM Trap Injection Fields */
+#define VM_TRAP_VALID               (1 << 31)
+#define VM_TRAP_ERROR_CODE          (1 << 11)
+#define VM_TRAP_HARDWARE            (3 << 8)
+/* End Intel VM Trap Injection Fields */
index 600e968..2a17b97 100644 (file)
@@ -18,6 +18,8 @@
 #include <vmm/virtio.h>
 #include <vmm/virtio_mmio.h>
 #include <vmm/virtio_ids.h>
+#include <vmm/sched.h>
+#include <ros/arch/trapframe.h>
 
 /* nowhere on my linux system. */
 #define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0]))
@@ -120,7 +122,7 @@ static int configwrite8(uint32_t addr, uint8_t val)
  * It would have been nice had intel encoded the IO exit info as nicely as they
  * encoded, some of the other exits.
  */
-int io(struct vmctl *v)
+int io(struct guest_thread *vm_thread)
 {
 
        /* Get a pointer to the memory at %rip. This is quite messy and part of the
@@ -132,33 +134,34 @@ int io(struct vmctl *v)
        uint16_t *ip16;
        uintptr_t ip;
        uint32_t edx;
+       struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
        /* for now, we're going to be a bit crude. In kernel, p is about v, so we just blow away
         * the upper 34 bits and take the rest + 1M as our address
         * TODO: put this in vmctl somewhere?
         */
-       ip = v->regs.tf_rip & 0x3fffffff;
-       edx = v->regs.tf_rdx;
+       ip = vm_tf->tf_rip & 0x3fffffff;
+       edx = vm_tf->tf_rdx;
        ip8 = (void *)ip;
        ip16 = (void *)ip;
        //printf("io: ip16 %p\n", *ip16, edx);
 
        if (*ip8 == 0xef) {
-               v->regs.tf_rip += 1;
+               vm_tf->tf_rip += 1;
                /* out at %edx */
                if (edx == 0xcf8) {
                        //printf("Set cf8 ");
-                       return configaddr(v->regs.tf_rax);
+                       return configaddr(vm_tf->tf_rax);
                }
                if (edx == 0xcfc) {
                        //printf("Set cfc ");
-                       return configwrite32(edx, v->regs.tf_rax);
+                       return configwrite32(edx, vm_tf->tf_rax);
                }
                printf("(out rax, edx): unhandled IO address dx @%p is 0x%x\n", ip8, edx);
                return -1;
        }
        // out %al, %dx
        if (*ip8 == 0xee) {
-               v->regs.tf_rip += 1;
+               vm_tf->tf_rip += 1;
                /* out al %edx */
                if (edx == 0xcfb) { // special!
                        printf("Just ignore the damned cfb write\n");
@@ -172,24 +175,24 @@ int io(struct vmctl *v)
                return -1;
        }
        if (*ip8 == 0xec) {
-               v->regs.tf_rip += 1;
+               vm_tf->tf_rip += 1;
                //printf("configread8 ");
-               return configread8(edx, &v->regs.tf_rax);
+               return configread8(edx, &vm_tf->tf_rax);
        }
        if (*ip8 == 0xed) {
-               v->regs.tf_rip += 1;
+               vm_tf->tf_rip += 1;
                if (edx == 0xcf8) {
                        //printf("read cf8 0x%lx\n", v->regs.tf_rax);
-                       v->regs.tf_rax = cf8;
+                       vm_tf->tf_rax = cf8;
                        return 0;
                }
                //printf("configread32 ");
-               return configread32(edx, &v->regs.tf_rax);
+               return configread32(edx, &vm_tf->tf_rax);
        }
        if (*ip16 == 0xed66) {
-               v->regs.tf_rip += 2;
+               vm_tf->tf_rip += 2;
                //printf("configread16 ");
-               return configread16(edx, &v->regs.tf_rax);
+               return configread16(edx, &vm_tf->tf_rax);
        }
        printf("unknown IO %p %x %x\n", ip8, *ip8, *ip16);
        return -1;
index 5f8fb2a..00c9819 100644 (file)
@@ -26,6 +26,7 @@
 #include <vmm/virtio_mmio.h>
 #include <vmm/virtio_ids.h>
 #include <vmm/virtio_config.h>
+#include <vmm/sched.h>
 
 #define IOAPIC_CONFIG 0x100
 #define IOAPIC_NUM_PINS 24
@@ -115,7 +116,8 @@ static void ioapic_write(int ix, uint64_t offset, uint32_t value)
 
 }
 
-int do_ioapic(struct vmctl *v, uint64_t gpa, int destreg, uint64_t *regp, int store)
+int do_ioapic(struct guest_thread *vm_thread, uint64_t gpa, int destreg,
+              uint64_t *regp, int store)
 {
        // TODO: compute an index for the ioapic array. 
        int ix = 0;
index 473928a..c5a8ba9 100644 (file)
@@ -39,6 +39,7 @@
 #include <vmm/virtio_mmio.h>
 #include <vmm/virtio_ids.h>
 #include <vmm/virtio_config.h>
+#include <vmm/sched.h>
 
 int debug_virtio_mmio = 0;
 #define DPRINTF(fmt, ...) \
@@ -414,14 +415,17 @@ void virtio_mmio_set_vring_irq(void)
        mmio.isr |= VIRTIO_MMIO_INT_VRING;
 }
 
-int virtio_mmio(struct vmctl *v, uint64_t gpa, int destreg, uint64_t *regp, int store)
+int virtio_mmio(struct guest_thread *vm_thread, uint64_t gpa, int destreg,
+                uint64_t *regp, int store)
 {
        if (store) {
                virtio_mmio_write(gpa, *regp);
-               DPRINTF("Write: mov %s to %s @%p val %p\n", regname(destreg), virtio_names[(uint8_t)gpa], gpa, *regp);
+               DPRINTF("Write: mov %s to %s @%p val %p\n", regname(destreg),
+                       virtio_names[(uint8_t)gpa], gpa, *regp);
        } else {
                *regp = virtio_mmio_read(gpa);
-               DPRINTF("Read: Set %s from %s @%p to %p\n", regname(destreg), virtio_names[(uint8_t)gpa], gpa, *regp);
+               DPRINTF("Read: Set %s from %s @%p to %p\n", regname(destreg),
+                       virtio_names[(uint8_t)gpa], gpa, *regp);
        }
 
 }
index 80a8d19..f742053 100644 (file)
@@ -19,6 +19,8 @@
 #include <vmm/virtio_mmio.h>
 #include <vmm/virtio_ids.h>
 #include <ros/arch/vmx.h>
+#include <vmm/sched.h>
+#include <ros/arch/trapframe.h>
 
 /* nowhere on my linux system. */
 #define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0]))
@@ -27,30 +29,34 @@ char *vmxexit[] = {
        VMX_EXIT_REASONS
 };
 
-void showstatus(FILE *f, struct vmctl *v)
+void showstatus(FILE *f, struct guest_thread *vm_thread)
 {
-       int shutdown = v->ret_code;
+       struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
+       int shutdown = vm_tf->tf_exit_reason;
        char *when = shutdown & VMX_EXIT_REASONS_FAILED_VMENTRY ? "entry" : "exit";
        shutdown &= ~VMX_EXIT_REASONS_FAILED_VMENTRY;
        char *reason = "UNKNOWN";
        if (shutdown < ARRAY_SIZE(vmxexit) && vmxexit[shutdown])
                reason = vmxexit[shutdown];
-       fprintf(f, "Shutdown: core %d, %s due to %s(0x%x); ret code 0x%x\n", v->core, when, reason, shutdown, v->ret_code);
-       fprintf(f, "  gva %p gpa %p cr3 %p\n", (void *)v->gva, (void *)v->gpa, (void *)v->cr3);
+       fprintf(f, "Shutdown: core %d, %s due to %s(0x%x); ret code 0x%x\n",
+               vm_tf->tf_guest_pcoreid, when, reason, shutdown,
+                       vm_tf->tf_exit_reason);
+       fprintf(f, "  gva %p gpa %p cr3 %p\n", (void *)vm_tf->tf_guest_va,
+               (void *)vm_tf->tf_guest_pa, (void *)vm_tf->tf_cr3);
 
-       fprintf(f, "  rax  0x%016lx\n",           v->regs.tf_rax);
-       fprintf(f, "  rbx  0x%016lx\n",           v->regs.tf_rbx);
-       fprintf(f, "  rcx  0x%016lx\n",           v->regs.tf_rcx);
-       fprintf(f, "  rdx  0x%016lx\n",           v->regs.tf_rdx);
-       fprintf(f, "  rbp  0x%016lx\n",           v->regs.tf_rbp);
-       fprintf(f, "  rsi  0x%016lx\n",           v->regs.tf_rsi);
-       fprintf(f, "  rdi  0x%016lx\n",           v->regs.tf_rdi);
-       fprintf(f, "  r8   0x%016lx\n",           v->regs.tf_r8);
-       fprintf(f, "  r9   0x%016lx\n",           v->regs.tf_r9);
-       fprintf(f, "  r10  0x%016lx\n",           v->regs.tf_r10);
-       fprintf(f, "  r11  0x%016lx\n",           v->regs.tf_r11);
-       fprintf(f, "  r12  0x%016lx\n",           v->regs.tf_r12);
-       fprintf(f, "  r13  0x%016lx\n",           v->regs.tf_r13);
-       fprintf(f, "  r14  0x%016lx\n",           v->regs.tf_r14);
-       fprintf(f, "  r15  0x%016lx\n",           v->regs.tf_r15);
+       fprintf(f, "  rax  0x%016lx\n",           vm_tf->tf_rax);
+       fprintf(f, "  rbx  0x%016lx\n",           vm_tf->tf_rbx);
+       fprintf(f, "  rcx  0x%016lx\n",           vm_tf->tf_rcx);
+       fprintf(f, "  rdx  0x%016lx\n",           vm_tf->tf_rdx);
+       fprintf(f, "  rbp  0x%016lx\n",           vm_tf->tf_rbp);
+       fprintf(f, "  rsi  0x%016lx\n",           vm_tf->tf_rsi);
+       fprintf(f, "  rdi  0x%016lx\n",           vm_tf->tf_rdi);
+       fprintf(f, "  r8   0x%016lx\n",           vm_tf->tf_r8);
+       fprintf(f, "  r9   0x%016lx\n",           vm_tf->tf_r9);
+       fprintf(f, "  r10  0x%016lx\n",           vm_tf->tf_r10);
+       fprintf(f, "  r11  0x%016lx\n",           vm_tf->tf_r11);
+       fprintf(f, "  r12  0x%016lx\n",           vm_tf->tf_r12);
+       fprintf(f, "  r13  0x%016lx\n",           vm_tf->tf_r13);
+       fprintf(f, "  r14  0x%016lx\n",           vm_tf->tf_r14);
+       fprintf(f, "  r15  0x%016lx\n",           vm_tf->tf_r15);
 }
index 2595fdc..b1c2a2f 100644 (file)
 #include <vmm/virtio_mmio.h>
 #include <vmm/virtio_ids.h>
 #include <vmm/virtio_config.h>
+#include <vmm/sched.h>
+#include <ros/arch/trapframe.h>
 
 struct emmsr {
        uint32_t reg;
        char *name;
-       int (*f) (struct vmctl * vcpu, struct emmsr *, uint32_t);
+       int (*f)(struct guest_thread *vm_thread, struct emmsr *, uint32_t);
        bool written;
        uint32_t edx, eax;
 };
@@ -50,12 +52,17 @@ static inline void write_msr(uint32_t reg, uint64_t val)
                                 "c"(reg));
 }
 
-int emsr_miscenable(struct vmctl *vcpu, struct emmsr *, uint32_t);
-int emsr_mustmatch(struct vmctl *vcpu, struct emmsr *, uint32_t);
-int emsr_readonly(struct vmctl *vcpu, struct emmsr *, uint32_t);
-int emsr_readzero(struct vmctl *vcpu, struct emmsr *, uint32_t);
-int emsr_fakewrite(struct vmctl *vcpu, struct emmsr *, uint32_t);
-int emsr_ok(struct vmctl *vcpu, struct emmsr *, uint32_t);
+static int emsr_miscenable(struct guest_thread *vm_thread, struct emmsr *,
+                           uint32_t);
+static int emsr_mustmatch(struct guest_thread *vm_thread, struct emmsr *,
+                          uint32_t);
+static int emsr_readonly(struct guest_thread *vm_thread, struct emmsr *,
+                         uint32_t);
+static int emsr_readzero(struct guest_thread *vm_thread, struct emmsr *,
+                         uint32_t);
+static int emsr_fakewrite(struct guest_thread *vm_thread, struct emmsr *,
+                          uint32_t);
+static int emsr_ok(struct guest_thread *vm_thread, struct emmsr *, uint32_t);
 
 struct emmsr emmsrs[] = {
        {MSR_IA32_MISC_ENABLE, "MSR_IA32_MISC_ENABLE", emsr_miscenable},
@@ -119,71 +126,81 @@ static uint64_t set_low8(uint64_t hi, uint8_t lo)
 /* this may be the only register that needs special handling.
  * If there others then we might want to extend teh emmsr struct.
  */
-int emsr_miscenable(struct vmctl *vcpu, struct emmsr *msr,
-                   uint32_t opcode) {
+static int emsr_miscenable(struct guest_thread *vm_thread, struct emmsr *msr,
+                           uint32_t opcode) {
        uint32_t eax, edx;
+       struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
+
        rdmsr(msr->reg, eax, edx);
        /* we just let them read the misc msr for now. */
        if (opcode == EXIT_REASON_MSR_READ) {
-               vcpu->regs.tf_rax = set_low32(vcpu->regs.tf_rax, eax);
-               vcpu->regs.tf_rax |= MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL;
-               vcpu->regs.tf_rdx = set_low32(vcpu->regs.tf_rdx, edx);
+               vm_tf->tf_rax = set_low32(vm_tf->tf_rax, eax);
+               vm_tf->tf_rax |= MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL;
+               vm_tf->tf_rdx = set_low32(vm_tf->tf_rdx, edx);
                return 0;
        } else {
                /* if they are writing what is already written, that's ok. */
-               if (((uint32_t) vcpu->regs.tf_rax == eax)
-                   && ((uint32_t) vcpu->regs.tf_rdx == edx))
+               if (((uint32_t) vm_tf->tf_rax == eax)
+                   && ((uint32_t) vm_tf->tf_rdx == edx))
                        return 0;
        }
-       fprintf(stderr, 
+       fprintf(stderr,
                "%s: Wanted to write 0x%x:0x%x, but could not; value was 0x%x:0x%x\n",
-                msr->name, (uint32_t) vcpu->regs.tf_rdx,
-                (uint32_t) vcpu->regs.tf_rax, edx, eax);
+                msr->name, (uint32_t) vm_tf->tf_rdx,
+                (uint32_t) vm_tf->tf_rax, edx, eax);
        return SHUTDOWN_UNHANDLED_EXIT_REASON;
 }
 
-int emsr_mustmatch(struct vmctl *vcpu, struct emmsr *msr,
-                  uint32_t opcode) {
+static int emsr_mustmatch(struct guest_thread *vm_thread, struct emmsr *msr,
+                          uint32_t opcode) {
        uint32_t eax, edx;
+       struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
+
        rdmsr(msr->reg, eax, edx);
        /* we just let them read the misc msr for now. */
        if (opcode == EXIT_REASON_MSR_READ) {
-               vcpu->regs.tf_rax = set_low32(vcpu->regs.tf_rax, eax);
-               vcpu->regs.tf_rdx = set_low32(vcpu->regs.tf_rdx, edx);
+               vm_tf->tf_rax = set_low32(vm_tf->tf_rax, eax);
+               vm_tf->tf_rdx = set_low32(vm_tf->tf_rdx, edx);
                return 0;
        } else {
                /* if they are writing what is already written, that's ok. */
-               if (((uint32_t) vcpu->regs.tf_rax == eax)
-                   && ((uint32_t) vcpu->regs.tf_rdx == edx))
+               if (((uint32_t) vm_tf->tf_rax == eax)
+                   && ((uint32_t) vm_tf->tf_rdx == edx))
                        return 0;
        }
        fprintf(stderr,
                "%s: Wanted to write 0x%x:0x%x, but could not; value was 0x%x:0x%x\n",
-                msr->name, (uint32_t) vcpu->regs.tf_rdx,
-                (uint32_t) vcpu->regs.tf_rax, edx, eax);
+                msr->name, (uint32_t) vm_tf->tf_rdx,
+                (uint32_t) vm_tf->tf_rax, edx, eax);
        return SHUTDOWN_UNHANDLED_EXIT_REASON;
 }
 
-int emsr_ok(struct vmctl *vcpu, struct emmsr *msr, uint32_t opcode)
+static int emsr_ok(struct guest_thread *vm_thread, struct emmsr *msr,
+                   uint32_t opcode)
 {
+       struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
+
        if (opcode == EXIT_REASON_MSR_READ) {
-               rdmsr(msr->reg, vcpu->regs.tf_rdx, vcpu->regs.tf_rax);
+               rdmsr(msr->reg, vm_tf->tf_rdx, vm_tf->tf_rax);
        } else {
                uint64_t val =
-                       (uint64_t) vcpu->regs.tf_rdx << 32 | vcpu->regs.tf_rax;
+                       (uint64_t) vm_tf->tf_rdx << 32 | vm_tf->tf_rax;
                write_msr(msr->reg, val);
        }
        return 0;
 }
 
-int emsr_readonly(struct vmctl *vcpu, struct emmsr *msr, uint32_t opcode)
+static int emsr_readonly(struct guest_thread *vm_thread, struct emmsr *msr,
+                         uint32_t opcode)
 {
        uint32_t eax, edx;
-       rdmsr((uint32_t) vcpu->regs.tf_rcx, eax, edx);
+       struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
+
+       rdmsr((uint32_t) vm_tf->tf_rcx, eax, edx);
        /* we just let them read the misc msr for now. */
        if (opcode == EXIT_REASON_MSR_READ) {
-               vcpu->regs.tf_rax = set_low32(vcpu->regs.tf_rax, eax);
-               vcpu->regs.tf_rdx = set_low32(vcpu->regs.tf_rdx, edx);
+               vm_tf->tf_rax = set_low32(vm_tf->tf_rax, eax);
+               vm_tf->tf_rdx = set_low32(vm_tf->tf_rdx, edx);
                return 0;
        }
 
@@ -191,11 +208,14 @@ int emsr_readonly(struct vmctl *vcpu, struct emmsr *msr, uint32_t opcode)
        return SHUTDOWN_UNHANDLED_EXIT_REASON;
 }
 
-int emsr_readzero(struct vmctl *vcpu, struct emmsr *msr, uint32_t opcode)
+static int emsr_readzero(struct guest_thread *vm_thread, struct emmsr *msr,
+                         uint32_t opcode)
 {
+       struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
+
        if (opcode == EXIT_REASON_MSR_READ) {
-               vcpu->regs.tf_rax = 0;
-               vcpu->regs.tf_rdx = 0;
+               vm_tf->tf_rax = 0;
+               vm_tf->tf_rdx = 0;
                return 0;
        }
 
@@ -204,9 +224,12 @@ int emsr_readzero(struct vmctl *vcpu, struct emmsr *msr, uint32_t opcode)
 }
 
 /* pretend to write it, but don't write it. */
-int emsr_fakewrite(struct vmctl *vcpu, struct emmsr *msr, uint32_t opcode)
+static int emsr_fakewrite(struct guest_thread *vm_thread, struct emmsr *msr,
+                          uint32_t opcode)
 {
        uint32_t eax, edx;
+       struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
+
        if (!msr->written) {
                rdmsr(msr->reg, eax, edx);
        } else {
@@ -215,30 +238,31 @@ int emsr_fakewrite(struct vmctl *vcpu, struct emmsr *msr, uint32_t opcode)
        }
        /* we just let them read the misc msr for now. */
        if (opcode == EXIT_REASON_MSR_READ) {
-               vcpu->regs.tf_rax = set_low32(vcpu->regs.tf_rax, eax);
-               vcpu->regs.tf_rdx = set_low32(vcpu->regs.tf_rdx, edx);
+               vm_tf->tf_rax = set_low32(vm_tf->tf_rax, eax);
+               vm_tf->tf_rdx = set_low32(vm_tf->tf_rdx, edx);
                return 0;
        } else {
                /* if they are writing what is already written, that's ok. */
-               if (((uint32_t) vcpu->regs.tf_rax == eax)
-                   && ((uint32_t) vcpu->regs.tf_rdx == edx))
+               if (((uint32_t) vm_tf->tf_rax == eax)
+                   && ((uint32_t) vm_tf->tf_rdx == edx))
                        return 0;
-               msr->edx = vcpu->regs.tf_rdx;
-               msr->eax = vcpu->regs.tf_rax;
+               msr->edx = vm_tf->tf_rdx;
+               msr->eax = vm_tf->tf_rax;
                msr->written = true;
        }
        return 0;
 }
 
 int
-msrio(struct vmctl *vcpu, uint32_t opcode) {
+msrio(struct guest_thread *vm_thread, uint32_t opcode) {
        int i;
+       struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
        for (i = 0; i < sizeof(emmsrs)/sizeof(emmsrs[0]); i++) {
-               if (emmsrs[i].reg != vcpu->regs.tf_rcx)
+               if (emmsrs[i].reg != vm_tf->tf_cr3)
                        continue;
-               return emmsrs[i].f(vcpu, &emmsrs[i], opcode);
+               return emmsrs[i].f(vm_thread, &emmsrs[i], opcode);
        }
-       fprintf(stderr,"msrio for 0x%lx failed\n", vcpu->regs.tf_rcx);
+       fprintf(stderr, "msrio for 0x%lx failed\n", vm_tf->tf_cr3);
        return SHUTDOWN_UNHANDLED_EXIT_REASON;
 }