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

[Xen-changelog] [xen master] xen/arm: Automatically find a PPI for the DOM0 event channel interrupt



commit a3214b4b9979320249b46d12d857a5a66cbcb49e
Author:     Julien Grall <julien.grall@xxxxxxxxxx>
AuthorDate: Thu Feb 19 18:12:04 2015 +0000
Commit:     Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Wed Feb 25 13:49:31 2015 +0000

    xen/arm: Automatically find a PPI for the DOM0 event channel interrupt
    
    Use the new vgic interface to know which virtual PPI is free and use it
    for the event channel code.
    
    At the DOM0 creation time, Xen doesn't know which vIRQ will be free.
    All the vIRQ will be reserved when we parse the device tree. So we can
    allocate the vIRQ just after the device tree has been parsed.
    
    It's safe to defer the allocation because no vIRQ can be injected as
    long as the vCPU is not online.
    
    As the device tree node "hypervisor" containing the description of the
    event channel interrupt is created earlier, add a placeholder which will
    be fix up once Xen has allocated the PPI.
    
    Also correct the check in arch_domain_create to use is_hardware_domain.
    
    Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 xen/arch/arm/domain.c                |   17 +++++++----
 xen/arch/arm/domain_build.c          |   51 ++++++++++++++++++++++++++++------
 xen/arch/arm/platform.c              |    7 ----
 xen/arch/arm/platforms/xgene-storm.c |    1 -
 xen/include/asm-arm/platform.h       |    4 --
 5 files changed, 53 insertions(+), 27 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 7a690b2..fdba081 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -542,13 +542,18 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags)
     if ( (rc = domain_vtimer_init(d)) != 0 )
         goto fail;
 
-    if ( d->domain_id )
+    /*
+     * The hardware domain will get a PPI later in
+     * arch/arm/domain_build.c  depending on the
+     * interrupt map of the hardware.
+     */
+    if ( !is_hardware_domain(d) )
+    {
         d->arch.evtchn_irq = GUEST_EVTCHN_PPI;
-    else
-        d->arch.evtchn_irq = platform_dom0_evtchn_ppi();
-
-    if ( !vgic_reserve_virq(d, d->arch.evtchn_irq) )
-        BUG();
+        /* At this stage vgic_reserve_virq should never fail */
+        if ( !vgic_reserve_virq(d, GUEST_EVTCHN_PPI) )
+            BUG();
+    }
 
     /*
      * Virtual UART is only used by linux early printk and decompress code.
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 137cd2a..9f1f59f 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -627,16 +627,10 @@ static int make_hypervisor_node(struct domain *d,
         return res;
 
     /*
-     * interrupts is evtchn upcall:
-     *  - Active-low level-sensitive
-     *  - All cpus
-     *
-     * TODO: Handle correctly the cpumask
+     * Placeholder for the event channel interrupt.  The values will be
+     * replaced later.
      */
-    DPRINT("  Event channel interrupt to %u\n", d->arch.evtchn_irq);
-    set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
-                   DT_IRQ_TYPE_LEVEL_LOW);
-
+    set_interrupt_ppi(intr, ~0, 0xf, DT_IRQ_TYPE_INVALID);
     res = fdt_property_interrupts(fdt, &intr, 1);
     if ( res )
         return res;
@@ -1277,6 +1271,43 @@ static void initrd_load(struct kernel_info *kinfo)
     }
 }
 
+static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo)
+{
+    int res, node;
+    gic_interrupt_t intr;
+
+    /*
+     * The allocation of the event channel IRQ has been deferred until
+     * now. At this time, all PPIs used by DOM0 have been registered.
+     */
+    res = vgic_allocate_ppi(d);
+    if ( res < 0 )
+        panic("Unable to allocate a PPI for the event channel interrupt\n");
+
+    d->arch.evtchn_irq = res;
+
+    printk("Allocating PPI %u for event channel interrupt\n",
+           d->arch.evtchn_irq);
+
+    /* Fix up "interrupts" in /hypervisor node */
+    node = fdt_path_offset(kinfo->fdt, "/hypervisor");
+    if ( node < 0 )
+        panic("Cannot find the /hypervisor node");
+
+    /* Interrupt event channel upcall:
+     *  - Active-low level-sensitive
+     *  - All CPUs
+     *
+     *  TODO: Handle properly the cpumask
+     */
+    set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
+                      DT_IRQ_TYPE_LEVEL_LOW);
+    res = fdt_setprop_inplace(kinfo->fdt, node, "interrupts",
+                              &intr, sizeof(intr));
+    if ( res )
+        panic("Cannot fix up \"interrupts\" property of the hypervisor node");
+}
+
 int construct_dom0(struct domain *d)
 {
     struct kernel_info kinfo = {};
@@ -1338,6 +1369,8 @@ int construct_dom0(struct domain *d)
     kernel_load(&kinfo);
     /* initrd_load will fix up the fdt, so call it before dtb_load */
     initrd_load(&kinfo);
+    /* Allocate the event channel IRQ and fix up the device tree */
+    evtchn_fixup(d, &kinfo);
     dtb_load(&kinfo);
 
     /* Now that we are done restore the original p2m and current. */
diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
index a79a098..86daf2b 100644
--- a/xen/arch/arm/platform.c
+++ b/xen/arch/arm/platform.c
@@ -160,13 +160,6 @@ bool_t platform_device_is_blacklisted(const struct 
dt_device_node *node)
     return (dt_match_node(blacklist, node) != NULL);
 }
 
-unsigned int platform_dom0_evtchn_ppi(void)
-{
-    if ( platform && platform->dom0_evtchn_ppi )
-        return platform->dom0_evtchn_ppi;
-    return GUEST_EVTCHN_PPI;
-}
-
 void platform_dom0_gnttab(paddr_t *start, paddr_t *size)
 {
     if ( platform && platform->dom0_gnttab_size )
diff --git a/xen/arch/arm/platforms/xgene-storm.c 
b/xen/arch/arm/platforms/xgene-storm.c
index ef3ba63..eee650e 100644
--- a/xen/arch/arm/platforms/xgene-storm.c
+++ b/xen/arch/arm/platforms/xgene-storm.c
@@ -232,7 +232,6 @@ PLATFORM_START(xgene_storm, "APM X-GENE STORM")
     .quirks = xgene_storm_quirks,
     .specific_mapping = xgene_storm_specific_mapping,
 
-    .dom0_evtchn_ppi = 24,
     .dom0_gnttab_start = 0x1f800000,
     .dom0_gnttab_size = 0x20000,
 PLATFORM_END
diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
index eefaca6..4eba37b 100644
--- a/xen/include/asm-arm/platform.h
+++ b/xen/include/asm-arm/platform.h
@@ -38,10 +38,6 @@ struct platform_desc {
      */
     const struct dt_device_match *blacklist_dev;
     /*
-     * The IRQ (PPI) to use to inject event channels to dom0.
-     */
-    unsigned int dom0_evtchn_ppi;
-    /*
      * The location of a region of physical address space which dom0
      * can use for grant table mappings. If size is zero defaults to
      * 0xb0000000-0xb0020000.
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.