static int kvm_msix_add(PCIDevice *dev, unsigned vector) { struct kvm_irq_routing_entry *entry = dev->msix_irq_entries + vector; int r; r = kvm_get_irq_route_gsi(kvm_context); if (r < 0) { 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(kvm_context, entry); if (r < 0) { fprintf(stderr, "%s: kvm_add_routing_entry failed: %s\n", __func__, strerror(-r)); return r; } r = kvm_commit_irq_routes(kvm_context); if (r < 0) { fprintf(stderr, "%s: kvm_commit_irq_routes failed: %s\n", __func__, strerror(-r)); return r; } return 0; }
static void kvm_msix_update(PCIDevice *dev, int vector, int was_masked, int is_masked) { struct kvm_irq_routing_entry 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. */ if (!mask_cleared) { return; } if (!dev->msix_entry_used[vector]) { return; } 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)) { int r; r = kvm_update_routing_entry(kvm_context, entry, &e); 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); r = kvm_commit_irq_routes(kvm_context); if (r) { fprintf(stderr, "%s: kvm_commit_irq_routes failed: %s\n", __func__, strerror(-r)); exit(1); } } }
static int kvm_msix_add(PCIDevice *dev, unsigned vector) { struct kvm_irq_routing_entry *entry = dev->msix_irq_entries + vector; int r; if (!kvm_has_gsi_routing(kvm_context)) { fprintf(stderr, "Warning: no MSI-X support found. " "At least kernel 2.6.30 is required for MSI-X support.\n" ); return -EOPNOTSUPP; } r = kvm_get_irq_route_gsi(kvm_context); if (r < 0) { 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(kvm_context, entry); if (r < 0) { fprintf(stderr, "%s: kvm_add_routing_entry failed: %s\n", __func__, strerror(-r)); return r; } r = kvm_commit_irq_routes(kvm_context); if (r < 0) { fprintf(stderr, "%s: kvm_commit_irq_routes failed: %s\n", __func__, strerror(-r)); return r; } return 0; }