Added explicit errno reporting from error() API.
[akaros.git] / kern / drivers / dev / nix.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  * devnix/#t: a device for NIX mode
8  *
9  * A struct nix is a "visitor" chunk of code.  It has a memory image, and can be
10  * told to run an arbitrary address (in that image or otherwise) in kernel mode
11  * on various pcores, to which it has exclusive access.
12  *
13  * TODO:
14  *
15  * - FOR THE MOMENT, this is only intended to run one NIX at a time.  Too many
16  * sharp edges for any other mode.
17  *
18  * - memory images: we have one now for all nixs.  that'll be a mess.
19  *
20  * - what do we want to do for refcnting?  decref on chan close?  or remove?
21  * how do we manage the struct nix memory? (MGMT)
22  *              - right now, we aren't decreffing at all.  it's easier to work with from
23  *              the shell, but it's definitely a debugging thing.  the proper way to do
24  *              these devices is to release on close (i think).  the use case for the
25  *              NIX is a "turn it on once and reboot if you don't like it", so this is
26  *              fine for now.
27  *              - we're using c->aux, which needs to be an uncounted ref, in my opinion.
28  *              i messed around with this for a long time with devsrv, and all the
29  *              different ways 9ns interacts with a device make it very tricky.
30  *              - once we start freeing, we'll need to manage the memory better.  if we
31  *              have holes in the nixs[], we'll need to handle that in nixgen
32  *
33  * - how are we going to stop a nix?
34  *              - graceful vs immediate?  with some sort of immediate power-cord style
35  *              halting, the entire nix is garbage once we pull the plug.  a more
36  *              graceful style would require the nix to poll or something - probably
37  *              overkill.
38  *              - could send an immediate kmsg (IPI), but we'd need to do some
39  *              bookkeeping to know we're interrupting a NIX and whatnot
40  *              - if we were sure it's a nix core, we might be able to send an immediate
41  *              message telling the core to just smp_idle.  doing that from hard IRQ
42  *              would break a little, so we'd need to be careful (adjust various
43  *              flags, etc).
44  *              - another option would be to hack the halted context and have it call
45  *              a cleanup function (which ultimately smp_idles)
46  *              - if we had a process running the core, and "running the NIX" was a
47  *              syscall or something, we'd want to abort the syscall.  but since the
48  *              syscall isn't trying to rendez or sleep, we couldn't use the existing
49  *              facilities.  so it's the same problem: know it is a nix, somehow
50  *              kill/cleanup.  then just smp_idle.
51  *              - we'll also need to unreserve a core first, so we don't have any
52  *              concurrent startups.  careful of various races with cores coming and
53  *              going.  we can lock the nix before sending the message, but stale RKMs
54  *              could exist for a while.
55  *              - maybe we use a ktask, named nixID or something, to help detect if a
56  *              nix is running.  might also need to track the number of messages sent
57  *              and completed (track completed via the wrapper)
58  */
59
60 #include <kmalloc.h>
61 #include <string.h>
62 #include <stdio.h>
63 #include <assert.h>
64 #include <error.h>
65 #include <pmap.h>
66 #include <sys/queue.h>
67 #include <smp.h>
68 #include <kref.h>
69 #include <atomic.h>
70 #include <alarm.h>
71 #include <event.h>
72 #include <umem.h>
73 #include <devalarm.h>
74 #include <arch/types.h>
75 #include <arch/emulate.h>
76 #include <kdebug.h>
77 #include <bitmap.h>
78
79 struct dev nixdevtab;
80
81 static char *devname(void)
82 {
83         return nixdevtab.name;
84 }
85
86 /* qid path types */
87 enum {
88         Qtopdir = 1,
89         Qclone,
90         Qstat,
91         Qnixdir,
92         Qctl,
93         Qimage,
94 };
95
96 /* The QID is the TYPE and the index into the nix array.
97  * We reserve the right to make it an id later. */
98 #define INDEX_SHIFT 5
99 /* nix's have an image.
100  * Note that the image can be read even as it is running. */
101 struct nix {
102         struct kref kref;
103         /* should this be an array of pages? Hmm. */
104         void *image;
105         unsigned long imagesize;
106         int id;
107         /* we could dynamically alloc one of these with num_cores */
108         DECLARE_BITMAP(cpus, MAX_NUM_CORES);
109 };
110
111 static spinlock_t nixlock = SPINLOCK_INITIALIZER_IRQSAVE;
112 /* array, not linked list. We expect few, might as well be cache friendly. */
113 static struct nix *nixs = NULL;
114 static int nnix = 0;
115 static int nixok = 0;
116 /* TODO: make this per-nix, somehow. */
117 static physaddr_t img_paddr = CONFIG_NIX_IMG_PADDR;
118 static size_t img_size = CONFIG_NIX_IMG_SIZE;
119
120 static atomic_t nixid = 0;
121
122 /* initial guest program. */
123 /*
124 .code64
125         pushq   %rax
126         pushq   %rdx
127         movb    $0x30, %al
128         movw    $0x3f8, %dx
129         outb    %al, %dx
130         popq    %rdx
131         popq    %rax
132         ret
133 */
134 unsigned char it[] = {
135   0x50, 0x52, 0xb0, 0x30, 0x66, 0xba, 0xf8, 0x03, 0xee, 0x5a, 0x58, 0xc3
136 };
137 unsigned int it_len = 12;
138
139
140 /* The index is not the id, for now.  The index is the spot in nixs[].  The id
141  * is an increasing integer, regardless of struct nix* reuse. */
142 static inline struct nix *QID2NIX(struct qid q)
143 {
144         return &nixs[q.path >> INDEX_SHIFT];
145 }
146
147 static inline int TYPE(struct qid q)
148 {
149         return ((q).path & ((1 << INDEX_SHIFT) - 1));
150 }
151
152 static inline int QID(int index, int type)
153 {
154         return ((index << INDEX_SHIFT) | type);
155 }
156
157 static inline int QID2ID(struct qid q)
158 {
159         return q.path >> INDEX_SHIFT;
160 }
161
162 /* TODO: (MGMT) not called yet.  -- we have to unlink the nix */
163 static void nix_release(struct kref *kref)
164 {
165         struct nix *v = container_of(kref, struct nix, kref);
166         spin_lock_irqsave(&nixlock);
167         /* cute trick. Save the last element of the array in place of the
168          * one we're deleting. Reduce nnix. Don't realloc; that way, next
169          * time we add a nix the allocator will just return.
170          * Well, this is stupid, because when we do this, we break
171          * the QIDs, which have pointers embedded in them.
172          * darn it, may have to use a linked list. Nope, will probably
173          * just walk the array until we find a matching id. Still ... yuck.
174          *
175          * If we have lots, we can track the lowest free, similar to FDs and low_fd.
176          * honestly, we need an integer allocator (vmem and magazine paper) */
177         if (v != &nixs[nnix - 1]) {
178                 /* free the image ... oops */
179                 /* get rid of the kref. */
180                 *v = nixs[nnix - 1];
181         }
182         nnix--;
183         spin_unlock(&nixlock);
184 }
185
186 /* NIX ids run in the range 0..infinity.  */
187 static int newnixid(void)
188 {
189         return atomic_fetch_and_add(&nixid, 1);
190 }
191
192 static int nixgen(struct chan *c, char *entry_name,
193                    struct dirtab *unused, int unused_nr_dirtab,
194                    int s, struct dir *dp)
195 {
196         struct qid q;
197         struct nix *nix_i;
198         /* Whether we're in one dir or at the top, .. still takes us to the top. */
199         if (s == DEVDOTDOT) {
200                 mkqid(&q, Qtopdir, 0, QTDIR);
201                 devdir(c, c->qid, devname(), 0, eve, 0555, dp);
202                 return 1;
203         }
204         switch (TYPE(c->qid)) {
205         case Qtopdir:
206                 /* Generate elements for the top level dir.  We support clone, stat,
207                  * nix dirs at the top level */
208                 if (s == 0) {
209                         mkqid(&q, Qclone, 0, QTFILE);
210                         devdir(c, q, "clone", 0, eve, 0666, dp);
211                         return 1;
212                 }
213                 s--;
214                 if (s == 0) {
215                         mkqid(&q, Qstat, 0, QTFILE);
216                         devdir(c, q, "stat", 0, eve, 0666, dp);
217                         return 1;
218                 }
219                 s--;    /* 1 -> 0th element, 2 -> 1st element, etc */
220                 spin_lock_irqsave(&nixlock);
221                 if (s >= nnix) {
222                         spin_unlock(&nixlock);
223                         return -1;
224                 }
225                 nix_i = &nixs[s];
226                 /* TODO (MGMT): if no nix_i, advance (in case of holes) */
227                 snprintf(get_cur_genbuf(), GENBUF_SZ, "nix%d", nix_i->id);
228                 spin_unlock(&nixlock);
229                 mkqid(&q, QID(s, Qnixdir), 0, QTDIR);
230                 devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
231                 return 1;
232         case Qnixdir:
233                 /* Gen the contents of the nix dirs */
234                 s += Qctl;      /* first time through, start on Qctl */
235                 switch (s) {
236                 case Qctl:
237                         mkqid(&q, QID(QID2ID(c->qid), Qctl), 0, QTFILE);
238                         devdir(c, q, "ctl", 0, eve, 0666, dp);
239                         return 1;
240                 case Qimage:
241                         mkqid(&q, QID(QID2ID(c->qid), Qimage), 0, QTFILE);
242                         devdir(c, q, "image", 0, eve, 0666, dp);
243                         return 1;
244                 }
245                 return -1;
246                 /* Need to also provide a direct hit for Qclone and all other files (at
247                  * all levels of the hierarchy).  Every file is both
248                  * generated (via the s increments in their respective directories) and
249                  * directly gen-able.  devstat() will call gen with a specific path in
250                  * the qid.  In these cases, we make a dir for whatever they are asking
251                  * for.  Note the qid stays the same.  I think this is what the old
252                  * plan9 comments above devgen were talking about for (ii).
253                  *
254                  * We don't need to do this for the directories - devstat will look for
255                  * the a directory by path and fail.  Then it will manually build the
256                  * stat output (check the -1 case in devstat). */
257         case Qclone:
258                 devdir(c, c->qid, "clone", 0, eve, 0666, dp);
259                 return 1;
260         case Qstat:
261                 devdir(c, c->qid, "stat", 0, eve, 0444, dp);
262                 return 1;
263         case Qctl:
264                 devdir(c, c->qid, "ctl", 0, eve, 0666, dp);
265                 return 1;
266         case Qimage:
267                 devdir(c, c->qid, "image", 0, eve, 0666, dp);
268                 return 1;
269         }
270         return -1;
271 }
272
273 void nixtest(void)
274 {
275         printk("nixtest ran on core %d\n", core_id());
276 }
277
278 static void nixinit(void)
279 {
280         size_t img_order = LOG2_UP(nr_pages(img_size));
281         void *img_kaddr;
282
283         if (img_size != 1ULL << img_order << PGSHIFT) {
284                 printk("nixinit rounding up image size to a power of 2 pgs (was %p)\n",
285                        img_size);
286                 img_size = 1ULL << img_order << PGSHIFT;
287         }
288         img_kaddr = get_cont_phys_pages_at(img_order, img_paddr, 0);
289         if (!img_kaddr) {
290                 printk("nixinit failed to get an image!\n");
291                 return;
292         }
293         nixok = 1;
294         printk("nixinit image at KVA %p of size %p\n", img_kaddr, img_size);
295 }
296
297 static struct chan *nixattach(char *spec)
298 {
299         if (!nixok)
300                 error(EFAIL, "No NIXs available");
301         struct chan *c = devattach(devname(), spec);
302         mkqid(&c->qid, Qtopdir, 0, QTDIR);
303         return c;
304 }
305
306 static struct walkqid *nixwalk(struct chan *c, struct chan *nc, char **name,
307                                 int nname)
308 {
309         return devwalk(c, nc, name, nname, 0, 0, nixgen);
310 }
311
312 static int nixstat(struct chan *c, uint8_t * db, int n)
313 {
314         return devstat(c, db, n, 0, 0, nixgen);
315 }
316
317 /* It shouldn't matter if p = current is DYING.  We'll eventually fail to insert
318  * the open chan into p's fd table, then decref the chan. */
319 static struct chan *nixopen(struct chan *c, int omode)
320 {
321         ERRSTACK(1);
322         struct nix *v = QID2NIX(c->qid);
323         if (waserror()) {
324                 nexterror();
325         }
326         switch (TYPE(c->qid)) {
327         case Qtopdir:
328         case Qnixdir:
329                 if (omode & O_REMCLO)
330                         error(EPERM, NULL);
331                 if (omode & O_WRITE)
332                         error(EISDIR, NULL);
333                 break;
334         case Qclone:
335                 spin_lock_irqsave(&nixlock);
336                 if (nnix >= 1) {
337                         spin_unlock_irqsave(&nixlock);
338                         set_errno(EBUSY);
339                         error(EFAIL, "Already have 1 nix, we don't support more");
340                 }
341                 nixs = krealloc(nixs, sizeof(nixs[0]) * (nnix + 1), 0);
342                 v = &nixs[nnix];
343                 mkqid(&c->qid, QID(nnix, Qctl), 0, QTFILE);
344                 nnix++;
345                 spin_unlock(&nixlock);
346                 kref_init(&v->kref, nix_release, 1);
347                 v->id = newnixid();
348                 v->image = KADDR(img_paddr);
349                 v->imagesize = img_size;
350                 printk("nix image is %p with %d bytes\n", v->image, v->imagesize);
351                 c->aux = v;
352                 bitmap_zero(v->cpus, MAX_NUM_CORES);
353                 memcpy(v->image, it, sizeof(it));
354                 break;
355         case Qstat:
356                 break;
357         case Qctl:
358         case Qimage:
359                 /* TODO: (MGMT) refcnting */
360                 //kref_get(&v->kref, 1);
361                 c->aux = QID2NIX(c->qid);
362                 break;
363         }
364         c->mode = openmode(omode);
365         /* Assumes c is unique (can't be closed concurrently */
366         c->flag |= COPEN;
367         c->offset = 0;
368         poperror();
369         return c;
370 }
371
372 static void nixcreate(struct chan *c, char *name, int omode, uint32_t perm)
373 {
374         error(EPERM, NULL);
375 }
376
377 static void nixremove(struct chan *c)
378 {
379         error(EPERM, NULL);
380 }
381
382 static int nixwstat(struct chan *c, uint8_t * dp, int n)
383 {
384         error(EFAIL, "No nixwstat");
385         return 0;
386 }
387
388 static void nixclose(struct chan *c)
389 {
390         struct nix *v = c->aux;
391         if (!v)
392                 return;
393         /* There are more closes than opens.  For instance, sysstat doesn't open,
394          * but it will close the chan it got from namec.  We only want to clean
395          * up/decref chans that were actually open. */
396         if (!(c->flag & COPEN))
397                 return;
398         switch (TYPE(c->qid)) {
399                 /* TODO: (MGMT) the idea of 'stopping' a nix is tricky.
400                  * for now, leave the NIX active even when we close ctl */
401         case Qctl:
402                 break;
403         case Qimage:
404                 //kref_put(&v->kref);
405                 break;
406         }
407 }
408
409 static long nixread(struct chan *c, void *ubuf, long n, int64_t offset)
410 {
411         struct nix *v = c->aux;
412         switch (TYPE(c->qid)) {
413         case Qtopdir:
414         case Qnixdir:
415                 return devdirread(c, ubuf, n, 0, 0, nixgen);
416         case Qstat:
417                 return readnum(offset, ubuf, n, nnix, NUMSIZE32);
418         case Qctl:
419                 assert(v);
420                 return readnum(offset, ubuf, n, v->id, NUMSIZE32);
421         case Qimage:
422                 assert(v);
423                 return readmem(offset, ubuf, n, v->image, v->imagesize);
424         default:
425                 panic("Bad QID %p in devnix", c->qid.path);
426         }
427         return 0;
428 }
429
430 static void nixwrapper(uint32_t srcid, long a0, long a1, long a2)
431 {
432         void (*f)(void) = (void (*)(void))a0;
433         f();
434         /* TODO: could do some tracking to say this message has been completed */
435 }
436
437 static long nixwrite(struct chan *c, void *ubuf, long n, int64_t off)
438 {
439         struct nix *v = c->aux;
440         ERRSTACK(1);
441         char buf[32];
442         struct cmdbuf *cb;
443         struct nix *nix;
444         uint64_t hexval;
445
446         switch (TYPE(c->qid)) {
447         case Qtopdir:
448         case Qnixdir:
449         case Qstat:
450                 error(EPERM, NULL);
451         case Qctl:
452                 nix = c->aux;
453                 cb = parsecmd(ubuf, n);
454                 /* TODO: lock the nix here, unlock in waserror and before popping */
455                 if (waserror()) {
456                         kfree(cb);
457                         nexterror();
458                 }
459                 if (cb->nf < 1)
460                         error(EFAIL, "short control request");
461                 if (!strcmp(cb->f[0], "run")) {
462                         int core;
463                         uintptr_t ip;
464                         if (cb->nf != 3)
465                                 error(EFAIL, "usage: run core entry");
466                         core = strtoul(cb->f[1], 0, 0);
467                         ip = strtoul(cb->f[2], 0, 0);
468                         if (!test_bit(core, nix->cpus))
469                                 error(EFAIL, "Bad core %d", core);
470                         send_kernel_message(core, nixwrapper, (long)ip, 0, 0, KMSG_ROUTINE);
471                 } else if (!strcmp(cb->f[0], "test")) {
472                         int core;
473                         if (cb->nf != 2)
474                                 error(EFAIL, "usage: test core");
475                         core = strtoul(cb->f[1], 0, 0);
476                         if (!test_bit(core, nix->cpus))
477                                 error(EFAIL, "Bad core %d", core);
478                         send_kernel_message(core, nixwrapper, (long)nixtest, 0, 0,
479                                             KMSG_ROUTINE);
480                 } else if (!strcmp(cb->f[0], "reserve")) {
481                         int core;
482                         if (cb->nf != 2)
483                                 error(EFAIL, "Usage: reserve core (-1 for any)");
484                         core = strtol(cb->f[1], 0, 0);
485                         if (core == -1) {
486                                 core = get_any_idle_core();
487                                 if (core < 0)
488                                         error(EFAIL, "No free idle cores!");
489                         } else {
490                                 if (get_specific_idle_core(core) < 0)
491                                         error(EFAIL, "Failed to reserve core %d\n", core);
492                         }
493                         set_bit(core, nix->cpus);
494                 } else if (!strcmp(cb->f[0], "check")) {
495                         int i;
496                         for(i = 0; i < MAX_NUM_CORES; i++) {
497                                 if (!test_bit(i, nix->cpus))
498                                         continue;
499                                 printk("Core %d is available to nix%d\n", i, nix->id);
500                         }
501                 } else if (!strcmp(cb->f[0], "stop")) {
502                         error(EFAIL, "can't stop a nix yet");
503                 } else {
504                         error(EFAIL, "%s: not implemented", cb->f[0]);
505                 }
506                 kfree(cb);
507                 poperror();
508                 break;
509         case Qimage:
510                 if (off < 0)
511                         error(EFAIL, "offset < 0!");
512
513                 if (off + n > v->imagesize) {
514                         n = v->imagesize - off;
515                 }
516
517                 if (memcpy_from_user_errno(current, v->image + off, ubuf, n) < 0)
518                         error(EFAIL, "%s: bad user addr %p", __FUNCTION__, ubuf);
519                 break;
520
521         default:
522                 panic("Bad QID %p in devnix", c->qid.path);
523         }
524         return n;
525 }
526
527 struct dev nixdevtab __devtab = {
528         "nix",
529
530         devreset,
531         nixinit,
532         devshutdown,
533         nixattach,
534         nixwalk,
535         nixstat,
536         nixopen,
537         nixcreate,
538         nixclose,
539         nixread,
540         devbread,
541         nixwrite,
542         devbwrite,
543         nixremove,
544         nixwstat,
545         devpower,
546 //  devconfig,
547         devchaninfo,
548 };