@samitouri / QOSamiQemu / commits / 3c98e446af

amd_iommu: Update command buffer head ptr in MMIO region after wraparound

When processing a command, amdvi_cmdbuf_run() increments cmdbuf_head and writes it to the emulated MMIO register space before checking whether it has reached the end of the command buffer. If the incremented value reaches the end of the buffer and the tail pointer is zero, the loop exits and the COMMAND_HEAD offset still contains an unwrapped value. There are no errors in command processing since internal cmdbuf_head state is always correctly updated, but the spec defines the CmdHeadPtr field in MMIO Offset 2000h Command Buffer Head Pointer Register as RW i.e. guest-visible, so it should be kept consistent. Wrap cmdbuf_head before updating COMMAND_HEAD so the MMIO-visible register always matches the internal command buffer head pointer position. Cc: qemu-stable@nongnu.org Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com> Reviewed-by: Sairaj Kodilkar <sarunkod@amd.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260512150044.334867-1-alejandro.j.jimenez@oracle.com>

Alejandro Jimenez committed May 12, 2026 at 15:00 UTC 3c98e446af825b5806c1e5cd1244b2431b15e884
1 file changed +1 -1
hw/i386/amd_iommu.c
+1 -1
@@ -1475,12 +1475,12 @@ static void amdvi_cmdbuf_run(AMDVIState *s)
1475 trace_amdvi_command_exec(s->cmdbuf_head, s->cmdbuf_tail, s->cmdbuf);
1476 amdvi_cmdbuf_exec(s);
1477 s->cmdbuf_head += AMDVI_COMMAND_SIZE;
1478 - amdvi_writeq_raw(s, AMDVI_MMIO_COMMAND_HEAD, s->cmdbuf_head);
1478
1479 /* wrap head pointer */
1480 if (s->cmdbuf_head >= s->cmdbuf_len * AMDVI_COMMAND_SIZE) {
1481 s->cmdbuf_head = 0;
1482 }
1483 + amdvi_writeq_raw(s, AMDVI_MMIO_COMMAND_HEAD, s->cmdbuf_head);
1484 }
1485 }
1486