[PATCH v2 3/9] qemu-kvm: Use upstream irq routing services

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Replace qemu-kvm's versions of kvm_add_irq_route, kvm_add_routing_entry,
kvm_init_irq_routing, kvm_arch_init_irq_routing, and
kvm_commit_irq_routes with the corresponding upstream services. Until
the MSI API is refactored, we only need to export kvm_add_routing_entry
for this.

Signed-off-by: Jan Kiszka <jan.kiszka@xxxxxxxxxxx>
---
 hw/device-assignment.c |   10 ++--
 hw/msi.c               |    4 +-
 hw/msix.c              |    8 ++--
 hw/pc.c                |    2 +-
 hw/pc_piix.c           |    4 --
 kvm-all.c              |   10 +---
 kvm-stub.c             |    4 +-
 kvm.h                  |    6 +-
 qemu-kvm-x86.c         |   50 --------------------
 qemu-kvm.c             |  117 +----------------------------------------------
 qemu-kvm.h             |   19 +-------
 target-i386/kvm.c      |    2 -
 12 files changed, 25 insertions(+), 211 deletions(-)

diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index 584cbb9..d8019fe 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -943,8 +943,8 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)
         }
         assigned_dev->entry->gsi = r;
 
-        kvm_add_routing_entry(assigned_dev->entry);
-        if (kvm_commit_irq_routes() < 0) {
+        kvm_add_routing_entry(kvm_state, assigned_dev->entry);
+        if (kvm_irqchip_commit_routes(kvm_state) < 0) {
             perror("assigned_dev_update_msi: kvm_commit_irq_routes");
             assigned_dev->cap.state &= ~ASSIGNED_DEVICE_MSI_ENABLED;
             return;
@@ -1028,7 +1028,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
         DEBUG("MSI-X vector %d, gsi %d, addr %08x_%08x, data %08x\n", i,
               r, entry->addr_hi, entry->addr_lo, entry->data);
 
-        kvm_add_routing_entry(&adev->entry[i]);
+        kvm_add_routing_entry(kvm_state, &adev->entry[i]);
 
         msix_entry.gsi = adev->entry[i].gsi;
         msix_entry.entry = i;
@@ -1039,7 +1039,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
         }
     }
 
-    if (r == 0 && kvm_commit_irq_routes() < 0) {
+    if (r == 0 && kvm_irqchip_commit_routes(kvm_state) < 0) {
 	    perror("assigned_dev_update_msix_mmio: kvm_commit_irq_routes");
 	    return -EINVAL;
     }
@@ -1504,7 +1504,7 @@ static void msix_mmio_write(void *opaque, target_phys_addr_t addr,
                     return;
                 }
 
-                ret = kvm_commit_irq_routes();
+                ret = kvm_irqchip_commit_routes(kvm_state);
                 if (ret) {
                     fprintf(stderr,
                             "Error committing irq routes (%d)\n", ret);
diff --git a/hw/msi.c b/hw/msi.c
index 5c179c2..3e623c2 100644
--- a/hw/msi.c
+++ b/hw/msi.c
@@ -178,7 +178,7 @@ static void kvm_msi_update(PCIDevice *dev)
     }
     dev->msi_entries_nr = nr_vectors;
     if (changed) {
-        r = kvm_commit_irq_routes();
+        r = kvm_irqchip_commit_routes(kvm_state);
         if (r) {
             fprintf(stderr, "%s: kvm_commit_irq_routes failed: %s\n", __func__,
                     strerror(-r));
@@ -196,7 +196,7 @@ static void kvm_msi_free(PCIDevice *dev)
         kvm_msi_message_del(&dev->msi_irq_entries[vector]);
     }
     if (dev->msi_entries_nr > 0) {
-        kvm_commit_irq_routes();
+        kvm_irqchip_commit_routes(kvm_state);
     }
     dev->msi_entries_nr = 0;
 }
diff --git a/hw/msix.c b/hw/msix.c
index 6e40957..55ddbf4 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -49,7 +49,7 @@ static void kvm_msix_free(PCIDevice *dev)
         }
     }
     if (changed) {
-        kvm_commit_irq_routes();
+        kvm_irqchip_commit_routes(kvm_state);
     }
 }
 
