summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicardo Koller2021-07-03 01:37:01 +0200
committerPeter Maydell2021-07-09 17:09:12 +0200
commitf4ec71d07cd2375c9080fbd4e85beffd05d73a11 (patch)
tree0daf9ee73f7b0525c93d5fee784a463f1db2670b
parenttests/boot-serial-test: Add STM32VLDISCOVERY board testcase (diff)
downloadqemu-f4ec71d07cd2375c9080fbd4e85beffd05d73a11.tar.gz
qemu-f4ec71d07cd2375c9080fbd4e85beffd05d73a11.tar.xz
qemu-f4ec71d07cd2375c9080fbd4e85beffd05d73a11.zip
hw/intc/arm_gicv3_cpuif: Fix virtual irq number check in icv_[dir|eoir]_write
icv_eoir_write() and icv_dir_write() ignore invalid virtual IRQ numbers (like LPIs). The issue is that these functions check against the number of implemented IRQs (QEMU's default is num_irq=288) which can be lower than the maximum virtual IRQ number (1020 - 1). The consequence is that if a hypervisor creates an LR for an IRQ between 288 and 1020, then the guest is unable to deactivate the resulting IRQ. Note that other functions that deal with large IRQ numbers, like icv_iar_read, check against 1020 and not against num_irq. Fix the checks by using GICV3_MAXIRQ (1020) instead of the number of implemented IRQs. Signed-off-by: Ricardo Koller <ricarkol@google.com> Message-id: 20210702233701.3369-1-ricarkol@google.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/intc/arm_gicv3_cpuif.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index 3e0641aff9..a032d505f5 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -1227,7 +1227,7 @@ static void icv_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
trace_gicv3_icv_dir_write(gicv3_redist_affid(cs), value);
- if (irq >= cs->gic->num_irq) {
+ if (irq >= GICV3_MAXIRQ) {
/* Also catches special interrupt numbers and LPIs */
return;
}
@@ -1262,7 +1262,7 @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1,
gicv3_redist_affid(cs), value);
- if (irq >= cs->gic->num_irq) {
+ if (irq >= GICV3_MAXIRQ) {
/* Also catches special interrupt numbers and LPIs */
return;
}