Revision 54dd9321

b/hw/vhost.c
454 454
    };
455 455
    struct VirtQueue *vvq = virtio_get_queue(vdev, idx);
456 456

  
457
    if (!vdev->binding->set_guest_notifier) {
458
        fprintf(stderr, "binding does not support guest notifiers\n");
459
        return -ENOSYS;
460
    }
461

  
462 457
    if (!vdev->binding->set_host_notifier) {
463 458
        fprintf(stderr, "binding does not support host notifiers\n");
464 459
        return -ENOSYS;
......
511 506
        r = -errno;
512 507
        goto fail_alloc;
513 508
    }
514
    r = vdev->binding->set_guest_notifier(vdev->binding_opaque, idx, true);
515
    if (r < 0) {
516
        fprintf(stderr, "Error binding guest notifier: %d\n", -r);
517
        goto fail_guest_notifier;
518
    }
519

  
520 509
    r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, true);
521 510
    if (r < 0) {
522 511
        fprintf(stderr, "Error binding host notifier: %d\n", -r);
......
541 530
fail_kick:
542 531
    vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false);
543 532
fail_host_notifier:
544
    vdev->binding->set_guest_notifier(vdev->binding_opaque, idx, false);
545
fail_guest_notifier:
546 533
fail_alloc:
547 534
    cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
548 535
                              0, 0);
......
568 555
        .index = idx,
569 556
    };
570 557
    int r;
571
    r = vdev->binding->set_guest_notifier(vdev->binding_opaque, idx, false);
572
    if (r < 0) {
573
        fprintf(stderr, "vhost VQ %d guest cleanup failed: %d\n", idx, r);
574
        fflush(stderr);
575
    }
576
    assert (r >= 0);
577

  
578 558
    r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false);
579 559
    if (r < 0) {
580 560
        fprintf(stderr, "vhost VQ %d host cleanup failed: %d\n", idx, r);
......
647 627
int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
648 628
{
649 629
    int i, r;
630
    if (!vdev->binding->set_guest_notifiers) {
631
        fprintf(stderr, "binding does not support guest notifiers\n");
632
        r = -ENOSYS;
633
        goto fail;
634
    }
635

  
636
    r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, true);
637
    if (r < 0) {
638
        fprintf(stderr, "Error binding guest notifier: %d\n", -r);
639
        goto fail_notifiers;
640
    }
650 641

  
651 642
    r = vhost_dev_set_features(hdev, hdev->log_enabled);
652 643
    if (r < 0) {
653
        goto fail;
644
        goto fail_features;
654 645
    }
655 646
    r = ioctl(hdev->control, VHOST_SET_MEM_TABLE, hdev->mem);
656 647
    if (r < 0) {
657 648
        r = -errno;
658
        goto fail;
649
        goto fail_mem;
659 650
    }
660 651
    for (i = 0; i < hdev->nvqs; ++i) {
661 652
        r = vhost_virtqueue_init(hdev,
......
675 666
                  (uint64_t)(unsigned long)hdev->log);
676 667
        if (r < 0) {
677 668
            r = -errno;
678
            goto fail_vq;
669
            goto fail_log;
679 670
        }
680 671
    }
681 672

  
682 673
    hdev->started = true;
683 674

  
684 675
    return 0;
676
fail_log:
685 677
fail_vq:
686 678
    while (--i >= 0) {
687 679
        vhost_virtqueue_cleanup(hdev,
......
689 681
                                hdev->vqs + i,
690 682
                                i);
691 683
    }
684
fail_mem:
685
fail_features:
686
    vdev->binding->set_guest_notifiers(vdev->binding_opaque, false);
687
fail_notifiers:
692 688
fail:
693 689
    return r;
694 690
}
695 691

  
696 692
void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
697 693
{
698
    int i;
694
    int i, r;
695

  
699 696
    for (i = 0; i < hdev->nvqs; ++i) {
700 697
        vhost_virtqueue_cleanup(hdev,
701 698
                                vdev,
......
704 701
    }
705 702
    vhost_client_sync_dirty_bitmap(&hdev->client, 0,
706 703
                                   (target_phys_addr_t)~0x0ull);
704
    r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, false);
705
    if (r < 0) {
706
        fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);
707
        fflush(stderr);
708
    }
709
    assert (r >= 0);
710

  
707 711
    hdev->started = false;
708 712
    qemu_free(hdev->log);
709 713
    hdev->log_size = 0;
b/hw/virtio-pci.c
451 451
    return 0;
452 452
}
453 453

  
454
static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
455
{
456
    VirtIOPCIProxy *proxy = opaque;
457
    VirtIODevice *vdev = proxy->vdev;
458
    int r, n;
459

  
460
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
461
        if (!virtio_queue_get_num(vdev, n)) {
462
            break;
463
        }
464

  
465
        r = virtio_pci_set_guest_notifier(opaque, n, assign);
466
        if (r < 0) {
467
            goto assign_error;
468
        }
469
    }
470

  
471
    return 0;
472

  
473
assign_error:
474
    /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
475
    while (--n >= 0) {
476
        virtio_pci_set_guest_notifier(opaque, n, !assign);
477
    }
478
    return r;
479
}
480

  
454 481
static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
455 482
{
456 483
    VirtIOPCIProxy *proxy = opaque;
......
488 515
    .load_queue = virtio_pci_load_queue,
489 516
    .get_features = virtio_pci_get_features,
490 517
    .set_host_notifier = virtio_pci_set_host_notifier,
491
    .set_guest_notifier = virtio_pci_set_guest_notifier,
518
    .set_guest_notifiers = virtio_pci_set_guest_notifiers,
492 519
};
493 520

  
494 521
static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
b/hw/virtio.h
93 93
    int (*load_config)(void * opaque, QEMUFile *f);
94 94
    int (*load_queue)(void * opaque, int n, QEMUFile *f);
95 95
    unsigned (*get_features)(void * opaque);
96
    int (*set_guest_notifier)(void * opaque, int n, bool assigned);
96
    int (*set_guest_notifiers)(void * opaque, bool assigned);
97 97
    int (*set_host_notifier)(void * opaque, int n, bool assigned);
98 98
} VirtIOBindings;
99 99

  

Also available in: Unified diff