@@ -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;
}
- 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@siemens.com> --- hw/device-assignment.c | 53 ++++++++++++++++++++++++++--------------------- 1 files changed, 29 insertions(+), 24 deletions(-)