[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 |