|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XEN PATCH v2 23/25] arm: new VGIC: its: Enable ITS emulation as a virtual MSI controller
Now that all ITS emulation functionality is in place, we advertise
the ITS device to the guest.
Based on Linux commit 0e4e82f154e38 by Andre Przywara
Signed-off-by: Mykyta Poturai <mykyta_poturai@xxxxxxxx>
---
xen/arch/arm/vgic/vgic-init.c | 7 +++++
xen/arch/arm/vgic/vgic-its.c | 2 +-
xen/arch/arm/vgic/vgic-mmio-v3.c | 44 ++++++++++++++++++++++++++++++--
xen/arch/arm/vgic/vgic-mmio.h | 5 ++++
4 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/xen/arch/arm/vgic/vgic-init.c b/xen/arch/arm/vgic/vgic-init.c
index 96f6669d38..fb27e440fc 100644
--- a/xen/arch/arm/vgic/vgic-init.c
+++ b/xen/arch/arm/vgic/vgic-init.c
@@ -18,6 +18,7 @@
#include <xen/lib.h>
#include <xen/sched.h>
#include <asm/new_vgic.h>
+#include <asm/gic_v3_its.h>
#include "vgic.h"
@@ -173,8 +174,14 @@ int domain_vgic_init(struct domain *d, unsigned int
nr_spis)
}
INIT_LIST_HEAD(&dist->lpi_list_head);
+ INIT_LIST_HEAD(&dist->lpi_translation_cache);
+ dist->lpi_list_count=0;
spin_lock_init(&dist->lpi_list_lock);
+ ret = vgic_v3_its_init_domain(d);
+ if ( ret )
+ return ret;
+
if ( dist->version == GIC_V2 )
ret = vgic_v2_map_resources(d);
else
diff --git a/xen/arch/arm/vgic/vgic-its.c b/xen/arch/arm/vgic/vgic-its.c
index 9534b26334..3b097bd0c4 100644
--- a/xen/arch/arm/vgic/vgic-its.c
+++ b/xen/arch/arm/vgic/vgic-its.c
@@ -168,7 +168,7 @@ static int update_lpi_config(struct domain *d, struct
vgic_irq *irq,
return 0;
}
-static int vgic_v3_lpi_sync_pending_status(struct domain *d, struct vgic_irq
*irq)
+int vgic_v3_lpi_sync_pending_status(struct domain *d, struct vgic_irq *irq)
{
struct vcpu *vcpu;
int byte_offset, bit_nr;
diff --git a/xen/arch/arm/vgic/vgic-mmio-v3.c b/xen/arch/arm/vgic/vgic-mmio-v3.c
index 0e3835d38a..84aa8568dc 100644
--- a/xen/arch/arm/vgic/vgic-mmio-v3.c
+++ b/xen/arch/arm/vgic/vgic-mmio-v3.c
@@ -29,7 +29,7 @@ bool vgic_has_its(struct domain *d)
if ( dist->version != GIC_V3 )
return false;
- return false;
+ return dist->has_its;
}
static struct vcpu *mpidr_to_vcpu(struct domain *d, unsigned long mpidr)
@@ -211,6 +211,29 @@ bool vgic_v3_emulate_reg(struct cpu_user_regs *regs, union
hsr hsr)
}
}
+void vgic_flush_pending_lpis(struct vcpu *vcpu)
+{
+ struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic;
+ struct vgic_irq *irq, *tmp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vgic_cpu->ap_list_lock, flags);
+
+ list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list)
+ {
+ if ( irq->intid >= VGIC_MIN_LPI )
+ {
+ spin_lock(&irq->irq_lock);
+ list_del(&irq->ap_list);
+ irq->vcpu = NULL;
+ spin_unlock(&irq->irq_lock);
+ vgic_put_irq(vcpu->domain, irq);
+ }
+ }
+
+ spin_unlock_irqrestore(&vgic_cpu->ap_list_lock, flags);
+}
+
/*
* The Revision field in the IIDR have the following meanings:
*
@@ -234,7 +257,15 @@ static unsigned long vgic_mmio_read_v3_misc(struct vcpu
*vcpu, paddr_t addr,
case GICD_TYPER:
value = vgic->nr_spis + VGIC_NR_PRIVATE_IRQS;
value = (value >> 5) - 1;
- value |= (INTERRUPT_ID_BITS_SPIS - 1) << 19;
+ if ( vgic_has_its(vcpu->domain) )
+ {
+ value |= (INTERRUPT_ID_BITS_ITS - 1) << 19;
+ value |= GICD_TYPE_LPIS;
+ }
+ else
+ {
+ value |= (INTERRUPT_ID_BITS_SPIS - 1) << 19;
+ }
break;
case GICD_TYPER2:
break;
@@ -365,6 +396,9 @@ static unsigned long vgic_mmio_read_v3r_typer(struct vcpu
*vcpu, paddr_t addr,
value = (u64)(mpidr & GENMASK(23, 0)) << 32;
value |= ((target_vcpu_id & 0xffff) << 8);
+ if ( vgic_has_its(vcpu->domain) )
+ value |= GICR_TYPER_PLPIS;
+
if ( vgic_mmio_vcpu_rdist_is_last(vcpu) )
value |= GICR_TYPER_LAST;
@@ -422,12 +456,18 @@ static void vgic_mmio_write_v3r_ctlr(struct vcpu *vcpu,
paddr_t addr,
GICR_CTLR_RWP);
if ( ctlr != GICR_CTLR_ENABLE_LPIS )
return;
+
+ vgic_flush_pending_lpis(vcpu);
+ vgic_its_invalidate_cache(vcpu->domain);
+ atomic_set(&vgic_cpu->ctlr, 0);
}
else
{
ctlr = atomic_cmpxchg(&vgic_cpu->ctlr, 0, GICR_CTLR_ENABLE_LPIS);
if ( ctlr != 0 )
return;
+
+ vgic_enable_lpis(vcpu);
}
}
diff --git a/xen/arch/arm/vgic/vgic-mmio.h b/xen/arch/arm/vgic/vgic-mmio.h
index 12f4d690f6..32fc7a6ba2 100644
--- a/xen/arch/arm/vgic/vgic-mmio.h
+++ b/xen/arch/arm/vgic/vgic-mmio.h
@@ -156,6 +156,7 @@ uint64_t update_64bit_reg(u64 reg, unsigned int offset,
unsigned int len,
#ifdef CONFIG_HAS_ITS
int vgic_its_inv_lpi(struct domain *d, struct vgic_irq *irq);
int vgic_its_invall(struct vcpu *vcpu);
+void vgic_its_invalidate_cache(struct domain *d);
#else
static inline int vgic_its_inv_lpi(struct domain *d, struct vgic_irq *irq)
{
@@ -166,6 +167,10 @@ static inline int vgic_its_invall(struct vcpu *vcpu)
{
return 0;
}
+
+static inline void vgic_its_invalidate_cache(struct domain *d)
+{
+}
#endif
#endif
--
2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |