Abort vminit for now
[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(2);
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 (omode != OREAD)
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         print_func_exit();
320         return c;
321 }
322
323 static void vmcreate(struct chan *c, char *name, int omode, uint32_t perm)
324 {
325         print_func_entry();
326         error(Eperm);
327         print_func_exit();
328 }
329
330 static void vmremove(struct chan *c)
331 {
332         print_func_entry();
333         error(Eperm);
334         print_func_exit();
335 }
336
337 static int vmwstat(struct chan *c, uint8_t *dp, int n)
338 {
339         print_func_entry();
340         error("No vmwstat");
341         print_func_exit();
342         return 0;
343 }
344
345 static void vmclose(struct chan *c)
346 {
347         print_func_entry();
348         struct vm *v = c->aux;
349         if (!v) {
350                 print_func_exit();
351                 return;
352         }
353         /* There are more closes than opens.  For instance, sysstat doesn't open,
354          * but it will close the chan it got from namec.  We only want to clean
355          * up/decref chans that were actually open. */
356         if (!(c->flag & COPEN)) {
357                 print_func_exit();
358                 return;
359         }
360         switch (TYPE(c->qid)) {
361                 /* for now, leave the VM active even when we close ctl */
362         case Qctl:
363                 break;
364         case Qimage:
365                 kref_put(&v->kref);
366                 break;
367         }
368         print_func_exit();
369 }
370
371 static long vmread(struct chan *c, void *ubuf, long n, int64_t offset)
372 {
373         print_func_entry();
374         struct vm *v = c->aux;
375         printd("VMREAD\n");
376         switch (TYPE(c->qid)) {
377         case Qtopdir:
378         case Qvmdir:
379                 print_func_exit();
380                 return devdirread(c, ubuf, n, 0, 0, vmgen);
381         case Qstat:
382                 print_func_exit();
383                 return readnum(offset, ubuf, n, nvm, NUMSIZE32);
384         case Qctl:
385                 assert(v);
386                 print_func_exit();
387                 return readnum(offset, ubuf, n, v->id, NUMSIZE32);
388         case Qimage:
389                 assert(v);
390                 print_func_exit();
391                 return readmem(offset, ubuf, n,
392                                v->image, v->imagesize);
393         default:
394                 panic("Bad QID %p in devvm", c->qid.path);
395         }
396         print_func_exit();
397         return 0;
398 }
399
400 static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
401 {
402         print_func_entry();
403         ERRSTACK(3);
404         char buf[32];
405         struct cmdbuf *cb;
406         struct vm *vm;
407         struct litevm *litevm;
408         uint64_t hexval;
409         printd("vmwrite(%p, %p, %d)\n", c, ubuf, n);
410         switch (TYPE(c->qid)) {
411         case Qtopdir:
412         case Qvmdir:
413         case Qstat:
414                 error(Eperm);
415         case Qctl:
416                 vm = c->aux;
417                 cb = parsecmd(ubuf, n);
418                 if (waserror()) {
419                         kfree(cb);
420                         nexterror();
421                 }
422                 if (!strcmp(cb->f[0], "run")) {
423                         int ret;
424                         if (cb->nf != 4)
425                                 error("usage: run vcpu emulated mmio_completed");
426                         litevm = vm->archvm;
427                         struct litevm_run vmr;
428                         vmr.vcpu = strtoul(cb->f[1], NULL, 0);
429                         vmr.emulated = strtoul(cb->f[2], NULL, 0);
430                         vmr.mmio_completed = strtoul(cb->f[3], NULL, 0);
431                         ret = vm_run(litevm, &vmr);
432                         printk("vm_run returns %d\n", ret);
433                         print_func_exit();
434                         return ret;
435                 } else if (!strcmp(cb->f[0], "stop")) {
436                         error("can't stop a vm yet");
437                 } else if (!strcmp(cb->f[0], "fillmem")) {
438                         struct chan *file;
439                         void *v;
440                         vm = c->aux;
441                         litevm = vm->archvm;
442                         uint64_t filesize;
443                         struct litevm_memory_region vmr;
444                         int got;
445
446                         if (cb->nf != 6)
447                                 error("usage: mapmem file slot flags addr size");
448                         vmr.slot = strtoul(cb->f[2], NULL, 0);
449                         vmr.flags = strtoul(cb->f[3], NULL, 0);
450                         vmr.guest_phys_addr = strtoul(cb->f[4], NULL, 0);
451                         filesize = strtoul(cb->f[5], NULL, 0);
452                         vmr.memory_size = (filesize + 4095) & ~4095ULL;
453
454                         file = namec(cb->f[1], Aopen, OREAD, 0);
455                         printk("after namec file is %p\n", file);
456                         if (waserror()){
457                                 cclose(file);
458                                 nexterror();
459                         }
460                         /* at some point we want to mmap from the kernel
461                          * but we don't have that yet. This all needs
462                          * rethinking but the abstractions of kvm do too.
463                          */
464                         v = kmalloc(vmr.memory_size, KMALLOC_WAIT);
465                         if (waserror()){
466                                 kfree(v);
467                                 nexterror();
468                         }
469
470                         readn(file, v, filesize);
471                         vmr.init_data = v;
472
473                         if (vm_set_memory_region(litevm, &vmr))
474                                 error("vm_set_memory_region failed");
475                         poperror();
476                         poperror();
477                         kfree(v);
478                         cclose(file);
479
480                 } else if (!strcmp(cb->f[0], "region")) {
481                         void *v;
482                         struct litevm_memory_region vmr;
483                         litevm = vm->archvm;
484                         if (cb->nf != 5)
485                                 error("usage: mapmem slot flags addr size");
486                         vmr.slot = strtoul(cb->f[2], NULL, 0);
487                         vmr.flags = strtoul(cb->f[3], NULL, 0);
488                         vmr.guest_phys_addr = strtoul(cb->f[4], NULL, 0);
489                         vmr.memory_size = strtoul(cb->f[5], NULL, 0);
490                         if (vm_set_memory_region(litevm, &vmr))
491                                 error("vm_set_memory_region failed");
492                 } else {
493                         error("%s: not implemented", cb->f[0]);
494                 }
495                 kfree(cb);
496                 poperror();
497                 break;
498         case Qimage:
499                 error("can't write an image yet");
500                 break;
501         default:
502                 panic("Bad QID %p in devvm", c->qid.path);
503         }
504         print_func_exit();
505         return n;
506 }
507
508 struct dev vmdevtab = {
509         'V',
510         "vm",
511
512         devreset,
513         vminit,
514         devshutdown,
515         vmattach,
516         vmwalk,
517         vmstat,
518         vmopen,
519         vmcreate,
520         vmclose,
521         vmread,
522         devbread,
523         vmwrite,
524         devbwrite,
525         vmremove,
526         vmwstat,
527         devpower,
528 //      devconfig,
529 //      devchaninfo,
530 };