[v6,1/8] hw/intc/arm_gic(v3)_kvm: Initialize gsi routing
diff mbox

Message ID 1473442237-3746-2-git-send-email-eric.auger@redhat.com
State New
Headers show

Commit Message

Auger Eric Sept. 9, 2016, 5:30 p.m. UTC
From: Eric Auger <eric.auger@linaro.org>

Advertise gsi routing and set up irqchip routing entries for
GIC SPIs.

This is not mandated as long as MSI routing is not used
(because the kernel sets a default irqchip routing table).
However once MSI routing gets used (for VIRTIO-PCI vhost for
example), the first call to KVM_SET_GSI_ROUTING overrides the
kernel default irqchip table.

If no routing entry exists for the GSI, any IRQFD signaling for
this GSI will fail.

Signed-off-by: Eric Auger <eric.auger@linaro.org>

---

RFC -> PATCH:
- KVM gsi/MSI routing for ARM now supported in 4.8
- use kvm_has_gsi_routing()
---
 hw/intc/arm_gic_kvm.c   | 12 ++++++++++++
 hw/intc/arm_gicv3_kvm.c | 13 +++++++++++++
 2 files changed, 25 insertions(+)

Comments

Peter Maydell Sept. 22, 2016, 2:23 p.m. UTC | #1
On 9 September 2016 at 18:30, Eric Auger <eric.auger@redhat.com> wrote:
> From: Eric Auger <eric.auger@linaro.org>
>
> Advertise gsi routing and set up irqchip routing entries for
> GIC SPIs.
>
> This is not mandated as long as MSI routing is not used
> (because the kernel sets a default irqchip routing table).
> However once MSI routing gets used (for VIRTIO-PCI vhost for
> example), the first call to KVM_SET_GSI_ROUTING overrides the
> kernel default irqchip table.
>
> If no routing entry exists for the GSI, any IRQFD signaling for
> this GSI will fail.
>
> Signed-off-by: Eric Auger <eric.auger@linaro.org>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

Patch
diff mbox

diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
index 5593cdb..ae7ac58 100644
--- a/hw/intc/arm_gic_kvm.c
+++ b/hw/intc/arm_gic_kvm.c
@@ -577,6 +577,18 @@  static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
                                           "not support vGICv2 migration");
         migrate_add_blocker(s->migration_blocker);
     }
+
+    if (kvm_has_gsi_routing()) {
+        /* set up irq routing */
+        kvm_init_irq_routing(kvm_state);
+        for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
+            kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
+        }
+
+        kvm_gsi_routing_allowed = true;
+
+        kvm_irqchip_commit_routes(kvm_state);
+    }
 }
 
 static void kvm_arm_gic_class_init(ObjectClass *klass, void *data)
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
index 711fde3..199a439 100644
--- a/hw/intc/arm_gicv3_kvm.c
+++ b/hw/intc/arm_gicv3_kvm.c
@@ -85,6 +85,7 @@  static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
     GICv3State *s = KVM_ARM_GICV3(dev);
     KVMARMGICv3Class *kgc = KVM_ARM_GICV3_GET_CLASS(s);
     Error *local_err = NULL;
+    int i;
 
     DPRINTF("kvm_arm_gicv3_realize\n");
 
@@ -127,6 +128,18 @@  static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
      */
     error_setg(&s->migration_blocker, "vGICv3 migration is not implemented");
     migrate_add_blocker(s->migration_blocker);
+
+    if (kvm_has_gsi_routing()) {
+        /* set up irq routing */
+        kvm_init_irq_routing(kvm_state);
+        for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
+            kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
+        }
+
+        kvm_gsi_routing_allowed = true;
+
+        kvm_irqchip_commit_routes(kvm_state);
+    }
 }
 
 static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data)