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