qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

msix.c (20505B)


      1 /*
      2  * MSI-X device support
      3  *
      4  * This module includes support for MSI-X in pci devices.
      5  *
      6  * Author: Michael S. Tsirkin <mst@redhat.com>
      7  *
      8  *  Copyright (c) 2009, Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)
      9  *
     10  * This work is licensed under the terms of the GNU GPL, version 2.  See
     11  * the COPYING file in the top-level directory.
     12  *
     13  * Contributions after 2012-01-13 are licensed under the terms of the
     14  * GNU GPL, version 2 or (at your option) any later version.
     15  */
     16 
     17 #include "qemu/osdep.h"
     18 #include "hw/pci/msi.h"
     19 #include "hw/pci/msix.h"
     20 #include "hw/pci/pci.h"
     21 #include "hw/xen/xen.h"
     22 #include "sysemu/xen.h"
     23 #include "migration/qemu-file-types.h"
     24 #include "migration/vmstate.h"
     25 #include "qemu/range.h"
     26 #include "qapi/error.h"
     27 #include "trace.h"
     28 
     29 /* MSI enable bit and maskall bit are in byte 1 in FLAGS register */
     30 #define MSIX_CONTROL_OFFSET (PCI_MSIX_FLAGS + 1)
     31 #define MSIX_ENABLE_MASK (PCI_MSIX_FLAGS_ENABLE >> 8)
     32 #define MSIX_MASKALL_MASK (PCI_MSIX_FLAGS_MASKALL >> 8)
     33 
     34 static MSIMessage msix_prepare_message(PCIDevice *dev, unsigned vector)
     35 {
     36     uint8_t *table_entry = dev->msix_table + vector * PCI_MSIX_ENTRY_SIZE;
     37     MSIMessage msg;
     38 
     39     msg.address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
     40     msg.data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
     41     return msg;
     42 }
     43 
     44 MSIMessage msix_get_message(PCIDevice *dev, unsigned vector)
     45 {
     46     return dev->msix_prepare_message(dev, vector);
     47 }
     48 
     49 /*
     50  * Special API for POWER to configure the vectors through
     51  * a side channel. Should never be used by devices.
     52  */
     53 void msix_set_message(PCIDevice *dev, int vector, struct MSIMessage msg)
     54 {
     55     uint8_t *table_entry = dev->msix_table + vector * PCI_MSIX_ENTRY_SIZE;
     56 
     57     pci_set_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR, msg.address);
     58     pci_set_long(table_entry + PCI_MSIX_ENTRY_DATA, msg.data);
     59     table_entry[PCI_MSIX_ENTRY_VECTOR_CTRL] &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
     60 }
     61 
     62 static uint8_t msix_pending_mask(int vector)
     63 {
     64     return 1 << (vector % 8);
     65 }
     66 
     67 static uint8_t *msix_pending_byte(PCIDevice *dev, int vector)
     68 {
     69     return dev->msix_pba + vector / 8;
     70 }
     71 
     72 static int msix_is_pending(PCIDevice *dev, int vector)
     73 {
     74     return *msix_pending_byte(dev, vector) & msix_pending_mask(vector);
     75 }
     76 
     77 void msix_set_pending(PCIDevice *dev, unsigned int vector)
     78 {
     79     *msix_pending_byte(dev, vector) |= msix_pending_mask(vector);
     80 }
     81 
     82 void msix_clr_pending(PCIDevice *dev, int vector)
     83 {
     84     *msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector);
     85 }
     86 
     87 static bool msix_vector_masked(PCIDevice *dev, unsigned int vector, bool fmask)
     88 {
     89     unsigned offset = vector * PCI_MSIX_ENTRY_SIZE;
     90     uint8_t *data = &dev->msix_table[offset + PCI_MSIX_ENTRY_DATA];
     91     /* MSIs on Xen can be remapped into pirqs. In those cases, masking
     92      * and unmasking go through the PV evtchn path. */
     93     if (xen_enabled() && xen_is_pirq_msi(pci_get_long(data))) {
     94         return false;
     95     }
     96     return fmask || dev->msix_table[offset + PCI_MSIX_ENTRY_VECTOR_CTRL] &
     97         PCI_MSIX_ENTRY_CTRL_MASKBIT;
     98 }
     99 
    100 bool msix_is_masked(PCIDevice *dev, unsigned int vector)
    101 {
    102     return msix_vector_masked(dev, vector, dev->msix_function_masked);
    103 }
    104 
    105 static void msix_fire_vector_notifier(PCIDevice *dev,
    106                                       unsigned int vector, bool is_masked)
    107 {
    108     MSIMessage msg;
    109     int ret;
    110 
    111     if (!dev->msix_vector_use_notifier) {
    112         return;
    113     }
    114     if (is_masked) {
    115         dev->msix_vector_release_notifier(dev, vector);
    116     } else {
    117         msg = msix_get_message(dev, vector);
    118         ret = dev->msix_vector_use_notifier(dev, vector, msg);
    119         assert(ret >= 0);
    120     }
    121 }
    122 
    123 static void msix_handle_mask_update(PCIDevice *dev, int vector, bool was_masked)
    124 {
    125     bool is_masked = msix_is_masked(dev, vector);
    126 
    127     if (is_masked == was_masked) {
    128         return;
    129     }
    130 
    131     msix_fire_vector_notifier(dev, vector, is_masked);
    132 
    133     if (!is_masked && msix_is_pending(dev, vector)) {
    134         msix_clr_pending(dev, vector);
    135         msix_notify(dev, vector);
    136     }
    137 }
    138 
    139 void msix_set_mask(PCIDevice *dev, int vector, bool mask)
    140 {
    141     unsigned offset;
    142     bool was_masked;
    143 
    144     assert(vector < dev->msix_entries_nr);
    145 
    146     offset = vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
    147 
    148     was_masked = msix_is_masked(dev, vector);
    149 
    150     if (mask) {
    151         dev->msix_table[offset] |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
    152     } else {
    153         dev->msix_table[offset] &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
    154     }
    155 
    156     msix_handle_mask_update(dev, vector, was_masked);
    157 }
    158 
    159 static bool msix_masked(PCIDevice *dev)
    160 {
    161     return dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK;
    162 }
    163 
    164 static void msix_update_function_masked(PCIDevice *dev)
    165 {
    166     dev->msix_function_masked = !msix_enabled(dev) || msix_masked(dev);
    167 }
    168 
    169 /* Handle MSI-X capability config write. */
    170 void msix_write_config(PCIDevice *dev, uint32_t addr,
    171                        uint32_t val, int len)
    172 {
    173     unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET;
    174     int vector;
    175     bool was_masked;
    176 
    177     if (!msix_present(dev) || !range_covers_byte(addr, len, enable_pos)) {
    178         return;
    179     }
    180 
    181     trace_msix_write_config(dev->name, msix_enabled(dev), msix_masked(dev));
    182 
    183     was_masked = dev->msix_function_masked;
    184     msix_update_function_masked(dev);
    185 
    186     if (!msix_enabled(dev)) {
    187         return;
    188     }
    189 
    190     pci_device_deassert_intx(dev);
    191 
    192     if (dev->msix_function_masked == was_masked) {
    193         return;
    194     }
    195 
    196     for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
    197         msix_handle_mask_update(dev, vector,
    198                                 msix_vector_masked(dev, vector, was_masked));
    199     }
    200 }
    201 
    202 static uint64_t msix_table_mmio_read(void *opaque, hwaddr addr,
    203                                      unsigned size)
    204 {
    205     PCIDevice *dev = opaque;
    206 
    207     assert(addr + size <= dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
    208     return pci_get_long(dev->msix_table + addr);
    209 }
    210 
    211 static void msix_table_mmio_write(void *opaque, hwaddr addr,
    212                                   uint64_t val, unsigned size)
    213 {
    214     PCIDevice *dev = opaque;
    215     int vector = addr / PCI_MSIX_ENTRY_SIZE;
    216     bool was_masked;
    217 
    218     assert(addr + size <= dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
    219 
    220     was_masked = msix_is_masked(dev, vector);
    221     pci_set_long(dev->msix_table + addr, val);
    222     msix_handle_mask_update(dev, vector, was_masked);
    223 }
    224 
    225 static const MemoryRegionOps msix_table_mmio_ops = {
    226     .read = msix_table_mmio_read,
    227     .write = msix_table_mmio_write,
    228     .endianness = DEVICE_LITTLE_ENDIAN,
    229     .valid = {
    230         .min_access_size = 4,
    231         .max_access_size = 8,
    232     },
    233     .impl = {
    234         .max_access_size = 4,
    235     },
    236 };
    237 
    238 static uint64_t msix_pba_mmio_read(void *opaque, hwaddr addr,
    239                                    unsigned size)
    240 {
    241     PCIDevice *dev = opaque;
    242     if (dev->msix_vector_poll_notifier) {
    243         unsigned vector_start = addr * 8;
    244         unsigned vector_end = MIN(addr + size * 8, dev->msix_entries_nr);
    245         dev->msix_vector_poll_notifier(dev, vector_start, vector_end);
    246     }
    247 
    248     return pci_get_long(dev->msix_pba + addr);
    249 }
    250 
    251 static void msix_pba_mmio_write(void *opaque, hwaddr addr,
    252                                 uint64_t val, unsigned size)
    253 {
    254 }
    255 
    256 static const MemoryRegionOps msix_pba_mmio_ops = {
    257     .read = msix_pba_mmio_read,
    258     .write = msix_pba_mmio_write,
    259     .endianness = DEVICE_LITTLE_ENDIAN,
    260     .valid = {
    261         .min_access_size = 4,
    262         .max_access_size = 8,
    263     },
    264     .impl = {
    265         .max_access_size = 4,
    266     },
    267 };
    268 
    269 static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
    270 {
    271     int vector;
    272 
    273     for (vector = 0; vector < nentries; ++vector) {
    274         unsigned offset =
    275             vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
    276         bool was_masked = msix_is_masked(dev, vector);
    277 
    278         dev->msix_table[offset] |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
    279         msix_handle_mask_update(dev, vector, was_masked);
    280     }
    281 }
    282 
    283 /*
    284  * Make PCI device @dev MSI-X capable
    285  * @nentries is the max number of MSI-X vectors that the device support.
    286  * @table_bar is the MemoryRegion that MSI-X table structure resides.
    287  * @table_bar_nr is number of base address register corresponding to @table_bar.
    288  * @table_offset indicates the offset that the MSI-X table structure starts with
    289  * in @table_bar.
    290  * @pba_bar is the MemoryRegion that the Pending Bit Array structure resides.
    291  * @pba_bar_nr is number of base address register corresponding to @pba_bar.
    292  * @pba_offset indicates the offset that the Pending Bit Array structure
    293  * starts with in @pba_bar.
    294  * Non-zero @cap_pos puts capability MSI-X at that offset in PCI config space.
    295  * @errp is for returning errors.
    296  *
    297  * Return 0 on success; set @errp and return -errno on error:
    298  * -ENOTSUP means lacking msi support for a msi-capable platform.
    299  * -EINVAL means capability overlap, happens when @cap_pos is non-zero,
    300  * also means a programming error, except device assignment, which can check
    301  * if a real HW is broken.
    302  */
    303 int msix_init(struct PCIDevice *dev, unsigned short nentries,
    304               MemoryRegion *table_bar, uint8_t table_bar_nr,
    305               unsigned table_offset, MemoryRegion *pba_bar,
    306               uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos,
    307               Error **errp)
    308 {
    309     int cap;
    310     unsigned table_size, pba_size;
    311     uint8_t *config;
    312 
    313     /* Nothing to do if MSI is not supported by interrupt controller */
    314     if (!msi_nonbroken) {
    315         error_setg(errp, "MSI-X is not supported by interrupt controller");
    316         return -ENOTSUP;
    317     }
    318 
    319     if (nentries < 1 || nentries > PCI_MSIX_FLAGS_QSIZE + 1) {
    320         error_setg(errp, "The number of MSI-X vectors is invalid");
    321         return -EINVAL;
    322     }
    323 
    324     table_size = nentries * PCI_MSIX_ENTRY_SIZE;
    325     pba_size = QEMU_ALIGN_UP(nentries, 64) / 8;
    326 
    327     /* Sanity test: table & pba don't overlap, fit within BARs, min aligned */
    328     if ((table_bar_nr == pba_bar_nr &&
    329          ranges_overlap(table_offset, table_size, pba_offset, pba_size)) ||
    330         table_offset + table_size > memory_region_size(table_bar) ||
    331         pba_offset + pba_size > memory_region_size(pba_bar) ||
    332         (table_offset | pba_offset) & PCI_MSIX_FLAGS_BIRMASK) {
    333         error_setg(errp, "table & pba overlap, or they don't fit in BARs,"
    334                    " or don't align");
    335         return -EINVAL;
    336     }
    337 
    338     cap = pci_add_capability(dev, PCI_CAP_ID_MSIX,
    339                               cap_pos, MSIX_CAP_LENGTH, errp);
    340     if (cap < 0) {
    341         return cap;
    342     }
    343 
    344     dev->msix_cap = cap;
    345     dev->cap_present |= QEMU_PCI_CAP_MSIX;
    346     config = dev->config + cap;
    347 
    348     pci_set_word(config + PCI_MSIX_FLAGS, nentries - 1);
    349     dev->msix_entries_nr = nentries;
    350     dev->msix_function_masked = true;
    351 
    352     pci_set_long(config + PCI_MSIX_TABLE, table_offset | table_bar_nr);
    353     pci_set_long(config + PCI_MSIX_PBA, pba_offset | pba_bar_nr);
    354 
    355     /* Make flags bit writable. */
    356     dev->wmask[cap + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |
    357                                              MSIX_MASKALL_MASK;
    358 
    359     dev->msix_table = g_malloc0(table_size);
    360     dev->msix_pba = g_malloc0(pba_size);
    361     dev->msix_entry_used = g_malloc0(nentries * sizeof *dev->msix_entry_used);
    362 
    363     msix_mask_all(dev, nentries);
    364 
    365     memory_region_init_io(&dev->msix_table_mmio, OBJECT(dev), &msix_table_mmio_ops, dev,
    366                           "msix-table", table_size);
    367     memory_region_add_subregion(table_bar, table_offset, &dev->msix_table_mmio);
    368     memory_region_init_io(&dev->msix_pba_mmio, OBJECT(dev), &msix_pba_mmio_ops, dev,
    369                           "msix-pba", pba_size);
    370     memory_region_add_subregion(pba_bar, pba_offset, &dev->msix_pba_mmio);
    371 
    372     dev->msix_prepare_message = msix_prepare_message;
    373 
    374     return 0;
    375 }
    376 
    377 int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
    378                             uint8_t bar_nr, Error **errp)
    379 {
    380     int ret;
    381     char *name;
    382     uint32_t bar_size = 4096;
    383     uint32_t bar_pba_offset = bar_size / 2;
    384     uint32_t bar_pba_size = QEMU_ALIGN_UP(nentries, 64) / 8;
    385 
    386     /*
    387      * Migration compatibility dictates that this remains a 4k
    388      * BAR with the vector table in the lower half and PBA in
    389      * the upper half for nentries which is lower or equal to 128.
    390      * No need to care about using more than 65 entries for legacy
    391      * machine types who has at most 64 queues.
    392      */
    393     if (nentries * PCI_MSIX_ENTRY_SIZE > bar_pba_offset) {
    394         bar_pba_offset = nentries * PCI_MSIX_ENTRY_SIZE;
    395     }
    396 
    397     if (bar_pba_offset + bar_pba_size > 4096) {
    398         bar_size = bar_pba_offset + bar_pba_size;
    399     }
    400 
    401     bar_size = pow2ceil(bar_size);
    402 
    403     name = g_strdup_printf("%s-msix", dev->name);
    404     memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, bar_size);
    405     g_free(name);
    406 
    407     ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr,
    408                     0, &dev->msix_exclusive_bar,
    409                     bar_nr, bar_pba_offset,
    410                     0, errp);
    411     if (ret) {
    412         return ret;
    413     }
    414 
    415     pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY,
    416                      &dev->msix_exclusive_bar);
    417 
    418     return 0;
    419 }
    420 
    421 static void msix_free_irq_entries(PCIDevice *dev)
    422 {
    423     int vector;
    424 
    425     for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
    426         dev->msix_entry_used[vector] = 0;
    427         msix_clr_pending(dev, vector);
    428     }
    429 }
    430 
    431 static void msix_clear_all_vectors(PCIDevice *dev)
    432 {
    433     int vector;
    434 
    435     for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
    436         msix_clr_pending(dev, vector);
    437     }
    438 }
    439 
    440 /* Clean up resources for the device. */
    441 void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar)
    442 {
    443     if (!msix_present(dev)) {
    444         return;
    445     }
    446     pci_del_capability(dev, PCI_CAP_ID_MSIX, MSIX_CAP_LENGTH);
    447     dev->msix_cap = 0;
    448     msix_free_irq_entries(dev);
    449     dev->msix_entries_nr = 0;
    450     memory_region_del_subregion(pba_bar, &dev->msix_pba_mmio);
    451     g_free(dev->msix_pba);
    452     dev->msix_pba = NULL;
    453     memory_region_del_subregion(table_bar, &dev->msix_table_mmio);
    454     g_free(dev->msix_table);
    455     dev->msix_table = NULL;
    456     g_free(dev->msix_entry_used);
    457     dev->msix_entry_used = NULL;
    458     dev->cap_present &= ~QEMU_PCI_CAP_MSIX;
    459     dev->msix_prepare_message = NULL;
    460 }
    461 
    462 void msix_uninit_exclusive_bar(PCIDevice *dev)
    463 {
    464     if (msix_present(dev)) {
    465         msix_uninit(dev, &dev->msix_exclusive_bar, &dev->msix_exclusive_bar);
    466     }
    467 }
    468 
    469 void msix_save(PCIDevice *dev, QEMUFile *f)
    470 {
    471     unsigned n = dev->msix_entries_nr;
    472 
    473     if (!msix_present(dev)) {
    474         return;
    475     }
    476 
    477     qemu_put_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE);
    478     qemu_put_buffer(f, dev->msix_pba, DIV_ROUND_UP(n, 8));
    479 }
    480 
    481 /* Should be called after restoring the config space. */
    482 void msix_load(PCIDevice *dev, QEMUFile *f)
    483 {
    484     unsigned n = dev->msix_entries_nr;
    485     unsigned int vector;
    486 
    487     if (!msix_present(dev)) {
    488         return;
    489     }
    490 
    491     msix_clear_all_vectors(dev);
    492     qemu_get_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE);
    493     qemu_get_buffer(f, dev->msix_pba, DIV_ROUND_UP(n, 8));
    494     msix_update_function_masked(dev);
    495 
    496     for (vector = 0; vector < n; vector++) {
    497         msix_handle_mask_update(dev, vector, true);
    498     }
    499 }
    500 
    501 /* Does device support MSI-X? */
    502 int msix_present(PCIDevice *dev)
    503 {
    504     return dev->cap_present & QEMU_PCI_CAP_MSIX;
    505 }
    506 
    507 /* Is MSI-X enabled? */
    508 int msix_enabled(PCIDevice *dev)
    509 {
    510     return (dev->cap_present & QEMU_PCI_CAP_MSIX) &&
    511         (dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
    512          MSIX_ENABLE_MASK);
    513 }
    514 
    515 /* Send an MSI-X message */
    516 void msix_notify(PCIDevice *dev, unsigned vector)
    517 {
    518     MSIMessage msg;
    519 
    520     assert(vector < dev->msix_entries_nr);
    521 
    522     if (!dev->msix_entry_used[vector]) {
    523         return;
    524     }
    525 
    526     if (msix_is_masked(dev, vector)) {
    527         msix_set_pending(dev, vector);
    528         return;
    529     }
    530 
    531     msg = msix_get_message(dev, vector);
    532 
    533     msi_send_message(dev, msg);
    534 }
    535 
    536 void msix_reset(PCIDevice *dev)
    537 {
    538     if (!msix_present(dev)) {
    539         return;
    540     }
    541     msix_clear_all_vectors(dev);
    542     dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
    543             ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
    544     memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
    545     memset(dev->msix_pba, 0, QEMU_ALIGN_UP(dev->msix_entries_nr, 64) / 8);
    546     msix_mask_all(dev, dev->msix_entries_nr);
    547 }
    548 
    549 /* PCI spec suggests that devices make it possible for software to configure
    550  * less vectors than supported by the device, but does not specify a standard
    551  * mechanism for devices to do so.
    552  *
    553  * We support this by asking devices to declare vectors software is going to
    554  * actually use, and checking this on the notification path. Devices that
    555  * don't want to follow the spec suggestion can declare all vectors as used. */
    556 
    557 /* Mark vector as used. */
    558 void msix_vector_use(PCIDevice *dev, unsigned vector)
    559 {
    560     assert(vector < dev->msix_entries_nr);
    561     dev->msix_entry_used[vector]++;
    562 }
    563 
    564 /* Mark vector as unused. */
    565 void msix_vector_unuse(PCIDevice *dev, unsigned vector)
    566 {
    567     assert(vector < dev->msix_entries_nr);
    568     if (!dev->msix_entry_used[vector]) {
    569         return;
    570     }
    571     if (--dev->msix_entry_used[vector]) {
    572         return;
    573     }
    574     msix_clr_pending(dev, vector);
    575 }
    576 
    577 void msix_unuse_all_vectors(PCIDevice *dev)
    578 {
    579     if (!msix_present(dev)) {
    580         return;
    581     }
    582     msix_free_irq_entries(dev);
    583 }
    584 
    585 unsigned int msix_nr_vectors_allocated(const PCIDevice *dev)
    586 {
    587     return dev->msix_entries_nr;
    588 }
    589 
    590 static int msix_set_notifier_for_vector(PCIDevice *dev, unsigned int vector)
    591 {
    592     MSIMessage msg;
    593 
    594     if (msix_is_masked(dev, vector)) {
    595         return 0;
    596     }
    597     msg = msix_get_message(dev, vector);
    598     return dev->msix_vector_use_notifier(dev, vector, msg);
    599 }
    600 
    601 static void msix_unset_notifier_for_vector(PCIDevice *dev, unsigned int vector)
    602 {
    603     if (msix_is_masked(dev, vector)) {
    604         return;
    605     }
    606     dev->msix_vector_release_notifier(dev, vector);
    607 }
    608 
    609 int msix_set_vector_notifiers(PCIDevice *dev,
    610                               MSIVectorUseNotifier use_notifier,
    611                               MSIVectorReleaseNotifier release_notifier,
    612                               MSIVectorPollNotifier poll_notifier)
    613 {
    614     int vector, ret;
    615 
    616     assert(use_notifier && release_notifier);
    617 
    618     dev->msix_vector_use_notifier = use_notifier;
    619     dev->msix_vector_release_notifier = release_notifier;
    620     dev->msix_vector_poll_notifier = poll_notifier;
    621 
    622     if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
    623         (MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
    624         for (vector = 0; vector < dev->msix_entries_nr; vector++) {
    625             ret = msix_set_notifier_for_vector(dev, vector);
    626             if (ret < 0) {
    627                 goto undo;
    628             }
    629         }
    630     }
    631     if (dev->msix_vector_poll_notifier) {
    632         dev->msix_vector_poll_notifier(dev, 0, dev->msix_entries_nr);
    633     }
    634     return 0;
    635 
    636 undo:
    637     while (--vector >= 0) {
    638         msix_unset_notifier_for_vector(dev, vector);
    639     }
    640     dev->msix_vector_use_notifier = NULL;
    641     dev->msix_vector_release_notifier = NULL;
    642     return ret;
    643 }
    644 
    645 void msix_unset_vector_notifiers(PCIDevice *dev)
    646 {
    647     int vector;
    648 
    649     assert(dev->msix_vector_use_notifier &&
    650            dev->msix_vector_release_notifier);
    651 
    652     if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
    653         (MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
    654         for (vector = 0; vector < dev->msix_entries_nr; vector++) {
    655             msix_unset_notifier_for_vector(dev, vector);
    656         }
    657     }
    658     dev->msix_vector_use_notifier = NULL;
    659     dev->msix_vector_release_notifier = NULL;
    660     dev->msix_vector_poll_notifier = NULL;
    661 }
    662 
    663 static int put_msix_state(QEMUFile *f, void *pv, size_t size,
    664                           const VMStateField *field, JSONWriter *vmdesc)
    665 {
    666     msix_save(pv, f);
    667 
    668     return 0;
    669 }
    670 
    671 static int get_msix_state(QEMUFile *f, void *pv, size_t size,
    672                           const VMStateField *field)
    673 {
    674     msix_load(pv, f);
    675     return 0;
    676 }
    677 
    678 static VMStateInfo vmstate_info_msix = {
    679     .name = "msix state",
    680     .get  = get_msix_state,
    681     .put  = put_msix_state,
    682 };
    683 
    684 const VMStateDescription vmstate_msix = {
    685     .name = "msix",
    686     .fields = (VMStateField[]) {
    687         {
    688             .name         = "msix",
    689             .version_id   = 0,
    690             .field_exists = NULL,
    691             .size         = 0,   /* ouch */
    692             .info         = &vmstate_info_msix,
    693             .flags        = VMS_SINGLE,
    694             .offset       = 0,
    695         },
    696         VMSTATE_END_OF_LIST()
    697     }
    698 };