xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: vijay.kilari@gmail.com
To: Ian.Campbell@citrix.com, julien.grall@citrix.com,
	stefano.stabellini@eu.citrix.com, stefano.stabellini@citrix.com,
	tim@xen.org, xen-devel@lists.xen.org
Cc: Prasun.Kapoor@caviumnetworks.com,
	manish.jaggi@caviumnetworks.com,
	Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>,
	vijay.kilari@gmail.com
Subject: [PATCH v5 16/22] xen/arm: ITS: Route LPIs
Date: Mon, 27 Jul 2015 16:41:58 +0530	[thread overview]
Message-ID: <1437995524-19772-17-git-send-email-vijay.kilari@gmail.com> (raw)
In-Reply-To: <1437995524-19772-1-git-send-email-vijay.kilari@gmail.com>

From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>

Allocate and initialize irq descriptor for LPIs and
route LPIs to guest

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
---
 xen/arch/arm/gic-v3-its.c     |   20 +++++++
 xen/arch/arm/gic-v3.c         |   17 +++++-
 xen/arch/arm/gic.c            |   38 ++++++++++++-
 xen/arch/arm/irq.c            |  126 ++++++++++++++++++++++++++++++++++++++---
 xen/arch/arm/vgic-v2.c        |    5 +-
 xen/arch/arm/vgic-v3-its.c    |   22 ++++++-
 xen/arch/arm/vgic-v3.c        |   17 ++++--
 xen/arch/arm/vgic.c           |   72 ++++++++++++++++++++++-
 xen/include/asm-arm/gic-its.h |   10 ++++
 xen/include/asm-arm/gic.h     |   11 +++-
 xen/include/asm-arm/irq.h     |    2 +
 xen/include/asm-arm/vgic.h    |    2 +
 12 files changed, 319 insertions(+), 23 deletions(-)

diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index 5ffd52f..0d8582a 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -110,6 +110,11 @@ void dump_cmd(its_cmd_block *cmd)
 void dump_cmd(its_cmd_block *cmd) { do {} while ( 0 ); }
 #endif
 
+u32 its_get_nr_event_ids(void)
+{
+    return (1 << its_data.eventid_bits);
+}
+
 /* RB-tree helpers for its_device */
 struct its_device *its_find_device(u32 devid)
 {
@@ -415,6 +420,21 @@ static void its_flush_and_invalidate_prop(struct irq_desc *desc, u8 *cfg)
     its_send_inv(its_dev, col, vid);
 }
 
