Begin work on true virtio mmio Kill tests/vmrunkernel.c Our makefiles, plus emacs...
[akaros.git] / user / vmm / vmx.c
1 #include <stdio.h> 
2 #include <pthread.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <fcntl.h>
6 #include <parlib/arch/arch.h>
7 #include <parlib/ros_debug.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <dirent.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <ros/syscall.h>
14 #include <sys/mman.h>
15 #include <vmm/coreboot_tables.h>
16 #include <ros/common.h>
17 #include <ros/vmm.h>
18 #include <vmm/virtio.h>
19 #include <vmm/virtio_mmio.h>
20 #include <vmm/virtio_ids.h>
21
22 // TODO: put this some common place for user and kernel mode. Once
23 // we know we need to. Not sure we want to expose this outside
24 // vmrunkernel anyway. Users may claim they want to write a vmm, but ...
25 #define VMX_EXIT_REASONS_FAILED_VMENTRY         0x80000000
26
27 #define EXIT_REASON_EXCEPTION_NMI       0
28 #define EXIT_REASON_EXTERNAL_INTERRUPT  1
29 #define EXIT_REASON_TRIPLE_FAULT        2
30
31 #define EXIT_REASON_PENDING_INTERRUPT   7
32 #define EXIT_REASON_NMI_WINDOW          8
33 #define EXIT_REASON_TASK_SWITCH         9
34 #define EXIT_REASON_CPUID               10
35 #define EXIT_REASON_HLT                 12
36 #define EXIT_REASON_INVD                13
37 #define EXIT_REASON_INVLPG              14
38 #define EXIT_REASON_RDPMC               15
39 #define EXIT_REASON_RDTSC               16
40 #define EXIT_REASON_VMCALL              18
41 #define EXIT_REASON_VMCLEAR             19
42 #define EXIT_REASON_VMLAUNCH            20
43 #define EXIT_REASON_VMPTRLD             21
44 #define EXIT_REASON_VMPTRST             22
45 #define EXIT_REASON_VMREAD              23
46 #define EXIT_REASON_VMRESUME            24
47 #define EXIT_REASON_VMWRITE             25
48 #define EXIT_REASON_VMOFF               26
49 #define EXIT_REASON_VMON                27
50 #define EXIT_REASON_CR_ACCESS           28
51 #define EXIT_REASON_DR_ACCESS           29
52 #define EXIT_REASON_IO_INSTRUCTION      30
53 #define EXIT_REASON_MSR_READ            31
54 #define EXIT_REASON_MSR_WRITE           32
55 #define EXIT_REASON_INVALID_STATE       33
56 #define EXIT_REASON_MWAIT_INSTRUCTION   36
57 #define EXIT_REASON_MONITOR_INSTRUCTION 39
58 #define EXIT_REASON_PAUSE_INSTRUCTION   40
59 #define EXIT_REASON_MCE_DURING_VMENTRY  41
60 #define EXIT_REASON_TPR_BELOW_THRESHOLD 43
61 #define EXIT_REASON_APIC_ACCESS         44
62 #define EXIT_REASON_EPT_VIOLATION       48
63 #define EXIT_REASON_EPT_MISCONFIG       49
64 #define EXIT_REASON_WBINVD              54
65 #define EXIT_REASON_XSETBV              55
66 #define EXIT_REASON_INVPCID             58
67
68 /* nowhere on my linux system. */
69 #define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0]))
70
71 char *vmxexit[] = {
72         [EXIT_REASON_EXCEPTION_NMI]        "EXCEPTION_NMI",
73         [EXIT_REASON_EXTERNAL_INTERRUPT]   "EXTERNAL_INTERRUPT",
74         [EXIT_REASON_TRIPLE_FAULT]         "TRIPLE_FAULT",
75         [EXIT_REASON_PENDING_INTERRUPT]    "PENDING_INTERRUPT",
76         [EXIT_REASON_NMI_WINDOW]           "NMI_WINDOW",
77         [EXIT_REASON_TASK_SWITCH]          "TASK_SWITCH",
78         [EXIT_REASON_CPUID]                "CPUID",
79         [EXIT_REASON_HLT]                  "HLT",
80         [EXIT_REASON_INVLPG]               "INVLPG",
81         [EXIT_REASON_RDPMC]                "RDPMC",
82         [EXIT_REASON_RDTSC]                "RDTSC",
83         [EXIT_REASON_VMCALL]               "VMCALL",
84         [EXIT_REASON_VMCLEAR]              "VMCLEAR",
85         [EXIT_REASON_VMLAUNCH]             "VMLAUNCH",
86         [EXIT_REASON_VMPTRLD]              "VMPTRLD",
87         [EXIT_REASON_VMPTRST]              "VMPTRST",
88         [EXIT_REASON_VMREAD]               "VMREAD",
89         [EXIT_REASON_VMRESUME]             "VMRESUME",
90         [EXIT_REASON_VMWRITE]              "VMWRITE",
91         [EXIT_REASON_VMOFF]                "VMOFF",
92         [EXIT_REASON_VMON]                 "VMON",
93         [EXIT_REASON_CR_ACCESS]            "CR_ACCESS",
94         [EXIT_REASON_DR_ACCESS]            "DR_ACCESS",
95         [EXIT_REASON_IO_INSTRUCTION]       "IO_INSTRUCTION",
96         [EXIT_REASON_MSR_READ]             "MSR_READ",
97         [EXIT_REASON_MSR_WRITE]            "MSR_WRITE",
98         [EXIT_REASON_MWAIT_INSTRUCTION]    "MWAIT_INSTRUCTION",
99         [EXIT_REASON_MONITOR_INSTRUCTION]  "MONITOR_INSTRUCTION",
100         [EXIT_REASON_PAUSE_INSTRUCTION]    "PAUSE_INSTRUCTION",
101         [EXIT_REASON_MCE_DURING_VMENTRY]   "MCE_DURING_VMENTRY",
102         [EXIT_REASON_TPR_BELOW_THRESHOLD]  "TPR_BELOW_THRESHOLD",
103         [EXIT_REASON_APIC_ACCESS]          "APIC_ACCESS",
104         [EXIT_REASON_EPT_VIOLATION]        "EPT_VIOLATION",
105         [EXIT_REASON_EPT_MISCONFIG]        "EPT_MISCONFIG",
106         [EXIT_REASON_WBINVD]               "WBINVD"
107 };
108
109 void showstatus(FILE *f, struct vmctl *v)
110 {
111         int shutdown;
112         char *when = shutdown & VMX_EXIT_REASONS_FAILED_VMENTRY ? "entry" : "exit";
113         shutdown &= 0xff;
114         char *reason = "UNKNOWN";
115         if (v->shutdown < ARRAY_SIZE(vmxexit) && vmxexit[v->shutdown])
116                 reason = vmxexit[v->shutdown];
117         fprintf(f, "Shutdown: core %d, %s due to %s(0x%x); ret code 0x%x\n", v->core, when, reason, v->shutdown, v->ret_code);
118         fprintf(f, "  gva %p gpa %p cr3 %p\n", (void *)v->gva, (void *)v->gpa, (void *)v->cr3);
119
120         fprintf(f, "  rax  0x%016lx\n",           v->regs.tf_rax);
121         fprintf(f, "  rbx  0x%016lx\n",           v->regs.tf_rbx);
122         fprintf(f, "  rcx  0x%016lx\n",           v->regs.tf_rcx);
123         fprintf(f, "  rdx  0x%016lx\n",           v->regs.tf_rdx);
124         fprintf(f, "  rbp  0x%016lx\n",           v->regs.tf_rbp);
125         fprintf(f, "  rsi  0x%016lx\n",           v->regs.tf_rsi);
126         fprintf(f, "  rdi  0x%016lx\n",           v->regs.tf_rdi);
127         fprintf(f, "  r8   0x%016lx\n",           v->regs.tf_r8);
128         fprintf(f, "  r9   0x%016lx\n",           v->regs.tf_r9);
129         fprintf(f, "  r10  0x%016lx\n",           v->regs.tf_r10);
130         fprintf(f, "  r11  0x%016lx\n",           v->regs.tf_r11);
131         fprintf(f, "  r12  0x%016lx\n",           v->regs.tf_r12);
132         fprintf(f, "  r13  0x%016lx\n",           v->regs.tf_r13);
133         fprintf(f, "  r14  0x%016lx\n",           v->regs.tf_r14);
134         fprintf(f, "  r15  0x%016lx\n",           v->regs.tf_r15);
135 }