Initialize guest xcr0, save and restore xcr0 between guest and Akaros
[akaros.git] / kern / arch / x86 / vmm / vmm.c
1 /* Copyright 2015 Google Inc.
2  *
3  * See LICENSE for details.
4  */
5
6 /* We're not going to falll into the trap of only compiling support
7  * for AMD OR Intel for an image. It all gets compiled in, and which
8  * one you use depends on on cpuinfo, not a compile-time
9  * switch. That's proven to be the best strategy.  Conditionally
10  * compiling in support is the path to hell.
11  */
12 #include <assert.h>
13 #include <pmap.h>
14 #include <smp.h>
15 #include <kmalloc.h>
16
17 #include <ros/vmm.h>
18 #include "intel/vmx.h"
19 #include "vmm.h"
20 #include <trap.h>
21 #include <umem.h>
22
23 #include <arch/x86.h>
24
25
26 /* TODO: have better cpuid info storage and checks */
27 bool x86_supports_vmx = FALSE;
28
29 /* Figure out what kind of CPU we are on, and if it supports any reasonable
30  * virtualization. For now, if we're not some sort of newer intel, don't
31  * bother. This does all cores. Again, note, we make these decisions at runtime,
32  * to avoid getting into the problems that compile-time decisions can cause.
33  * At this point, of course, it's still all intel.
34  */
35 void vmm_init(void)
36 {
37         int ret;
38         /* Check first for intel capabilities. This is hence two back-to-back
39          * implementationd-dependent checks. That's ok, it's all msr dependent.
40          */
41         ret = intel_vmm_init();
42         if (! ret) {
43                 x86_supports_vmx = TRUE;
44                 return;
45         }
46
47         /* TODO: AMD. Will we ever care? It's not clear. */
48         printk("vmm_init failed, ret %d\n", ret);
49         return;
50 }
51
52 void vmm_pcpu_init(void)
53 {
54         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
55
56         pcpui->guest_pcoreid = -1;
57         if (!x86_supports_vmx)
58                 return;
59         if (! intel_vmm_pcpu_init()) {
60                 printd("vmm_pcpu_init worked\n");
61                 return;
62         }
63         /* TODO: AMD. Will we ever care? It's not clear. */
64         printk("vmm_pcpu_init failed\n");
65 }
66
67 /* Initializes a process to run virtual machine contexts, returning the number
68  * initialized, optionally setting errno */
69 int vmm_struct_init(struct proc *p, unsigned int nr_guest_pcores,
70                     struct vmm_gpcore_init *u_gpcis, int flags)
71 {
72         struct vmm *vmm = &p->vmm;
73         unsigned int i;
74         struct vmm_gpcore_init gpci;
75
76         if (flags & ~VMM_ALL_FLAGS) {
77                 set_errstr("%s: flags is 0x%lx, VMM_ALL_FLAGS is 0x%lx\n", __func__,
78                            flags, VMM_ALL_FLAGS);
79                 set_errno(EINVAL);
80                 return 0;
81         }
82         vmm->flags = flags;
83         if (!x86_supports_vmx) {
84                 set_errno(ENODEV);
85                 return 0;
86         }
87         qlock(&vmm->qlock);
88         if (vmm->vmmcp) {
89                 set_errno(EINVAL);
90                 qunlock(&vmm->qlock);
91                 return 0;
92         }
93         /* Set this early, so cleanup checks the gpc array */
94         vmm->vmmcp = TRUE;
95         nr_guest_pcores = MIN(nr_guest_pcores, num_cores);
96         vmm->amd = 0;
97         vmm->guest_pcores = kzmalloc(sizeof(void*) * nr_guest_pcores, KMALLOC_WAIT);
98         for (i = 0; i < nr_guest_pcores; i++) {
99                 if (copy_from_user(&gpci, &u_gpcis[i],
100                                    sizeof(struct vmm_gpcore_init))) {
101                         set_error(EINVAL, "Bad pointer %p for gps", u_gpcis);
102                         break;
103                 }
104                 vmm->guest_pcores[i] = create_guest_pcore(p, &gpci);
105                 /* If we failed, we'll clean it up when the process dies */
106                 if (!vmm->guest_pcores[i]) {
107                         set_errno(ENOMEM);
108                         break;
109                 }
110         }
111         vmm->nr_guest_pcores = i;
112         for (int i = 0; i < VMM_VMEXIT_NR_TYPES; i++)
113                 vmm->vmexits[i] = 0;
114         qunlock(&vmm->qlock);
115         return i;
116 }
117
118 /* Has no concurrency protection - only call this when you know you have the
119  * only ref to vmm.  For instance, from __proc_free, where there is only one ref
120  * to the proc (and thus proc.vmm). */
121 void __vmm_struct_cleanup(struct proc *p)
122 {
123         struct vmm *vmm = &p->vmm;
124         if (!vmm->vmmcp)
125                 return;
126         for (int i = 0; i < vmm->nr_guest_pcores; i++) {
127                 if (vmm->guest_pcores[i])
128                         destroy_guest_pcore(vmm->guest_pcores[i]);
129         }
130         kfree(vmm->guest_pcores);
131         ept_flush(p->env_pgdir.eptp);
132         vmm->vmmcp = FALSE;
133 }
134
135 int vmm_poke_guest(struct proc *p, int guest_pcoreid)
136 {
137         struct guest_pcore *gpc;
138         int pcoreid;
139
140         gpc = lookup_guest_pcore(p, guest_pcoreid);
141         if (!gpc) {
142                 set_error(ENOENT, "Bad guest_pcoreid %d", guest_pcoreid);
143                 return -1;
144         }
145         /* We're doing an unlocked peek; it could change immediately.  This is a
146          * best effort service. */
147         pcoreid = ACCESS_ONCE(gpc->cpu);
148         if (pcoreid == -1) {
149                 /* So we know that we'll miss the poke for the posted IRQ.  We could
150                  * return an error.  However, error handling for this case isn't
151                  * particularly helpful (yet).  The absence of the error does not mean
152                  * the IRQ was posted.  We'll still return 0, meaning "the user didn't
153                  * mess up; we tried." */
154                 return 0;
155         }
156         send_ipi(pcoreid, I_POKE_CORE);
157         return 0;
158 }
159
160 struct guest_pcore *lookup_guest_pcore(struct proc *p, int guest_pcoreid)
161 {
162         /* nr_guest_pcores is written once at setup and never changed */
163         if (guest_pcoreid >= p->vmm.nr_guest_pcores)
164                 return 0;
165         return p->vmm.guest_pcores[guest_pcoreid];
166 }
167
168 struct guest_pcore *load_guest_pcore(struct proc *p, int guest_pcoreid)
169 {
170         struct guest_pcore *gpc;
171         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
172
173         gpc = lookup_guest_pcore(p, guest_pcoreid);
174         if (!gpc)
175                 return 0;
176         assert(pcpui->guest_pcoreid == -1);
177         spin_lock(&p->vmm.lock);
178         if (gpc->cpu != -1) {
179                 spin_unlock(&p->vmm.lock);
180                 return 0;
181         }
182         gpc->cpu = core_id();
183         spin_unlock(&p->vmm.lock);
184         /* We've got dibs on the gpc; we don't need to hold the lock any longer. */
185         pcpui->guest_pcoreid = guest_pcoreid;
186         ept_sync_context(gpc_get_eptp(gpc));
187         vmx_load_guest_pcore(gpc);
188         /* Load guest's xcr0 */
189         lxcr0(gpc->xcr0);
190         return gpc;
191 }
192
193 void unload_guest_pcore(struct proc *p, int guest_pcoreid)
194 {
195         struct guest_pcore *gpc;
196         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
197
198         gpc = lookup_guest_pcore(p, guest_pcoreid);
199         assert(gpc);
200         spin_lock(&p->vmm.lock);
201         assert(gpc->cpu != -1);
202         ept_sync_context(gpc_get_eptp(gpc));
203         vmx_unload_guest_pcore(gpc);
204         gpc->cpu = -1;
205
206         /* Save guest's xcr0 and restore Akaros's default. */
207         gpc->xcr0 = rxcr0();
208         lxcr0(x86_default_xcr0);
209
210         /* As soon as we unlock, this gpc can be started on another core */
211         spin_unlock(&p->vmm.lock);
212         pcpui->guest_pcoreid = -1;
213 }
214
215 /* emulated msr. For now, an msr value and a pointer to a helper that
216  * performs the requested operation.
217  */
218 struct emmsr {
219         uint32_t reg;
220         char *name;
221         bool (*f)(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
222                   uint64_t *rax, uint32_t opcode);
223         bool written;
224         uint32_t edx, eax;
225 };
226
227 static bool emsr_miscenable(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
228                             uint64_t *rax, uint32_t opcode);
229 static bool emsr_mustmatch(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
230                            uint64_t *rax, uint32_t opcode);
231 static bool emsr_readonly(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
232                           uint64_t *rax, uint32_t opcode);
233 static bool emsr_readzero(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
234                           uint64_t *rax, uint32_t opcode);
235 static bool emsr_fakewrite(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
236                            uint64_t *rax, uint32_t opcode);
237 static bool emsr_ok(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
238                     uint64_t *rax, uint32_t opcode);
239 static bool emsr_fake_apicbase(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
240                                uint64_t *rax, uint32_t opcode);
241
242 struct emmsr emmsrs[] = {
243         {MSR_IA32_MISC_ENABLE, "MSR_IA32_MISC_ENABLE", emsr_miscenable},
244         {MSR_IA32_SYSENTER_CS, "MSR_IA32_SYSENTER_CS", emsr_ok},
245         {MSR_IA32_SYSENTER_EIP, "MSR_IA32_SYSENTER_EIP", emsr_ok},
246         {MSR_IA32_SYSENTER_ESP, "MSR_IA32_SYSENTER_ESP", emsr_ok},
247         {MSR_IA32_UCODE_REV, "MSR_IA32_UCODE_REV", emsr_fakewrite},
248         {MSR_CSTAR, "MSR_CSTAR", emsr_fakewrite},
249         {MSR_IA32_VMX_BASIC_MSR, "MSR_IA32_VMX_BASIC_MSR", emsr_fakewrite},
250         {MSR_IA32_VMX_PINBASED_CTLS_MSR, "MSR_IA32_VMX_PINBASED_CTLS_MSR",
251          emsr_fakewrite},
252         {MSR_IA32_VMX_PROCBASED_CTLS_MSR, "MSR_IA32_VMX_PROCBASED_CTLS_MSR",
253          emsr_fakewrite},
254         {MSR_IA32_VMX_PROCBASED_CTLS2, "MSR_IA32_VMX_PROCBASED_CTLS2",
255          emsr_fakewrite},
256         {MSR_IA32_VMX_EXIT_CTLS_MSR, "MSR_IA32_VMX_EXIT_CTLS_MSR",
257          emsr_fakewrite},
258         {MSR_IA32_VMX_ENTRY_CTLS_MSR, "MSR_IA32_VMX_ENTRY_CTLS_MSR",
259          emsr_fakewrite},
260         {MSR_IA32_ENERGY_PERF_BIAS, "MSR_IA32_ENERGY_PERF_BIAS",
261          emsr_fakewrite},
262         {MSR_LBR_SELECT, "MSR_LBR_SELECT", emsr_ok},
263         {MSR_LBR_TOS, "MSR_LBR_TOS", emsr_ok},
264         {MSR_LBR_NHM_FROM, "MSR_LBR_NHM_FROM", emsr_ok},
265         {MSR_LBR_NHM_TO, "MSR_LBR_NHM_TO", emsr_ok},
266         {MSR_LBR_CORE_FROM, "MSR_LBR_CORE_FROM", emsr_ok},
267         {MSR_LBR_CORE_TO, "MSR_LBR_CORE_TO", emsr_ok},
268
269         // grumble.
270         {MSR_OFFCORE_RSP_0, "MSR_OFFCORE_RSP_0", emsr_ok},
271         {MSR_OFFCORE_RSP_1, "MSR_OFFCORE_RSP_1", emsr_ok},
272         // louder.
273         {MSR_PEBS_LD_LAT_THRESHOLD, "MSR_PEBS_LD_LAT_THRESHOLD", emsr_ok},
274         // aaaaaahhhhhhhhhhhhhhhhhhhhh
275         {MSR_ARCH_PERFMON_EVENTSEL0, "MSR_ARCH_PERFMON_EVENTSEL0", emsr_ok},
276         {MSR_ARCH_PERFMON_EVENTSEL1, "MSR_ARCH_PERFMON_EVENTSEL0", emsr_ok},
277         {MSR_IA32_PERF_CAPABILITIES, "MSR_IA32_PERF_CAPABILITIES", emsr_ok},
278         // unsafe.
279         {MSR_IA32_APICBASE, "MSR_IA32_APICBASE", emsr_fake_apicbase},
280
281         // mostly harmless.
282         {MSR_TSC_AUX, "MSR_TSC_AUX", emsr_fakewrite},
283         {MSR_RAPL_POWER_UNIT, "MSR_RAPL_POWER_UNIT", emsr_readzero},
284
285         // TBD
286         {MSR_IA32_TSC_DEADLINE, "MSR_IA32_TSC_DEADLINE", emsr_fakewrite},
287 };
288
289 /* this may be the only register that needs special handling.
290  * If there others then we might want to extend the emmsr struct.
291  */
292 bool emsr_miscenable(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
293                      uint64_t *rax, uint32_t opcode)
294 {
295         uint32_t eax, edx;
296
297         rdmsr(msr->reg, eax, edx);
298         /* we just let them read the misc msr for now. */
299         if (opcode == VMM_MSR_EMU_READ) {
300                 *rax = eax;
301                 *rax |= MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL;
302                 *rdx = edx;
303                 return TRUE;
304         } else {
305                 /* if they are writing what is already written, that's ok. */
306                 if (((uint32_t) *rax == eax) && ((uint32_t) *rdx == edx))
307                         return TRUE;
308         }
309         printk
310                 ("%s: Wanted to write 0x%x:0x%x, but could not; value was 0x%x:0x%x\n",
311                  msr->name, (uint32_t) *rdx, (uint32_t) *rax, edx, eax);
312         return FALSE;
313 }
314
315 /* TODO: this looks like a copy-paste for the read side.  What's the purpose of
316  * mustmatch?  No one even uses it. */
317 bool emsr_mustmatch(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
318                     uint64_t *rax, uint32_t opcode)
319 {
320         uint32_t eax, edx;
321
322         rdmsr(msr->reg, eax, edx);
323         /* we just let them read the misc msr for now. */
324         if (opcode == VMM_MSR_EMU_READ) {
325                 *rax = eax;
326                 *rdx = edx;
327                 return TRUE;
328         } else {
329                 /* if they are writing what is already written, that's ok. */
330                 if (((uint32_t) *rax == eax) && ((uint32_t) *rdx == edx))
331                         return TRUE;
332         }
333         printk
334                 ("%s: Wanted to write 0x%x:0x%x, but could not; value was 0x%x:0x%x\n",
335                  msr->name, (uint32_t) *rdx, (uint32_t) *rax, edx, eax);
336         return FALSE;
337 }
338
339 bool emsr_readonly(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
340                    uint64_t *rax, uint32_t opcode)
341 {
342         uint32_t eax, edx;
343
344         rdmsr((uint32_t) *rcx, eax, edx);
345         if (opcode == VMM_MSR_EMU_READ) {
346                 *rax = eax;
347                 *rdx = edx;
348                 return TRUE;
349         }
350
351         printk("%s: Tried to write a readonly register\n", msr->name);
352         return FALSE;
353 }
354
355 bool emsr_readzero(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
356                    uint64_t *rax, uint32_t opcode)
357 {
358         if (opcode == VMM_MSR_EMU_READ) {
359                 *rax = 0;
360                 *rdx = 0;
361                 return TRUE;
362         }
363
364         printk("%s: Tried to write a readonly register\n", msr->name);
365         return FALSE;
366 }
367
368 /* pretend to write it, but don't write it. */
369 bool emsr_fakewrite(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
370                     uint64_t *rax, uint32_t opcode)
371 {
372         uint32_t eax, edx;
373
374         if (!msr->written) {
375                 rdmsr(msr->reg, eax, edx);
376         } else {
377                 edx = msr->edx;
378                 eax = msr->eax;
379         }
380         /* we just let them read the misc msr for now. */
381         if (opcode == VMM_MSR_EMU_READ) {
382                 *rax = eax;
383                 *rdx = edx;
384                 return TRUE;
385         } else {
386                 /* if they are writing what is already written, that's ok. */
387                 if (((uint32_t) *rax == eax) && ((uint32_t) *rdx == edx))
388                         return TRUE;
389                 msr->edx = *rdx;
390                 msr->eax = *rax;
391                 msr->written = TRUE;
392         }
393         return TRUE;
394 }
395
396 bool emsr_ok(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
397              uint64_t *rax, uint32_t opcode)
398 {
399         if (opcode == VMM_MSR_EMU_READ) {
400                 rdmsr(msr->reg, *rdx, *rax);
401         } else {
402                 uint64_t val = (uint64_t) *rdx << 32 | *rax;
403
404                 write_msr(msr->reg, val);
405         }
406         return TRUE;
407 }
408
409 /* pretend to write it, but don't write it. */
410 bool emsr_fake_apicbase(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
411                         uint64_t *rax, uint32_t opcode)
412 {
413         uint32_t eax, edx;
414
415         if (!msr->written) {
416                 //rdmsr(msr->reg, eax, edx);
417                 /* TODO: tightly coupled to the addr in vmrunkernel.  We want this func
418                  * to return the val that vmrunkernel put into the VMCS. */
419                 eax = 0xfee00900;
420                 edx = 0;
421         } else {
422                 edx = msr->edx;
423                 eax = msr->eax;
424         }
425         /* we just let them read the misc msr for now. */
426         if (opcode == VMM_MSR_EMU_READ) {
427                 *rax = eax;
428                 *rdx = edx;
429                 return TRUE;
430         } else {
431                 /* if they are writing what is already written, that's ok. */
432                 if (((uint32_t) *rax == eax) && ((uint32_t) *rdx == edx))
433                         return 0;
434                 msr->edx = *rdx;
435                 msr->eax = *rax;
436                 msr->written = TRUE;
437         }
438         return TRUE;
439 }
440
441 bool vmm_emulate_msr(uint64_t *rcx, uint64_t *rdx, uint64_t *rax, int op)
442 {
443         for (int i = 0; i < ARRAY_SIZE(emmsrs); i++) {
444                 if (emmsrs[i].reg != *rcx)
445                         continue;
446                 return emmsrs[i].f(&emmsrs[i], rcx, rdx, rax, op);
447         }
448         return FALSE;
449 }