Revision fd704adc

b/hw/vfio_pci.c
72 72
    };
73 73

  
74 74
    ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
75

  
76
    vdev->interrupt = VFIO_INT_NONE;
77 75
}
78 76

  
79 77
/*
......
278 276

  
279 277
    g_free(irq_set);
280 278

  
281
    if (!ret) {
282
        vdev->interrupt = msix ? VFIO_INT_MSIX : VFIO_INT_MSI;
283
    }
284

  
285 279
    return ret;
286 280
}
287 281

  
......
296 290
            vdev->host.domain, vdev->host.bus, vdev->host.slot,
297 291
            vdev->host.function, nr);
298 292

  
299
    if (vdev->interrupt != VFIO_INT_MSIX) {
300
        vfio_disable_interrupts(vdev);
301
    }
302

  
303
    if (!vdev->msi_vectors) {
304
        vdev->msi_vectors = g_malloc0(vdev->msix->entries *
305
                                      sizeof(VFIOMSIVector));
306
    }
307

  
308 293
    vector = &vdev->msi_vectors[nr];
309 294
    vector->vdev = vdev;
310 295
    vector->use = true;
......
457 442
    pci_set_word(config + PCI_MSI_FLAGS, flags);
458 443
}
459 444

  
445
static void vfio_enable_msix(VFIODevice *vdev)
446
{
447
    vfio_disable_interrupts(vdev);
448

  
449
    vdev->msi_vectors = g_malloc0(vdev->msix->entries * sizeof(VFIOMSIVector));
450

  
451
    vdev->interrupt = VFIO_INT_MSIX;
452

  
453
    if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
454
                                  vfio_msix_vector_release)) {
455
        error_report("vfio: msix_set_vector_notifiers failed\n");
456
    }
457

  
458
    DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
459
            vdev->host.bus, vdev->host.slot, vdev->host.function);
460
}
461

  
460 462
static void vfio_enable_msi(VFIODevice *vdev)
461 463
{
462 464
    int ret, i;
......
529 531

  
530 532
    msi_set_qsize(&vdev->pdev, vdev->nr_vectors);
531 533

  
534
    vdev->interrupt = VFIO_INT_MSI;
535

  
532 536
    DPRINTF("%s(%04x:%02x:%02x.%x) Enabled %d MSI vectors\n", __func__,
533 537
            vdev->host.domain, vdev->host.bus, vdev->host.slot,
534 538
            vdev->host.function, vdev->nr_vectors);
535 539
}
536 540

  
537
static void vfio_disable_msi_x(VFIODevice *vdev, bool msix)
541
static void vfio_disable_msi_common(VFIODevice *vdev)
542
{
543
    g_free(vdev->msi_vectors);
544
    vdev->msi_vectors = NULL;
545
    vdev->nr_vectors = 0;
546
    vdev->interrupt = VFIO_INT_NONE;
547

  
548
    vfio_enable_intx(vdev);
549
}
550

  
551
static void vfio_disable_msix(VFIODevice *vdev)
552
{
553
    msix_unset_vector_notifiers(&vdev->pdev);
554

  
555
    if (vdev->nr_vectors) {
556
        vfio_disable_irqindex(vdev, VFIO_PCI_MSIX_IRQ_INDEX);
557
    }
558

  
559
    vfio_disable_msi_common(vdev);
560

  
561
    DPRINTF("%s(%04x:%02x:%02x.%x, msi%s)\n", __func__,
562
            vdev->host.domain, vdev->host.bus, vdev->host.slot,
563
            vdev->host.function, msix ? "x" : "");
564
}
565

  
566
static void vfio_disable_msi(VFIODevice *vdev)
538 567
{
539 568
    int i;
540 569

  
541
    vfio_disable_irqindex(vdev, msix ? VFIO_PCI_MSIX_IRQ_INDEX :
542
                                       VFIO_PCI_MSI_IRQ_INDEX);
570
    vfio_disable_irqindex(vdev, VFIO_PCI_MSI_IRQ_INDEX);
543 571

  
544 572
    for (i = 0; i < vdev->nr_vectors; i++) {
545 573
        VFIOMSIVector *vector = &vdev->msi_vectors[i];
......
558 586
                                NULL, NULL, NULL);
559 587
        }
560 588

  
561
        if (msix) {
562
            msix_vector_unuse(&vdev->pdev, i);
563
        }
564

  
565 589
        event_notifier_cleanup(&vector->interrupt);
566 590
    }
567 591

  
568
    g_free(vdev->msi_vectors);
569
    vdev->msi_vectors = NULL;
570
    vdev->nr_vectors = 0;
571

  
572
    if (!msix) {
573
        msi_set_qsize(&vdev->pdev, 0); /* Actually still means 1 vector */
