VMM: Make the virtio poke guest functions respect the destination field Now that we have a multicore vm, the guest needs to be able to dictate the core to send its interrupts to on a per device basis. Change-Id: Ia1abe9581581d64e060b5c82d435f8bf9ddde3fd Signed-off-by: Gan Shun Lim <ganshun@gmail.com> [checkpatch warning] Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/tests/vmm/vmrunkernel.c b/tests/vmm/vmrunkernel.c index f6a0abc..3150087 100644 --- a/tests/vmm/vmrunkernel.c +++ b/tests/vmm/vmrunkernel.c
@@ -186,10 +186,17 @@ // FIXME. volatile int consdata = 0; -/* TODO: pass a core id to poke_guest */ -static void virtio_poke_guest(uint8_t vec) +static void virtio_poke_guest(uint8_t vec, uint32_t dest) { - vmm_interrupt_guest(vm, 0, vec); + if (dest < vm->nr_gpcs) { + vmm_interrupt_guest(vm, dest, vec); + return; + } + if (dest != 0xffffffff) + panic("INVALID DESTINATION: 0x%02x\n", dest); + + for (int i = 0; i < vm->nr_gpcs; i++) + vmm_interrupt_guest(vm, i, vec); } static struct virtio_mmio_dev cons_mmio_dev = {
diff --git a/user/vmm/include/vmm/virtio_mmio.h b/user/vmm/include/vmm/virtio_mmio.h index 54471da..835e1aa 100644 --- a/user/vmm/include/vmm/virtio_mmio.h +++ b/user/vmm/include/vmm/virtio_mmio.h
@@ -201,7 +201,7 @@ // This utility function will be called when the device needs to interrupt // the guest. You can have it do whatever you want, but it is required. - void (*poke_guest)(uint8_t vec); + void (*poke_guest)(uint8_t vec, uint32_t dest); // Status flags for the device uint8_t status; @@ -218,6 +218,9 @@ // Actual vector the device will inject. uint8_t vec; + + // Destination the interrupt is routed to. + uint32_t dest; }; // Sets the VIRTIO_MMIO_INT_VRING bit in the interrupt status
diff --git a/user/vmm/virtio_blk.c b/user/vmm/virtio_blk.c index c54592f..6d15363 100644 --- a/user/vmm/virtio_blk.c +++ b/user/vmm/virtio_blk.c
@@ -131,6 +131,6 @@ virtio_add_used_desc(vq, head, wlen); virtio_mmio_set_vring_irq(dev); - dev->poke_guest(dev->vec); + dev->poke_guest(dev->vec, dev->dest); } }
diff --git a/user/vmm/virtio_lguest_console.c b/user/vmm/virtio_lguest_console.c index ffc0787..480d367 100644 --- a/user/vmm/virtio_lguest_console.c +++ b/user/vmm/virtio_lguest_console.c
@@ -89,7 +89,7 @@ // NOTE: assuming that the mmio transport was used for now. virtio_mmio_set_vring_irq(dev); if (dev->poke_guest) - dev->poke_guest(dev->vec); + dev->poke_guest(dev->vec, dev->dest); else VIRTIO_DEV_ERRX(vq->vqdev, "The host MUST provide a way for device interrupts to be sent to the guest. The 'poke_guest' function pointer on the vq->vqdev->transport_dev (assumed to be a struct virtio_mmio_dev) was not set."); @@ -150,7 +150,7 @@ // NOTE: assuming that the mmio transport was used for now virtio_mmio_set_vring_irq(dev); if (dev->poke_guest) - dev->poke_guest(dev->vec); + dev->poke_guest(dev->vec, dev->dest); else VIRTIO_DEV_ERRX(vq->vqdev, "The host MUST provide a way for device interrupts to be sent to the guest. The 'poke_guest' function pointer on the vq->vqdev->transport_dev (assumed to be a struct virtio_mmio_dev) was not set.");
diff --git a/user/vmm/virtio_mmio.c b/user/vmm/virtio_mmio.c index 9be52fe..7c30741 100644 --- a/user/vmm/virtio_mmio.c +++ b/user/vmm/virtio_mmio.c
@@ -451,7 +451,7 @@ // Notify the driver that the device-specific config changed virtio_mmio_set_cfg_irq(mmio_dev); if (mmio_dev->poke_guest) - mmio_dev->poke_guest(mmio_dev->vec); + mmio_dev->poke_guest(mmio_dev->vec, mmio_dev->dest); return; }
diff --git a/user/vmm/virtio_net.c b/user/vmm/virtio_net.c index 72c7a6f..9e7d9e3 100644 --- a/user/vmm/virtio_net.c +++ b/user/vmm/virtio_net.c
@@ -111,7 +111,7 @@ virtio_add_used_desc(vq, head, num_read + VIRTIO_HEADER_SIZE); virtio_mmio_set_vring_irq(dev); - dev->poke_guest(dev->vec); + dev->poke_guest(dev->vec, dev->dest); } } @@ -154,6 +154,6 @@ virtio_add_used_desc(vq, head, 0); virtio_mmio_set_vring_irq(dev); - dev->poke_guest(dev->vec); + dev->poke_guest(dev->vec, dev->dest); } }