GIC CDEOI does a priority-drop for the current interrupt domain; when this is the virtual interrupt domain we must update the virtual APR register rather than a physical one.
Signed-off-by: Peter Maydell <[email protected]> --- target/arm/tcg/gicv5-cpuif.c | 21 ++++++++++++++++----- target/arm/tcg/trace-events | 1 + 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/target/arm/tcg/gicv5-cpuif.c b/target/arm/tcg/gicv5-cpuif.c index f8d58b5a537..aeacc812fe0 100644 --- a/target/arm/tcg/gicv5-cpuif.c +++ b/target/arm/tcg/gicv5-cpuif.c @@ -1221,13 +1221,24 @@ static void gic_cdeoi_write(CPUARMState *env, const ARMCPRegInfo *ri, */ bool virtual; GICv5Domain domain = gicv5_domain_for_insn(env, ri, &virtual); - uint64_t *apr = &env->gicv5_cpuif.icc_apr[domain]; - trace_gicv5_cdeoi(domain); + if (virtual) { + uint64_t *apr = &env->gicv5_cpuif.ich_apr_el2; - /* clear lowest bit, doing nothing if already zero */ - *apr &= *apr - 1; - gicv5_update_irq_fiq(env); + trace_gicv5_vcdeoi(); + + /* clear lowest bit, doing nothing if already zero */ + *apr &= *apr - 1; + gicv5_update_virq_vfiq(env); + } else { + uint64_t *apr = &env->gicv5_cpuif.icc_apr[domain]; + + trace_gicv5_cdeoi(domain); + + /* clear lowest bit, doing nothing if already zero */ + *apr &= *apr - 1; + gicv5_update_irq_fiq(env); + } } static void gic_cddi_write(CPUARMState *env, const ARMCPRegInfo *ri, diff --git a/target/arm/tcg/trace-events b/target/arm/tcg/trace-events index 75f40c44f26..8e7e4c119db 100644 --- a/target/arm/tcg/trace-events +++ b/target/arm/tcg/trace-events @@ -7,6 +7,7 @@ gicv5_recalc_virt_ppi_hppi(uint32_t id, uint8_t prio) "virtual domain new PPI HP gicv5_gicr_cdia_fail(int domain, const char *reason) "domain %d CDIA attempt failed: %s" gicv5_gicr_cdia(int domain, uint32_t id) "domain %d CDIA acknowledge of interrupt 0x%x" gicv5_cdeoi(int domain) "domain %d CDEOI performing priority drop" +gicv5_vcdeoi(void) "virtual interrupt domain CDEOI performing priority drop" gicv5_cddi(int domain, uint32_t id) "domain %d CDDI deactivating interrupt ID 0x%x" gicv5_update_irq_fiq(bool irq, bool fiq, bool nmi) "now IRQ %d FIQ %d NMI %d" gicv5_update_virq_vfiq(bool virq, bool vinmi) "now VIRQ %d VINMI %d" -- 2.43.0
