15eb463782f57cab1a9de9c6a29e82d7f91ad463
[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         char *p;
75         long nn;
76         int total = 0, want = n;
77
78         p = vp;
79         while(n > 0) {
80                 nn = devtab[c->type]->read(c, p, n, c->offset);
81                 printk("readn: Got %d@%lld\n", nn, c->offset);
82                 if(nn == 0)
83                         error("%s: wanted %d, got %d", Eshort, total, want);
84                 c->offset += nn;
85                 p += nn;
86                 n -= nn;
87                 total += nn;
88         }
89 }
90
91
92 static void vm_release(struct kref *kref)
93 {
94         struct vm *v = container_of(kref, struct vm, kref);
95         spin_lock_irqsave(&vmlock);
96         /* cute trick. Save the last element of the array in place of the
97          * one we're deleting. Reduce nvm. Don't realloc; that way, next
98          * time we add a vm the allocator will just return.
99          * Well, this is stupid, because when we do this, we break
100          * the QIDs, which have pointers embedded in them.
101          * darn it, may have to use a linked list. Nope, will probably
102          * just walk the array until we find a matching id. Still ... yuck.
103          */
104         if (v != &vms[nvm-1]){
105                 /* free the image ... oops */
106                 /* get rid of the kref. */
107                 *v = vms[nvm-1];
108         }
109         nvm--;
110         spin_unlock(&vmlock);
111 }
112
113 static int newvmid(void)
114 {
115         int id;
116         spin_lock_irqsave(vmidlock);
117         id = kref_refcnt(vmid);
118         kref_get(vmid, 1);
119         spin_unlock(vmidlock);
120         return id;
121 }
122
123 static int vmgen(struct chan *c, char *entry_name,
124                  struct dirtab *unused, int unused_nr_dirtab,
125                  int s, struct dir *dp)
126 {
127         struct qid q;
128         struct vm *vm_i;
129         printd("GEN s %d\n", s);
130         /* Whether we're in one dir or at the top, .. still takes us to the top. */
131         if (s == DEVDOTDOT) {
132                 mkqid(&q, Qtopdir, 0, QTDIR);
133                 devdir(c, c->qid, "#V", 0, eve, 0555, dp);
134                 return 1;
135         }
136         printd("TYPE %d\n", TYPE(c->qid));
137         switch (TYPE(c->qid)) {
138         case Qtopdir:
139                 printd("Qtopdir s %d nvm %d\n", s, nvm);
140                 /* Generate elements for the top level dir.  We support clone, stat,
141                  * vm dirs at the top level */
142                 if (s == 0) {
143                         mkqid(&q, Qclone, 0, QTFILE);
144                         devdir(c, q, "clone", 0, eve, 0666, dp);
145                         return 1;
146                 }
147                 s--;
148                 if (s == 0) {
149                         mkqid(&q, Qstat, 0, QTFILE);
150                         devdir(c, q, "stat", 0, eve, 0666, dp);
151                         return 1;
152                 }
153                 s--;    /* 1 -> 0th element, 2 -> 1st element, etc */
154                 spin_lock_irqsave(&vmlock);
155                 if (s >= nvm){
156                         printd("DONE qtopdir\n");
157                         spin_unlock(&vmlock);
158                         return -1;
159                 }
160                 vm_i = &vms[s];
161                 snprintf(get_cur_genbuf(), GENBUF_SZ, "vm%d", vm_i->id);
162                 spin_unlock(&vmlock);
163                 mkqid(&q, QID(vm_i, Qvmdir), 0, QTDIR);
164                 devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
165                 return 1;
166         case Qvmdir:
167                 /* Gen the contents of the vm dirs */
168                 s += Qctl;      /* first time through, start on Qctl */
169                 switch (s) {
170                 case Qctl:
171                         mkqid(&q, QID(QID2VM(c->qid), Qctl), 0, QTFILE);
172                         devdir(c, q, "ctl", 0, eve, 0666, dp);
173                         return 1;
174                 case Qimage:
175                         mkqid(&q, QID(QID2VM(c->qid), Qimage), 0, QTFILE);
176                         devdir(c, q, "image", 0, eve, 0666, dp);
177                         return 1;
178                 }
179                 return -1;
180                 /* Need to also provide a direct hit for Qclone and all other files (at
181                  * all levels of the hierarchy).  Every file is both
182                  * generated (via the s increments in their respective directories) and
183                  * directly gen-able.  devstat() will call gen with a specific path in
184                  * the qid.  In these cases, we make a dir for whatever they are asking
185                  * for.  Note the qid stays the same.  I think this is what the old
186                  * plan9 comments above devgen were talking about for (ii).
187                  *
188                  * We don't need to do this for the directories - devstat will look for
189                  * the a directory by path and fail.  Then it will manually build the
190                  * stat output (check the -1 case in devstat). */
191         case Qclone:
192                 devdir(c, c->qid, "clone", 0, eve, 0666, dp);
193                 return 1;
194         case Qstat:
195                 devdir(c, c->qid, "stat", 0, eve, 0444, dp);
196                 return 1;
197         case Qctl:
198                 devdir(c, c->qid, "ctl", 0, eve, 0666, dp);
199                 return 1;
200         case Qimage:
201                 devdir(c, c->qid, "image", 0, eve, 0666, dp);
202                 return 1;
203         }
204         return -1;
205 }
206
207 static void vminit(void)
208 {
209         int i;
210         spinlock_init_irqsave(&vmlock);
211         spinlock_init_irqsave(vmidlock);
212         i = vmx_init();
213         printk("vminit: litevm_init returns %d\n", i);
214
215 }
216
217 static struct chan *vmattach(char *spec)
218 {
219         struct chan *c = devattach('V', spec);
220         mkqid(&c->qid, Qtopdir, 0, QTDIR);
221         return c;
222 }
223
224 static struct walkqid *vmwalk(struct chan *c, struct chan *nc, char **name,
225                               int nname)
226 {
227         return devwalk(c, nc, name, nname, 0, 0, vmgen);
228 }
229
230 static int vmstat(struct chan *c, uint8_t *db, int n)
231 {
232         return devstat(c, db, n, 0, 0, vmgen);
233 }
234
235 /* It shouldn't matter if p = current is DYING.  We'll eventually fail to insert
236  * the open chan into p's fd table, then decref the chan. */
237 static struct chan *vmopen(struct chan *c, int omode)
238 {
239         ERRSTACK(2);
240         struct vm *v = QID2VM(c->qid);
241         printk("vmopen: v is %p\n", v);
242         if (waserror()){
243                 nexterror();
244         }
245         switch (TYPE(c->qid)) {
246         case Qtopdir:
247         case Qvmdir:
248                 if (omode & ORCLOSE)
249                         error(Eperm);
250                 if (omode != OREAD)
251                         error(Eisdir);
252                 break;
253         case Qclone:
254                 spin_lock_irqsave(&vmlock);
255                 vms = krealloc(vms, sizeof(vms[0])*(nvm+1),0);
256                 v = &vms[nvm];
257                 nvm++;
258                 spin_unlock(&vmlock);
259                 kref_init(&v->kref, vm_release, 1);
260                 v->id = newvmid();
261                 mkqid(&c->qid, QID(v, Qctl), 0, QTFILE);
262                 c->aux = v;
263                 printd("New VM id %d\n", v->id);
264                 v->archvm = vmx_open();
265                 if (!v->archvm)
266                         error("vm_open failed");
267                 if (vmx_create_vcpu(v->archvm, 1) < 0)
268                         error("vm_create failed");
269                 break;
270         case Qstat:
271                 break;
272         case Qctl:
273         case Qimage:
274                 c->aux = QID2VM(c->qid);
275                 printk("open qctl: aux is %p\n", c->aux);
276                 break;
277         }
278         c->mode = openmode(omode);
279         /* Assumes c is unique (can't be closed concurrently */
280         c->flag |= COPEN;
281         c->offset = 0;
282         return c;
283 }
284
285 static void vmcreate(struct chan *c, char *name, int omode, uint32_t perm)
286 {
287         error(Eperm);
288 }
289
290 static void vmremove(struct chan *c)
291 {
292         error(Eperm);
293 }
294
295 static int vmwstat(struct chan *c, uint8_t *dp, int n)
296 {
297         error("No vmwstat");
298         return 0;
299 }
300
301 static void vmclose(struct chan *c)
302 {
303         struct vm *v = c->aux;
304         if (!v)
305                 return;
306         /* There are more closes than opens.  For instance, sysstat doesn't open,
307          * but it will close the chan it got from namec.  We only want to clean
308          * up/decref chans that were actually open. */
309         if (!(c->flag & COPEN))
310                 return;
311         switch (TYPE(c->qid)) {
312                 /* for now, leave the VM active even when we close ctl */
313         case Qctl:
314                 break;
315         case Qimage:
316                 kref_put(&v->kref);
317                 break;
318         }
319 }
320
321 static long vmread(struct chan *c, void *ubuf, long n, int64_t offset)
322 {
323         struct vm *v = c->aux;
324         printd("VMREAD\n");
325         switch (TYPE(c->qid)) {
326         case Qtopdir:
327         case Qvmdir:
328                 return devdirread(c, ubuf, n, 0, 0, vmgen);
329         case Qstat:
330                 return readnum(offset, ubuf, n, nvm, NUMSIZE32);
331         case Qctl:
332                 assert(v);
333                 return readnum(offset, ubuf, n, v->id, NUMSIZE32);
334         case Qimage:
335                 assert(v);
336                 return readmem(offset, ubuf, n,
337                                v->image, v->imagesize);
338         default:
339                 panic("Bad QID %p in devvm", c->qid.path);
340         }
341         return 0;
342 }
343
344 static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
345 {
346         ERRSTACK(3);
347         char buf[32];
348         struct cmdbuf *cb;
349         struct vm *vm;
350         struct litevm *litevm;
351         uint64_t hexval;
352         printd("vmwrite(%p, %p, %d)\n", c, ubuf, n);
353         switch (TYPE(c->qid)) {
354         case Qtopdir:
355         case Qvmdir:
356         case Qstat:
357                 error(Eperm);
358         case Qctl:
359                 vm = c->aux;
360                 cb = parsecmd(ubuf, n);
361                 if (waserror()) {
362                         kfree(cb);
363                         nexterror();
364                 }
365                 if (!strcmp(cb->f[0], "run")) {
366                         int ret;
367                         if (cb->nf != 4)
368                                 error("usage: run vcpu emulated mmio_completed");
369                         litevm = vm->archvm;
370                         struct litevm_run vmr;
371                         vmr.vcpu = strtoul(cb->f[1], NULL, 0);
372                         vmr.emulated = strtoul(cb->f[2], NULL, 0);
373                         vmr.mmio_completed = strtoul(cb->f[3], NULL, 0);
374                         ret = vm_run(litevm, &vmr);
375                         printk("vm_run returns %d\n", ret);
376                         return ret;
377                 } else if (!strcmp(cb->f[0], "stop")) {
378                         error("can't stop a vm yet");
379                 } else if (!strcmp(cb->f[0], "fillmem")) {
380                         struct chan *file;
381                         void *v;
382                         vm = c->aux;
383                         litevm = vm->archvm;
384                         uint64_t filesize;
385                         struct litevm_memory_region vmr;
386                         int got;
387
388                         if (cb->nf != 6)
389                                 error("usage: mapmem file slot flags addr size");
390                         vmr.slot = strtoul(cb->f[2], NULL, 0);
391                         vmr.flags = strtoul(cb->f[3], NULL, 0);
392                         vmr.guest_phys_addr = strtoul(cb->f[4], NULL, 0);
393                         filesize = strtoul(cb->f[5], NULL, 0);
394                         vmr.memory_size = (filesize + 4095) & ~4095ULL;
395
396                         file = namec(cb->f[1], Aopen, OREAD, 0);
397                         printk("after namec file is %p\n", file);
398                         if (waserror()){
399                                 cclose(file);
400                                 nexterror();
401                         }
402                         /* at some point we want to mmap from the kernel
403                          * but we don't have that yet. This all needs
404                          * rethinking but the abstractions of kvm do too.
405                          */
406                         v = kmalloc(vmr.memory_size, KMALLOC_WAIT);
407                         if (waserror()){
408                                 kfree(v);
409                                 nexterror();
410                         }
411
412                         readn(file, v, filesize);
413                         vmr.init_data = v;
414
415                         if (vm_set_memory_region(litevm, &vmr))
416                                 error("vm_set_memory_region failed");
417                         poperror();
418                         poperror();
419                         kfree(v);
420                         cclose(file);
421
422                 } else if (!strcmp(cb->f[0], "region")) {
423                         void *v;
424                         struct litevm_memory_region vmr;
425                         litevm = vm->archvm;
426                         if (cb->nf != 5)
427                                 error("usage: mapmem slot flags addr size");
428                         vmr.slot = strtoul(cb->f[2], NULL, 0);
429                         vmr.flags = strtoul(cb->f[3], NULL, 0);
430                         vmr.guest_phys_addr = strtoul(cb->f[4], NULL, 0);
431                         vmr.memory_size = strtoul(cb->f[5], NULL, 0);
432                         if (vm_set_memory_region(litevm, &vmr))
433                                 error("vm_set_memory_region failed");
434                 } else {
435                         error("%s: not implemented", cb->f[0]);
436                 }
437                 kfree(cb);
438                 poperror();
439                 break;
440         case Qimage:
441                 error("can't write an image yet");
442                 break;
443         default:
444                 panic("Bad QID %p in devvm", c->qid.path);
445         }
446         return n;
447 }
448
449 struct dev vmdevtab = {
450         'V',
451         "vm",
452
453         devreset,
454         vminit,
455         devshutdown,
456         vmattach,
457         vmwalk,
458         vmstat,
459         vmopen,
460         vmcreate,
461         vmclose,
462         vmread,
463         devbread,
464         vmwrite,
465         devbwrite,
466         vmremove,
467         vmwstat,
468         devpower,
469 //      devconfig,
470 //      devchaninfo,
471 };