static void ivshmem_setup_msi(IVShmemState * s) { int i; /* allocate the MSI-X vectors */ if (!msix_init(&s->dev, s->vectors, 1, 0)) { pci_register_bar(&s->dev, 1, msix_bar_size(&s->dev), PCI_BASE_ADDRESS_SPACE_MEMORY, msix_mmio_map); IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors); } else { IVSHMEM_DPRINTF("msix initialization failed\n"); exit(1); } /* 'activate' the vectors */ for (i = 0; i < s->vectors; i++) { msix_vector_use(&s->dev, i); } /* allocate Qemu char devices for receiving interrupts */ s->eventfd_table = qemu_mallocz(s->vectors * sizeof(EventfdEntry)); }
int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, uint8_t bar_nr) { int ret; char *name; uint32_t bar_size = 4096; uint32_t bar_pba_offset = bar_size / 2; uint32_t bar_pba_size = (nentries / 8 + 1) * 8; /* * Migration compatibility dictates that this remains a 4k * BAR with the vector table in the lower half and PBA in * the upper half for nentries which is lower or equal to 128. * No need to care about using more than 65 entries for legacy * machine types who has at most 64 queues. */ if (nentries * PCI_MSIX_ENTRY_SIZE > bar_pba_offset) { bar_pba_offset = nentries * PCI_MSIX_ENTRY_SIZE; } if (bar_pba_offset + bar_pba_size > 4096) { bar_size = bar_pba_offset + bar_pba_size; } if (bar_size & (bar_size - 1)) { bar_size = 1 << qemu_fls(bar_size); } name = g_strdup_printf("%s-msix", dev->name); memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, bar_size); g_free(name); ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr, 0, &dev->msix_exclusive_bar, bar_nr, bar_pba_offset, 0); if (ret) { return ret; } pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY, &dev->msix_exclusive_bar); return 0; }
static void e1000e_init_msix(E1000EState *s) { PCIDevice *d = PCI_DEVICE(s); int res = msix_init(PCI_DEVICE(s), E1000E_MSIX_VEC_NUM, &s->msix, E1000E_MSIX_IDX, E1000E_MSIX_TABLE, &s->msix, E1000E_MSIX_IDX, E1000E_MSIX_PBA, 0xA0, NULL); if (res < 0) { trace_e1000e_msix_init_fail(res); } else { if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) { msix_uninit(d, &s->msix, &s->msix); } } }
int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, uint8_t bar_nr) { int ret; char *name; /* * Migration compatibility dictates that this remains a 4k * BAR with the vector table in the lower half and PBA in * the upper half. Do not use these elsewhere! */ #define MSIX_EXCLUSIVE_BAR_SIZE 4096 #define MSIX_EXCLUSIVE_BAR_TABLE_OFFSET 0 #define MSIX_EXCLUSIVE_BAR_PBA_OFFSET (MSIX_EXCLUSIVE_BAR_SIZE / 2) #define MSIX_EXCLUSIVE_CAP_OFFSET 0 if (nentries * PCI_MSIX_ENTRY_SIZE > MSIX_EXCLUSIVE_BAR_PBA_OFFSET) { return -EINVAL; } name = g_strdup_printf("%s-msix", dev->name); memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, MSIX_EXCLUSIVE_BAR_SIZE); g_free(name); ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr, MSIX_EXCLUSIVE_BAR_TABLE_OFFSET, &dev->msix_exclusive_bar, bar_nr, MSIX_EXCLUSIVE_BAR_PBA_OFFSET, MSIX_EXCLUSIVE_CAP_OFFSET); if (ret) { memory_region_destroy(&dev->msix_exclusive_bar); return ret; } pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY, &dev->msix_exclusive_bar); return 0; }
static void ivshmem_setup_msi(IVShmemState * s) { int i; /* allocate the MSI-X vectors */ memory_region_init(&s->msix_bar, "ivshmem-msix", 4096); if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) { pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix_bar); IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors); } else { IVSHMEM_DPRINTF("msix initialization failed\n"); exit(1); } /* 'activate' the vectors */ for (i = 0; i < s->vectors; i++) { msix_vector_use(&s->dev, i); } /* allocate QEMU char devices for receiving interrupts */ s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry)); }