574
    }
592
    vfio_disable_msi_common(vdev);
575 593

  
576
    DPRINTF("%s(%04x:%02x:%02x.%x, msi%s)\n", __func__,
577
            vdev->host.domain, vdev->host.bus, vdev->host.slot,
578
            vdev->host.function, msix ? "x" : "");
594
    msi_set_qsize(&vdev->pdev, 0); /* Actually still means 1 vector */
579 595

  
580
    vfio_enable_intx(vdev);
596
    DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
597
            vdev->host.bus, vdev->host.slot, vdev->host.function);
581 598
}
582 599

  
583 600
/*
......
763 780
        if (!was_enabled && is_enabled) {
764 781
            vfio_enable_msi(vdev);
765 782
        } else if (was_enabled && !is_enabled) {
766
            vfio_disable_msi_x(vdev, false);
783
            vfio_disable_msi(vdev);
767 784
        }
768 785
    }
769 786

  
......
776 793
        is_enabled = msix_enabled(pdev);
777 794

  
778 795
        if (!was_enabled && is_enabled) {
779
            /* vfio_msix_vector_use handles this automatically */
796
            vfio_enable_msix(vdev);
780 797
        } else if (was_enabled && !is_enabled) {
781
            vfio_disable_msi_x(vdev, true);
798
            vfio_disable_msix(vdev);
782 799
        }
783 800
    }
784 801
}
......
973 990
        vfio_disable_intx(vdev);
974 991
        break;
975 992
    case VFIO_INT_MSI:
976
        vfio_disable_msi_x(vdev, false);
993
        vfio_disable_msi(vdev);
977 994
        break;
978 995
    case VFIO_INT_MSIX:
979
        vfio_disable_msi_x(vdev, true);
996
        vfio_disable_msix(vdev);
980 997
        break;
981 998
    }
982 999
}
......
1094 1111
        return ret;
1095 1112
    }
1096 1113

  
1097
    ret = msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
1098
                                    vfio_msix_vector_release);
1099
    if (ret) {
1100
        error_report("vfio: msix_set_vector_notifiers failed %d\n", ret);
1101
        msix_uninit(&vdev->pdev, &vdev->bars[vdev->msix->table_bar].mem,
1102
                    &vdev->bars[vdev->msix->pba_bar].mem);
1103
        return ret;
1104
    }
1105

  
1106 1114
    return 0;
1107 1115
}
1108 1116

  
......
1111 1119
    msi_uninit(&vdev->pdev);
1112 1120

  
1113 1121
    if (vdev->msix) {
1114
        /* FIXME: Why can't unset just silently do nothing?? */
1115
        if (vdev->pdev.msix_vector_use_notifier &&
1116
            vdev->pdev.msix_vector_release_notifier) {
1117
            msix_unset_vector_notifiers(&vdev->pdev);
1118
        }
1119

  
1120 1122
        msix_uninit(&vdev->pdev, &vdev->bars[vdev->msix->table_bar].mem,
1121 1123
                    &vdev->bars[vdev->msix->pba_bar].mem);
1122 1124
    }

Also available in: Unified diff