VMM: Add struct virtual_machine, use it in MMIO
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 25 Apr 2016 19:49:59 +0000 (15:49 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 2 May 2016 21:11:15 +0000 (17:11 -0400)
As a whole, we'll need to track the overall state of the virtual machine.
That's what the struct virtual_machine is for.  Over time, we'll add more
bits to it, such as the memory mapping.

All VMM threads will know about their VM.  We'll need to track that
throughout the VMM.  MMIO creates threads, so it'll need to pass that
along.  (We might be able to infer it from current_uthread, but we're
already passing a guest_thread *).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
user/vmm/include/vmm/vmm.h
user/vmm/virtio-mmio.c

index ff0f615..f473dd8 100644 (file)
@@ -9,6 +9,13 @@
 #include <ros/vmm.h>
 #include <vmm/sched.h>
 
+/* Structure to encapsulate all of the bookkeeping for a VM. */
+struct virtual_machine {
+       struct guest_thread                     **gths;
+       unsigned int                            nr_gpcs;
+       struct vmm_gpcore_init          *gpcis;
+};
+
 char *regname(uint8_t reg);
 int decode(struct guest_thread *vm_thread, uint64_t *gpa, uint8_t *destreg,
            uint64_t **regp, int *store, int *size, int *advance);
@@ -19,3 +26,10 @@ int msrio(struct guest_thread *vm_thread, struct vmm_gpcore_init *gpci,
 int do_ioapic(struct guest_thread *vm_thread, uint64_t gpa,
               int destreg, uint64_t *regp, int store);
 
+/* Lookup helpers */
+
+static struct virtual_machine *gth_to_vm(struct guest_thread *gth)
+{
+       /* TODO */
+       return 0;
+}
index c5a8ba9..7e472f3 100644 (file)
@@ -67,6 +67,7 @@ typedef struct {
        struct vqdev *vqdev;
 } mmiostate;
 
+/* TODO: probably embed this in the struct virtual_machine */
 static mmiostate mmio;
 
 void register_virtio_mmio(struct vqdev *vqdev, uint64_t virtio_base)
@@ -75,7 +76,6 @@ void register_virtio_mmio(struct vqdev *vqdev, uint64_t virtio_base)
        mmio.vqdev = vqdev;
 }
 
-static uint32_t virtio_mmio_read(uint64_t gpa);
 char *virtio_names[] = {
        [VIRTIO_MMIO_MAGIC_VALUE] "VIRTIO_MMIO_MAGIC_VALUE",
        [VIRTIO_MMIO_VERSION] "VIRTIO_MMIO_VERSION",
@@ -108,7 +108,7 @@ char *virtio_names[] = {
 /* We're going to attempt to make mmio stateless, since the real machine is in
  * the guest kernel. From what we know so far, all IO to the mmio space is 32 bits.
  */
-static uint32_t virtio_mmio_read(uint64_t gpa)
+static uint32_t virtio_mmio_read(struct virtual_machine *vm, uint64_t gpa)
 {
 
        unsigned int offset = gpa - mmio.bar;
@@ -209,7 +209,8 @@ static uint32_t virtio_mmio_read(uint64_t gpa)
     return 0;
 }
 
-static void virtio_mmio_write(uint64_t gpa, uint32_t value)
+static void virtio_mmio_write(struct virtual_machine *vm, uint64_t gpa,
+                              uint32_t value)
 {
        uint64_t val64;
        uint32_t low, high;
@@ -415,15 +416,15 @@ void virtio_mmio_set_vring_irq(void)
        mmio.isr |= VIRTIO_MMIO_INT_VRING;
 }
 
-int virtio_mmio(struct guest_thread *vm_thread, uint64_t gpa, int destreg,
+int virtio_mmio(struct guest_thread *gth, uint64_t gpa, int destreg,
                 uint64_t *regp, int store)
 {
        if (store) {
-               virtio_mmio_write(gpa, *regp);
+               virtio_mmio_write(gth_to_vm(gth), 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);
+               *regp = virtio_mmio_read(gth_to_vm(gth), gpa);
                DPRINTF("Read: Set %s from %s @%p to %p\n", regname(destreg),
                        virtio_names[(uint8_t)gpa], gpa, *regp);
        }