- tests: bump QOS_PATH_MAX_ELEMENT_SIZE again - softmmu/physmem: fix memory leak in dirty_memory_extend() - crypto: run qcrypto_pbkdf2_count_iters in a new thread - hw/audio/virtio-sound: fix heap buffer overflow - hw/intc/arm_gic: fix spurious level triggered interrupts - ui/sdl2: set swap interval explicitly when OpenGL is enabled - target/riscv/kvm: tolerate KVM disable ext errors - virtio: remove virtio_tswap16s() call in vring_packed_event_read() - block: fix -Werror=maybe-uninitialized false-positive - hw/remote/vfio-user: Fix config space access byte order - hw/loongarch/virt: Fix memory leak - hw/intc/riscv_aplic: APLICs should add child earlier than realize - stdvga: fix screen blanking - ui/gtk: Draw guest frame at refresh cycle - target/i386: fix size of EBP writeback in gen_enter() - virtio-net: drop too short packets early - target/ppc: Fix lxv/stxv MSR facility check - target/ppc: Fix lxvx/stxvx facility check - virtio-snd: add max size bounds check in input cb(CVE-2024-7730) Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com> (cherry picked from commit e2eb79f1867bb8d8d870e758f06d2a32b3a4fc8a)
83 lines
3.9 KiB
Diff
83 lines
3.9 KiB
Diff
From 0cb9a00d295cbf0ade0a55cea1039aec793fddf0 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jan=20Kl=C3=B6tzke?= <jan.kloetzke@kernkonzept.com>
|
|
Date: Fri, 13 Sep 2024 15:31:50 +0100
|
|
Subject: [PATCH] hw/intc/arm_gic: fix spurious level triggered interrupts
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
On GICv2 and later, level triggered interrupts are pending when either
|
|
the interrupt line is asserted or the interrupt was made pending by a
|
|
GICD_ISPENDRn write. Making a level triggered interrupt pending by
|
|
software persists until either the interrupt is acknowledged or cleared
|
|
by writing GICD_ICPENDRn. As long as the interrupt line is asserted,
|
|
the interrupt is pending in any case.
|
|
|
|
This logic is transparently implemented in gic_test_pending() for
|
|
GICv1 and GICv2. The function combines the "pending" irq_state flag
|
|
(used for edge triggered interrupts and software requests) and the
|
|
line status (tracked in the "level" field). However, we also
|
|
incorrectly set the pending flag on a guest write to GICD_ISENABLERn
|
|
if the line of a level triggered interrupt was asserted. This keeps
|
|
the interrupt pending even if the line is de-asserted after some
|
|
time.
|
|
|
|
This incorrect logic is a leftover of the initial 11MPCore GIC
|
|
implementation. That handles things slightly differently to the
|
|
architected GICv1 and GICv2. The 11MPCore TRM does not give a lot of
|
|
detail on the corner cases of its GIC's behaviour, and historically
|
|
we have not wanted to investigate exactly what it does in reality, so
|
|
QEMU's GIC model takes the approach of "retain our existing behaviour
|
|
for 11MPCore, and implement the architectural standard for later GIC
|
|
revisions".
|
|
|
|
On that basis, commit 8d999995e45c10 in 2013 is where we added the
|
|
"level-triggered interrupt with the line asserted" handling to
|
|
gic_test_pending(), and we deliberately kept the old behaviour of
|
|
gic_test_pending() for REV_11MPCORE. That commit should have added
|
|
the "only if 11MPCore" condition to the setting of the pending bit on
|
|
writes to GICD_ISENABLERn, but forgot it.
|
|
|
|
Add the missing "if REV_11MPCORE" condition, so that our behaviour
|
|
on GICv1 and GICv2 matches the GIC architecture requirements.
|
|
|
|
Cc: qemu-stable@nongnu.org
|
|
Fixes: 8d999995e45c10 ("arm_gic: Fix GIC pending behavior")
|
|
Signed-off-by: Jan Klötzke <jan.kloetzke@kernkonzept.com>
|
|
Message-id: 20240911114826.3558302-1-jan.kloetzke@kernkonzept.com
|
|
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
|
[PMM: expanded comment a little and converted to coding-style form;
|
|
expanded commit message with the historical backstory]
|
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
|
(cherry picked from commit 110684c9a69a02cbabfbddcd3afa921826ad565c)
|
|
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
|
---
|
|
hw/intc/arm_gic.c | 11 ++++++++---
|
|
1 file changed, 8 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
|
|
index 074cf50af2..dfe7a0a729 100644
|
|
--- a/hw/intc/arm_gic.c
|
|
+++ b/hw/intc/arm_gic.c
|
|
@@ -1263,9 +1263,14 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
|
|
trace_gic_enable_irq(irq + i);
|
|
}
|
|
GIC_DIST_SET_ENABLED(irq + i, cm);
|
|
- /* If a raised level triggered IRQ enabled then mark
|
|
- is as pending. */
|
|
- if (GIC_DIST_TEST_LEVEL(irq + i, mask)
|
|
+ /*
|
|
+ * If a raised level triggered IRQ enabled then mark
|
|
+ * it as pending on 11MPCore. For other GIC revisions we
|
|
+ * handle the "level triggered and line asserted" check
|
|
+ * at the other end in gic_test_pending().
|
|
+ */
|
|
+ if (s->revision == REV_11MPCORE
|
|
+ && GIC_DIST_TEST_LEVEL(irq + i, mask)
|
|
&& !GIC_DIST_TEST_EDGE_TRIGGER(irq + i)) {
|
|
DPRINTF("Set %d pending mask %x\n", irq + i, mask);
|
|
GIC_DIST_SET_PENDING(irq + i, mask);
|
|
--
|
|
2.41.0.windows.1
|
|
|