Beispiel #1
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);
        }
    }
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
static void kvm_msix_update(PCIDevice *dev, int vector,
                            int was_masked, int is_masked)
{
    KVMMsiMessage new_entry, *entry;
    int mask_cleared = was_masked && !is_masked;
    int r;

    /* 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;
    kvm_msix_message_from_vector(dev, vector, &new_entry);
    r = kvm_msi_message_update(entry, &new_entry);
    if (r < 0) {
        fprintf(stderr, "%s: kvm_update_msix failed: %s\n", __func__,
                strerror(-r));
        exit(1);
    }
    if (r > 0) {
        *entry = new_entry;
        r = kvm_commit_irq_routes();
        if (r) {
            fprintf(stderr, "%s: kvm_commit_irq_routes failed: %s\n", __func__,
		    strerror(-r));
            exit(1);
        }
    }
}
Beispiel #5
0
static void kvm_msix_del(PCIDevice *dev, unsigned vector)
{
    if (dev->msix_entry_used[vector]) {
        return;
    }
    kvm_del_routing_entry(kvm_context, &dev->msix_irq_entries[vector]);
    kvm_commit_irq_routes(kvm_context);
}
Beispiel #6
0
/* KVM specific MSIX helpers */
static void kvm_msix_free(PCIDevice *dev)
{
    int vector, changed = 0;
    for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
        if (dev->msix_entry_used[vector]) {
            kvm_del_routing_entry(kvm_context, &dev->msix_irq_entries[vector]);
            changed = 1;
        }
    }
    if (changed) {
        kvm_commit_irq_routes(kvm_context);
    }
}
Beispiel #7
0
static int kvm_msix_vector_add(PCIDevice *dev, unsigned vector)
{
    KVMMsiMessage *kmm = dev->msix_irq_entries + vector;
    int r;

    kvm_msix_message_from_vector(dev, vector, kmm);
    r = kvm_msi_message_add(kmm);
    if (r < 0) {
        fprintf(stderr, "%s: kvm_add_msix failed: %s\n", __func__, strerror(-r));
        return r;
    }

    r = kvm_commit_irq_routes();
    if (r < 0) {
        fprintf(stderr, "%s: kvm_commit_irq_routes failed: %s\n", __func__, strerror(-r));
        return r;
    }
    return 0;
}
Beispiel #8
0
static void kvm_msix_vector_del(PCIDevice *dev, unsigned vector)
{
    kvm_msi_message_del(&dev->msix_irq_entries[vector]);
    kvm_commit_irq_routes();
}