In hardware, the GICv5 stream protocol is a set of 1:1 links between the IRS and the attached CPU interfaces, which means the IRS always implicitly knows which CPU it has received a command from. For QEMU, these are all function calls, and so the IRS doesn't know unless we pass the cpuidx. For most of the stream protocol commands, the IRS so far hasn't needed to know, because operations on physical interrupts are the same whichever CPU requests them. But for virtual interrupts the operation will be on the interrupts of whichever VM owns the VPE currently resident on the requesting CPU, so we do need to know which one that is.
Add a cpuidx argument to every function corresponding to a stream protocol command that can operate on a virtual interrupt. Signed-off-by: Peter Maydell <[email protected]> --- hw/intc/arm_gicv5.c | 18 ++++++++++-------- include/hw/intc/arm_gicv5_stream.h | 25 +++++++++++++++++-------- target/arm/tcg/gicv5-cpuif.c | 21 ++++++++++++--------- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/hw/intc/arm_gicv5.c b/hw/intc/arm_gicv5.c index 01ee303d393..fc1f09f51e8 100644 --- a/hw/intc/arm_gicv5.c +++ b/hw/intc/arm_gicv5.c @@ -568,7 +568,8 @@ static hwaddr l1_vmte_addr(GICv5Common *cs, const GICv5VMTConfig *cfg, } void gicv5_set_priority(GICv5Common *cs, uint32_t id, uint8_t priority, - GICv5Domain domain, GICv5IntType type, bool virtual) + GICv5Domain domain, GICv5IntType type, bool virtual, + uint32_t cpuidx) { GICv5 *s = ARM_GICV5(cs); uint32_t iaffid; @@ -623,7 +624,8 @@ void gicv5_set_priority(GICv5Common *cs, uint32_t id, uint8_t priority, } void gicv5_set_enabled(GICv5Common *cs, uint32_t id, bool enabled, - GICv5Domain domain, GICv5IntType type, bool virtual) + GICv5Domain domain, GICv5IntType type, bool virtual, + uint32_t cpuidx) { GICv5 *s = ARM_GICV5(cs); uint32_t iaffid; @@ -676,7 +678,7 @@ void gicv5_set_enabled(GICv5Common *cs, uint32_t id, bool enabled, void gicv5_set_pending(GICv5Common *cs, uint32_t id, bool pending, GICv5Domain domain, GICv5IntType type, bool virtual, - uint32_t vm) + uint32_t vm, uint32_t cpuidx) { GICv5 *s = ARM_GICV5(cs); uint32_t iaffid; @@ -729,7 +731,7 @@ void gicv5_set_pending(GICv5Common *cs, uint32_t id, bool pending, void gicv5_set_handling(GICv5Common *cs, uint32_t id, GICv5HandlingMode handling, GICv5Domain domain, - GICv5IntType type, bool virtual) + GICv5IntType type, bool virtual, uint32_t cpuidx) { GICv5 *s = ARM_GICV5(cs); @@ -777,7 +779,7 @@ void gicv5_set_handling(GICv5Common *cs, uint32_t id, void gicv5_set_target(GICv5Common *cs, uint32_t id, uint32_t iaffid, GICv5RoutingMode irm, GICv5Domain domain, - GICv5IntType type, bool virtual) + GICv5IntType type, bool virtual, uint32_t cpuidx) { GICv5 *s = ARM_GICV5(cs); uint32_t old_iaffid; @@ -889,7 +891,7 @@ static uint64_t spi_state_to_icsr(GICv5SPIState *spi) } uint64_t gicv5_request_config(GICv5Common *cs, uint32_t id, GICv5Domain domain, - GICv5IntType type, bool virtual) + GICv5IntType type, bool virtual, uint32_t cpuidx) { GICv5 *s = ARM_GICV5(cs); uint64_t icsr; @@ -933,7 +935,7 @@ uint64_t gicv5_request_config(GICv5Common *cs, uint32_t id, GICv5Domain domain, } void gicv5_activate(GICv5Common *cs, uint32_t id, GICv5Domain domain, - GICv5IntType type, bool virtual) + GICv5IntType type, bool virtual, uint32_t cpuidx) { GICv5 *s = ARM_GICV5(cs); uint32_t iaffid; @@ -991,7 +993,7 @@ void gicv5_activate(GICv5Common *cs, uint32_t id, GICv5Domain domain, } void gicv5_deactivate(GICv5Common *cs, uint32_t id, GICv5Domain domain, - GICv5IntType type, bool virtual) + GICv5IntType type, bool virtual, uint32_t cpuidx) { GICv5 *s = ARM_GICV5(cs); uint32_t iaffid; diff --git a/include/hw/intc/arm_gicv5_stream.h b/include/hw/intc/arm_gicv5_stream.h index ea27d6aec0f..0d62f86820d 100644 --- a/include/hw/intc/arm_gicv5_stream.h +++ b/include/hw/intc/arm_gicv5_stream.h @@ -59,6 +59,7 @@ GICv5CPUIFStatus gicv5_set_gicv5state(ARMCPU *cpu, GICv5Common *cs, * @domain: interrupt Domain to act on * @type: interrupt type (LPI or SPI) * @virtual: true if this is a virtual interrupt + * @cpuidx: IRS CPU index of this CPU interface * * Set priority of an interrupt; matches stream interface SetPriority * command from CPUIF to IRS. There is no report back of @@ -66,7 +67,7 @@ GICv5CPUIFStatus gicv5_set_gicv5state(ARMCPU *cpu, GICv5Common *cs, */ void gicv5_set_priority(GICv5Common *cs, uint32_t id, uint8_t priority, GICv5Domain domain, - GICv5IntType type, bool virtual); + GICv5IntType type, bool virtual, uint32_t cpuidx); /** * gicv5_set_enabled @@ -76,6 +77,7 @@ void gicv5_set_priority(GICv5Common *cs, uint32_t id, * @domain: interrupt Domain to act on * @type: interrupt type (LPI or SPI) * @virtual: true if this is a virtual interrupt + * @cpuidx: IRS CPU index of this CPU interface * * Set enabled state of an interrupt; matches stream interface * SetEnabled command from CPUIF to IRS. There is no report back of @@ -83,7 +85,7 @@ void gicv5_set_priority(GICv5Common *cs, uint32_t id, */ void gicv5_set_enabled(GICv5Common *cs, uint32_t id, bool enabled, GICv5Domain domain, - GICv5IntType type, bool virtual); + GICv5IntType type, bool virtual, uint32_t cpuidx); /** * gicv5_set_pending @@ -94,6 +96,7 @@ void gicv5_set_enabled(GICv5Common *cs, uint32_t id, * @type: interrupt type (LPI or SPI) * @virtual: true if this is a virtual interrupt * @vm: VM ID (for virtual interrupts) + * @cpuidx: IRS CPU index of this CPU interface * * Set pending state of an interrupt; matches stream interface * SetPending command from CPUIF to IRS. There is no report back of @@ -101,7 +104,8 @@ void gicv5_set_enabled(GICv5Common *cs, uint32_t id, */ void gicv5_set_pending(GICv5Common *cs, uint32_t id, bool pending, GICv5Domain domain, - GICv5IntType type, bool virtual, uint32_t vm); + GICv5IntType type, bool virtual, uint32_t vm, + uint32_t cpuidx); /** * gicv5_set_handling @@ -111,6 +115,7 @@ void gicv5_set_pending(GICv5Common *cs, uint32_t id, * @domain: interrupt Domain to act on * @type: interrupt type (LPI or SPI) * @virtual: true if this is a virtual interrupt + * @cpuidx: IRS CPU index of this CPU interface * * Set handling mode of an interrupt (edge/level); matches stream * interface SetHandling command from CPUIF to IRS. There is no report @@ -118,7 +123,7 @@ void gicv5_set_pending(GICv5Common *cs, uint32_t id, */ void gicv5_set_handling(GICv5Common *cs, uint32_t id, GICv5HandlingMode handling, GICv5Domain domain, - GICv5IntType type, bool virtual); + GICv5IntType type, bool virtual, uint32_t cpuidx); /** * gicv5_set_target @@ -129,6 +134,7 @@ void gicv5_set_handling(GICv5Common *cs, uint32_t id, * @domain: interrupt Domain to act on * @type: interrupt type (LPI or SPI) * @virtual: true if this is a virtual interrupt + * @cpuidx: IRS CPU index of this CPU interface * * Set handling mode of an interrupt (edge/level); matches stream * interface SetHandling command from CPUIF to IRS. There is no report @@ -136,7 +142,7 @@ void gicv5_set_handling(GICv5Common *cs, uint32_t id, */ void gicv5_set_target(GICv5Common *cs, uint32_t id, uint32_t iaffid, GICv5RoutingMode irm, GICv5Domain domain, - GICv5IntType type, bool virtual); + GICv5IntType type, bool virtual, uint32_t cpuidx); /** * gicv5_request_config @@ -145,6 +151,7 @@ void gicv5_set_target(GICv5Common *cs, uint32_t id, uint32_t iaffid, * @domain: interrupt domain to act on * @type: interrupt type (LPI or SPI) * @virtual: true if this is a virtual interrupt + * @cpuidx: IRS CPU index of this CPU interface * * Query the current configuration of an interrupt; matches stream * interface RequestConfig command from CPUIF to IRS and the @@ -159,7 +166,7 @@ void gicv5_set_target(GICv5Common *cs, uint32_t id, uint32_t iaffid, * ICC_ICSR_EL1. */ uint64_t gicv5_request_config(GICv5Common *cs, uint32_t id, GICv5Domain domain, - GICv5IntType type, bool virtual); + GICv5IntType type, bool virtual, uint32_t cpuidx); /** * gicv5_activate @@ -168,6 +175,7 @@ uint64_t gicv5_request_config(GICv5Common *cs, uint32_t id, GICv5Domain domain, * @domain: interrupt domain to act on * @type: interrupt type (LPI or SPI) * @virtual: true if this is a virtual interrupt + * @cpuidx: IRS CPU index of this CPU interface * * Activate the IRS's highest priority pending interrupt; matches the * stream interface's Activate command. @@ -182,7 +190,7 @@ uint64_t gicv5_request_config(GICv5Common *cs, uint32_t id, GICv5Domain domain, * its hppi[][] array. */ void gicv5_activate(GICv5Common *cs, uint32_t id, GICv5Domain domain, - GICv5IntType type, bool virtual); + GICv5IntType type, bool virtual, uint32_t cpuidx); /** * gicv5_forward_interrupt @@ -230,12 +238,13 @@ GICv5PendingIrq gicv5_get_hppi(GICv5Common *cs, GICv5Domain domain, * @domain: interrupt Domain to act on * @type: interrupt type (LPI or SPI) * @virtual: true if this is a virtual interrupt + * @cpuidx: IRS CPU index of this CPU interface * * Deactivate the specified interrupt. There is no report back of * success/failure to the CPUIF in the protocol. */ void gicv5_deactivate(GICv5Common *cs, uint32_t id, GICv5Domain domain, - GICv5IntType type, bool virtual); + GICv5IntType type, bool virtual, uint32_t cpuidx); /** * gicv5_set_resident diff --git a/target/arm/tcg/gicv5-cpuif.c b/target/arm/tcg/gicv5-cpuif.c index 406c980af5e..ed34196d7ce 100644 --- a/target/arm/tcg/gicv5-cpuif.c +++ b/target/arm/tcg/gicv5-cpuif.c @@ -680,7 +680,7 @@ static void gic_cddis_write(CPUARMState *env, const ARMCPRegInfo *ri, bool virtual; GICv5Domain domain = gicv5_domain_for_insn(env, ri, &virtual); - gicv5_set_enabled(gic, id, false, domain, type, virtual); + gicv5_set_enabled(gic, id, false, domain, type, virtual, env->gicv5.cpuidx); } static void gic_cden_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -692,7 +692,7 @@ static void gic_cden_write(CPUARMState *env, const ARMCPRegInfo *ri, bool virtual; GICv5Domain domain = gicv5_domain_for_insn(env, ri, &virtual); - gicv5_set_enabled(gic, id, true, domain, type, virtual); + gicv5_set_enabled(gic, id, true, domain, type, virtual, env->gicv5.cpuidx); } static void gic_cdpri_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -705,7 +705,8 @@ static void gic_cdpri_write(CPUARMState *env, const ARMCPRegInfo *ri, bool virtual; GICv5Domain domain = gicv5_domain_for_insn(env, ri, &virtual); - gicv5_set_priority(gic, id, priority, domain, type, virtual); + gicv5_set_priority(gic, id, priority, domain, type, virtual, + env->gicv5.cpuidx); } static void gic_cdaff_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -719,7 +720,8 @@ static void gic_cdaff_write(CPUARMState *env, const ARMCPRegInfo *ri, bool virtual; GICv5Domain domain = gicv5_domain_for_insn(env, ri, &virtual); - gicv5_set_target(gic, id, iaffid, irm, domain, type, virtual); + gicv5_set_target(gic, id, iaffid, irm, domain, type, virtual, + env->gicv5.cpuidx); } static void gic_cdpend_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -759,7 +761,8 @@ static void gic_cdpend_write(CPUARMState *env, const ARMCPRegInfo *ri, } } - gicv5_set_pending(gic, id, pending, domain, type, virtual, vm); + gicv5_set_pending(gic, id, pending, domain, type, virtual, vm, + env->gicv5.cpuidx); } static void gic_cdrcfg_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -772,7 +775,7 @@ static void gic_cdrcfg_write(CPUARMState *env, const ARMCPRegInfo *ri, GICv5Domain domain = gicv5_domain_for_insn(env, ri, &virtual); env->gicv5_cpuif.icc_icsr_el1 = - gicv5_request_config(gic, id, domain, type, virtual); + gicv5_request_config(gic, id, domain, type, virtual, env->gicv5.cpuidx); } static void gic_cdhm_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -785,7 +788,7 @@ static void gic_cdhm_write(CPUARMState *env, const ARMCPRegInfo *ri, bool virtual; GICv5Domain domain = gicv5_domain_for_insn(env, ri, &virtual); - gicv5_set_handling(gic, id, hm, domain, type, virtual); + gicv5_set_handling(gic, id, hm, domain, type, virtual, env->gicv5.cpuidx); } static uint64_t gic_ppi_hmr_read(CPUARMState *env, const ARMCPRegInfo *ri) @@ -1466,7 +1469,7 @@ static uint64_t gicr_cdia_read(CPUARMState *env, const ARMCPRegInfo *ri) * name of the stream command, does both "set Active" and * "maybe set not Pending" as a single atomic action. */ - gicv5_activate(gic, id, domain, type, virtual); + gicv5_activate(gic, id, domain, type, virtual, env->gicv5.cpuidx); break; default: g_assert_not_reached(); @@ -1543,7 +1546,7 @@ static void gic_cddi_write(CPUARMState *env, const ARMCPRegInfo *ri, case GICV5_LPI: case GICV5_SPI: /* Tell the IRS to deactivate this interrupt */ - gicv5_deactivate(gic, id, domain, type, virtual); + gicv5_deactivate(gic, id, domain, type, virtual, env->gicv5.cpuidx); break; default: break; -- 2.43.0
