This change removes current assumptions of a single mmio device, and allows us to handle multiple devices naturally. Removed legacy virtio_mmio_base and virtio_irq fields.
Bug: 28824279 Change-Id: I62640634d98290e6328948ec9fe071cf4632fd1b Signed-off-by: Gan Shun <[email protected]> --- tests/vmm/vmrunkernel.c | 12 ++---------- user/vmm/include/vmm/vmm.h | 13 ++++++++++--- user/vmm/vmexit.c | 29 ++++++++++++++--------------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/tests/vmm/vmrunkernel.c b/tests/vmm/vmrunkernel.c index 1f8d96c..fe9e575 100644 --- a/tests/vmm/vmrunkernel.c +++ b/tests/vmm/vmrunkernel.c @@ -381,8 +381,6 @@ int main(int argc, char **argv) ((uint32_t *)a_page)[0x30/4] = 0x01060015; //((uint32_t *)a_page)[0x30/4] = 0xDEADBEEF; - vm->virtio_irq = 17; /* TODO: is this an option? or a #define? */ - argc--, argv++; // switches ... // Sorry, I don't much like the gnu opt parsing code. @@ -400,10 +398,6 @@ int main(int argc, char **argv) argc--, argv++; maxresume = strtoull(argv[0], 0, 0); break; - case 'i': - argc--, argv++; - vm->virtio_irq = strtoull(argv[0], 0, 0); - break; case 'c': argc--, argv++; cmdline_extra = argv[0]; @@ -622,11 +616,9 @@ int main(int argc, char **argv) fprintf(stderr, "kernbase for pml4 is 0x%llx and entry is %llx\n", kernbase, entry); fprintf(stderr, "p512 %p p512[0] is 0x%lx p1 %p p1[0] is 0x%x\n", p512, p512[0], p1, p1[0]); - vm->virtio_mmio_base = 0x100000000; - - cons_mmio_dev.addr = vm->virtio_mmio_base; + cons_mmio_dev.addr = 0x100000000; cons_mmio_dev.vqdev = &cons_vqdev; - vm->cons_mmio_dev = &cons_mmio_dev; + vm->virtio_mmio_devices[VIRTIO_MMIO_CONSOLE_DEV] = &cons_mmio_dev; vmm_run_task(vm, timer_thread, 0); diff --git a/user/vmm/include/vmm/vmm.h b/user/vmm/include/vmm/vmm.h index 5b5e7a1..971f2d0 100644 --- a/user/vmm/include/vmm/vmm.h +++ b/user/vmm/include/vmm/vmm.h @@ -9,6 +9,15 @@ #include <ros/vmm.h> #include <vmm/sched.h> +/* The listing of VIRTIO MMIO devices. We currently only expect to have 2, + * console and network. Only the console is implemented right now.*/ +enum { + VIRTIO_MMIO_CONSOLE_DEV, + + /* This should always be the last entry. */ + VIRTIO_MMIO_MAX_NUM_DEV = 2, +}; + /* Structure to encapsulate all of the bookkeeping for a VM. */ struct virtual_machine { struct guest_thread **gths; @@ -18,10 +27,8 @@ struct virtual_machine { /* TODO: put these in appropriate structures. e.g., virtio things in * something related to virtio. low4k in something related to the guest's * memory. */ - uintptr_t virtio_mmio_base; - int virtio_irq; uint8_t *low4k; - struct virtio_mmio_dev *cons_mmio_dev; + struct virtio_mmio_dev *virtio_mmio_devices[VIRTIO_MMIO_MAX_NUM_DEV]; }; char *regname(uint8_t reg); diff --git a/user/vmm/vmexit.c b/user/vmm/vmexit.c index 615a86f..f1fb83f 100644 --- a/user/vmm/vmexit.c +++ b/user/vmm/vmexit.c @@ -24,25 +24,24 @@ static bool handle_ept_fault(struct guest_thread *gth) if (decode(gth, &gpa, ®x, ®p, &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? */ - if (size < 0) { - // TODO: It would be preferable for the decoder to return an - // unsigned value, so that we don't have to worry - // about this. I don't know if it's even possible for - // the width to be negative; - VIRTIO_DRI_ERRX(vm->cons_mmio_dev->vqdev, - "Driver tried to access the device with a negative access width in the instruction?"); - } - //fprintf(stderr, "RIP is 0x%x\n", vm_tf->tf_rip); if (store) - virtio_mmio_wr(vm, vm->cons_mmio_dev, gpa, size, (uint32_t *)regp); + virtio_mmio_wr(vm, vm->virtio_mmio_devices[i], gpa, size, + (uint32_t *)regp); else - *regp = virtio_mmio_rd(vm, vm->cons_mmio_dev, gpa, size); - - } else if (PG_ADDR(gpa) == 0xfec00000) { + *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); @@ -52,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; } -- 2.8.0.rc3.226.g39d4020 -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
