- rename to assigned_dev_set_msix_vectors - drop unused msg_ctrl - use pci_get_* accessors - rename variable va to msix_page - clarify comment on msg_data == 0 optimization - fix coding style Signed-off-by: Jan Kiszka <jan.kiszka@xxxxxxxxxxx> --- hw/device-assignment.c | 53 ++++++++++++++++++++++++++--------------------- 1 files changed, 29 insertions(+), 24 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 7a8f702..83951a3 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -949,42 +949,43 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev) } } -static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) +static int assigned_dev_set_msix_vectors(PCIDevice *pci_dev) { AssignedDevice *adev = DO_UPCAST(AssignedDevice, dev, pci_dev); uint16_t entries_nr = 0, entries_max_nr; int pos = 0, i, r = 0; - uint32_t msg_addr, msg_upper_addr, msg_data, msg_ctrl; + uint32_t msg_addr, msg_upper_addr, msg_data; struct kvm_assigned_msix_nr msix_nr; struct kvm_assigned_msix_entry msix_entry; - void *va = adev->msix_table_page; + void *msix_page = adev->msix_table_page; pos = pci_find_capability(pci_dev, PCI_CAP_ID_MSIX); - entries_max_nr = *(uint16_t *)(pci_dev->config + pos + 2); + entries_max_nr = pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS); entries_max_nr &= PCI_MSIX_FLAGS_QSIZE; entries_max_nr += 1; /* Get the usable entry number for allocating */ for (i = 0; i < entries_max_nr; i++) { - memcpy(&msg_ctrl, va + i * 16 + 12, 4); - memcpy(&msg_data, va + i * 16 + 8, 4); - /* Ignore unused entry even it's unmasked */ - if (msg_data == 0) + /* Assuming IA-32 MSI message format: + * Ignore unused entry (invalid vector) */ + if (pci_get_long(msix_page + i * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_DATA) == 0) { continue; - entries_nr ++; + } + entries_nr++; } - if (entries_nr == 0) { fprintf(stderr, "MSI-X entry number is zero!\n"); return -EINVAL; } + msix_nr.assigned_dev_id = calc_assigned_dev_id(adev); msix_nr.entry_nr = entries_nr; r = kvm_assign_set_msix_nr(kvm_state, &msix_nr); if (r != 0) { fprintf(stderr, "fail to set MSI-X entry number for MSIX! %s\n", - strerror(-r)); + strerror(-r)); return r; } @@ -995,19 +996,23 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) msix_entry.assigned_dev_id = msix_nr.assigned_dev_id; entries_nr = 0; for (i = 0; i < entries_max_nr; i++) { - if (entries_nr >= msix_nr.entry_nr) + if (entries_nr >= msix_nr.entry_nr) { break; - memcpy(&msg_ctrl, va + i * 16 + 12, 4); - memcpy(&msg_data, va + i * 16 + 8, 4); - if (msg_data == 0) + } + msg_data = pci_get_long(msix_page + i * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_DATA); + if (msg_data == 0) { continue; - - memcpy(&msg_addr, va + i * 16, 4); - memcpy(&msg_upper_addr, va + i * 16 + 4, 4); + } + msg_addr = pci_get_long(msix_page + i * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_LOWER_ADDR); + msg_upper_addr = pci_get_long(msix_page + i * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_UPPER_ADDR); r = kvm_get_irq_route_gsi(); - if (r < 0) + if (r < 0) { return r; + } adev->entry[entries_nr].gsi = r; adev->entry[entries_nr].type = KVM_IRQ_ROUTING_MSI; @@ -1026,13 +1031,13 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) break; } DEBUG("MSI-X entry gsi 0x%x, entry %d\n!", - msix_entry.gsi, msix_entry.entry); - entries_nr ++; + msix_entry.gsi, msix_entry.entry); + entries_nr++; } if (r == 0 && kvm_commit_irq_routes() < 0) { - perror("assigned_dev_update_msix_mmio: kvm_commit_irq_routes"); - return -EINVAL; + perror("assigned_dev_update_msix_mmio: kvm_commit_irq_routes"); + return -EINVAL; } return r; @@ -1070,7 +1075,7 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev) assigned_irq_data.flags = KVM_DEV_IRQ_HOST_MSIX | KVM_DEV_IRQ_GUEST_MSIX; - if (assigned_dev_update_msix_mmio(pci_dev) < 0) { + if (assigned_dev_set_msix_vectors(pci_dev) < 0) { perror("assigned_dev_update_msix_mmio"); return; } -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html