static void msix_handle_mask_update(PCIDevice *dev, int vector) { if (!msix_is_masked(dev, vector) && msix_is_pending(dev, vector)) { msix_clr_pending(dev, vector); msix_notify(dev, vector); } }
/* Invoke the notifier if vector entry is used and unmasked. */ static int msix_notify_if_unmasked(PCIDevice *dev, unsigned vector, int masked) { assert(dev->msix_mask_notifier); if (!dev->msix_entry_used[vector] || msix_is_masked(dev, vector)) { return 0; } return dev->msix_mask_notifier(dev, vector, masked); }
static void msix_mmio_write(void *opaque, target_phys_addr_t addr, uint64_t val, unsigned size) { PCIDevice *dev = opaque; unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3; int vector = offset / PCI_MSIX_ENTRY_SIZE; int was_masked = msix_is_masked(dev, vector); pci_set_long(dev->msix_table_page + offset, val); if (kvm_enabled() && kvm_irqchip_in_kernel()) { kvm_msix_update(dev, vector, was_masked, msix_is_masked(dev, vector)); } if (was_masked != msix_is_masked(dev, vector) && dev->msix_mask_notifier) { int r = dev->msix_mask_notifier(dev, vector, msix_is_masked(dev, vector)); assert(r >= 0); } msix_handle_mask_update(dev, vector); }
static int msix_set_notifier_for_vector(PCIDevice *dev, unsigned int vector) { MSIMessage msg; if (msix_is_masked(dev, vector)) { return 0; } msg = msix_get_message(dev, vector); return dev->msix_vector_use_notifier(dev, vector, msg); }
static void msix_table_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { PCIDevice *dev = opaque; int vector = addr / PCI_MSIX_ENTRY_SIZE; bool was_masked; was_masked = msix_is_masked(dev, vector); pci_set_long(dev->msix_table + addr, val); msix_handle_mask_update(dev, vector, was_masked); }
static void msix_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) { PCIDevice *dev = opaque; unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3; int vector = offset / MSIX_ENTRY_SIZE; pci_set_long(dev->msix_table_page + offset, val); if (!msix_is_masked(dev, vector) && msix_is_pending(dev, vector)) { msix_clr_pending(dev, vector); msix_notify(dev, vector); } }
static void msix_mask_all(struct PCIDevice *dev, unsigned nentries) { int vector; for (vector = 0; vector < nentries; ++vector) { unsigned offset = vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL; bool was_masked = msix_is_masked(dev, vector); dev->msix_table[offset] |= PCI_MSIX_ENTRY_CTRL_MASKBIT; msix_handle_mask_update(dev, vector, was_masked); } }
/* Send an MSI-X message */ void msix_notify(PCIDevice *dev, unsigned vector) { MSIMessage msg; //fprintf(stdout, "qemu:msix: msix_notify \n"); if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) return; if (msix_is_masked(dev, vector)) { msix_set_pending(dev, vector); return; } msg = msix_get_message(dev, vector); stl_le_phys(msg.address, msg.data); }
static void msix_handle_mask_update(PCIDevice *dev, int vector, bool was_masked) { bool is_masked = msix_is_masked(dev, vector); if (is_masked == was_masked) { return; } msix_fire_vector_notifier(dev, vector, is_masked); if (!is_masked && msix_is_pending(dev, vector)) { msix_clr_pending(dev, vector); msix_notify(dev, vector); } }
/* Send an MSI-X message */ void msix_notify(PCIDevice *dev, unsigned vector) { MSIMessage msg; if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) return; if (msix_is_masked(dev, vector)) { msix_set_pending(dev, vector); return; } msg = msix_get_message(dev, vector); msi_send_message(dev, msg); }
/* Send an MSI-X message */ void msix_notify(PCIDevice *dev, unsigned vector) { MSIMessage msg; if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) return; if (msix_is_masked(dev, vector)) { msix_set_pending(dev, vector); return; } msg = msix_get_message(dev, vector); address_space_stl_le(&dev->bus_master_as, msg.address, msg.data, MEMTXATTRS_UNSPECIFIED, NULL); }
/* Send an MSI-X message */ void msix_notify(PCIDevice *dev, unsigned vector) { uint8_t *table_entry = dev->msix_table_page + vector * PCI_MSIX_ENTRY_SIZE; uint64_t address; uint32_t data; if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) return; if (msix_is_masked(dev, vector)) { msix_set_pending(dev, vector); return; } address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR); data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA); stl_le_phys(address, data); }
static void ivshmem_vector_poll(PCIDevice *dev, unsigned int vector_start, unsigned int vector_end) { IVShmemState *s = IVSHMEM_COMMON(dev); unsigned int vector; IVSHMEM_DPRINTF("vector poll %p %d-%d\n", dev, vector_start, vector_end); vector_end = MIN(vector_end, s->vectors); for (vector = vector_start; vector < vector_end; vector++) { EventNotifier *notifier = &s->peers[s->vm_id].eventfds[vector]; if (!msix_is_masked(dev, vector)) { continue; } if (event_notifier_test_and_clear(notifier)) { msix_set_pending(dev, vector); } } }