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

[Xen-devel] [PATCH v5 14/22] xen/arm: ITS: Allocate irq descriptors for LPIs



From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>

Allocate irq descriptors for LPIs dynamically and
also update irq_to_pending helper for LPIs

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
---
 xen/arch/arm/gic-v3-its.c         |   15 +++++++++++++++
 xen/arch/arm/gic-v3.c             |    6 ++++++
 xen/arch/arm/irq.c                |   12 +++++++++++-
 xen/arch/arm/vgic-v3-its.c        |   22 ++++++++++++++++++++++
 xen/arch/arm/vgic.c               |   13 ++++++++++---
 xen/include/asm-arm/domain.h      |    1 +
 xen/include/asm-arm/gic-its.h     |    6 ++++++
 xen/include/asm-arm/gic.h         |    2 ++
 xen/include/asm-arm/gic_v3_defs.h |    3 ++-
 9 files changed, 75 insertions(+), 5 deletions(-)

diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index e16fa03..0d17885 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -1038,6 +1038,7 @@ int __init its_init(struct rdist_prop *rdists)
     struct its_node *its;
     struct its_node_info *info;
     struct dt_device_node *np = NULL;
+    struct irq_desc *desc;
     uint32_t i, nr_its = 0;
 
     static const struct dt_device_match its_device_ids[] __initconst =
@@ -1079,6 +1080,20 @@ int __init its_init(struct rdist_prop *rdists)
     its_lpi_init(rdists->id_bits);
     its_alloc_lpi_tables();
 
+    /* Allocate LPI irq descriptors */
+    irq_desc_lpi = xzalloc_array(struct irq_desc, num_of_lpis);
+    if ( !irq_desc_lpi )
+        return -ENOSPC;
+
+    for ( i = 0; i < num_of_lpis; i++ )
+    {
+       desc = &irq_desc_lpi[i];
+       init_one_irq_desc(desc);
+       desc->irq = FIRST_GIC_LPI + i;
+       desc->arch.type = DT_IRQ_TYPE_EDGE_BOTH;
+       desc->action = NULL;
+    }
+
     return 0;
 }
 
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 3b4dea3..98d45bc 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -1280,6 +1280,12 @@ static int __init gicv3_init(void)
                      gicv3.rdist_stride);
     gicv3_init_v2(node, dbase);
 
+    reg = readl_relaxed(GICD + GICD_TYPER);
+
+    gicv3.rdist_data.id_bits = ((reg >> GICD_TYPE_ID_BITS_SHIFT) &
+                                GICD_TYPE_ID_BITS_MASK) + 1;
+    gicv3_info.nr_id_bits = gicv3.rdist_data.id_bits;
+
     spin_lock_init(&gicv3.lock);
 
     spin_lock(&gicv3.lock);
diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index 85cacb0..63feb43 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -31,6 +31,7 @@
 static unsigned int local_irqs_type[NR_LOCAL_IRQS];
 static DEFINE_SPINLOCK(local_irqs_type_lock);
 
+irq_desc_t *irq_desc_lpi;
 /* Number of LPI supported in XEN */
 unsigned int num_of_lpis = 8192;
 
@@ -64,7 +65,16 @@ static DEFINE_PER_CPU(irq_desc_t[NR_LOCAL_IRQS], 
local_irq_desc);
 irq_desc_t *__irq_to_desc(int irq)
 {
     if (irq < NR_LOCAL_IRQS) return &this_cpu(local_irq_desc)[irq];
-    return &irq_desc[irq-NR_LOCAL_IRQS];
+    else if ( irq >= NR_LOCAL_IRQS && irq < NR_IRQS)
+        return &irq_desc[irq-NR_LOCAL_IRQS];
+#ifdef HAS_GICV3 
+    else if ( gic_is_lpi(irq) )
+    {
+        ASSERT(irq_desc_lpi != NULL);
+        return &irq_desc_lpi[irq - FIRST_GIC_LPI];
+    }
+#endif
+    return NULL;
 }
 
 int __init arch_init_one_irq_desc(struct irq_desc *desc)
diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
index 4afb62b..b8f32ed 100644
--- a/xen/arch/arm/vgic-v3-its.c
+++ b/xen/arch/arm/vgic-v3-its.c
@@ -69,6 +69,12 @@ void vits_setup_hw(struct gic_its_info *its_info)
     vits_hw.info = its_info;
 }
 
