summaryrefslogtreecommitdiff
path: root/hw/virtio-pci.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2010-10-06 15:20:17 +0200
committerMichael S. Tsirkin <mst@redhat.com>2010-10-07 12:19:47 +0200
commit54dd932128ae08d6a5a6668551508e30520b0f86 (patch)
treef6126186157f59ddb28daffeb3b47001d8bcfdd8 /hw/virtio-pci.c
parent010ec6293409f10b88631c36145944b9c3277ce1 (diff)
downloadqemu-54dd932128ae08d6a5a6668551508e30520b0f86.tar.gz
virtio: change set guest notifier to per-device
When using irqfd with vhost-net to inject interrupts, a single evenfd might inject multiple interrupts. Implementing this is much easier with a single per-device callback to set guest notifiers. Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/virtio-pci.c')
-rw-r--r--hw/virtio-pci.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 86e6b0a561..729917d891 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -451,6 +451,33 @@ static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
return 0;
}
+static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
+{
+ VirtIOPCIProxy *proxy = opaque;
+ VirtIODevice *vdev = proxy->vdev;
+ int r, n;
+
+ for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
+ if (!virtio_queue_get_num(vdev, n)) {
+ break;
+ }
+
+ r = virtio_pci_set_guest_notifier(opaque, n, assign);
+ if (r < 0) {
+ goto assign_error;
+ }
+ }
+
+ return 0;
+
+assign_error:
+ /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
+ while (--n >= 0) {
+ virtio_pci_set_guest_notifier(opaque, n, !assign);
+ }
+ return r;
+}
+
static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
{
VirtIOPCIProxy *proxy = opaque;
@@ -488,7 +515,7 @@ static const VirtIOBindings virtio_pci_bindings = {
.load_queue = virtio_pci_load_queue,
.get_features = virtio_pci_get_features,
.set_host_notifier = virtio_pci_set_host_notifier,
- .set_guest_notifier = virtio_pci_set_guest_notifier,
+ .set_guest_notifiers = virtio_pci_set_guest_notifiers,
};
static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,