Revision ade80dc8

b/hw/virtio-pci.c
24 24
#include "net.h"
25 25
#include "block_int.h"
26 26
#include "loader.h"
27
#include "kvm.h"
27 28

  
28 29
/* from Linux's linux/virtio_pci.h */
29 30

  
......
415 416
    return proxy->host_features;
416 417
}
417 418

  
419
static void virtio_pci_guest_notifier_read(void *opaque)
420
{
421
    VirtQueue *vq = opaque;
422
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
423
    if (event_notifier_test_and_clear(n)) {
424
        virtio_irq(vq);
425
    }
426
}
427

  
428
static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
429
{
430
    VirtIOPCIProxy *proxy = opaque;
431
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
432
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
433

  
434
    if (assign) {
435
        int r = event_notifier_init(notifier, 0);
436
        if (r < 0) {
437
            return r;
438
        }
439
        qemu_set_fd_handler(event_notifier_get_fd(notifier),
440
                            virtio_pci_guest_notifier_read, NULL, vq);
441
    } else {
442
        qemu_set_fd_handler(event_notifier_get_fd(notifier),
443
                            NULL, NULL, NULL);
444
        event_notifier_cleanup(notifier);
445
    }
446

  
447
    return 0;
448
}
449

  
450
static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
451
{
452
    VirtIOPCIProxy *proxy = opaque;
453
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
454
    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
455
    int r;
456
    if (assign) {
457
        r = event_notifier_init(notifier, 1);
458
        if (r < 0) {
459
            return r;
460
        }
461
        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
462
                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
463
                                       n, assign);
464
        if (r < 0) {
465
            event_notifier_cleanup(notifier);
466
        }
467
    } else {
468
        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
469
                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
470
                                       n, assign);
471
        if (r < 0) {
472
            return r;
473
        }
474
        event_notifier_cleanup(notifier);
475
    }
476
    return r;
477
}
478

  
418 479
static const VirtIOBindings virtio_pci_bindings = {
419 480
    .notify = virtio_pci_notify,
420 481
    .save_config = virtio_pci_save_config,
......
422 483
    .save_queue = virtio_pci_save_queue,
423 484
    .load_queue = virtio_pci_load_queue,
424 485
    .get_features = virtio_pci_get_features,
486
    .set_host_notifier = virtio_pci_set_host_notifier,
487
    .set_guest_notifier = virtio_pci_set_guest_notifier,
425 488
};
426 489

  
427 490
static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,

Also available in: Unified diff