Get oprofile working more correctly.
[akaros.git] / kern / drivers / dev / vm.c
index 0554b45..3067594 100644 (file)
@@ -61,6 +61,15 @@ static int vmok = 0;
 static spinlock_t vmidlock[1];
 static struct kref vmid[1] = { {(void *)1, fake_release} };
 
+/* not clear what .h to put these in. Put them here. */
+
+struct litevm *vmx_open(void);
+int vmx_create_vcpu(struct litevm *litevm, int n);
+int vmx_init(void);
+int vm_set_memory_region(struct litevm *litevm,
+                                                struct litevm_memory_region *mem);
+int vm_run(struct litevm *litevm, struct litevm_run *litevm_run);
+
 static inline struct vm *
 QID2VM(struct qid q)
 {
@@ -81,7 +90,7 @@ static inline int QID(int index, int type)
 /* we'll need this somewhere more generic. */
 static void readn(struct chan *c, void *vp, long n)
 {
-       print_func_entry();
+       //print_func_entry();
        char *p;
        long nn;
        int total = 0, want = n;
@@ -91,19 +100,19 @@ static void readn(struct chan *c, void *vp, long n)
                nn = devtab[c->type].read(c, p, n, c->offset);
                printk("readn: Got %d@%lld\n", nn, c->offset);
                if (nn == 0)
-                       error("%s: wanted %d, got %d", Eshort, total, want);
+                       error("%s: wanted %d, got %d", Eshort, want, total);
                c->offset += nn;
                p += nn;
                n -= nn;
                total += nn;
        }
-       print_func_exit();
+       //print_func_exit();
 }
 
 /* not called yet.  -- we have to unlink the vm */
 static void vm_release(struct kref *kref)
 {
-       print_func_entry();
+       //print_func_entry();
        struct vm *v = container_of(kref, struct vm, kref);
        spin_lock_irqsave(&vmlock);
        /* cute trick. Save the last element of the array in place of the
@@ -121,7 +130,7 @@ static void vm_release(struct kref *kref)
        }
        nvm--;
        spin_unlock(&vmlock);
-       print_func_exit();
+       //print_func_exit();
 }
 
 /* VM ids run in the range 1..infinity. But vmx.c wants them
@@ -129,13 +138,13 @@ static void vm_release(struct kref *kref)
  */
 static int newvmid(void)
 {
-       print_func_entry();
+       //print_func_entry();
        int id;
        spin_lock_irqsave(vmidlock);
        id = kref_refcnt(vmid);
        kref_get(vmid, 1);
        spin_unlock(vmidlock);
-       print_func_exit();
+       //print_func_exit();
        return id - 1;
 }
 
@@ -143,7 +152,7 @@ static int vmgen(struct chan *c, char *entry_name,
                                 struct dirtab *unused, int unused_nr_dirtab,
                                 int s, struct dir *dp)
 {
-       print_func_entry();
+       //print_func_entry();
        struct qid q;
        struct vm *vm_i;
        printd("GEN s %d\n", s);
@@ -151,7 +160,7 @@ static int vmgen(struct chan *c, char *entry_name,
        if (s == DEVDOTDOT) {
                mkqid(&q, Qtopdir, 0, QTDIR);
                devdir(c, c->qid, "#V", 0, eve, 0555, dp);
-               print_func_exit();
+               //print_func_exit();
                return 1;
        }
        printd("TYPE %d\n", TYPE(c->qid));
@@ -163,14 +172,14 @@ static int vmgen(struct chan *c, char *entry_name,
                        if (s == 0) {
                                mkqid(&q, Qclone, 0, QTFILE);
                                devdir(c, q, "clone", 0, eve, 0666, dp);
-                               print_func_exit();
+                               //print_func_exit();
                                return 1;
                        }
                        s--;
                        if (s == 0) {
                                mkqid(&q, Qstat, 0, QTFILE);
                                devdir(c, q, "stat", 0, eve, 0666, dp);
-                               print_func_exit();
+                               //print_func_exit();
                                return 1;
                        }
                        s--;    /* 1 -> 0th element, 2 -> 1st element, etc */
@@ -178,16 +187,15 @@ static int vmgen(struct chan *c, char *entry_name,
                        if (s >= nvm) {
                                printd("DONE qtopdir\n");
                                spin_unlock(&vmlock);
-                               print_func_exit();
+                               //print_func_exit();
                                return -1;
                        }
                        vm_i = &vms[s];
                        snprintf(get_cur_genbuf(), GENBUF_SZ, "vm%d", vm_i->id);
                        spin_unlock(&vmlock);
-                       printk("clone vm_i is %p\n", vm_i);
                        mkqid(&q, QID(s, Qvmdir), 0, QTDIR);
                        devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
-                       print_func_exit();
+                       //print_func_exit();
                        return 1;
                case Qvmdir:
                        /* Gen the contents of the vm dirs */
@@ -196,15 +204,15 @@ static int vmgen(struct chan *c, char *entry_name,
                                case Qctl:
                                        mkqid(&q, QID(s-Qctl, Qctl), 0, QTFILE);
                                        devdir(c, q, "ctl", 0, eve, 0666, dp);
-                                       print_func_exit();
+                                       //print_func_exit();
                                        return 1;
                                case Qimage:
                                        mkqid(&q, QID(s-Qctl, Qimage), 0, QTFILE);
                                        devdir(c, q, "image", 0, eve, 0666, dp);
-                                       print_func_exit();
+                                       //print_func_exit();
                                        return 1;
                        }
-                       print_func_exit();
+                       //print_func_exit();
                        return -1;
                        /* Need to also provide a direct hit for Qclone and all other files (at
                         * all levels of the hierarchy).  Every file is both
@@ -219,28 +227,28 @@ static int vmgen(struct chan *c, char *entry_name,
                         * stat output (check the -1 case in devstat). */
                case Qclone:
                        devdir(c, c->qid, "clone", 0, eve, 0666, dp);
-                       print_func_exit();
+                       //print_func_exit();
                        return 1;
                case Qstat:
                        devdir(c, c->qid, "stat", 0, eve, 0444, dp);
-                       print_func_exit();
+                       //print_func_exit();
                        return 1;
                case Qctl:
                        devdir(c, c->qid, "ctl", 0, eve, 0666, dp);
-                       print_func_exit();
+                       //print_func_exit();
                        return 1;
                case Qimage:
                        devdir(c, c->qid, "image", 0, eve, 0666, dp);
-                       print_func_exit();
+                       //print_func_exit();
                        return 1;
        }
-       print_func_exit();
+       //print_func_exit();
        return -1;
 }
 
 static void vminit(void)
 {
-       print_func_entry();
+       //print_func_entry();
        int i;
        spinlock_init_irqsave(&vmlock);
        spinlock_init_irqsave(vmidlock);
@@ -249,32 +257,32 @@ static void vminit(void)
                vmok = 1;
        printk("vminit: litevm_init returns %d\n", i);
 
-       print_func_exit();
+       //print_func_exit();
 }
 
 static struct chan *vmattach(char *spec)
 {
-       print_func_entry();
+       //print_func_entry();
        if (!vmok)
                error("No VMs available");
        struct chan *c = devattach('V', spec);
        mkqid(&c->qid, Qtopdir, 0, QTDIR);
-       print_func_exit();
+       //print_func_exit();
        return c;
 }
 
 static struct walkqid *vmwalk(struct chan *c, struct chan *nc, char **name,
                                                          int nname)
 {
-       print_func_entry();
-       print_func_exit();
+       //print_func_entry();
+       //print_func_exit();
        return devwalk(c, nc, name, nname, 0, 0, vmgen);
 }
 
 static int vmstat(struct chan *c, uint8_t * db, int n)
 {
-       print_func_entry();
-       print_func_exit();
+       //print_func_entry();
+       //print_func_exit();
        return devstat(c, db, n, 0, 0, vmgen);
 }
 
@@ -282,7 +290,7 @@ static int vmstat(struct chan *c, uint8_t * db, int n)
  * the open chan into p's fd table, then decref the chan. */
 static struct chan *vmopen(struct chan *c, int omode)
 {
-       print_func_entry();
+       //print_func_entry();
        ERRSTACK(1);
        struct vm *v = QID2VM(c->qid);
        printk("vmopen: v is %p\n", v);
@@ -334,45 +342,45 @@ static struct chan *vmopen(struct chan *c, int omode)
        c->flag |= COPEN;
        c->offset = 0;
        poperror();
-       print_func_exit();
+       //print_func_exit();
        return c;
 }
 
 static void vmcreate(struct chan *c, char *name, int omode, uint32_t perm)
 {
-       print_func_entry();
+       //print_func_entry();
        error(Eperm);
-       print_func_exit();
+       //print_func_exit();
 }
 
 static void vmremove(struct chan *c)
 {
-       print_func_entry();
+       //print_func_entry();
        error(Eperm);
-       print_func_exit();
+       //print_func_exit();
 }
 
 static int vmwstat(struct chan *c, uint8_t * dp, int n)
 {
-       print_func_entry();
+       //print_func_entry();
        error("No vmwstat");
-       print_func_exit();
+       //print_func_exit();
        return 0;
 }
 
 static void vmclose(struct chan *c)
 {
-       print_func_entry();
+       //print_func_entry();
        struct vm *v = c->aux;
        if (!v) {
-               print_func_exit();
+               //print_func_exit();
                return;
        }
        /* There are more closes than opens.  For instance, sysstat doesn't open,
         * but it will close the chan it got from namec.  We only want to clean
         * up/decref chans that were actually open. */
        if (!(c->flag & COPEN)) {
-               print_func_exit();
+               //print_func_exit();
                return;
        }
        switch (TYPE(c->qid)) {
@@ -383,40 +391,40 @@ static void vmclose(struct chan *c)
                        kref_put(&v->kref);
                        break;
        }
-       print_func_exit();
+       //print_func_exit();
 }
 
 static long vmread(struct chan *c, void *ubuf, long n, int64_t offset)
 {
-       print_func_entry();
+       //print_func_entry();
        struct vm *v = c->aux;
        printd("VMREAD\n");
        switch (TYPE(c->qid)) {
                case Qtopdir:
                case Qvmdir:
-                       print_func_exit();
+                       //print_func_exit();
                        return devdirread(c, ubuf, n, 0, 0, vmgen);
                case Qstat:
-                       print_func_exit();
+                       //print_func_exit();
                        return readnum(offset, ubuf, n, nvm, NUMSIZE32);
                case Qctl:
                        assert(v);
-                       print_func_exit();
+                       //print_func_exit();
                        return readnum(offset, ubuf, n, v->id, NUMSIZE32);
                case Qimage:
                        assert(v);
-                       print_func_exit();
+                       //print_func_exit();
                        return readmem(offset, ubuf, n, v->image, v->imagesize);
                default:
                        panic("Bad QID %p in devvm", c->qid.path);
        }
-       print_func_exit();
+       //print_func_exit();
        return 0;
 }
 
 static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
 {
-       print_func_entry();
+       //print_func_entry();
        ERRSTACK(3);
        char buf[32];
        struct cmdbuf *cb;
@@ -446,9 +454,11 @@ static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
                                vmr.vcpu = strtoul(cb->f[1], NULL, 0);
                                vmr.emulated = strtoul(cb->f[2], NULL, 0);
                                vmr.mmio_completed = strtoul(cb->f[3], NULL, 0);
+                               disable_irq();
                                ret = vm_run(litevm, &vmr);
+                               enable_irq();
                                printk("vm_run returns %d\n", ret);
-                               print_func_exit();
+                               //print_func_exit();
                                return ret;
                        } else if (!strcmp(cb->f[0], "stop")) {
                                error("can't stop a vm yet");
@@ -471,6 +481,7 @@ static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
                                file = namec(cb->f[1], Aopen, OREAD, 0);
                                printk("after namec file is %p\n", file);
                                if (waserror()) {
+                                       printk("File open, alloc bad\n");
                                        cclose(file);
                                        nexterror();
                                }
@@ -480,6 +491,8 @@ static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
                                 */
                                v = kmalloc(vmr.memory_size, KMALLOC_WAIT);
                                if (waserror()) {
+                                       printk("memory allocated, read bad %s\n", 
+                                               current_errstr());
                                        kfree(v);
                                        nexterror();
                                }
@@ -489,6 +502,8 @@ static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
 
                                if (vm_set_memory_region(litevm, &vmr))
                                        error("vm_set_memory_region failed");
+                               void monitor(void *);
+                               monitor(NULL);
                                poperror();
                                poperror();
                                kfree(v);
@@ -503,6 +518,7 @@ static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
                                vmr.flags = strtoul(cb->f[2], NULL, 0);
                                vmr.guest_phys_addr = strtoul(cb->f[3], NULL, 0);
                                vmr.memory_size = strtoul(cb->f[4], NULL, 0);
+                               vmr.init_data = NULL;
                                if (vm_set_memory_region(litevm, &vmr))
                                        error("vm_set_memory_region failed");
                        } else {
@@ -517,7 +533,7 @@ static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
                default:
                        panic("Bad QID %p in devvm", c->qid.path);
        }
-       print_func_exit();
+       //print_func_exit();
        return n;
 }