Adds chaninfo()
[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         return;
233         print_func_entry();
234         int i;
235         spinlock_init_irqsave(&vmlock);
236         spinlock_init_irqsave(vmidlock);
237         i = vmx_init();
238         printk("vminit: litevm_init returns %d\n", i);
239
240         print_func_exit();
241 }
242
243 static struct chan *vmattach(char *spec)
244 {
245         print_func_entry();
246         struct chan *c = devattach('V', spec);
247         mkqid(&c->qid, Qtopdir, 0, QTDIR);
248         print_func_exit();
249         return c;
250 }
251
252 static struct walkqid *vmwalk(struct chan *c, struct chan *nc, char **name,
253                               int nname)
254 {
255         print_func_entry();
256         print_func_exit();
257         return devwalk(c, nc, name, nname, 0, 0, vmgen);
258 }
259
260 static int vmstat(struct chan *c, uint8_t *db, int n)
261 {
262         print_func_entry();
263         print_func_exit();
264         return devstat(c, db, n, 0, 0, vmgen);
265 }
266
267 /* It shouldn't matter if p = current is DYING.  We'll eventually fail to insert
268  * the open chan into p's fd table, then decref the chan. */
269 static struct chan *vmopen(struct chan *c, int omode)
270 {
271         print_func_entry();
272         ERRSTACK(1);
273         struct vm *v = QID2VM(c->qid);
274         printk("vmopen: v is %p\n", v);
275         if (waserror()){
276                 nexterror();
277         }
278         switch (TYPE(c->qid)) {
279         case Qtopdir:
280         case Qvmdir:
281                 if (omode & ORCLOSE)
282                         error(Eperm);
283                 if (!IS_RDONLY(omode))
284                         error(Eisdir);
285                 break;
286         case Qclone:
287                 spin_lock_irqsave(&vmlock);
288                 vms = krealloc(vms, sizeof(vms[0])*(nvm+1),0);
289                 v = &vms[nvm];
290                 nvm++;
291                 spin_unlock(&vmlock);
292                 kref_init(&v->kref, vm_release, 1);
293                 v->id = newvmid();
294                 mkqid(&c->qid, QID(v, Qctl), 0, QTFILE);
295                 c->aux = v;
296                 printd("New VM id %d\n", v->id);
297                 v->archvm = vmx_open();
298                 if (!v->archvm){
299                         printk("vm_open failed\n");
300                         error("vm_open failed");
301                 }
302                 if (vmx_create_vcpu(v->archvm, v->id) < 0){
303                         printk("vm_create failed");
304                         error("vm_create failed");
305                 }
306                 break;
307         case Qstat:
308                 break;
309         case Qctl:
310         case Qimage:
311                 c->aux = QID2VM(c->qid);
312                 printk("open qctl: aux is %p\n", c->aux);
313                 break;
314         }
315         c->mode = openmode(omode);
316         /* Assumes c is unique (can't be closed concurrently */
317         c->flag |= COPEN;
318         c->offset = 0;
319         poperror();
320         print_func_exit();
321         return c;
322 }
323
324 static void vmcreate(struct chan *c, char *name, int omode, uint32_t perm)
325 {
326         print_func_entry();
327         error(Eperm);
328         print_func_exit();
329 }
330
331 static void vmremove(struct chan *c)
332 {
333         print_func_entry();
334         error(Eperm);
335         print_func_exit();
336 }
337
338 static int vmwstat(struct chan *c, uint8_t *dp, int n)
339 {
340         print_func_entry();
341         error("No vmwstat");
342         print_func_exit();
343         return 0;
344 }
345
346 static void vmclose(struct chan *c)
347 {
348         print_func_entry();
349         struct vm *v = c->aux;
350         if (!v) {
351                 print_func_exit();
352                 return;
353         }
354         /* There are more closes than opens.  For instance, sysstat doesn't open,
355          * but it will close the chan it got from namec.  We only want to clean
356          * up/decref chans that were actually open. */
357         if (!(c->flag & COPEN)) {
358                 print_func_exit();
359                 return;
360         }
361         switch (TYPE(c->qid)) {
362                 /* for now, leave the VM active even when we close ctl */
363         case Qctl:
364                 break;
365         case Qimage:
366                 kref_put(&v->kref);
367                 break;
368         }
369         print_func_exit();
370 }
371
372 static long vmread(struct chan *c, void *ubuf, long n, int64_t offset)
373 {
374         print_func_entry();
375         struct vm *v = c->aux;
376         printd("VMREAD\n");
377         switch (TYPE(c->qid)) {
378         case Qtopdir:
379         case Qvmdir:
380                 print_func_exit();
381                 return devdirread(c, ubuf, n, 0, 0, vmgen);
382         case Qstat:
383                 print_func_exit();
384                 return readnum(offset, ubuf, n, nvm, NUMSIZE32);
385         case Qctl:
386                 assert(v);
387                 print_func_exit();
388                 return readnum(offset, ubuf, n, v->id, NUMSIZE32);
389         case Qimage:
390                 assert(v);
391                 print_func_exit();
392                 return readmem(offset, ubuf, n,
393                                v->image, v->imagesize);
394         default:
395                 panic("Bad QID %p in devvm", c->qid.path);
396         }
397         print_func_exit();
398         return 0;
399 }
400
401 static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
402 {
403         print_func_entry();
404         ERRSTACK(3);
405         char buf[32];
406         struct cmdbuf *cb;
407         struct vm *vm;
408         struct litevm *litevm;
409         uint64_t hexval;
410         printd("vmwrite(%p, %p, %d)\n", c, ubuf, n);
411         switch (TYPE(c->qid)) {
412         case Qtopdir:
413         case Qvmdir:
414         case Qstat:
415                 error(Eperm);
416         case Qctl:
417                 vm = c->aux;
418                 cb = parsecmd(ubuf, n);
419                 if (waserror()) {
420                         kfree(cb);
421                         nexterror();
422                 }
423                 if (!strcmp(cb->f[0], "run")) {
424                         int ret;
425                         if (cb->nf != 4)
426                                 error("usage: run vcpu emulated mmio_completed");
427                         litevm = vm->archvm;
428                         struct litevm_run vmr;
429                         vmr.vcpu = strtoul(cb->f[1], NULL, 0);
430                         vmr.emulated = strtoul(cb->f[2], NULL, 0);
431                         vmr.mmio_completed = strtoul(cb->f[3], NULL, 0);
432                         ret = vm_run(litevm, &vmr);
433                         printk("vm_run returns %d\n", ret);
434                         print_func_exit();
435                         return ret;
436                 } else if (!strcmp(cb->f[0], "stop")) {
437                         error("can't stop a vm yet");
438                 } else if (!strcmp(cb->f[0], "fillmem")) {
439                         struct chan *file;
440                         void *v;
441                         vm = c->aux;
442                         litevm = vm->archvm;
443                         uint64_t filesize;
444                         struct litevm_memory_region vmr;
445                         int got;
446
447                         if (cb->nf != 6)
448                                 error("usage: mapmem file slot flags addr size");
449                         vmr.slot = strtoul(cb->f[2], NULL, 0);
450                         vmr.flags = strtoul(cb->f[3], NULL, 0);
451                         vmr.guest_phys_addr = strtoul(cb->f[4], NULL, 0);
452                         filesize = strtoul(cb->f[5], NULL, 0);
453                         vmr.memory_size = (filesize + 4095) & ~4095ULL;
454
455                         file = namec(cb->f[1], Aopen, OREAD, 0);
456                         printk("after namec file is %p\n", file);
457                         if (waserror()){
458                                 cclose(file);
459                                 nexterror();
460                         }
461                         /* at some point we want to mmap from the kernel
462                          * but we don't have that yet. This all needs
463                          * rethinking but the abstractions of kvm do too.
464                          */
465                         v = kmalloc(vmr.memory_size, KMALLOC_WAIT);
466                         if (waserror()){
467                                 kfree(v);
468                                 nexterror();
469                         }
470
471                         readn(file, v, filesize);
472                         vmr.init_data = v;
473
474                         if (vm_set_memory_region(litevm, &vmr))
475                                 error("vm_set_memory_region failed");
476                         poperror();
477                         poperror();
478                         kfree(v);
479                         cclose(file);
480
481                 } else if (!strcmp(cb->f[0], "region")) {
482                         void *v;
483                         struct litevm_memory_region vmr;
484                         litevm = vm->archvm;
485                         if (cb->nf != 5)
486                                 error("usage: mapmem slot flags addr size");
487                         vmr.slot = strtoul(cb->f[2], NULL, 0);
488                         vmr.flags = strtoul(cb->f[3], NULL, 0);
489                         vmr.guest_phys_addr = strtoul(cb->f[4], NULL, 0);
490                         vmr.memory_size = strtoul(cb->f[5], NULL, 0);
491                         if (vm_set_memory_region(litevm, &vmr))
492                                 error("vm_set_memory_region failed");
493                 } else {
494                         error("%s: not implemented", cb->f[0]);
495                 }
496                 kfree(cb);
497                 poperror();
498                 break;
499         case Qimage:
500                 error("can't write an image yet");
501                 break;
502         default:
503                 panic("Bad QID %p in devvm", c->qid.path);
504         }
505         print_func_exit();
506         return n;
507 }
508
509 struct dev vmdevtab __devtab = {
510         'V',
511         "vm",
512
513         devreset,
514         vminit,
515         devshutdown,
516         vmattach,
517         vmwalk,
518         vmstat,
519         vmopen,
520         vmcreate,
521         vmclose,
522         vmread,
523         devbread,
524         vmwrite,
525         devbwrite,
526         vmremove,
527         vmwstat,
528         devpower,
529 //      devconfig,
530         devchaninfo,
531 };