From 7175a562f157d39725ab396e39c1e8e410d206b3 Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Tue, 18 Jun 2024 16:22:20 +0100 Subject: hw/intc/arm_gic: Fix deactivation of SPI lines Julien reported that he has seen strange behaviour when running Xen on QEMU using GICv2. When Xen migrates a guest's vCPU from one pCPU to another while the vCPU is handling an interrupt, the guest is unable to properly deactivate interrupts. Looking at it a little closer, our GICv2 model treats deactivation of SPI lines as if they were PPI's, i.e banked per CPU core. The state for active interrupts should only be banked for PPI lines, not for SPI lines. Make deactivation of SPI lines unbanked, similar to how we handle writes to GICD_ICACTIVER. Reported-by: Julien Grall Signed-off-by: Edgar E. Iglesias Message-id: 20240605143044.2029444-2-edgar.iglesias@gmail.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/intc/gic_internal.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index 8d29b40..8ddbf55 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -280,6 +280,8 @@ static inline void gic_set_active(GICState *s, int irq, int cpu) static inline void gic_clear_active(GICState *s, int irq, int cpu) { + unsigned int cm; + if (gic_is_vcpu(cpu)) { uint32_t *entry = gic_get_lr_entry(s, irq, cpu); GICH_LR_CLEAR_ACTIVE(*entry); @@ -301,11 +303,13 @@ static inline void gic_clear_active(GICState *s, int irq, int cpu) * the GIC is secure. */ if (!s->security_extn || GIC_DIST_TEST_GROUP(phys_irq, 1 << rcpu)) { - GIC_DIST_CLEAR_ACTIVE(phys_irq, 1 << rcpu); + cm = phys_irq < GIC_INTERNAL ? 1 << rcpu : ALL_CPU_MASK; + GIC_DIST_CLEAR_ACTIVE(phys_irq, cm); } } } else { - GIC_DIST_CLEAR_ACTIVE(irq, 1 << cpu); + cm = irq < GIC_INTERNAL ? 1 << cpu : ALL_CPU_MASK; + GIC_DIST_CLEAR_ACTIVE(irq, cm); } } -- cgit v1.1