Handle multiple virtio mmio devices.
[akaros.git] / user / vmm / vmexit.c
index bf12f5b..f1fb83f 100644 (file)
@@ -24,12 +24,24 @@ static bool handle_ept_fault(struct guest_thread *gth)
 
        if (decode(gth, &gpa, &regx, &regp, &store, &size, &advance))
                return FALSE;
+       assert(size >= 0);
        /* TODO use helpers for some of these addr checks.  the fee/fec ones might
         * be wrong too. */
-       if (PG_ADDR(gpa) == vm->virtio_mmio_base) {
+       for (int i = 0; i < VIRTIO_MMIO_MAX_NUM_DEV; i++) {
+               if (vm->virtio_mmio_devices[i] == NULL)
+                       continue;
+               if (PG_ADDR(gpa) != vm->virtio_mmio_devices[i]->addr)
+                       continue;
                /* TODO: can the guest cause us to spawn off infinite threads? */
-               virtio_mmio(gth, gpa, regx, regp, store);
-       } else if (PG_ADDR(gpa) == 0xfec00000) {
+               if (store)
+                       virtio_mmio_wr(vm, vm->virtio_mmio_devices[i], gpa, size,
+                                      (uint32_t *)regp);
+               else
+                       *regp = virtio_mmio_rd(vm, vm->virtio_mmio_devices[i], gpa, size);
+               vm_tf->tf_rip += advance;
+               return TRUE;
+       }
+       if (PG_ADDR(gpa) == 0xfec00000) {
                do_ioapic(gth, gpa, regx, regp, store);
        } else if (PG_ADDR(gpa) == 0) {
                memmove(regp, &vm->low4k[gpa], size);
@@ -39,7 +51,7 @@ static bool handle_ept_fault(struct guest_thread *gth)
                                vm_tf->tf_exit_reason);
                fprintf(stderr, "Returning 0xffffffff\n");
                showstatus(stderr, gth);
-               // Just fill the whole register for now.
+               /* Just fill the whole register for now. */
                *regp = (uint64_t) -1;
                return FALSE;
        }