This structure is not available when !CONFIG_KVM. While an incomplete type works if it's not used, you can't do address arithmetic on it. Use a new type kvm_msix_message instead. Signed-off-by: Avi Kivity <avi@xxxxxxxxxx> --- hw/msix.c | 60 ++++++++++++++++++++++++++++++++++++++++++------------------ hw/pci.h | 9 ++++++++- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/hw/msix.c b/hw/msix.c index 6abf059..e00fc6c 100644 --- a/hw/msix.c +++ b/hw/msix.c @@ -48,13 +48,29 @@ int msix_supported; #ifdef CONFIG_KVM + +static void kvm_msix_message_to_routing_entry(struct kvm_msix_message *kmm, + struct kvm_irq_routing_entry *e) +{ + e->type = KVM_IRQ_ROUTING_MSI; + e->flags = 0; + e->u.msi.address_lo = kmm->addr_lo; + e->u.msi.address_hi = kmm->addr_hi; + e->u.msi.data = kmm->data; +} + /* KVM specific MSIX helpers */ static void kvm_msix_free(PCIDevice *dev) { int vector, changed = 0; + struct kvm_msix_message *kmm; + struct kvm_irq_routing_entry entry; + for (vector = 0; vector < dev->msix_entries_nr; ++vector) { if (dev->msix_entry_used[vector]) { - kvm_del_routing_entry(&dev->msix_irq_entries[vector]); + kmm = &dev->msix_irq_entries[vector]; + kvm_msix_message_to_routing_entry(kmm, &entry); + kvm_del_routing_entry(&entry); changed = 1; } } @@ -63,21 +79,20 @@ static void kvm_msix_free(PCIDevice *dev) } } -static void kvm_msix_routing_entry(PCIDevice *dev, unsigned vector, - struct kvm_irq_routing_entry *entry) +static void kvm_msix_message_from_vector(PCIDevice *dev, unsigned vector, + struct kvm_msix_message *kmm) { uint8_t *table_entry = dev->msix_table_page + vector * MSIX_ENTRY_SIZE; - entry->type = KVM_IRQ_ROUTING_MSI; - entry->flags = 0; - entry->u.msi.address_lo = pci_get_long(table_entry + MSIX_MSG_ADDR); - entry->u.msi.address_hi = pci_get_long(table_entry + MSIX_MSG_UPPER_ADDR); - entry->u.msi.data = pci_get_long(table_entry + MSIX_MSG_DATA); + + kmm->addr_lo = pci_get_long(table_entry + MSIX_MSG_ADDR); + kmm->addr_hi = pci_get_long(table_entry + MSIX_MSG_UPPER_ADDR); + kmm->data = pci_get_long(table_entry + MSIX_MSG_DATA); } static void kvm_msix_update(PCIDevice *dev, int vector, int was_masked, int is_masked) { - struct kvm_irq_routing_entry e = {}, *entry; + struct kvm_msix_message e = {}, *entry; int mask_cleared = was_masked && !is_masked; /* It is only legal to change an entry when it is masked. Therefore, it is * enough to update the routing in kernel when mask is being cleared. */ @@ -89,16 +104,20 @@ static void kvm_msix_update(PCIDevice *dev, int vector, } entry = dev->msix_irq_entries + vector; e.gsi = entry->gsi; - kvm_msix_routing_entry(dev, vector, &e); - if (memcmp(&entry->u.msi, &e.u.msi, sizeof entry->u.msi)) { + kvm_msix_message_from_vector(dev, vector, &e); + if (memcmp(entry, &e, sizeof e) != 0) { + struct kvm_irq_routing_entry old, new; int r; - r = kvm_update_routing_entry(entry, &e); + + kvm_msix_message_to_routing_entry(entry, &old); + kvm_msix_message_to_routing_entry(&e, &new); + r = kvm_update_routing_entry(&old, &new); if (r) { fprintf(stderr, "%s: kvm_update_routing_entry failed: %s\n", __func__, strerror(-r)); exit(1); } - memcpy(&entry->u.msi, &e.u.msi, sizeof entry->u.msi); + *entry = e; r = kvm_commit_irq_routes(); if (r) { fprintf(stderr, "%s: kvm_commit_irq_routes failed: %s\n", __func__, @@ -110,7 +129,8 @@ static void kvm_msix_update(PCIDevice *dev, int vector, static int kvm_msix_add(PCIDevice *dev, unsigned vector) { - struct kvm_irq_routing_entry *entry = dev->msix_irq_entries + vector; + struct kvm_msix_message *kmm = dev->msix_irq_entries + vector; + struct kvm_irq_routing_entry entry; int r; if (!kvm_has_gsi_routing()) { @@ -125,9 +145,10 @@ static int kvm_msix_add(PCIDevice *dev, unsigned vector) fprintf(stderr, "%s: kvm_get_irq_route_gsi failed: %s\n", __func__, strerror(-r)); return r; } - entry->gsi = r; - kvm_msix_routing_entry(dev, vector, entry); - r = kvm_add_routing_entry(entry); + kmm->gsi = r; + kvm_msix_message_from_vector(dev, vector, kmm); + kvm_msix_message_to_routing_entry(kmm, &entry); + r = kvm_add_routing_entry(&entry); if (r < 0) { fprintf(stderr, "%s: kvm_add_routing_entry failed: %s\n", __func__, strerror(-r)); return r; @@ -143,10 +164,13 @@ static int kvm_msix_add(PCIDevice *dev, unsigned vector) static void kvm_msix_del(PCIDevice *dev, unsigned vector) { + struct kvm_irq_routing_entry entry; + if (dev->msix_entry_used[vector]) { return; } - kvm_del_routing_entry(&dev->msix_irq_entries[vector]); + kvm_msix_message_to_routing_entry(&dev->msix_irq_entries[vector], &entry); + kvm_del_routing_entry(&entry); kvm_commit_irq_routes(); } #else diff --git a/hw/pci.h b/hw/pci.h index 825ccbe..0370e89 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -133,6 +133,13 @@ enum { typedef int (*msix_mask_notifier_func)(PCIDevice *, unsigned vector, void *opaque, int masked); +struct kvm_msix_message { + uint32_t gsi; + uint32_t addr_lo; + uint32_t addr_hi; + uint32_t data; +}; + struct PCIDevice { DeviceState qdev; /* PCI config space */ @@ -196,7 +203,7 @@ struct PCIDevice { * on the rest of the region. */ target_phys_addr_t msix_page_size; - struct kvm_irq_routing_entry *msix_irq_entries; + struct kvm_msix_message *msix_irq_entries; void **msix_mask_notifier_opaque; msix_mask_notifier_func msix_mask_notifier; -- 1.7.3.1 -- 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