This now enables vmx via vmxon and vmclear works too
[akaros.git] / kern / drivers / dev / vm.c
1 //#define DEBUG
2 /* Copyright 2014 Google Inc.
3  * Copyright (c) 2013 The Regents of the University of California
4  * Barret Rhoden <brho@cs.berkeley.edu>
5  * See LICENSE for details.
6  *
7  * devvm/#V: a device for VMs
8  *
9  */
10
11 #include <kmalloc.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <assert.h>
15 #include <error.h>
16 #include <pmap.h>
17 #include <sys/queue.h>
18 #include <smp.h>
19 #include <kref.h>
20 #include <atomic.h>
21 #include <alarm.h>
22 #include <event.h>
23 #include <umem.h>
24 #include <devalarm.h>
25 #include <arch/types.h>
26 #include <arch/vm.h>
27 #include <arch/emulate.h>
28 #include <arch/vmdebug.h>
29
30 /* qid path types */
31 enum {
32         Qtopdir = 1,
33         Qclone,
34         Qstat,
35         Qvmdir,
36         Qctl,
37         Qimage,
38 };
39
40 /* This paddr/kaddr is a bit dangerous.  it'll work so long as we don't need all
41  * 64 bits for a physical address (48 is the current norm on x86_64).
42  * We're probably going to move to a model where we put the VM index or something
43  * into the qid, but this works for now.
44  */
45 #define ADDR_SHIFT 5
46 #define QID2VM(q) ((struct vm*)KADDR(((q).path >> ADDR_SHIFT)))
47 #define TYPE(q) ((q).path & ((1 << ADDR_SHIFT) - 1))
48 #define QID(ptr, type) ((PADDR(ptr) << ADDR_SHIFT) | type)
49
50 /* vm's have an image.
51  * Note that the image can be read even as it is running. */
52 struct vm {
53         struct vm *next;
54         struct kref                                     kref;
55         /* should this be an array of pages? Hmm. */
56         void                                           *image;
57         unsigned long                                   imagesize;
58         int                                             id;
59         struct litevm                                  *archvm;
60 };
61
62 static spinlock_t vmlock;
63 /* array, not linked list. We expect few, might as well be cache friendly. */
64 static struct vm *vms = NULL;
65 static int nvm = 0;
66
67 static spinlock_t vmidlock[1];
68 static struct kref vmid[1] = { {(void *)1, fake_release} };
69
70 /* we'll need this somewhere more generic. */
71 static void
72 readn(struct chan *c, void *vp, long n)
73 {
74         print_func_entry();
75         char *p;
76         long nn;
77         int total = 0, want = n;
78
79         p = vp;
80         while(n > 0) {
81                 nn = devtab[c->type]->read(c, p, n, c->offset);
82                 printk("readn: Got %d@%lld\n", nn, c->offset);
83                 if(nn == 0)
84                         error("%s: wanted %d, got %d", Eshort, total, want);
85                 c->offset += nn;
86                 p += nn;
87                 n -= nn;
88                 total += nn;
89         }
90         print_func_exit();
91 }
92
93
94 static void vm_release(struct kref *kref)
95 {
96         print_func_entry();
97         struct vm *v = container_of(kref, struct vm, kref);
98         spin_lock_irqsave(&vmlock);
99         /* cute trick. Save the last element of the array in place of the
100          * one we're deleting. Reduce nvm. Don't realloc; that way, next
101          * time we add a vm the allocator will just return.
102          * Well, this is stupid, because when we do this, we break
103          * the QIDs, which have pointers embedded in them.
104          * darn it, may have to use a linked list. Nope, will probably
105          * just walk the array until we find a matching id. Still ... yuck.
106          */
107         if (v != &vms[nvm-1]){
108                 /* free the image ... oops */
109                 /* get rid of the kref. */
110                 *v = vms[nvm-1];
111         }
112         nvm--;
113         spin_unlock(&vmlock);
114         print_func_exit();
115 }
116
117 /* VM ids run in the range 1..infinity. But vmx.c wants them
118  * 0-based.
119  */
120 static int newvmid(void)
121 {
122         print_func_entry();
123         int id;
124         spin_lock_irqsave(vmidlock);
125         id = kref_refcnt(vmid);
126         kref_get(vmid, 1);
127         spin_unlock(vmidlock);
128         print_func_exit();
129         return id-1;
130 }
131
132 static int vmgen(struct chan *c, char *entry_name,
133                  struct dirtab *unused, int unused_nr_dirtab,
134                  int s, struct dir *dp)
135 {
136         print_func_entry();
137         struct qid q;
138         struct vm *vm_i;
139         printd("GEN s %d\n", s);
140         /* Whether we're in one dir or at the top, .. still takes us to the top. */
141         if (s == DEVDOTDOT) {
142                 mkqid(&q, Qtopdir, 0, QTDIR);
143                 devdir(c, c->qid, "#V", 0, eve, 0555, dp);
144                 print_func_exit();
145                 return 1;
146         }
147         printd("TYPE %d\n", TYPE(c->qid));
148         switch (TYPE(c->qid)) {
149         case Qtopdir:
150                 printd("Qtopdir s %d nvm %d\n", s, nvm);
151                 /* Generate elements for the top level dir.  We support clone, stat,
152                  * vm dirs at the top level */
153                 if (s == 0) {
154                         mkqid(&q, Qclone, 0, QTFILE);
155                         devdir(c, q, "clone", 0, eve, 0666, dp);
156                         print_func_exit();
157                         return 1;
158                 }
159                 s--;
160                 if (s == 0) {
161                         mkqid(&q, Qstat, 0, QTFILE);
162                         devdir(c, q, "stat", 0, eve, 0666, dp);
163                         print_func_exit();
164                         return 1;
165                 }
166                 s--;    /* 1 -> 0th element, 2 -> 1st element, etc */
167                 spin_lock_irqsave(&vmlock);
168                 if (s >= nvm){
169                         printd("DONE qtopdir\n");
170                         spin_unlock(&vmlock);
171                         print_func_exit();
172                         return -1;
173                 }
174                 vm_i = &vms[s];
175                 snprintf(get_cur_genbuf(), GENBUF_SZ, "vm%d", vm_i->id);
176                 spin_unlock(&vmlock);
177                 mkqid(&q, QID(vm_i, Qvmdir), 0, QTDIR);
178                 devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
179                 print_func_exit();
180                 return 1;
181         case Qvmdir:
182                 /* Gen the contents of the vm dirs */
183                 s += Qctl;      /* first time through, start on Qctl */
184                 switch (s) {
185                 case Qctl:
186                         mkqid(&q, QID(QID2VM(c->qid), Qctl), 0, QTFILE);
187                         devdir(c, q, "ctl", 0, eve, 0666, dp);
188                         print_func_exit();
189                         return 1;
190                 case Qimage:
191                         mkqid(&q, QID(QID2VM(c->qid), Qimage), 0, QTFILE);
192                         devdir(c, q, "image", 0, eve, 0666, dp);
193                         print_func_exit();
194                         return 1;
195                 }
196                 print_func_exit();
197                 return -1;
198                 /* Need to also provide a direct hit for Qclone and all other files (at
199                  * all levels of the hierarchy).  Every file is both
200                  * generated (via the s increments in their respective directories) and
201                  * directly gen-able.  devstat() will call gen with a specific path in
202                  * the qid.  In these cases, we make a dir for whatever they are asking
203                  * for.  Note the qid stays the same.  I think this is what the old
204                  * plan9 comments above devgen were talking about for (ii).
205                  *
206                  * We don't need to do this for the directories - devstat will look for
207                  * the a directory by path and fail.  Then it will manually build the
208                  * stat output (check the -1 case in devstat). */
209         case Qclone:
210                 devdir(c, c->qid, "clone", 0, eve, 0666, dp);
211                 print_func_exit();
212                 return 1;
213         case Qstat:
214                 devdir(c, c->qid, "stat", 0, eve, 0444, dp);
215                 print_func_exit();
216                 return 1;
217         case Qctl:
218                 devdir(c, c->qid, "ctl", 0, eve, 0666, dp);
219                 print_func_exit();
220                 return 1;
221         case Qimage:
222                 devdir(c, c->qid, "image", 0, eve, 0666, dp);
223                 print_func_exit();
224                 return 1;
225         }
226         print_func_exit();
227         return -1;
228 }
229
230 static void vminit(void)
231 {
232         print_func_entry();
233         int i;
234         spinlock_init_irqsave(&vmlock);
235         spinlock_init_irqsave(vmidlock);
236         i = vmx_init();
237         printk("vminit: litevm_init returns %d\n", i);
238
239         print_func_exit();
240 }
241
242 static struct chan *vmattach(char *spec)
243 {
244         print_func_entry();
245         struct chan *c = devattach('V', spec);
246         mkqid(&c->qid, Qtopdir, 0, QTDIR);
247         print_func_exit();
248         return c;
249 }
250
251 static struct walkqid *vmwalk(struct chan *c, struct chan *nc, char **name,
252                               int nname)
253 {
254         print_func_entry();
255         print_func_exit();
256         return devwalk(c, nc, name, nname, 0, 0, vmgen);
257 }
258
259 static int vmstat(struct chan *c, uint8_t *db, int n)
260 {
261         print_func_entry();
262         print_func_exit();
263         return devstat(c, db, n, 0, 0, vmgen);
264 }
265
266 /* It shouldn't matter if p = current is DYING.  We'll eventually fail to insert
267  * the open chan into p's fd table, then decref the chan. */
268 static struct chan *vmopen(struct chan *c, int omode)
269 {
270         print_func_entry();
271         ERRSTACK(2);
272         struct vm *v = QID2VM(c->qid);
273         printk("vmopen: v is %p\n", v);
274         if (waserror()){
275                 nexterror();
276         }
277         switch (TYPE(c->qid)) {
278         case Qtopdir:
279         case Qvmdir:
280                 if (omode & ORCLOSE)
281                         error(Eperm);
282                 if (omode != OREAD)
283                         error(Eisdir);
284                 break;
285         case Qclone:
286                 spin_lock_irqsave(&vmlock);
287                 vms = krealloc(vms, sizeof(vms[0])*(nvm+1),0);
288                 v = &vms[nvm];
289                 nvm++;
290                 spin_unlock(&vmlock);
291                 kref_init(&v->kref, vm_release, 1);
292                 v->id = newvmid();
293                 mkqid(&c->qid, QID(v, Qctl), 0, QTFILE);
294                 c->aux = v;
295                 printd("New VM id %d\n", v->id);
296                 v->archvm = vmx_open();
297                 if (!v->archvm){
298                         printk("vm_open failed\n");
299                         error("vm_open failed");
300                 }
301                 if (vmx_create_vcpu(v->archvm, v->id) < 0){
302                         printk("vm_create failed");
303                         error("vm_create failed");
304                 }
305                 break;
306         case Qstat:
307                 break;
308         case Qctl:
309         case Qimage:
310                 c->aux = QID2VM(c->qid);
311                 printk("open qctl: aux is %p\n", c->aux);
312                 break;
313         }
314         c->mode = openmode(omode);
315         /* Assumes c is unique (can't be closed concurrently */
316         c->flag |= COPEN;
317         c->offset = 0;
318         print_func_exit();
319         return c;
320 }
321
322 static void vmcreate(struct chan *c, char *name, int omode, uint32_t perm)
323 {
324         print_func_entry();
325         error(Eperm);
326         print_func_exit();
327 }
328
329 static void vmremove(struct chan *c)
330 {
331         print_func_entry();
332         error(Eperm);
333         print_func_exit();
334 }
335
336 static int vmwstat(struct chan *c, uint8_t *dp, int n)
337 {
338         print_func_entry();
339         error("No vmwstat");
340         print_func_exit();
341         return 0;
342 }
343
344 static void vmclose(struct chan *c)
345 {
346         print_func_entry();
347         struct vm *v = c->aux;
348         if (!v) {
349                 print_func_exit();
350                 return;
351         }
352         /* There are more closes than opens.  For instance, sysstat doesn't open,
353          * but it will close the chan it got from namec.  We only want to clean
354          * up/decref chans that were actually open. */
355         if (!(c->flag & COPEN)) {
356                 print_func_exit();
357                 return;
358         }
359         switch (TYPE(c->qid)) {
360                 /* for now, leave the VM active even when we close ctl */
361         case Qctl:
362                 break;
363         case Qimage:
364                 kref_put(&v->kref);
365                 break;
366         }
367         print_func_exit();
368 }
369
370 static long vmread(struct chan *c, void *ubuf, long n, int64_t offset)
371 {
372         print_func_entry();
373         struct vm *v = c->aux;
374         printd("VMREAD\n");
375         switch (TYPE(c->qid)) {
376         case Qtopdir:
377         case Qvmdir:
378                 print_func_exit();
379                 return devdirread(c, ubuf, n, 0, 0, vmgen);
380         case Qstat:
381                 print_func_exit();
382                 return readnum(offset, ubuf, n, nvm, NUMSIZE32);
383         case Qctl:
384                 assert(v);
385                 print_func_exit();
386                 return readnum(offset, ubuf, n, v->id, NUMSIZE32);
387         case Qimage:
388                 assert(v);
389                 print_func_exit();
390                 return readmem(offset, ubuf, n,
391                                v->image, v->imagesize);
392         default:
393                 panic("Bad QID %p in devvm", c->qid.path);
394         }
395         print_func_exit();
396         return 0;
397 }
398
399 static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
400 {
401         print_func_entry();
402         ERRSTACK(3);
403         char buf[32];
404         struct cmdbuf *cb;
405         struct vm *vm;
406         struct litevm *litevm;
407         uint64_t hexval;
408         printd("vmwrite(%p, %p, %d)\n", c, ubuf, n);
409         switch (TYPE(c->qid)) {
410         case Qtopdir:
411         case Qvmdir:
412         case Qstat:
413                 error(Eperm);
414         case Qctl:
415                 vm = c->aux;
416                 cb = parsecmd(ubuf, n);
417                 if (waserror()) {
418                         kfree(cb);
419                         nexterror();
420                 }
421                 if (!strcmp(cb->f[0], "run")) {
422                         int ret;
423                         if (cb->nf != 4)
424                                 error("usage: run vcpu emulated mmio_completed");
425                         litevm = vm->archvm;
426                         struct litevm_run vmr;
427                         vmr.vcpu = strtoul(cb->f[1], NULL, 0);
428                         vmr.emulated = strtoul(cb->f[2], NULL, 0);
429                         vmr.mmio_completed = strtoul(cb->f[3], NULL, 0);
430                         ret = vm_run(litevm, &vmr);
431                         printk("vm_run returns %d\n", ret);
432                         print_func_exit();
433                         return ret;
434                 } else if (!strcmp(cb->f[0], "stop")) {
435                         error("can't stop a vm yet");
436                 } else if (!strcmp(cb->f[0], "fillmem")) {
437                         struct chan *file;
438                         void *v;
439                         vm = c->aux;
440                         litevm = vm->archvm;
441                         uint64_t filesize;
442                         struct litevm_memory_region vmr;
443                         int got;
444
445                         if (cb->nf != 6)
446                                 error("usage: mapmem file slot flags addr size");
447                         vmr.slot = strtoul(cb->f[2], NULL, 0);
448                         vmr.flags = strtoul(cb->f[3], NULL, 0);
449                         vmr.guest_phys_addr = strtoul(cb->f[4], NULL, 0);
450                         filesize = strtoul(cb->f[5], NULL, 0);
451                         vmr.memory_size = (filesize + 4095) & ~4095ULL;
452
453                         file = namec(cb->f[1], Aopen, OREAD, 0);
454                         printk("after namec file is %p\n", file);
455                         if (waserror()){
456                                 cclose(file);
457                                 nexterror();
458                         }
459                         /* at some point we want to mmap from the kernel
460                          * but we don't have that yet. This all needs
461                          * rethinking but the abstractions of kvm do too.
462                          */
463                         v = kmalloc(vmr.memory_size, KMALLOC_WAIT);
464                         if (waserror()){
465                                 kfree(v);
466                                 nexterror();
467                         }
468
469                         readn(file, v, filesize);
470                         vmr.init_data = v;
471
472                         if (vm_set_memory_region(litevm, &vmr))
473                                 error("vm_set_memory_region failed");
474                         poperror();
475                         poperror();
476                         kfree(v);
477                         cclose(file);
478
479                 } else if (!strcmp(cb->f[0], "region")) {
480                         void *v;
481                         struct litevm_memory_region vmr;
482                         litevm = vm->archvm;
483                         if (cb->nf != 5)
484                                 error("usage: mapmem slot flags addr size");
485                         vmr.slot = strtoul(cb->f[2], NULL, 0);
486                         vmr.flags = strtoul(cb->f[3], NULL, 0);
487                         vmr.guest_phys_addr = strtoul(cb->f[4], NULL, 0);
488                         vmr.memory_size = strtoul(cb->f[5], NULL, 0);
489                         if (vm_set_memory_region(litevm, &vmr))
490                                 error("vm_set_memory_region failed");
491                 } else {
492                         error("%s: not implemented", cb->f[0]);
493                 }
494                 kfree(cb);
495                 poperror();
496                 break;
497         case Qimage:
498                 error("can't write an image yet");
499                 break;
500         default:
501                 panic("Bad QID %p in devvm", c->qid.path);
502         }
503         print_func_exit();
504         return n;
505 }
506
507 struct dev vmdevtab = {
508         'V',
509         "vm",
510
511         devreset,
512         vminit,
513         devshutdown,
514         vmattach,
515         vmwalk,
516         vmstat,
517         vmopen,
518         vmcreate,
519         vmclose,
520         vmread,
521         devbread,
522         vmwrite,
523         devbwrite,
524         vmremove,
525         vmwstat,
526         devpower,
527 //      devconfig,
528 //      devchaninfo,
529 };