+bool_t is_domain_lpi(struct domain *d, unsigned int lpi)
+{
+    return ((lpi >= FIRST_GIC_LPI) &&
+            (lpi < (d->arch.vgic.nr_lpis + FIRST_GIC_LPI)));
+}
+
 static inline uint32_t vits_get_max_collections(struct domain *d)
 {
     /* Collection ID is only 16 bit */
@@ -1049,6 +1055,21 @@ int vits_domain_init(struct domain *d)
 
     vits = d->arch.vgic.vits;
 
+    d->arch.vgic.pending_lpis = xzalloc_array(struct pending_irq,
+                                              d->arch.vgic.nr_lpis);
+    if ( d->arch.vgic.pending_lpis == NULL )
+    {
+        xfree(d->arch.vgic.vits);
+        return -ENOMEM;
+    }
+
+    for ( i = 0; i < d->arch.vgic.nr_lpis; i++ )
+    {
+        INIT_LIST_HEAD(&d->arch.vgic.pending_lpis[i].inflight);
+        INIT_LIST_HEAD(&d->arch.vgic.pending_lpis[i].lr_queue);
+        d->arch.vgic.pending_lpis[i].irq = FIRST_GIC_LPI + i;
+    }
+
     spin_lock_init(&vits->lock);
     spin_lock_init(&vits->prop_lock);
 
@@ -1056,6 +1077,7 @@ int vits_domain_init(struct domain *d)
     if ( !vits->collections )
     {
         xfree(d->arch.vgic.vits);
+        xfree(d->arch.vgic.pending_lpis);
         return -ENOMEM;
     }
 
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index a6835a8..ab5e81b 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -30,6 +30,7 @@
 
 #include <asm/mmio.h>
 #include <asm/gic.h>
+#include <asm/gic-its.h>
 #include <asm/vgic.h>
 
 static inline struct vgic_irq_rank *vgic_get_rank(struct vcpu *v, int rank)
@@ -375,13 +376,19 @@ int vgic_to_sgi(struct vcpu *v, register_t sgir, enum 
gic_sgi_mode irqmode, int
 
 struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq)
 {
-    struct pending_irq *n;
+    struct pending_irq *n = NULL;
     /* Pending irqs allocation strategy: the first vgic.nr_spis irqs
-     * are used for SPIs; the rests are used for per cpu irqs */
+     * are used for SPIs; the rests are used for per cpu irqs.
+     * For LPIs pending_irq structures are allocated separately */
     if ( irq < 32 )
         n = &v->arch.vgic.pending_irqs[irq];
-    else
+    else if ( irq < vgic_num_irqs(v->domain) )
         n = &v->domain->arch.vgic.pending_irqs[irq - 32];
+#ifdef HAS_GICV3
+    else if ( is_domain_lpi(v->domain, irq) )
+        n = &v->domain->arch.vgic.pending_lpis[irq - FIRST_GIC_LPI];
+#endif
+    ASSERT(n != NULL);
     return n;
 }
 
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index c4cf65e..3f26d17 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -108,6 +108,7 @@ struct arch_domain
 #ifdef HAS_GICV3
         /* Virtual ITS */
         struct vgic_its *vits;
+        struct pending_irq *pending_lpis;
         int gicr_ctlr;
         /* GIC V3 addressing */
         /* List of contiguous occupied by the redistributors */
diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h
index 30316fd..7bb645e 100644
--- a/xen/include/asm-arm/gic-its.h
+++ b/xen/include/asm-arm/gic-its.h
@@ -21,11 +21,14 @@
 #include <asm/gic_v3_defs.h>
 #include <xen/rbtree.h>
 
+extern irq_desc_t *irq_desc_lpi;
 /* Number of LPI supported */
 extern unsigned int num_of_lpis;
 
 #define MASK_4K                         0xfffffffff000UL
 #define MAPC_ITT_IPA_SHIFT              8
+/* Number of LPIs allocated per domain */
+#define NR_LPIS                         8192
 /*
  * ITS registers, offsets from ITS_base
  */
@@ -146,6 +149,8 @@ struct vgic_its
    unsigned long cmd_qsize;
    /* ITS mmio physical base */
    paddr_t gits_base;
+   /* ITS mmio physical size */
+   unsigned long gits_size;
    /* GICR ctrl register */
    uint32_t ctrl;
    /* LPI propbase */
@@ -348,6 +353,7 @@ struct gic_its_info {
     struct its_node_info *its_hw;
 };
 
+bool_t is_domain_lpi(struct domain *d, unsigned int lpi);
 int its_init(struct rdist_prop *rdists);
 int its_cpu_init(void);
 int vits_get_vitt_entry(struct domain *d, uint32_t devid,
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index f80f291..2f5d5e3 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -303,6 +303,8 @@ struct gic_info {
     unsigned int maintenance_irq;
     /* Pointer to the device tree node representing the interrupt controller */
     const struct dt_device_node *node;
+    /* Number of IRQ ID bits supported */
+    uint32_t nr_id_bits;
     /* LPIs are support information */
     bool_t lpi_supported; 
 };
diff --git a/xen/include/asm-arm/gic_v3_defs.h 
b/xen/include/asm-arm/gic_v3_defs.h
index 4233bd5..68978e8 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -46,7 +46,8 @@
 #define GICC_SRE_EL2_ENEL1           (1UL << 3)
 
 /* Additional bits in GICD_TYPER defined by GICv3 */
-#define GICD_TYPE_ID_BITS_SHIFT 19
+#define GICD_TYPE_ID_BITS_SHIFT      19
+#define GICD_TYPE_ID_BITS_MASK       0x1f
 
 #define GICD_TYPER_LPIS_SUPPORTED    (1U << 17)
 #define GICD_CTLR_RWP                (1UL << 31)
-- 
1.7.9.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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