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
next prev 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).