vmm: Remove references to pthreads
[akaros.git] / user / vmm / vmx.c
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <parlib/arch/arch.h>
6 #include <parlib/ros_debug.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <dirent.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ros/syscall.h>
13 #include <sys/mman.h>
14 #include <vmm/coreboot_tables.h>
15 #include <ros/common.h>
16 #include <vmm/vmm.h>
17 #include <vmm/virtio.h>
18 #include <vmm/virtio_mmio.h>
19 #include <vmm/virtio_ids.h>
20 #include <ros/arch/vmx.h>
21 #include <vmm/sched.h>
22 #include <ros/arch/mmu.h>
23 #include <ros/arch/trapframe.h>
24
25 char *vmxexit[] = {
26         VMX_EXIT_REASONS
27 };
28
29 void showstatus(FILE *f, struct guest_thread *vm_thread)
30 {
31         struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
32         int shutdown = vm_tf->tf_exit_reason;
33         char *when = shutdown & VMX_EXIT_REASONS_FAILED_VMENTRY ? "entry" : "exit";
34         shutdown &= ~VMX_EXIT_REASONS_FAILED_VMENTRY;
35         char *reason = "UNKNOWN";
36         if (shutdown < COUNT_OF(vmxexit) && vmxexit[shutdown])
37                 reason = vmxexit[shutdown];
38         fprintf(f, "Shutdown: core %d, %s due to %s(0x%x); ret code 0x%x\n",
39                 vm_tf->tf_guest_pcoreid, when, reason, shutdown,
40                         vm_tf->tf_exit_reason);
41         fprintf_vm_tf(f, vm_tf);
42 }
43
44 /* Convert a kernel guest virtual address to physical address.
45  * Assumes that the guest VA is in the high negative address space.
46  * TODO: Takes the vm_thread argument so that we can walk the page tables
47  * instead of just coercing the pointer. Therefore, this is not in vmm.h
48  * since it may get complex. */
49 int gvatogpa(struct guest_thread *vm_thread, uint64_t va, uint64_t *pa)
50 {
51         assert(vm_thread != NULL);
52         struct vm_trapframe *vm_tf = gth_to_vmtf(vm_thread);
53         uint64_t *ptptr = (uint64_t *)vm_tf->tf_cr3;
54         uint64_t entry;
55
56         for (int shift = PML4_SHIFT; shift >= PML1_SHIFT; shift -= BITS_PER_PML) {
57                 entry = ptptr[PMLx(va, shift)];
58
59                 if (!PAGE_PRESENT(entry))
60                         return -1;
61                 if ((entry & PTE_PS) != 0) {
62                         uint64_t bitmask = ((1 << shift) - 1);
63
64                         *pa = (((uint64_t)va & bitmask) | (entry & ~bitmask));
65                         return 0;
66                 }
67                 ptptr = (uint64_t *)PG_ADDR(entry);
68         }
69         *pa = ((uint64_t)va & 0xfff) | (uint64_t)ptptr;
70         return 0;
71 }
72
73 /* Get the RIP as a physical address. */
74 int rippa(struct guest_thread *vm_thread, uint64_t *pa)
75 {
76         assert(vm_thread != NULL);
77         return gvatogpa(vm_thread, gth_to_vmtf(vm_thread)->tf_rip, pa);
78 }