@samitouri / QOSamiQemu / commits / 9ec3a7a53c

target/arm: GICv5 cpuif: Don't set HPPIV bit in GICv5PendingIrq::intid

In gic_hppi() we return the current highest priority pending interrupt in a GICv5PendingIrq struct. We try to set up the intid field of that struct to be the form that is used by the ICC_HPPIR register, which has a "valid" bit in bit 33. Unfortunately the GICv5PendingIrq defines the intid field as a uint32_t, so Coverity points out that the bit doesn't actually fit. Move the handling of the valid bit to the callsite, and make this function report "no pending interrupt" with GICv5PendingIrq::prio == PRIO_IDLE, consistently with how we use this struct in other places. CID: 1659594 Fixes: 9edad4ff3 ("target/arm: GICv5 cpuif: Implement ICC_HPPIR_EL1") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260512093856.3197700-3-peter.maydell@linaro.org

Peter Maydell committed May 12, 2026 at 10:38 UTC 9ec3a7a53ce8ba8b09bfe567c2be66ce2ecb1df6
2 files changed +12 -8
include/hw/intc/arm_gicv5_types.h
+2
@@ -97,6 +97,8 @@ typedef enum GICv5TriggerMode {
97 *
98 * In this struct the intid includes the interrupt type in bits
99 * [31:29] (i.e. it is in the form defined by R_TJPHS).
100 + *
101 + * "No pending interrupt" is represented by @prio == PRIO_IDLE.
102 */
103 typedef struct GICv5PendingIrq {
104 uint32_t intid;
target/arm/tcg/gicv5-cpuif.c
+10 -8
@@ -129,10 +129,9 @@ static GICv5PendingIrq gic_hppi(CPUARMState *env, GICv5Domain domain)
129 {
130 /*
131 * Return the current highest priority pending interrupt for the
132 - * specified domain, if it has sufficient priority to preempt. The
133 - * intid field of the return value will be in the format of the
134 - * ICC_HPPIR register (and will be zero if and only if there is no
135 - * interrupt that can preempt).
132 + * specified domain, if it has sufficient priority to preempt.
133 + * If there is no interrupt that can preempt we signal this by
134 + * returning a struct with prio == PRIO_IDLE.
135 */
136
137 GICv5Common *gic = gicv5_get_gic(env);
@@ -166,7 +165,6 @@ static GICv5PendingIrq gic_hppi(CPUARMState *env, GICv5Domain domain)
165 best.prio >= gic_running_prio(env, domain)) {
166 return (GICv5PendingIrq) { .intid = 0, .prio = PRIO_IDLE };
167 }
169 - best.intid |= R_ICC_HPPIR_EL1_HPPIV_MASK;
168 return best;
169 }
170
@@ -575,7 +573,12 @@ static uint64_t gic_icc_hppir_el1_read(CPUARMState *env, const ARMCPRegInfo *ri)
573 {
574 GICv5Domain domain = gicv5_logical_domain(env);
575 GICv5PendingIrq hppi = gic_hppi(env, domain);
578 - return hppi.intid;
576 +
577 + if (hppi.prio == PRIO_IDLE) {
578 + /* No valid interrupt */
579 + return 0;
580 + }
581 + return hppi.intid | R_ICC_HPPIR_EL1_HPPIV_MASK;
582 }
583
584 static bool gic_hppi_is_nmi(CPUARMState *env, GICv5PendingIrq hppi,
@@ -602,13 +605,12 @@ static uint64_t gicr_cdia_read(CPUARMState *env, const ARMCPRegInfo *ri)
605
606 bool cdnmia = ri->opc2 == 1;
607
605 - if (!hppi.intid) {
608 + if (hppi.prio == PRIO_IDLE) {
609 /* No interrupt available to acknowledge */
610 trace_gicv5_gicr_cdia_fail(domain,
611 "no available interrupt to acknowledge");
612 return 0;
613 }
611 - assert(hppi.prio != PRIO_IDLE);
614
615 if (gic_hppi_is_nmi(env, hppi, domain) != cdnmia) {
616 /* GICR CDIA only acknowledges non-NMI; GICR CDNMIA only NMI */