@@ -89,7 +89,7 @@ static void kvm_msix_update(PCIDevice *dev, int vector,
     }
     if (r > 0) {
         *entry = new_entry;
-        r = kvm_commit_irq_routes();
+        r = kvm_irqchip_commit_routes(kvm_state);
         if (r) {
             fprintf(stderr, "%s: kvm_commit_irq_routes failed: %s\n", __func__,
 		    strerror(-r));
@@ -110,7 +110,7 @@ static int kvm_msix_vector_add(PCIDevice *dev, unsigned vector)
         return r;
     }
 
-    r = kvm_commit_irq_routes();
+    r = kvm_irqchip_commit_routes(kvm_state);
     if (r < 0) {
         fprintf(stderr, "%s: kvm_commit_irq_routes failed: %s\n", __func__, strerror(-r));
         return r;
@@ -121,7 +121,7 @@ static int kvm_msix_vector_add(PCIDevice *dev, unsigned vector)
 static void kvm_msix_vector_del(PCIDevice *dev, unsigned vector)
 {
     kvm_msi_message_del(&dev->msix_irq_entries[vector]);
-    kvm_commit_irq_routes();
+    kvm_irqchip_commit_routes(kvm_state);
 }
 
 /* Add MSI-X capability to the config space for the device. */
diff --git a/hw/pc.c b/hw/pc.c
index 70abb6c..e38a63d 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1158,7 +1158,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
 
     register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
 
-    if (!no_hpet) {
+    if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) {
         DeviceState *hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL);
 
         if (hpet) {
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 156fcc8..ef0202a 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -57,7 +57,6 @@ static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
 
 const char *global_cpu_model; /* cpu hotadd */
 
-#ifdef UNUSED_UPSTREAM_KVM
 static void kvm_piix3_setup_irq_routing(bool pci_enabled)
 {
 #ifdef CONFIG_KVM
@@ -90,7 +89,6 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
     }
 #endif /* CONFIG_KVM */
 }
-#endif
 
 static void kvm_piix3_gsi_handler(void *opaque, int n, int level)
 {
@@ -195,9 +193,7 @@ static void pc_init1(MemoryRegion *system_memory,
 
     gsi_state = g_malloc0(sizeof(*gsi_state));
     if (kvm_enabled() && kvm_irqchip_in_kernel()) {
-#ifdef UNUSED_UPSTREAM_KVM
         kvm_piix3_setup_irq_routing(pci_enabled);
-#endif
         gsi = qemu_allocate_irqs(kvm_piix3_gsi_handler, gsi_state,
                                  GSI_NUM_PINS);
     } else {
diff --git a/kvm-all.c b/kvm-all.c
index 515ba6e..afcad44 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -83,13 +83,9 @@ struct KVMState
 #ifdef KVM_CAP_IRQ_ROUTING
     struct kvm_irq_routing *irq_routes;
     int nr_allocated_irq_routes;
-#ifdef UNUSED_UPSTREAM_KVM
     uint32_t *used_gsi_bitmap;
     unsigned int max_gsi;
 #endif
-#endif
-    void *used_gsi_bitmap;
-    int max_gsi;
 };
 
 KVMState *kvm_state;
@@ -760,7 +756,6 @@ int kvm_irqchip_set_irq(KVMState *s, int irq, int level)
     return (s->irqchip_inject_ioctl == KVM_IRQ_LINE) ? 1 : event.status;
 }
 
-#ifdef UNUSED_UPSTREAM_KVM
 #ifdef KVM_CAP_IRQ_ROUTING
 static void set_gsi(KVMState *s, unsigned int gsi)
 {
@@ -794,8 +789,8 @@ static void kvm_init_irq_routing(KVMState *s)
     kvm_arch_init_irq_routing(s);
 }
 
-static void kvm_add_routing_entry(KVMState *s,
-                                  struct kvm_irq_routing_entry *entry)
+void kvm_add_routing_entry(KVMState *s,
+                           struct kvm_irq_routing_entry *entry)
 {
     struct kvm_irq_routing_entry *new;
     int n, size;
@@ -845,7 +840,6 @@ static void kvm_init_irq_routing(KVMState *s)
 {
 }
 #endif /* !KVM_CAP_IRQ_ROUTING */
-#endif
 
 static int kvm_irqchip_create(KVMState *s)
 {
diff --git a/kvm-stub.c b/kvm-stub.c
index c98170e..266dc4a 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -16,6 +16,8 @@
 #include "gdbstub.h"
 #include "kvm.h"
 
+KVMState *kvm_state;
+
 int kvm_irqchip_in_kernel(void)
 {
     return 0;
@@ -155,7 +157,7 @@ int kvm_msi_message_update(KVMMsiMessage *old, KVMMsiMessage *new)
     return -ENOSYS;
 }
 
-int kvm_commit_irq_routes(void)
+int kvm_irqchip_commit_routes(KVMState *s)
 {
     return -ENOSYS;
 }
diff --git a/kvm.h b/kvm.h
index c7c9d79..b84aa40 100644
--- a/kvm.h
+++ b/kvm.h
@@ -130,9 +130,7 @@ void kvm_arch_reset_vcpu(CPUState *env);
 int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr);
 int kvm_arch_on_sigbus(int code, void *addr);
 
-#ifdef UNUSED_UPSTREAM_KVM
 void kvm_arch_init_irq_routing(KVMState *s);
-#endif
 
 int kvm_irqchip_set_irq(KVMState *s, int irq, int level);
 
@@ -229,7 +227,9 @@ int kvm_msi_message_add(KVMMsiMessage *msg);
 int kvm_msi_message_del(KVMMsiMessage *msg);
 int kvm_msi_message_update(KVMMsiMessage *old, KVMMsiMessage *new);
 
-int kvm_commit_irq_routes(void);
+#ifndef NEED_CPU_H
+int kvm_irqchip_commit_routes(KVMState *s);
+#endif
 
 int kvm_irqchip_in_kernel(void);
 
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 6fe48a4..e5b94b0 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -158,53 +158,3 @@ int kvm_arch_set_ioport_access(unsigned long start, unsigned long size,
     return 0;
 }
 #endif
-
-/*
- * Setup x86 specific IRQ routing
- */
-int kvm_arch_init_irq_routing(void)
-{
-    int i, r;
-
-    if (kvm_has_gsi_routing()) {
-        kvm_clear_gsi_routes();
-        for (i = 0; i < 8; ++i) {
-            if (i == 2) {
-                continue;
-            }
-            r = kvm_add_irq_route(i, KVM_IRQCHIP_PIC_MASTER, i);
-            if (r < 0) {
-                return r;
-            }
-        }
-        for (i = 8; i < 16; ++i) {
-            r = kvm_add_irq_route(i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
-            if (r < 0) {
-                return r;
-            }
-        }
-        for (i = 0; i < 24; ++i) {
-            if (i == 0) {
-                r = kvm_add_irq_route(i, KVM_IRQCHIP_IOAPIC, 2);
-            } else if (i != 2) {
-                r = kvm_add_irq_route(i, KVM_IRQCHIP_IOAPIC, i);
-            }
-            if (r < 0) {
-                return r;
-            }
-        }
-        kvm_commit_irq_routes();
-
-        if (!kvm_has_pit_state2()) {
-            no_hpet = 1;
-        }
-    } else {
-        /* If kernel can't do irq routing, interrupt source
-         * override 0->2 can not be set up as required by HPET.
-         * so we have to disable it.
-         */
-        no_hpet = 1;
-    }
-
-    return 0;
-}
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 7e6cbf9..37af80f 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -30,17 +30,6 @@
 
 #define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1))
 
-static inline void set_gsi(KVMState *s, unsigned int gsi)
-{
-    uint32_t *bitmap = s->used_gsi_bitmap;
-
-    if (gsi < s->max_gsi) {
-        bitmap[gsi / 32] |= 1U << (gsi % 32);
-    } else {
-        DPRINTF("Invalid GSI %u\n", gsi);
-    }
-}
-
 static inline void clear_gsi(KVMState *s, unsigned int gsi)
 {
     uint32_t *bitmap = s->used_gsi_bitmap;
@@ -52,38 +41,6 @@ static inline void clear_gsi(KVMState *s, unsigned int gsi)
     }
 }
 
-static int kvm_init_irq_routing(KVMState *s)
-{
-#ifdef KVM_CAP_IRQ_ROUTING
-    int r, gsi_count;
-
-    gsi_count = kvm_check_extension(s, KVM_CAP_IRQ_ROUTING);
-    if (gsi_count > 0) {
-        int gsi_bits, i;
-
-        /* Round up so we can search ints using ffs */
-        gsi_bits = ALIGN(gsi_count, 32);
-        s->used_gsi_bitmap = g_malloc0(gsi_bits / 8);
-        s->max_gsi = gsi_bits;
-
-        /* Mark any over-allocated bits as already in use */
-        for (i = gsi_count; i < gsi_bits; i++) {
-            set_gsi(s, i);
-        }
-    }
-
-    s->irq_routes = g_malloc0(sizeof(*s->irq_routes));
-    s->nr_allocated_irq_routes = 0;
-
-    r = kvm_arch_init_irq_routing();
-    if (r < 0) {
-        return r;
-    }
-#endif
-
-    return 0;
-}
-
 int kvm_create_irqchip(KVMState *s)
 {
 #ifdef KVM_CAP_IRQCHIP
@@ -107,10 +64,7 @@ int kvm_create_irqchip(KVMState *s)
 #endif
     s->irqchip_in_kernel = 1;
 
-    r = kvm_init_irq_routing(s);
-    if (r < 0) {
-        return r;
-    }
+    kvm_init_irq_routing(s);
 #endif
 
     return 0;
@@ -248,60 +202,6 @@ int kvm_clear_gsi_routes(void)
 #endif
 }
 
-int kvm_add_routing_entry(struct kvm_irq_routing_entry *entry)
-{
-#ifdef KVM_CAP_IRQ_ROUTING
-    KVMState *s = kvm_state;
-    struct kvm_irq_routing *z;
-    struct kvm_irq_routing_entry *new;
-    int n, size;
-
-    if (s->irq_routes->nr == s->nr_allocated_irq_routes) {
-        n = s->nr_allocated_irq_routes * 2;
-        if (n < 64) {
-            n = 64;
-        }
-        size = sizeof(struct kvm_irq_routing);
-        size += n * sizeof(*new);
-        z = realloc(s->irq_routes, size);
-        if (!z) {
-            return -ENOMEM;
-        }
-        s->nr_allocated_irq_routes = n;
-        s->irq_routes = z;
-    }
-    n = s->irq_routes->nr++;
-    new = &s->irq_routes->entries[n];
-    memset(new, 0, sizeof(*new));
-    new->gsi = entry->gsi;
-    new->type = entry->type;
-    new->flags = entry->flags;
-    new->u = entry->u;
-
-    set_gsi(s, entry->gsi);
-
-    return 0;
-#else
-    return -ENOSYS;
-#endif
-}
-
-int kvm_add_irq_route(int gsi, int irqchip, int pin)
-{
-#ifdef KVM_CAP_IRQ_ROUTING
-    struct kvm_irq_routing_entry e;
-
-    e.gsi = gsi;
-    e.type = KVM_IRQ_ROUTING_IRQCHIP;
-    e.flags = 0;
-    e.u.irqchip.irqchip = irqchip;
-    e.u.irqchip.pin = pin;
-    return kvm_add_routing_entry(&e);
-#else
-    return -ENOSYS;
-#endif
-}
-
 int kvm_del_routing_entry(struct kvm_irq_routing_entry *entry)
 {
 #ifdef KVM_CAP_IRQ_ROUTING
@@ -422,18 +322,6 @@ int kvm_del_irq_route(int gsi, int irqchip, int pin)
 #endif
 }
 
-int kvm_commit_irq_routes(void)
-{
-#ifdef KVM_CAP_IRQ_ROUTING
-    KVMState *s = kvm_state;
-
-    s->irq_routes->flags = 0;
-    return kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
-#else
-    return -ENOSYS;
-#endif
-}
-
 int kvm_get_irq_route_gsi(void)
 {
     KVMState *s = kvm_state;
@@ -477,7 +365,8 @@ int kvm_msi_message_add(KVMMsiMessage *msg)
     msg->gsi = ret;
 
     kvm_msi_routing_entry(&e, msg);
-    return kvm_add_routing_entry(&e);
+    kvm_add_routing_entry(kvm_state, &e);
+    return 0;
 }
 
 int kvm_msi_message_del(KVMMsiMessage *msg)
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 653370e..6235800 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -183,14 +183,6 @@ int kvm_deassign_pci_device(KVMState *s,
 int kvm_clear_gsi_routes(void);
 
 /*!
- * \brief Adds an irq route to the temporary irq routing table
- *
- * Adds an irq route to the temporary irq routing table.  Nothing is
- * committed to the running VM.
- */
-int kvm_add_irq_route(int gsi, int irqchip, int pin);
-
-/*!
  * \brief Removes an irq route from the temporary irq routing table
  *
  * Adds an irq route to the temporary irq routing table.  Nothing is
@@ -199,13 +191,8 @@ int kvm_add_irq_route(int gsi, int irqchip, int pin);
 int kvm_del_irq_route(int gsi, int irqchip, int pin);
 
 struct kvm_irq_routing_entry;
-/*!
- * \brief Adds a routing entry to the temporary irq routing table
- *
- * Adds a filled routing entry to the temporary irq routing table. Nothing is
- * committed to the running VM.
- */
-int kvm_add_routing_entry(struct kvm_irq_routing_entry *entry);
+
+void kvm_add_routing_entry(KVMState *s, struct kvm_irq_routing_entry *entry);
 
 /*!
  * \brief Removes a routing from the temporary irq routing table
@@ -245,8 +232,6 @@ void kvm_hpet_disable_kpit(void);
 
 void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write);
 
-int kvm_arch_init_irq_routing(void);
-
 int kvm_add_ioport_region(unsigned long start, unsigned long size,
                           bool is_hot_plug);
 int kvm_remove_ioport_region(unsigned long start, unsigned long size,
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index ee2d3f8..7096752 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2017,7 +2017,6 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env)
            ((env->segs[R_CS].selector  & 3) != 3);
 }
 
-#ifdef UNUSED_UPSTREAM_KVM
 void kvm_arch_init_irq_routing(KVMState *s)
 {
     if (!kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
@@ -2028,6 +2027,5 @@ void kvm_arch_init_irq_routing(KVMState *s)
         no_hpet = 1;
     }
 }
-#endif
 
 #include "qemu-kvm-x86.c"
-- 
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


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux