diff options
| author | Alejandro Jimenez <alejandro.j.jimenez@oracle.com> | 2026-05-12 15:00:44 +0000 |
|---|---|---|
| committer | Michael Tokarev <mjt@tls.msk.ru> | 2026-06-16 17:45:41 +0300 |
| commit | 7d07b86a62e3bd61b3add23b9d24296b0e266598 (patch) | |
| tree | 739d2a034f2af1cbb4acae6312b3620de4ae46ef | |
| parent | 1aea3c267d2147f95b361bcf17d1801090bb7b9e (diff) | |
| download | qemu-7d07b86a62e3bd61b3add23b9d24296b0e266598.tar.gz qemu-7d07b86a62e3bd61b3add23b9d24296b0e266598.zip | |
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>
(cherry picked from commit 3c98e446af825b5806c1e5cd1244b2431b15e884)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
| -rw-r--r-- | hw/i386/amd_iommu.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index 197e452e3c..5d6a405263 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -1475,12 +1475,12 @@ static void amdvi_cmdbuf_run(AMDVIState *s) trace_amdvi_command_exec(s->cmdbuf_head, s->cmdbuf_tail, s->cmdbuf); amdvi_cmdbuf_exec(s); s->cmdbuf_head += AMDVI_COMMAND_SIZE; - amdvi_writeq_raw(s, AMDVI_MMIO_COMMAND_HEAD, s->cmdbuf_head); /* wrap head pointer */ if (s->cmdbuf_head >= s->cmdbuf_len * AMDVI_COMMAND_SIZE) { s->cmdbuf_head = 0; } + amdvi_writeq_raw(s, AMDVI_MMIO_COMMAND_HEAD, s->cmdbuf_head); } } |
