When the bit0 of the LLI register is configured as master 1,
it can cause incorrect data reading, and even lead to qemu crash.
Constructed 1 LLI item. The initial LLI register points to the address of the LLI item.
But the bit 0 of the LLI register is 1, which mean read from Master1 port.
According to the description in the PL080 manual, the address for the next LLI should be word aligned.
Configuration
../configure --target-list=arm-softmmu --enable-debug
Reproducer
./qemu-system-arm -M versatilepb -m 128M -nographic -S \
-device loader,addr=0x00002000,data=0x00000004,data-len=4 \
-device loader,addr=0x00002004,data=0x00001004,data-len=4 \
-device loader,addr=0x00002008,data=0x00000000,data-len=4 \
-device loader,addr=0x0000200c,data=0x9e4bf001,data-len=4 \
-device loader,addr=0x00000000,data=0x44332211,data-len=4 \
-device loader,addr=0x00000004,data=0x88776655,data-len=4 \
-device loader,addr=0x00001000,data=0x00000000,data-len=4 \
-device loader,addr=0x00001004,data=0x00000000,data-len=4 \
-device loader,addr=0x10130030,data=0x00000001,data-len=4 \
-device loader,addr=0x10130100,data=0x00000000,data-len=4 \
-device loader,addr=0x10130104,data=0x00001000,data-len=4 \
-device loader,addr=0x10130108,data=0x00002001,data-len=4 \
-device loader,addr=0x1013010C,data=0x1e4bf001,data-len=4 \
-device loader,addr=0x10130110,data=0x0000c001,data-len=4
Qemu Crash.
The result correctly after fixed
(qemu) xp /1wx 0x00001000
00001000: 0x44332211
(qemu) xp /1wx 0x00001004
00001004: 0x88776655
Signed-off-by: Tao Ding <dingtao0430@163.com>
---
hw/dma/pl080.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 4f97943b28..4e24f6595a 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -102,6 +102,7 @@ static void pl080_run(PL080State *s)
int size;
uint8_t buff[4];
uint32_t req;
+ uint32_t next_lli;
s->tc_mask = 0;
for (c = 0; c < s->nchannels; c++) {
@@ -191,21 +192,22 @@ again:
ch->ctrl = (ch->ctrl & 0xfffff000) | size;
if (size == 0) {
/* Transfer complete. */
- if (ch->lli) {
+ next_lli = (ch->lli & ~3);
+ if (next_lli) {
ch->src = address_space_ldl_le(&s->downstream_as,
- ch->lli,
+ next_lli,
MEMTXATTRS_UNSPECIFIED,
NULL);
ch->dest = address_space_ldl_le(&s->downstream_as,
- ch->lli + 4,
+ next_lli + 4,
MEMTXATTRS_UNSPECIFIED,
NULL);
ch->ctrl = address_space_ldl_le(&s->downstream_as,
- ch->lli + 12,
+ next_lli + 12,
MEMTXATTRS_UNSPECIFIED,
NULL);
ch->lli = address_space_ldl_le(&s->downstream_as,
- ch->lli + 8,
+ next_lli + 8,
MEMTXATTRS_UNSPECIFIED,
NULL);
} else {
--
2.43.0
On Thu, 12 Mar 2026 at 08:02, Tao Ding <dingtao0430@163.com> wrote: > > When the bit0 of the LLI register is configured as master 1, > it can cause incorrect data reading, and even lead to qemu crash. > > Constructed 1 LLI item. The initial LLI register points to the address of the LLI item. > But the bit 0 of the LLI register is 1, which mean read from Master1 port. > According to the description in the PL080 manual, the address for the next LLI should be word aligned. > > Configuration > ../configure --target-list=arm-softmmu --enable-debug > Reproducer > ./qemu-system-arm -M versatilepb -m 128M -nographic -S \ > -device loader,addr=0x00002000,data=0x00000004,data-len=4 \ > -device loader,addr=0x00002004,data=0x00001004,data-len=4 \ > -device loader,addr=0x00002008,data=0x00000000,data-len=4 \ > -device loader,addr=0x0000200c,data=0x9e4bf001,data-len=4 \ > -device loader,addr=0x00000000,data=0x44332211,data-len=4 \ > -device loader,addr=0x00000004,data=0x88776655,data-len=4 \ > -device loader,addr=0x00001000,data=0x00000000,data-len=4 \ > -device loader,addr=0x00001004,data=0x00000000,data-len=4 \ > -device loader,addr=0x10130030,data=0x00000001,data-len=4 \ > -device loader,addr=0x10130100,data=0x00000000,data-len=4 \ > -device loader,addr=0x10130104,data=0x00001000,data-len=4 \ > -device loader,addr=0x10130108,data=0x00002001,data-len=4 \ > -device loader,addr=0x1013010C,data=0x1e4bf001,data-len=4 \ > -device loader,addr=0x10130110,data=0x0000c001,data-len=4 > > Qemu Crash. > > The result correctly after fixed > (qemu) xp /1wx 0x00001000 > 00001000: 0x44332211 > (qemu) xp /1wx 0x00001004 > 00001004: 0x88776655 > > Signed-off-by: Tao Ding <dingtao0430@163.com> > --- The crash only happens because of a different PL080 bug where we weren't correctly handling invalid swidth and dwidth values, which is fixed by this patch I sent last week: https://patchew.org/QEMU/20260306152140.2191653-1-peter.maydell@linaro.org/ but we are certainly mishandling the LLI register here. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM
© 2016 - 2026 Red Hat, Inc.