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);
 	}
 }