vmm: Move user_data to struct guest_thread (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 11 Sep 2017 19:19:16 +0000 (15:19 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 14 Sep 2017 20:37:58 +0000 (16:37 -0400)
There's no need for it to be part of the gpci.  Soon, gpci will also hang
off the guest thread, as part of the "dynamic guest thread" changes.

This required a little cleanup for the VM LAPIC timer/alarms.  It's easier
to pass around pointers to the guest threads, since the gth can easily give
you the gpc_id and gpci.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/ros/vmm.h
tests/vmm/vmrunkernel.c
user/vmm/include/vmm/sched.h
user/vmm/include/vmm/vmm.h
user/vmm/vmxmsr.c

index 9812f89..60e5c67 100644 (file)
@@ -14,7 +14,6 @@ struct vmm_gpcore_init {
        void                                    *posted_irq_desc;
        void                                    *vapic_addr;
        void                                    *apic_addr;
-       void                                    *user_data;
        uintptr_t                               fsbase;
        uintptr_t                               gsbase;
 };
index 8e374b8..144f0e4 100644 (file)
@@ -311,11 +311,11 @@ void *inject_timer_spurious(void *args)
 /* This injects the timer interrupt to the guest. */
 void *inject_timer(void *args)
 {
-       uint64_t gpcoreid = (uint64_t)args;
-       struct vmm_gpcore_init *gpci = &gpcis[gpcoreid];
+       struct guest_thread *gth = (struct guest_thread*)args;
+       struct vmm_gpcore_init *gpci = gth_to_gpci(gth);
        uint8_t vector = ((uint32_t *)gpci->vapic_addr)[0x32] & 0xff;
 
-       vmm_interrupt_guest(vm, gpcoreid, vector);
+       vmm_interrupt_guest(vm, gth->gpc_id, vector);
        return 0;
 }
 
@@ -329,8 +329,8 @@ void timer_alarm_handler(struct alarm_waiter *waiter)
        uint32_t divide_config_reg;
        uint32_t multiplier;
        uint32_t timer_mode;
-       uint64_t gpcoreid = *((uint64_t *)waiter->data);
-       struct vmm_gpcore_init *gpci = &gpcis[gpcoreid];
+       struct guest_thread *gth = (struct guest_thread*)waiter->data;
+       struct vmm_gpcore_init *gpci = gth_to_gpci(gth);
 
        vector = ((uint32_t *)gpci->vapic_addr)[0x32] & 0xff;
        timer_mode = (((uint32_t *)gpci->vapic_addr)[0x32] >> 17) & 0x03;
@@ -351,7 +351,7 @@ void timer_alarm_handler(struct alarm_waiter *waiter)
 
        /* We spin up a task to inject the timer because vmm_interrupt_guest
         * may block and we can't do that from vcore context. */
-       vmm_run_task(vm, inject_timer, (void *)gpcoreid);
+       vmm_run_task(vm, inject_timer, gth);
 }
 
 /* This sets up the structs for each of the guest pcore's timers, but
@@ -359,14 +359,14 @@ void timer_alarm_handler(struct alarm_waiter *waiter)
  * values to the x2apic msrs. */
 void init_timer_alarms(void)
 {
-       uint64_t *gpcoreids = malloc(sizeof(uint64_t) * vm->nr_gpcs);
-
        for (uint64_t i = 0; i < vm->nr_gpcs; i++) {
                struct alarm_waiter *timer_alarm = malloc(sizeof(struct alarm_waiter));
+               struct guest_thread *gth = gpcid_to_gth(vm, i);
 
-               gpcoreids[i] = i;
-               gpcis[i].user_data = (void *)timer_alarm;
-               timer_alarm->data = gpcoreids + i;
+               /* TODO: consider a struct to bundle a bunch of things, not just
+                * timer_alarm. */
+               gth->user_data = (void *)timer_alarm;
+               timer_alarm->data = gth;
                init_awaiter(timer_alarm, timer_alarm_handler);
        }
 }
index 276c560..ae76a9d 100644 (file)
@@ -34,6 +34,7 @@ struct guest_thread {
        uth_mutex_t                                     *halt_mtx;
        uth_cond_var_t                          *halt_cv;
        unsigned long                           nr_vmexits;
+       void                                            *user_data;
        // TODO: work out a real ops strategy.
        bool (*vmcall)(struct guest_thread *gth, struct vm_trapframe *);
 };
index a6c1ff3..9e39337 100644 (file)
@@ -106,6 +106,7 @@ int vmm_interrupt_guest(struct virtual_machine *vm, unsigned int gpcoreid,
 uintptr_t load_elf(char *filename, uint64_t offset, uint64_t *highest,
                    Elf64_Ehdr *ehdr_out);
 ssize_t setup_initrd(char *filename, void *membase, size_t memsize);
+
 /* Lookup helpers */
 
 static struct virtual_machine *gth_to_vm(struct guest_thread *gth)
@@ -125,6 +126,12 @@ static struct vmm_gpcore_init *gth_to_gpci(struct guest_thread *gth)
        return &vm->gpcis[gth->gpc_id];
 }
 
+static struct guest_thread *gpcid_to_gth(struct virtual_machine *vm,
+                                         unsigned int gpc_id)
+{
+       return vm->gths[gpc_id];
+}
+
 static struct virtual_machine *get_my_vm(void)
 {
        return ((struct vmm_thread*)current_uthread)->vm;
index 39ee1ce..2d1bd52 100644 (file)
@@ -192,7 +192,7 @@ static int apic_icr_write(struct guest_thread *vm_thread,
        return 0;
 }
 
-static int apic_timer_write(struct guest_thread *vm_thread,
+static int apic_timer_write(struct guest_thread *gth,
                             struct vmm_gpcore_init *gpci)
 {
        uint32_t multiplier;
@@ -200,7 +200,7 @@ static int apic_timer_write(struct guest_thread *vm_thread,
        uint32_t initial_count;
        uint32_t divide_config_reg;
        struct alarm_waiter *timer_waiter;
-       struct vm_trapframe *vm_tf = gth_to_vmtf(vm_thread);
+       struct vm_trapframe *vm_tf = gth_to_vmtf(gth);
        int apic_offset = vm_tf->tf_rcx & 0xff;
 
        ((uint32_t *)(gpci->vapic_addr))[apic_offset] =
@@ -210,9 +210,7 @@ static int apic_timer_write(struct guest_thread *vm_thread,
        vector = ((uint32_t *)gpci->vapic_addr)[0x32] & 0xff;
        initial_count = ((uint32_t *)gpci->vapic_addr)[0x38];
        divide_config_reg = ((uint32_t *)gpci->vapic_addr)[0x3E];
-       timer_waiter = (struct alarm_waiter *)gpci->user_data;
-
-       uint64_t gpcoreid = *((uint64_t *)timer_waiter->data);
+       timer_waiter = (struct alarm_waiter*)gth->user_data;
 
        /* This is a precaution on my part, in case the guest tries to look at
         * the current count on the lapic. I wanted it to be something other than