xen/arm: support irq delivery to vcpu > 0
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>
Wed, 13 Aug 2014 16:29:38 +0000 (17:29 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Wed, 3 Sep 2014 14:23:25 +0000 (15:23 +0100)
Use vgic_get_target_vcpu to retrieve the target vcpu from do_IRQ.
Remove in-code comments about missing implementation of SGI delivery to
vcpus other than 0.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/arm/gic.c
xen/arch/arm/irq.c
xen/arch/arm/vgic.c
xen/include/asm-arm/vgic.h

index 3e75fc5915e501ea8b468ec0c3b7392516eaf12c..f5c7c9145e4dc97a06ebce13e36ec9f089b54c12 100644 (file)
@@ -137,7 +137,8 @@ void gic_route_irq_to_guest(struct domain *d, struct irq_desc *desc,
 
     gic_set_irq_properties(desc, cpumask_of(smp_processor_id()), GIC_PRI_IRQ);
 
-    /* TODO: do not assume delivery to vcpu0 */
+    /* Use vcpu0 to retrieve the pending_irq struct. Given that we only
+     * route SPIs to guests, it doesn't make any difference. */
     p = irq_to_pending(d->vcpu[0], desc->irq);
     p->desc = desc;
 }
index 3a8acbf228202cd232f54ca31a6391d12b737e12..49ca467841d8abd03ca46ab7223193d7ff0b35b2 100644 (file)
@@ -198,8 +198,9 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq)
         desc->status |= IRQ_INPROGRESS;
         desc->arch.eoi_cpu = smp_processor_id();
 
-        /* XXX: inject irq into all guest vcpus */
-        vgic_vcpu_inject_irq(d->vcpu[0], irq);
+        /* the irq cannot be a PPI, we only support delivery of SPIs to
+         * guests */
+        vgic_vcpu_inject_spi(d, irq);
         goto out_no_end;
     }
 
index e0dcaf64f78289db881ed89ec15bf6fa8f9823fd..ed7108eab24ecee7c30dfbf9e2a7d05309c5fcb6 100644 (file)
@@ -401,6 +401,17 @@ out:
         smp_send_event_check_mask(cpumask_of(v->processor));
 }
 
+void vgic_vcpu_inject_spi(struct domain *d, unsigned int irq)
+{
+    struct vcpu *v;
+
+    /* the IRQ needs to be an SPI */
+    ASSERT(irq >= 32 && irq <= gic_number_lines());
+
+    v = vgic_get_target_vcpu(d->vcpu[0], irq);
+    vgic_vcpu_inject_irq(v, irq);
+}
+
 /*
  * Local variables:
  * mode: C
index 434a62512b267650b1c30cb90072ffa47e6dcfb5..9b1db0477f936871e83f2f21c229e960a940c030 100644 (file)
@@ -161,6 +161,7 @@ extern void domain_vgic_free(struct domain *d);
 extern int vcpu_vgic_init(struct vcpu *v);
 extern struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int irq);
 extern void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq);
+extern void vgic_vcpu_inject_spi(struct domain *d, unsigned int irq);
 extern void vgic_clear_pending_irqs(struct vcpu *v);
 extern struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq);
 extern struct vgic_irq_rank *vgic_rank_offset(struct vcpu *v, int b, int n, int s);