+void its_set_lpi_properties(struct irq_desc *desc,
+                            const cpumask_t *cpu_mask,
+                            unsigned int priority)
+{
+    unsigned long flags;
+    u8 *cfg;
+
+    spin_lock_irqsave(&its_lock, flags);
+    cfg = gic_rdists->prop_page + desc->irq - FIRST_GIC_LPI;
+    *cfg = (*cfg & 3) | (priority & LPI_PRIORITY_MASK) ;
+
+    its_flush_and_invalidate_prop(desc, cfg);
+    spin_unlock_irqrestore(&its_lock, flags);
+}
+
 static void its_set_lpi_state(struct irq_desc *desc, int enable)
 {
     u8 *cfg;
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 58e878e..8c7c5cf 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -535,6 +535,16 @@ static void gicv3_set_irq_properties(struct irq_desc *desc,
     spin_unlock(&gicv3.lock);
 }
 
+static void gicv3_set_properties(struct irq_desc *desc,
+                                 const cpumask_t *cpu_mask,
+                                 unsigned int priority)
+{
+    if ( gic_is_lpi(desc->irq) )
+        its_set_lpi_properties(desc, cpu_mask, priority);
+    else
+        gicv3_set_irq_properties(desc, cpu_mask, priority);
+}
+
 static void __init gicv3_dist_init(void)
 {
     uint32_t type;
@@ -912,7 +922,7 @@ static void gicv3_update_lr(int lr, const struct pending_irq *p,
     val |= ((uint64_t)p->priority & 0xff) << GICH_LR_PRIORITY_SHIFT;
     val |= ((uint64_t)p->irq & GICH_LR_VIRTUAL_MASK) << GICH_LR_VIRTUAL_SHIFT;
 
-   if ( p->desc != NULL )
+   if ( p->desc != NULL && !(gic_is_lpi(p->irq)) )
        val |= GICH_LR_HW | (((uint64_t)p->desc->irq & GICH_LR_PHYSICAL_MASK)
                            << GICH_LR_PHYSICAL_SHIFT);
 
@@ -1312,7 +1322,10 @@ static int __init gicv3_init(void)
     spin_lock(&gicv3.lock);
 
     if ( gicv3_dist_supports_lpis() )
+    {
         gicv3_info.lpi_supported = 1;
+        gicv3_info.nr_event_ids = its_get_nr_event_ids();
+    }
     else
         gicv3_info.lpi_supported = 0;
 
@@ -1336,7 +1349,7 @@ static const struct gic_hw_operations gicv3_ops = {
     .eoi_irq             = gicv3_eoi_irq,
     .deactivate_irq      = gicv3_dir_irq,
     .read_irq            = gicv3_read_irq,
-    .set_irq_properties  = gicv3_set_irq_properties,
+    .set_irq_properties  = gicv3_set_properties,
     .send_SGI            = gicv3_send_sgi,
     .disable_interface   = gicv3_disable_interface,
     .update_lr           = gicv3_update_lr,
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 092087d..f6be0e9 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -33,6 +33,7 @@
 #include <asm/device.h>
 #include <asm/io.h>
 #include <asm/gic.h>
+#include <asm/gic-its.h>
 #include <asm/vgic.h>
 
 static void gic_restore_pending_irqs(struct vcpu *v);
@@ -67,11 +68,23 @@ bool_t gic_is_lpi(unsigned int irq)
     return gic_hw_ops->is_lpi(irq);
 }
 
+/* Returns number of PPIs/SGIs/SPIs supported */
 unsigned int gic_number_lines(void)
 {
     return gic_hw_ops->info->nr_lines;
 }
 
+/* Validates PPIs/SGIs/SPIs/LPIs supported */
+bool_t gic_is_valid_irq(unsigned int irq)
+{
+    return ((irq < gic_hw_ops->info->nr_lines) || gic_is_lpi(irq));
+}
+
+unsigned int gic_nr_event_ids(void)
+{
+    return gic_hw_ops->info->nr_event_ids;
+}
+
 bool_t gic_lpi_supported(void)
 {
     return gic_hw_ops->info->lpi_supported;
@@ -134,7 +147,8 @@ void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask,
                           unsigned int priority)
 {
     ASSERT(priority <= 0xff);     /* Only 8 bits of priority */
-    ASSERT(desc->irq < gic_number_lines());/* Can't route interrupts that don't exist */
+    /* Can't route interrupts that don't exist */
+    ASSERT(gic_is_valid_irq(desc->irq));
     ASSERT(test_bit(_IRQ_DISABLED, &desc->status));
     ASSERT(spin_is_locked(&desc->lock));
 
@@ -183,6 +197,24 @@ out:
     return res;
 }
 
+int gic_route_lpi_to_guest(struct domain *d, unsigned int virq,
+                           struct irq_desc *desc, unsigned int priority)
+{
+    ASSERT(spin_is_locked(&desc->lock));
+    ASSERT(virq < gic_nr_event_ids());
+
+    desc->handler = get_guest_hw_irq_controller(desc->irq);
+    set_bit(_IRQ_GUEST, &desc->status);
+
+    /* Set cpumask to current processor */
+    gic_set_irq_properties(desc, cpumask_of(smp_processor_id()), priority);
+
+    /* Enable LPI by default? */
+    desc->handler->enable(desc);
+
+    return 0;
+}
+
 /* This function only works with SPIs for now */
 int gic_remove_irq_from_guest(struct domain *d, unsigned int virq,
                               struct irq_desc *desc)
@@ -440,7 +472,7 @@ static void gic_update_one_lr(struct vcpu *v, int i)
         if ( test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) &&
              test_and_clear_bit(GIC_IRQ_GUEST_QUEUED, &p->status) )
         {
-            if ( p->desc == NULL )
+            if ( p->desc == NULL  || gic_is_lpi(irq) )
             {
                  lr_val.state |= GICH_LR_PENDING;
                  gic_hw_ops->write_lr(i, &lr_val);
@@ -663,7 +695,7 @@ void gic_interrupt(struct cpu_user_regs *regs, int is_fiq)
         /* Reading IRQ will ACK it */
         irq = gic_hw_ops->read_irq();
 
-        if ( likely(irq >= 16 && irq < 1020) )
+        if ( (likely(irq >= 16 && irq < 1020)) || likely(gic_is_lpi(irq)) )
         {
             local_irq_enable();
             do_IRQ(regs, irq, is_fiq);
diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index ccbe088..ae301a4 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -26,6 +26,7 @@
 #include <xen/sched.h>
 
 #include <asm/gic.h>
+#include <asm/gic-its.h>
 #include <asm/vgic.h>
 
 static unsigned int local_irqs_type[NR_LOCAL_IRQS];
@@ -221,7 +222,7 @@ int request_irq(unsigned int irq, unsigned int irqflags,
      * which interrupt is which (messes up the interrupt freeing
      * logic etc).
      */
-    if ( irq >= nr_irqs )
+    if ( !gic_is_valid_irq(irq) )
         return -EINVAL;
     if ( !handler )
         return -EINVAL;
@@ -279,11 +280,28 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq)
 
         set_bit(_IRQ_INPROGRESS, &desc->status);
 
-        /*
-         * The irq cannot be a PPI, we only support delivery of SPIs to
-         * guests.
-	 */
-        vgic_vcpu_inject_spi(info->d, info->virq);
+#ifdef HAS_GICV3
+        if ( gic_is_lpi(irq) )
+        {
+            struct its_device *dev = get_irq_its_device(desc);
+            unsigned int vdevid = dev->virt_device_id;
+            unsigned int eventID = irq_to_vid(desc);
+
+            if ( info->d->domain_id != dev->domain_id)
+            {
+                printk("LPI %"PRId32" not assigned to domain.. dropping \n",
+                       irq);
+                goto out_no_end;
+            }
+            vgic_vcpu_inject_lpi(info->d, vdevid, eventID);
+        }
+        else
+#endif
+            /*
+             * The irq cannot be a PPI, we only support delivery of SPIs to
+             * guests
+             */
+            vgic_vcpu_inject_spi(info->d, info->virq);
         goto out_no_end;
     }
 
@@ -449,10 +467,102 @@ err:
 
 bool_t is_assignable_irq(unsigned int irq)
 {
-    /* For now, we can only route SPIs to the guest */
-    return ((irq >= NR_LOCAL_IRQS) && (irq < gic_number_lines()));
+    /* For now, we can only route SPI/LPIs to the guest */
+    return (((irq >= NR_LOCAL_IRQS) && (irq < gic_number_lines())) ||
+              gic_is_lpi(irq));
 }
 
+#ifdef HAS_GICV3
+/*
+ * Route an LPI to a specific guest.
+ */
+int route_lpi_to_guest(struct domain *d, unsigned int vid,
+                       unsigned int irq, const char *devname)
+{
+    struct irqaction *action;
+    struct irq_guest *info;
+    struct irq_desc *desc;
+    unsigned long flags;
+    int retval = 0;
+
+    if ( !gic_is_lpi(irq) )
+    {
+        printk(XENLOG_G_ERR "Only LPI can be routed \n");
+        return -EINVAL;
+    }
+
+    action = xmalloc(struct irqaction);
+    if ( !action )
+        return -ENOMEM;
+
+    info = xmalloc(struct irq_guest);
+    if ( !info )
+    {
+        xfree(action);
+        return -ENOMEM;
+    }
+    info->d = d;
+
+    action->dev_id = info;
+    action->name = devname;
+    action->free_on_release = 1;
+
+    desc = irq_to_desc(irq);
+    spin_lock_irqsave(&desc->lock, flags);
+
+    ASSERT(desc->msi_desc != NULL);
+    desc->msi_desc->eventID = vid;
+    if ( desc->arch.type == DT_IRQ_TYPE_INVALID )
+    {
+        printk(XENLOG_G_ERR "LPI %u has not been configured\n", irq);
+        retval = -EIO;
+        goto out;
+    }
+
+    /*
+     * If the IRQ is already used by by same domain
+     */
+    if ( desc->action != NULL )
+    {
+        struct domain *ad = irq_get_domain(desc);
+
+        if ( test_bit(_IRQ_GUEST, &desc->status) && d == ad )
+        {
+            printk(XENLOG_G_ERR
+                   "d%u: vID %u is already assigned to domain %u\n",
+                   d->domain_id, irq, d->domain_id);
+            retval = -EBUSY;
+            goto out;
+        }
+    }
+
+    retval = __setup_irq(desc, 0, action);
+    if ( retval )
+        goto out;
+
+    retval = gic_route_lpi_to_guest(d, vid, desc, GIC_PRI_IRQ);
+
+    spin_unlock_irqrestore(&desc->lock, flags);
+
+    if ( retval )
+    {
+        /* TODO: for LPI */
+        release_irq(desc->irq, info);
+        goto free_info;
+    }
+
+    return 0;
+
+out:
+    spin_unlock_irqrestore(&desc->lock, flags);
+    xfree(action);
+free_info:
+    xfree(info);
+
+    return retval;
+}
+#endif
+
 /*
  * Route an IRQ to a specific guest.
  * For now only SPIs are assignable to the guest.
diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index 524787b..4517a62 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -520,11 +520,14 @@ static int vgic_v2_get_irq_priority(struct vcpu *v, unsigned int irq)
 {
     int priority;
     struct vgic_irq_rank *rank = vgic_rank_irq(v, irq);
+    unsigned long flags;
 
-    ASSERT(spin_is_locked(&rank->lock));
+    vgic_lock_rank(v, rank, flags);
     priority = vgic_byte_read(rank->ipriority[REG_RANK_INDEX(8,
                                               irq, DABT_WORD)], 0, irq & 0x3);
 
+    vgic_lock_rank(v, rank, flags);
+
     return priority;
 }
 
diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
index b8f32ed..5323192 100644
--- a/xen/arch/arm/vgic-v3-its.c
+++ b/xen/arch/arm/vgic-v3-its.c
@@ -75,6 +75,11 @@ bool_t is_domain_lpi(struct domain *d, unsigned int lpi)
             (lpi < (d->arch.vgic.nr_lpis + FIRST_GIC_LPI)));
 }
 
+bool_t is_valid_collection(struct domain *d, uint32_t col)
+{
+    return (col <= (d->max_vcpus + 1));
+}
+
 static inline uint32_t vits_get_max_collections(struct domain *d)
 {
     /* Collection ID is only 16 bit */
@@ -371,7 +376,7 @@ static int vits_process_int(struct vcpu *v, struct vgic_its *vits,
     DPRINTK("%pv: vITS: INT: Device 0x%"PRIx32" id %"PRId32"\n",
             v, dev_id, event);
 
-    /* TODO: Inject LPI */
+    vgic_vcpu_inject_lpi(v->domain, dev_id, event);
 
     return 0;
 }
@@ -586,6 +591,21 @@ static inline uint32_t vits_get_word(uint32_t reg_offset, uint64_t val)
         return (u32)(val >> 32);
 }
 
+uint8_t vits_get_priority(struct vcpu *v, uint32_t vlpi)
+{
+    struct vgic_its *vits = v->domain->arch.vgic.vits;
+    uint8_t priority;
+
+    ASSERT(vlpi < vits->prop_size);
+
+    spin_lock(&vits->prop_lock);
+    priority = *((u8*)vits->prop_page + vlpi);
+    priority &= LPI_PRIORITY_MASK;
+    spin_unlock(&vits->prop_lock);
+
+    return priority;
+}
+
 static int vgic_v3_gits_lpi_mmio_read(struct vcpu *v, mmio_info_t *info)
 {
     uint32_t offset;
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index a466a8f..9e6e3ff 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -1140,12 +1140,21 @@ static const struct mmio_handler_ops vgic_distr_mmio_handler = {
 
 static int vgic_v3_get_irq_priority(struct vcpu *v, unsigned int irq)
 {
-    int priority;
-    struct vgic_irq_rank *rank = vgic_rank_irq(v, irq);
+    int priority = 0;
+    struct vgic_irq_rank *rank;
+    unsigned long flags;
 
-    ASSERT(spin_is_locked(&rank->lock));
-    priority = vgic_byte_read(rank->ipriority[REG_RANK_INDEX(8,
+    if ( !gic_is_lpi(irq) )
+    {
+        rank = vgic_rank_irq(v, irq);
+
+        vgic_lock_rank(v, rank, flags);
+        priority = vgic_byte_read(rank->ipriority[REG_RANK_INDEX(8,
                                               irq, DABT_WORD)], 0, irq & 0x3);
+        vgic_unlock_rank(v, rank, flags);
+    }
+    else if ( gic_lpi_supported() && is_domain_lpi(v->domain, irq) )
+        priority = vits_get_priority(v, irq);
 
     return priority;
 }
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index ab5e81b..57c0f52 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -33,6 +33,12 @@
 #include <asm/gic-its.h>
 #include <asm/vgic.h>
 
+static inline bool_t is_domains_lpi(struct domain *d, unsigned int irq)
+{
+    return ((irq > FIRST_GIC_LPI) &&
+            (irq < (d->arch.vgic.nr_lpis + FIRST_GIC_LPI)));
+}
+
 static inline struct vgic_irq_rank *vgic_get_rank(struct vcpu *v, int rank)
 {
     if ( rank == 0 )
@@ -414,14 +420,11 @@ void vgic_clear_pending_irqs(struct vcpu *v)
 void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int virq)
 {
     uint8_t priority;
-    struct vgic_irq_rank *rank = vgic_rank_irq(v, virq);
     struct pending_irq *iter, *n = irq_to_pending(v, virq);
     unsigned long flags;
     bool_t running;
 
-    vgic_lock_rank(v, rank, flags);
     priority = v->domain->arch.vgic.handler->get_irq_priority(v, virq);
-    vgic_unlock_rank(v, rank, flags);
 
     spin_lock_irqsave(&v->arch.vgic.lock, flags);
 
@@ -478,6 +481,69 @@ void vgic_vcpu_inject_spi(struct domain *d, unsigned int virq)
     vgic_vcpu_inject_irq(v, virq);
 }
 
+#ifdef HAS_GICV3
+void vgic_vcpu_inject_lpi(struct domain *d, unsigned int vdevid,
+                          unsigned int eventID)
+{
+    struct vdevice_table dt_entry;
+    struct vitt vitt_entry;
+    uint32_t col_id, target;
+
+    if ( eventID > gic_nr_event_ids() )
+    {
+        dprintk(XENLOG_WARNING,
+                "Invalid eventID %"PRId32" ..dropping\n", vdevid);
+        return;
+    }
+
+    if ( vits_get_vdevice_entry(d, vdevid, &dt_entry) )
+    {
+        dprintk(XENLOG_WARNING,
+                "Failed to read dt entry for dev 0x%"PRIx32" ..dropping\n",
+                vdevid);
+        return;
+    }
+
+    if ( dt_entry.vitt_ipa == INVALID_PADDR )
+    {
+        dprintk(XENLOG_WARNING,
+                "Event %"PRId32" of dev 0x%"PRIx32" is invalid..dropping\n",
+                eventID, vdevid);
+        return;
+    }
+
+    if ( vits_get_vitt_entry(d, vdevid, eventID, &vitt_entry) )
+    {
+        dprintk(XENLOG_WARNING,
+                "Event %"PRId32" of dev 0x%"PRIx32" is invalid..dropping\n",
+                eventID, vdevid);
+        return;
+    }
+
+    col_id = vitt_entry.vcollection;
+
+    if ( !vitt_entry.valid || !is_valid_collection(d, col_id) ||
+         !is_domain_lpi(d, vitt_entry.vlpi) )
+    {
+        dprintk(XENLOG_WARNING,
+                "vlpi %"PRId32" for dev 0x%"PRIx32" is not valid..dropping\n",
+                vitt_entry.vlpi, vdevid);
+        return;
+    }
+
+    target = d->arch.vgic.vits->collections[col_id].target_address;
+    if ( target > d->max_vcpus )
+    {
+        dprintk(XENLOG_WARNING,
+                "vlpi %"PRId32" got invalid target %"PRId32" dev 0x%"PRIx32"\n",
+                vitt_entry.vlpi, target, vdevid);
+        return;
+    }
+
+    vgic_vcpu_inject_irq(d->vcpu[target], vitt_entry.vlpi);
+}
+#endif
+
 void arch_evtchn_inject(struct vcpu *v)
 {
     vgic_vcpu_inject_irq(v, v->domain->arch.evtchn_irq);
diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h
index 110516a..870c9a8 100644
--- a/xen/include/asm-arm/gic-its.h
+++ b/xen/include/asm-arm/gic-its.h
@@ -315,6 +315,10 @@ struct its_device {
     u32                     nr_lpis;
     /* Physical Device id */
     u32                     device_id;
+    /* Virtual Device id */
+    u32                     virt_device_id;
+    /* Domain id */
+    int                     domain_id;
     /* RB-tree entry */
     struct rb_node          node;
 };
@@ -353,17 +357,23 @@ struct gic_its_info {
     struct its_node_info *its_hw;
 };
 
+bool_t is_valid_collection(struct domain *d, uint32_t col);
 bool_t is_domain_lpi(struct domain *d, unsigned int lpi);
 hw_irq_controller *its_get_host_lpi_type(void);
 hw_irq_controller *its_get_guest_lpi_type(void);
+u32 its_get_nr_event_ids(void);
 int its_init(struct rdist_prop *rdists);
 int its_cpu_init(void);
+void its_set_lpi_properties(struct irq_desc *desc,
+                            const cpumask_t *cpu_mask,
+                            unsigned int priority);
 int vits_get_vitt_entry(struct domain *d, uint32_t devid,
                         uint32_t event, struct vitt *entry);
 int vits_get_vdevice_entry(struct domain *d, uint32_t devid,
                            struct vdevice_table *entry);
 void vits_setup_hw(struct gic_its_info *info);
 int vits_map_lpi_prop(struct domain *d);
+uint8_t vits_get_priority(struct vcpu *v, uint32_t pid);
 
 #endif /* __ASM_ARM_GIC_ITS_H__ */
 /*
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 2edf9de..15bd6eb 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -226,6 +226,9 @@ extern void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mas
 extern int gic_route_irq_to_guest(struct domain *, unsigned int virq,
                                   struct irq_desc *desc,
                                   unsigned int priority);
+extern int gic_route_lpi_to_guest(struct domain *d, unsigned int virq,
+                                   struct irq_desc *desc,
+                                   unsigned int priority);
 
 /* Remove an IRQ passthrough to a guest */
 int gic_remove_irq_from_guest(struct domain *d, unsigned int virq,
@@ -282,8 +285,12 @@ extern void send_SGI_allbutself(enum gic_sgi sgi);
 /* print useful debug info */
 extern void gic_dump_info(struct vcpu *v);
 
-/* Number of interrupt lines */
+/* Number of interrupt lines (PPIs + SGIs + SPIs)*/
 extern unsigned int gic_number_lines(void);
+/* Check if irq is valid */
+bool_t gic_is_valid_irq(unsigned int irq);
+/* Number of event ids supported */
+extern unsigned int gic_nr_event_ids(void);
 /* LPI support info */
 bool_t gic_lpi_supported(void);
 
@@ -307,6 +314,8 @@ struct gic_info {
     const struct dt_device_node *node;
     /* Number of IRQ ID bits supported */
     uint32_t nr_id_bits;
+    /* Number of Event IDs supported */
+    uint32_t nr_event_ids;
     /* LPIs are support information */
     bool_t lpi_supported; 
 };
diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
index 5923127..00d5345 100644
--- a/xen/include/asm-arm/irq.h
+++ b/xen/include/asm-arm/irq.h
@@ -49,6 +49,8 @@ bool_t is_assignable_irq(unsigned int irq);
 void init_IRQ(void);
 void init_secondary_IRQ(void);
 
+int route_lpi_to_guest(struct domain *d, unsigned int vid,
+                       unsigned int irq, const char *devname);
 int route_irq_to_guest(struct domain *d, unsigned int virq,
                        unsigned int irq, const char *devname);
 int release_guest_irq(struct domain *d, unsigned int irq);
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 41cadb1..b11faa0 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -196,6 +196,8 @@ 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 virq);
 extern void vgic_vcpu_inject_spi(struct domain *d, unsigned int virq);
+extern void vgic_vcpu_inject_lpi(struct domain *d, unsigned int devid,
+                                 unsigned int eventID);
 extern void vgic_clear_pending_irqs(struct vcpu *v);
 extern struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq);
 extern struct pending_irq *spi_to_pending(struct domain *d, unsigned int irq);
-- 
1.7.9.5

  parent reply	other threads:[~2015-07-27 11:11 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-27 11:11 [PATCH v5 00/22] Add ITS support vijay.kilari
2015-07-27 11:11 ` [PATCH v5 01/22] xen/arm: Return success if dt node does not have irq mapping vijay.kilari
2015-07-28 13:13   ` Julien Grall
2015-07-28 13:23     ` Ian Campbell
2015-07-28 13:27       ` Julien Grall
2015-09-02 15:25   ` Ian Campbell
2015-07-27 11:11 ` [PATCH v5 02/22] xen/arm: Add bitmap_find_next_zero_area helper function vijay.kilari
2015-08-11 13:53   ` Jan Beulich
2015-07-27 11:11 ` [PATCH v5 03/22] xen: Add log2 functionality vijay.kilari
2015-07-27 11:11 ` [PATCH v5 04/22] xen/arm: Set nr_cpu_ids to available number of cpus vijay.kilari
2015-07-28 13:21   ` Julien Grall
2015-07-27 11:11 ` [PATCH v5 05/22] xen/arm: ITS: Port ITS driver to Xen vijay.kilari
2015-07-28 16:46   ` Julien Grall
2015-07-29 15:22     ` Vijay Kilari
2015-07-29 16:06       ` Ian Campbell
2015-07-29 16:18         ` Vijay Kilari
2015-07-31 10:28     ` Vijay Kilari
2015-07-31 11:10       ` Julien Grall
2015-07-27 11:11 ` [PATCH v5 06/22] xen/arm: ITS: Add helper functions to manage its_devices vijay.kilari
2015-07-27 11:11 ` [PATCH v5 07/22] xen/arm: ITS: Add virtual ITS driver vijay.kilari
2015-07-28 17:13   ` Julien Grall
2015-07-31  6:49     ` Vijay Kilari
2015-07-31 10:14       ` Julien Grall
2015-07-31 10:32         ` Ian Campbell
2015-07-27 11:11 ` [PATCH v5 08/22] xen/arm: ITS: Add virtual ITS commands support vijay.kilari
2015-07-28 18:04   ` Julien Grall
2015-07-31  6:57     ` Vijay Kilari
2015-07-31 10:16       ` Julien Grall
2015-07-27 11:11 ` [PATCH v5 09/22] xen/arm: ITS: Export ITS info to Virtual ITS vijay.kilari
2015-07-28 18:14   ` Julien Grall
2015-07-31  7:01     ` Vijay Kilari
2015-08-03 15:58       ` Julien Grall
2015-07-27 11:11 ` [PATCH v5 10/22] xen/arm: ITS: Add GITS registers emulation vijay.kilari
2015-07-28 19:01   ` Julien Grall
2015-07-31  7:25     ` Vijay Kilari
2015-07-31 10:28       ` Julien Grall
2015-08-01  8:50     ` Vijay Kilari
2015-08-03 11:19       ` Julien Grall
2015-07-27 11:11 ` [PATCH v5 11/22] xen/arm: ITS: Enable physical and virtual ITS driver compilation vijay.kilari
2015-07-27 11:11 ` [PATCH v5 12/22] xen/arm: ITS: Add GICR register emulation vijay.kilari
2015-07-30 17:04   ` Julien Grall
2015-07-31  9:08     ` Vijay Kilari
2015-07-31 11:05       ` Julien Grall
2015-08-01 10:25         ` Vijay Kilari
2015-08-01 15:51           ` Julien Grall
2015-08-03  9:36             ` Vijay Kilari
2015-08-03 13:01               ` Julien Grall
2015-08-03 13:51                 ` Vijay Kilari
2015-08-03 13:58                   ` Julien Grall
2015-08-04  6:55                     ` Vijay Kilari
2015-08-04  8:44                       ` Julien Grall
2015-07-27 11:11 ` [PATCH v5 13/22] xen/arm: ITS: Implement gic_is_lpi helper function vijay.kilari
2015-07-30 17:14   ` Julien Grall
2015-07-27 11:11 ` [PATCH v5 14/22] xen/arm: ITS: Allocate irq descriptors for LPIs vijay.kilari
2015-08-04 13:21   ` Julien Grall
2015-07-27 11:11 ` [PATCH v5 15/22] xen/arm: ITS: implement hw_irq_controller " vijay.kilari
2015-08-04 13:45   ` Julien Grall
2015-08-06  8:15     ` Vijay Kilari
2015-08-06 10:05       ` Julien Grall
2015-08-06 10:11         ` Julien Grall
2015-07-27 11:11 ` vijay.kilari [this message]
2015-08-04 14:54   ` [PATCH v5 16/22] xen/arm: ITS: Route LPIs Julien Grall
2015-07-27 11:11 ` [PATCH v5 17/22] xen/arm: ITS: Initialize physical ITS vijay.kilari
2015-08-17 19:00   ` Julien Grall
2015-07-27 11:12 ` [PATCH v5 18/22] xen/arm: ITS: Add domain specific ITS initialization vijay.kilari
2015-08-17 18:57   ` Julien Grall
2015-07-27 11:12 ` [PATCH v5 19/22] xen/arm: ITS: Add APIs to add and assign device vijay.kilari
2015-08-17 19:17   ` Julien Grall
2015-07-27 11:12 ` [PATCH v5 20/22] xen/arm: ITS: Map ITS translation space vijay.kilari
2015-08-17 19:20   ` Julien Grall
2015-08-18 19:14   ` Julien Grall
2015-08-18 22:37     ` Marc Zyngier
2015-09-02 15:45       ` Ian Campbell
2015-09-02 15:59         ` Marc Zyngier
2015-07-27 11:12 ` [PATCH v5 21/22] xen/arm: ITS: Generate ITS node for Dom0 vijay.kilari
2015-08-17 19:41   ` Julien Grall
2015-08-21 23:02     ` Vijay Kilari
2015-08-21 23:48       ` Julien Grall
2015-08-26 12:40     ` Vijay Kilari
2015-08-27  0:02       ` Julien Grall
2015-07-27 11:12 ` [PATCH v5 22/22] xen/arm: ITS: Add pci devices in ThunderX vijay.kilari

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1437995524-19772-17-git-send-email-vijay.kilari@gmail.com \
    --to=vijay.kilari@gmail.com \
    --cc=Ian.Campbell@citrix.com \
    --cc=Prasun.Kapoor@caviumnetworks.com \
    --cc=Vijaya.Kumar@caviumnetworks.com \
    --cc=julien.grall@citrix.com \
    --cc=manish.jaggi@caviumnetworks.com \
    --cc=stefano.stabellini@citrix.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).