From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Sairaj Kodilkar <sarunkod@amd.com>,
Vasant Hegde <vasant.hegde@amd.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Richard Henderson <richard.henderson@linaro.org>,
Eduardo Habkost <eduardo@habkost.net>,
Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Subject: [PULL 11/17] hw/i386/amd_iommu: Fix event log generation
Date: Fri, 1 Aug 2025 10:25:26 -0400 [thread overview]
Message-ID: <c0ef803a879b97f3d269348c968fb3874c2761f6.1754058276.git.mst@redhat.com> (raw)
In-Reply-To: <cover.1754058276.git.mst@redhat.com>
From: Sairaj Kodilkar <sarunkod@amd.com>
Current event logging code is broken, because of following issues
1. The code uses '|' instead of '&' to test the bit field, which causes
vIOMMU to generate overflow interrupt for every log entry.
2. Code does not update the eventlog tail MMIO register after adding an
entry to the buffer, because of which guest cannot process new
entries (as head == tail means buffer is empty).
3. Compares eventlog tail (which is byte offset in the buffer) to
eventlog length (which is number of maximum entries in the buffer).
This causes vIOMMU to generate only fix number of event logs, after
which it keeps on generating overflow interrupts, without
actually resetting the log buffer.
4. Updates ComWaitInt instead of EventLogInt bitfield in Status
register. Guest checks this field to see if there are new event log
entries in the buffer.
5. Does not reset event log head and tail pointers when guest writes to
eventlog base register.
Fix above issues, so that guest can process event log entries.
Fixes: d29a09ca68428 ("hw/i386: Introduce AMD IOMMU")
Signed-off-by: Sairaj Kodilkar <sarunkod@amd.com>
Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
Message-Id: <20250801060507.3382-7-sarunkod@amd.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/i386/amd_iommu.h | 1 +
hw/i386/amd_iommu.c | 44 +++++++++++++++++++++++++++++++++++---------
2 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h
index 67078c6f1e..2476296c49 100644
--- a/hw/i386/amd_iommu.h
+++ b/hw/i386/amd_iommu.h
@@ -111,6 +111,7 @@
#define AMDVI_MMIO_STATUS_CMDBUF_RUN (1 << 4)
#define AMDVI_MMIO_STATUS_EVT_RUN (1 << 3)
#define AMDVI_MMIO_STATUS_COMP_INT (1 << 2)
+#define AMDVI_MMIO_STATUS_EVENT_INT (1 << 1)
#define AMDVI_MMIO_STATUS_EVT_OVF (1 << 0)
#define AMDVI_CMDBUF_ID_BYTE 0x07
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 6925085d29..26be69bec8 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -160,10 +160,10 @@ static void amdvi_writeq(AMDVIState *s, hwaddr addr, uint64_t val)
(oldval_preserved | newval_write) & ~newval_w1c_set);
}
-/* OR a 64-bit register with a 64-bit value */
+/* AND a 64-bit register with a 64-bit value */
static bool amdvi_test_mask(AMDVIState *s, hwaddr addr, uint64_t val)
{
- return amdvi_readq(s, addr) | val;
+ return amdvi_readq(s, addr) & val;
}
/* OR a 64-bit register with a 64-bit value storing result in the register */
@@ -192,19 +192,31 @@ static void amdvi_generate_msi_interrupt(AMDVIState *s)
}
}
+static uint32_t get_next_eventlog_entry(AMDVIState *s)
+{
+ uint32_t evtlog_size = s->evtlog_len * AMDVI_EVENT_LEN;
+ return (s->evtlog_tail + AMDVI_EVENT_LEN) % evtlog_size;
+}
+
static void amdvi_log_event(AMDVIState *s, uint64_t *evt)
{
+ uint32_t evtlog_tail_next;
+
/* event logging not enabled */
if (!s->evtlog_enabled || amdvi_test_mask(s, AMDVI_MMIO_STATUS,
AMDVI_MMIO_STATUS_EVT_OVF)) {
return;
}
+ evtlog_tail_next = get_next_eventlog_entry(s);
+
/* event log buffer full */
- if (s->evtlog_tail >= s->evtlog_len) {
- amdvi_assign_orq(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_EVT_OVF);
- /* generate interrupt */
- amdvi_generate_msi_interrupt(s);
+ if (evtlog_tail_next == s->evtlog_head) {
+ /* generate overflow interrupt */
+ if (s->evtlog_intr) {
+ amdvi_assign_orq(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_EVT_OVF);
+ amdvi_generate_msi_interrupt(s);
+ }
return;
}
@@ -213,9 +225,13 @@ static void amdvi_log_event(AMDVIState *s, uint64_t *evt)
trace_amdvi_evntlog_fail(s->evtlog, s->evtlog_tail);
}
- s->evtlog_tail += AMDVI_EVENT_LEN;
- amdvi_assign_orq(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_COMP_INT);
- amdvi_generate_msi_interrupt(s);
+ s->evtlog_tail = evtlog_tail_next;
+ amdvi_writeq_raw(s, AMDVI_MMIO_EVENT_TAIL, s->evtlog_tail);
+
+ if (s->evtlog_intr) {
+ amdvi_assign_orq(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_EVENT_INT);
+ amdvi_generate_msi_interrupt(s);
+ }
}
static void amdvi_setevent_bits(uint64_t *buffer, uint64_t value, int start,
@@ -731,9 +747,19 @@ static inline void amdvi_handle_excllim_write(AMDVIState *s)
static inline void amdvi_handle_evtbase_write(AMDVIState *s)
{
uint64_t val = amdvi_readq(s, AMDVI_MMIO_EVENT_BASE);
+
+ if (amdvi_readq(s, AMDVI_MMIO_STATUS) & AMDVI_MMIO_STATUS_EVENT_INT)
+ /* Do not reset if eventlog interrupt bit is set*/
+ return;
+
s->evtlog = val & AMDVI_MMIO_EVTLOG_BASE_MASK;
s->evtlog_len = 1UL << (amdvi_readq(s, AMDVI_MMIO_EVTLOG_SIZE_BYTE)
& AMDVI_MMIO_EVTLOG_SIZE_MASK);
+
+ /* clear tail and head pointer to 0 when event base is updated */
+ s->evtlog_tail = s->evtlog_head = 0;
+ amdvi_writeq_raw(s, AMDVI_MMIO_EVENT_HEAD, s->evtlog_head);
+ amdvi_writeq_raw(s, AMDVI_MMIO_EVENT_TAIL, s->evtlog_tail);
}
static inline void amdvi_handle_evttail_write(AMDVIState *s)
--
MST
next prev parent reply other threads:[~2025-08-01 14:39 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-01 14:24 [PULL 00/17] virtio,pci,pc: bugfixes Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 01/17] virtio: fix off-by-one and invalid access in virtqueue_ordered_fill Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 02/17] vhost: Do not abort on log-start error Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 03/17] vhost: Do not abort on log-stop error Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 04/17] virtio-net: Fix VLAN filter table reset timing Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 05/17] pcie_sriov: Fix configuration and state synchronization Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 06/17] hw/i386/amd_iommu: Fix MMIO register write tracing Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 07/17] hw/i386/amd_iommu: Remove unused and wrongly set ats_enabled field Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 08/17] hw/i386/amd_iommu: Move IOAPIC memory region initialization to the end Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 09/17] hw/i386/amd_iommu: Fix amdvi_write*() Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 10/17] hw/i386/amd_iommu: Support MMIO writes to the status register Michael S. Tsirkin
2025-08-01 14:25 ` Michael S. Tsirkin [this message]
2025-08-01 14:25 ` [PULL 12/17] tests/acpi: virt: add an empty HEST file Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 13/17] tests/qtest/bios-tables-test: extend to also check HEST table Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 14/17] tests/acpi: virt: update HEST file with its current data Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 15/17] intel_iommu: Allow both Status Write and Interrupt Flag in QI wait Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 16/17] MAINTAINERS: add net/vhost* files under `vhost` Michael S. Tsirkin
2025-08-01 14:25 ` [PULL 17/17] net/vdpa: fix potential fd leak in net_init_vhost_vdpa() Michael S. Tsirkin
2025-08-01 19:34 ` [PULL 00/17] virtio,pci,pc: bugfixes Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c0ef803a879b97f3d269348c968fb3874c2761f6.1754058276.git.mst@redhat.com \
--to=mst@redhat.com \
--cc=eduardo@habkost.net \
--cc=marcel.apfelbaum@gmail.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=sarunkod@amd.com \
--cc=vasant.hegde@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).