All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] riscv-iommu: always send MRIF notice MSI
@ 2026-07-27  2:27 flavien.solt97
  2026-07-27  2:28 ` [PATCH v3 1/3] hw/misc/iommu-testdev: support PCI MSI test writes flavien.solt97
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: flavien.solt97 @ 2026-07-27  2:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, Andrew Jones, Tao Tang

From a13bfa64b84ac70c9e257253616ce650fc3e794b Mon Sep 17 00:00:00 2001
From: Flavien Solt <flavien.solt97@gmail.com>
Date: Mon, 27 Jul 2026 09:45:06 +0800
Subject: [PATCH v3 0/3] riscv-iommu: always send MRIF notice MSI

The AIA specification requires an IOMMU to send the configured notice
MSI after storing an MSI to an MRIF even when the destination interrupt
is disabled. QEMU currently reads the MRIF interrupt-enable word and
returns without sending the notice when the matching bit is clear.

Patch 1 lets iommu-testdev select an MSI payload and supplies its PCI
requester ID. Patch 2 removes the invalid enable-bit gate. Patch 3 checks
both enable states through qemu-system-riscv64.

The complete RISC-V IOMMU qtest suite passes:

  MRIF notice: enable=0 pending=0x20 notice=0x12d
  MRIF notice: enable=1 pending=0x20 notice=0x12d
  6/6 tests passed

This revision resends unchanged code after hunk headers in v2 were
hard-wrapped in transit. The messages use patch-safe MIME transfer
encoding. Patch 1 now carries Tao Tang's Reviewed-by tag.

Changes in v3:
  - Resend with patch-safe MIME transfer encoding.
  - Add Tao Tang's Reviewed-by tag to patch 1.

Changes in v2:
  - Wrap the fix commit message.
  - Keep the existing notification comment.
  - Add deterministic IE-clear and IE-set qtests.

Flavien Solt (3):
  hw/misc/iommu-testdev: support PCI MSI test writes
  hw/riscv/riscv-iommu.c: always send MRIF notice MSI
  tests/qtest: add RISC-V IOMMU MRIF notice tests

 hw/misc/iommu-testdev.c         |  14 ++++-
 hw/riscv/riscv-iommu.c          |  13 ----
 include/hw/misc/iommu-testdev.h |   1 +
 tests/qtest/iommu-riscv-test.c  | 102 ++++++++++++++++++++++++++++++++
 4 files changed, 115 insertions(+), 15 deletions(-)


base-commit: 499039798cdad7d86b787fec0eaf1da4151c0f05
-- 
2.54.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/3] hw/misc/iommu-testdev: support PCI MSI test writes
  2026-07-27  2:27 [PATCH v3 0/3] riscv-iommu: always send MRIF notice MSI flavien.solt97
@ 2026-07-27  2:28 ` flavien.solt97
  2026-07-27  4:11   ` Nutty.Liu
  2026-07-27  2:28 ` [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI flavien.solt97
  2026-07-27  2:28 ` [PATCH v3 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests flavien.solt97
  2 siblings, 1 reply; 9+ messages in thread
From: flavien.solt97 @ 2026-07-27  2:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, Andrew Jones, Tao Tang

From 84574de55c0f63f0963b3e5e0d477b18de91cf33 Mon Sep 17 00:00:00 2001
From: Flavien Solt <flavien.solt97@gmail.com>
Date: Sun, 26 Jul 2026 17:51:16 +0800
Subject: [PATCH v3 1/3] hw/misc/iommu-testdev: support PCI MSI test writes

iommu-testdev writes ITD_DMA_WRITE_VAL with unspecified requester
attributes. RISC-V MSI remapping tests need to select an interrupt
identity in the payload. The MSI trap also identifies the device through
MemTxAttrs.requester_id.

Add a write-value register with the existing constant as its reset
default. Populate the requester ID from the PCI function. Existing
translation tests retain their payload while interrupt-remapping tests
can issue a valid MSI for the test device.

Signed-off-by: Flavien Solt <flavien.solt97@gmail.com>
Reviewed-by: Tao Tang <tangtao1634@phytium.com.cn>
---
 hw/misc/iommu-testdev.c         | 14 ++++++++++++--
 include/hw/misc/iommu-testdev.h |  1 +
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/hw/misc/iommu-testdev.c b/hw/misc/iommu-testdev.c
index 15eb6de..6428a57 100644
--- a/hw/misc/iommu-testdev.c
+++ b/hw/misc/iommu-testdev.c
@@ -28,6 +28,7 @@ struct IOMMUTestDevState {
     uint64_t dma_paddr;
     uint32_t dma_len;
     uint32_t dma_result;
+    uint32_t dma_write_val;
     bool dma_armed; /* armed until a trigger consumes the request */

     AddressSpace *dma_as;   /* IOMMU-mediated DMA AS for this device */
@@ -80,6 +81,7 @@ static void iommu_testdev_maybe_run_dma(IOMMUTestDevState *s)

     /* Initialize MemTxAttrs from generic register. */
     attrs.secure = ITD_ATTRS_GET_SECURE(s->dma_attrs_cfg);
+    attrs.requester_id = pci_requester_id(&s->parent_obj);

     space_valid = ITD_ATTRS_GET_SPACE_VALID(s->dma_attrs_cfg);
     if (space_valid) {
@@ -97,12 +99,12 @@ static void
iommu_testdev_maybe_run_dma(IOMMUTestDevState *s)

     as = s->dma_as;

-    /* Step 1: Write ITD_DMA_WRITE_VAL to DMA address */
+    /* Step 1: Write the configured test value to DMA address */
     trace_iommu_testdev_dma_write(s->dma_vaddr, s->dma_len);

     for (int i = 0; i < s->dma_len; i++) {
         /* Data is written in little-endian order */
-        write_buf[i] = (ITD_DMA_WRITE_VAL >> ((i % 4) * 8)) & 0xff;
+        write_buf[i] = (s->dma_write_val >> ((i % 4) * 8)) & 0xff;
     }
     write_res = dma_memory_write(as, s->dma_vaddr, write_buf,
                                  s->dma_len, attrs);
@@ -186,6 +188,9 @@ static uint64_t iommu_testdev_mmio_read(void
*opaque, hwaddr addr,
     case ITD_REG_DMA_ATTRS:
         value = s->dma_attrs_cfg;
         break;
+    case ITD_REG_DMA_WRITE_VAL:
+        value = s->dma_write_val;
+        break;
     default:
         value = 0;
         break;
@@ -240,6 +245,9 @@ static void iommu_testdev_mmio_write(void *opaque,
hwaddr addr, uint64_t val,
     case ITD_REG_DMA_ATTRS:
         s->dma_attrs_cfg = data;
         break;
+    case ITD_REG_DMA_WRITE_VAL:
+        s->dma_write_val = data;
+        break;
     default:
         break;
     }
@@ -263,6 +271,7 @@ static void iommu_testdev_realize(PCIDevice *pdev,
Error **errp)
     s->dma_paddr = 0;
     s->dma_len = 0;
     s->dma_result = ITD_DMA_RESULT_IDLE;
+    s->dma_write_val = ITD_DMA_WRITE_VAL;
     s->dma_armed = false;
     s->dma_attrs_cfg = ITD_ATTRS_SET_SPACE(0, ITD_ATTRS_SPACE_NONSECURE);
     s->dma_as = pci_device_iommu_address_space(pdev);
@@ -280,6 +289,7 @@ static void iommu_testdev_reset(DeviceState *dev)
     s->dma_paddr = 0;
     s->dma_len = 0;
     s->dma_result = ITD_DMA_RESULT_IDLE;
+    s->dma_write_val = ITD_DMA_WRITE_VAL;
     s->dma_armed = false;
     s->dma_attrs_cfg = ITD_ATTRS_SET_SPACE(0, ITD_ATTRS_SPACE_NONSECURE);
 }
diff --git a/include/hw/misc/iommu-testdev.h b/include/hw/misc/iommu-testdev.h
index 3383659..2f4e931 100644
--- a/include/hw/misc/iommu-testdev.h
+++ b/include/hw/misc/iommu-testdev.h
@@ -81,6 +81,7 @@ enum {
     ITD_REG_DMA_ATTRS       = 0x18,
     ITD_REG_DMA_GPA_LO      = 0x1c,
     ITD_REG_DMA_GPA_HI      = 0x20,
+    ITD_REG_DMA_WRITE_VAL   = 0x24,
     BAR0_SIZE               = 0x1000,
 };

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI
  2026-07-27  2:27 [PATCH v3 0/3] riscv-iommu: always send MRIF notice MSI flavien.solt97
  2026-07-27  2:28 ` [PATCH v3 1/3] hw/misc/iommu-testdev: support PCI MSI test writes flavien.solt97
@ 2026-07-27  2:28 ` flavien.solt97
  2026-07-27  3:52   ` Nutty.Liu
                     ` (2 more replies)
  2026-07-27  2:28 ` [PATCH v3 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests flavien.solt97
  2 siblings, 3 replies; 9+ messages in thread
From: flavien.solt97 @ 2026-07-27  2:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, qemu-stable, Andrew Jones, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei,
	Chao Liu

From 42f759d7e7f4eca064638622d52aa38be11b956b Mon Sep 17 00:00:00 2001
From: Flavien Solt <flavien.solt97@gmail.com>
Date: Sun, 26 Jul 2026 17:52:03 +0800
Subject: [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI

The AIA specification requires an IOMMU to send the configured notice
MSI after storing an MSI to an MRIF, even when the corresponding
interrupt-enable bit is clear.

riscv_iommu_msi_write() currently reads the MRIF interrupt-enable
doubleword and suppresses the notice MSI when the matching bit is zero.
This makes notice delivery depend on a bit that AIA requires the IOMMU
to ignore.

Remove the enable-word read and send the notice MSI unconditionally
after updating the MRIF pending bit.

Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
Cc: qemu-stable@nongnu.org
Reviewed-by: Andrew Jones <andrew.jones@oss.qualcomm.com>
Signed-off-by: Flavien Solt <flavien.solt97@gmail.com>
---
 hw/riscv/riscv-iommu.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index f6865d1..2bbac30 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -788,19 +788,6 @@ static MemTxResult
riscv_iommu_msi_write(RISCVIOMMUState *s,
         goto err;
     }

-    /* Get MRIF enable bits */
-    addr = addr + sizeof(intn);
-    res = dma_memory_read(s->target_as, addr, &intn, sizeof(intn), attrs);
-    if (res != MEMTX_OK) {
-        cause = RISCV_IOMMU_FQ_CAUSE_MSI_LOAD_FAULT;
-        goto err;
-    }
-
-    if (!(intn & data)) {
-        /* notification disabled, MRIF update completed. */
-        return MEMTX_OK;
-    }
-
     /* Send notification message */
     addr = PPN_PHYS(get_field(pte[1], RISCV_IOMMU_MSI_MRIF_NPPN));
     n190 = get_field(pte[1], RISCV_IOMMU_MSI_MRIF_NID) |
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests
  2026-07-27  2:27 [PATCH v3 0/3] riscv-iommu: always send MRIF notice MSI flavien.solt97
  2026-07-27  2:28 ` [PATCH v3 1/3] hw/misc/iommu-testdev: support PCI MSI test writes flavien.solt97
  2026-07-27  2:28 ` [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI flavien.solt97
@ 2026-07-27  2:28 ` flavien.solt97
  2026-07-27  6:25   ` Chao Liu
  2 siblings, 1 reply; 9+ messages in thread
From: flavien.solt97 @ 2026-07-27  2:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, Andrew Jones, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu,
	Fabiano Rosas, Laurent Vivier, Paolo Bonzini

From a13bfa64b84ac70c9e257253616ce650fc3e794b Mon Sep 17 00:00:00 2001
From: Flavien Solt <flavien.solt97@gmail.com>
Date: Sun, 26 Jul 2026 17:54:04 +0800
Subject: [PATCH v3 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests

Exercise MRIF-mode MSI writes through iommu-testdev with the destination
interrupt-enable bit both clear and set. Each case requires the pending
bit to be stored plus the configured notice ID to reach guest memory.

The enable-clear case regresses the notice suppression fixed by the
previous patch. The enable-set case provides a control for the existing
path.

Signed-off-by: Flavien Solt <flavien.solt97@gmail.com>
---
 tests/qtest/iommu-riscv-test.c | 102 +++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/tests/qtest/iommu-riscv-test.c b/tests/qtest/iommu-riscv-test.c
index 2638024..85f79ea 100644
--- a/tests/qtest/iommu-riscv-test.c
+++ b/tests/qtest/iommu-riscv-test.c
@@ -14,6 +14,7 @@
 #include "hw/pci/pci_regs.h"
 #include "hw/misc/iommu-testdev.h"
 #include "hw/riscv/riscv-iommu-bits.h"
+#include "libqos/qos-iommu-testdev.h"
 #include "libqos/qos-riscv-iommu.h"
 #include "libqos/riscv-iommu.h"

@@ -26,6 +27,13 @@
 #define RISCV_BUS_MMIO_LIMIT       0x80000000
 #define RISCV_ECAM_ALLOC_PTR       0x30000000

+#define RISCV_MRIF_MSI_IOVA        0x00000000fee00000ull
+#define RISCV_MRIF_MSI_PT_GPA      (QRIOMMU_SPACE_OFFS + 0x00030000ull)
+#define RISCV_MRIF_BASE_GPA        (QRIOMMU_SPACE_OFFS + 0x00031000ull)
+#define RISCV_MRIF_NOTICE_GPA      (QRIOMMU_SPACE_OFFS + 0x00032000ull)
+#define RISCV_MRIF_INTID           5u
+#define RISCV_MRIF_NOTICE_ID       0x12du
+
 typedef struct RiscvIommuTestState {
     QTestState *qts;
     QGenericPCIBus gbus;
@@ -264,6 +272,96 @@ static void test_riscv_iommu_nested(void)
     run_riscv_iommu_translation(&cfg);
 }

+static void riscv_iommu_setup_mrif_context(RiscvIommuTestState *state)
+{
+    uint64_t dc_addr;
+    uint64_t msiptp;
+    uint64_t pte0;
+    uint64_t pte1;
+
+    qtest_memset(state->qts, QRIOMMU_SPACE_OFFS + QRIOMMU_DDT_BASE, 0,
+                 0x1000);
+    qtest_memset(state->qts, RISCV_MRIF_MSI_PT_GPA, 0, 0x1000);
+    qtest_memset(state->qts, RISCV_MRIF_BASE_GPA, 0, 0x1000);
+    qtest_memset(state->qts, RISCV_MRIF_NOTICE_GPA, 0, 4);
+
+    dc_addr = QRIOMMU_SPACE_OFFS + QRIOMMU_DDT_BASE +
+              state->testdev->devfn * sizeof(struct riscv_iommu_dc);
+
+    msiptp = (RISCV_MRIF_MSI_PT_GPA >> 12) |
+             ((uint64_t)RISCV_IOMMU_DC_MSIPTP_MODE_FLAT << 60);
+
+    qtest_writeq(state->qts, dc_addr + 0, RISCV_IOMMU_DC_TC_V);
+    qtest_writeq(state->qts, dc_addr + 8, 0);
+    qtest_writeq(state->qts, dc_addr + 16, 0);
+    qtest_writeq(state->qts, dc_addr + 24, 0);
+    qtest_writeq(state->qts, dc_addr + 32, msiptp);
+    qtest_writeq(state->qts, dc_addr + 40, 0);
+    qtest_writeq(state->qts, dc_addr + 48, RISCV_MRIF_MSI_IOVA >> 12);
+    qtest_writeq(state->qts, dc_addr + 56, 0);
+
+    pte0 = RISCV_IOMMU_MSI_PTE_V |
+           ((uint64_t)RISCV_IOMMU_MSI_PTE_M_MRIF << 1) |
+           ((RISCV_MRIF_BASE_GPA >> 9) << 7);
+    pte1 = ((RISCV_MRIF_NOTICE_GPA >> 12) << 10) | RISCV_MRIF_NOTICE_ID;
+
+    qtest_writeq(state->qts, RISCV_MRIF_MSI_PT_GPA, pte0);
+    qtest_writeq(state->qts, RISCV_MRIF_MSI_PT_GPA + 8, pte1);
+
+    qriommu_program_regs(state->qts, state->iommu_base);
+}
+
+static void run_riscv_iommu_mrif_notice(bool enable_bit)
+{
+    RiscvIommuTestState state = { 0 };
+    uint64_t pending;
+    uint64_t enabled;
+    uint32_t notice;
+    uint32_t dma_result;
+
+    if (!riscv_iommu_test_setup(&state)) {
+        return;
+    }
+
+    riscv_iommu_check(state.qts, state.iommu_base, QRIOMMU_TM_BARE);
+    riscv_iommu_setup_mrif_context(&state);
+
+    enabled = enable_bit ? (1ull << RISCV_MRIF_INTID) : 0;
+    qtest_writeq(state.qts, RISCV_MRIF_BASE_GPA + 8, enabled);
+    qpci_io_writel(state.testdev, state.testdev_bar, ITD_REG_DMA_WRITE_VAL,
+                   RISCV_MRIF_INTID);
+
+    dma_result = qos_iommu_testdev_trigger_dma(
+        state.testdev, state.testdev_bar, RISCV_MRIF_MSI_IOVA,
+        RISCV_MRIF_NOTICE_GPA, DMA_LEN, qriommu_build_dma_attrs());
+
+    pending = qtest_readq(state.qts, RISCV_MRIF_BASE_GPA);
+    notice = qtest_readl(state.qts, RISCV_MRIF_NOTICE_GPA);
+
+    g_test_message("MRIF notice: enable=%u pending=0x%" PRIx64
+                   " notice=0x%x", enable_bit, pending, notice);
+
+    /*
+     * Interrupt remapping consumes the original DMA write; the generic
+     * test device cannot read it back from the supplied physical address.
+     */
+    g_assert_cmpuint(dma_result, ==, ITD_DMA_ERR_MISMATCH);
+    g_assert_cmpuint(pending & (1ull << RISCV_MRIF_INTID), !=, 0);
+    g_assert_cmpuint(notice, ==, RISCV_MRIF_NOTICE_ID);
+
+    riscv_iommu_test_teardown(&state);
+}
+
+static void test_riscv_iommu_mrif_notice_enable_clear(void)
+{
+    run_riscv_iommu_mrif_notice(false);
+}
+
+static void test_riscv_iommu_mrif_notice_enable_set(void)
+{
+    run_riscv_iommu_mrif_notice(true);
+}
+
 int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
@@ -275,5 +373,9 @@ int main(int argc, char **argv)
                    test_riscv_iommu_g_stage_only);
     qtest_add_func("/iommu-testdev/translation/ns-nested",
                    test_riscv_iommu_nested);
+    qtest_add_func("/iommu-testdev/mrif-notice/enable-clear",
+                   test_riscv_iommu_mrif_notice_enable_clear);
+    qtest_add_func("/iommu-testdev/mrif-notice/enable-set",
+                   test_riscv_iommu_mrif_notice_enable_set);
     return g_test_run();
 }
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI
  2026-07-27  2:28 ` [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI flavien.solt97
@ 2026-07-27  3:52   ` Nutty.Liu
  2026-07-27  6:16   ` Chao Liu
  2026-07-27  6:24   ` Chao Liu
  2 siblings, 0 replies; 9+ messages in thread
From: Nutty.Liu @ 2026-07-27  3:52 UTC (permalink / raw)
  To: flavien.solt97, qemu-devel
  Cc: qemu-riscv, qemu-stable, Andrew Jones, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei,
	Chao Liu


On 7/27/2026 10:28 AM, flavien.solt97@gmail.com wrote:
>  From 42f759d7e7f4eca064638622d52aa38be11b956b Mon Sep 17 00:00:00 2001
> From: Flavien Solt <flavien.solt97@gmail.com>
> Date: Sun, 26 Jul 2026 17:52:03 +0800
> Subject: [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI
>
> The AIA specification requires an IOMMU to send the configured notice
> MSI after storing an MSI to an MRIF, even when the corresponding
> interrupt-enable bit is clear.
>
> riscv_iommu_msi_write() currently reads the MRIF interrupt-enable
> doubleword and suppresses the notice MSI when the matching bit is zero.
> This makes notice delivery depend on a bit that AIA requires the IOMMU
> to ignore.
>
> Remove the enable-word read and send the notice MSI unconditionally
> after updating the MRIF pending bit.
>
> Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
> Cc: qemu-stable@nongnu.org
> Reviewed-by: Andrew Jones <andrew.jones@oss.qualcomm.com>
> Signed-off-by: Flavien Solt <flavien.solt97@gmail.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>

Thanks,
Nutty
> ---
>   hw/riscv/riscv-iommu.c | 13 -------------
>   1 file changed, 13 deletions(-)
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index f6865d1..2bbac30 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -788,19 +788,6 @@ static MemTxResult
> riscv_iommu_msi_write(RISCVIOMMUState *s,
>           goto err;
>       }
>
> -    /* Get MRIF enable bits */
> -    addr = addr + sizeof(intn);
> -    res = dma_memory_read(s->target_as, addr, &intn, sizeof(intn), attrs);
> -    if (res != MEMTX_OK) {
> -        cause = RISCV_IOMMU_FQ_CAUSE_MSI_LOAD_FAULT;
> -        goto err;
> -    }
> -
> -    if (!(intn & data)) {
> -        /* notification disabled, MRIF update completed. */
> -        return MEMTX_OK;
> -    }
> -
>       /* Send notification message */
>       addr = PPN_PHYS(get_field(pte[1], RISCV_IOMMU_MSI_MRIF_NPPN));
>       n190 = get_field(pte[1], RISCV_IOMMU_MSI_MRIF_NID) |


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/3] hw/misc/iommu-testdev: support PCI MSI test writes
  2026-07-27  2:28 ` [PATCH v3 1/3] hw/misc/iommu-testdev: support PCI MSI test writes flavien.solt97
@ 2026-07-27  4:11   ` Nutty.Liu
  0 siblings, 0 replies; 9+ messages in thread
From: Nutty.Liu @ 2026-07-27  4:11 UTC (permalink / raw)
  To: flavien.solt97, qemu-devel; +Cc: qemu-riscv, Andrew Jones, Tao Tang


On 7/27/2026 10:28 AM, flavien.solt97@gmail.com wrote:
>  From 84574de55c0f63f0963b3e5e0d477b18de91cf33 Mon Sep 17 00:00:00 2001
> From: Flavien Solt <flavien.solt97@gmail.com>
> Date: Sun, 26 Jul 2026 17:51:16 +0800
> Subject: [PATCH v3 1/3] hw/misc/iommu-testdev: support PCI MSI test writes
>
> iommu-testdev writes ITD_DMA_WRITE_VAL with unspecified requester
> attributes. RISC-V MSI remapping tests need to select an interrupt
> identity in the payload. The MSI trap also identifies the device through
> MemTxAttrs.requester_id.
>
> Add a write-value register with the existing constant as its reset
> default. Populate the requester ID from the PCI function. Existing
> translation tests retain their payload while interrupt-remapping tests
> can issue a valid MSI for the test device.
>
> Signed-off-by: Flavien Solt <flavien.solt97@gmail.com>
> Reviewed-by: Tao Tang <tangtao1634@phytium.com.cn>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>

Thanks,
Nutty
> ---
>   hw/misc/iommu-testdev.c         | 14 ++++++++++++--
>   include/hw/misc/iommu-testdev.h |  1 +
>   2 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/hw/misc/iommu-testdev.c b/hw/misc/iommu-testdev.c
> index 15eb6de..6428a57 100644
> --- a/hw/misc/iommu-testdev.c
> +++ b/hw/misc/iommu-testdev.c
> @@ -28,6 +28,7 @@ struct IOMMUTestDevState {
>       uint64_t dma_paddr;
>       uint32_t dma_len;
>       uint32_t dma_result;
> +    uint32_t dma_write_val;
>       bool dma_armed; /* armed until a trigger consumes the request */
>
>       AddressSpace *dma_as;   /* IOMMU-mediated DMA AS for this device */
> @@ -80,6 +81,7 @@ static void iommu_testdev_maybe_run_dma(IOMMUTestDevState *s)
>
>       /* Initialize MemTxAttrs from generic register. */
>       attrs.secure = ITD_ATTRS_GET_SECURE(s->dma_attrs_cfg);
> +    attrs.requester_id = pci_requester_id(&s->parent_obj);
>
>       space_valid = ITD_ATTRS_GET_SPACE_VALID(s->dma_attrs_cfg);
>       if (space_valid) {
> @@ -97,12 +99,12 @@ static void
> iommu_testdev_maybe_run_dma(IOMMUTestDevState *s)
>
>       as = s->dma_as;
>
> -    /* Step 1: Write ITD_DMA_WRITE_VAL to DMA address */
> +    /* Step 1: Write the configured test value to DMA address */
>       trace_iommu_testdev_dma_write(s->dma_vaddr, s->dma_len);
>
>       for (int i = 0; i < s->dma_len; i++) {
>           /* Data is written in little-endian order */
> -        write_buf[i] = (ITD_DMA_WRITE_VAL >> ((i % 4) * 8)) & 0xff;
> +        write_buf[i] = (s->dma_write_val >> ((i % 4) * 8)) & 0xff;
>       }
>       write_res = dma_memory_write(as, s->dma_vaddr, write_buf,
>                                    s->dma_len, attrs);
> @@ -186,6 +188,9 @@ static uint64_t iommu_testdev_mmio_read(void
> *opaque, hwaddr addr,
>       case ITD_REG_DMA_ATTRS:
>           value = s->dma_attrs_cfg;
>           break;
> +    case ITD_REG_DMA_WRITE_VAL:
> +        value = s->dma_write_val;
> +        break;
>       default:
>           value = 0;
>           break;
> @@ -240,6 +245,9 @@ static void iommu_testdev_mmio_write(void *opaque,
> hwaddr addr, uint64_t val,
>       case ITD_REG_DMA_ATTRS:
>           s->dma_attrs_cfg = data;
>           break;
> +    case ITD_REG_DMA_WRITE_VAL:
> +        s->dma_write_val = data;
> +        break;
>       default:
>           break;
>       }
> @@ -263,6 +271,7 @@ static void iommu_testdev_realize(PCIDevice *pdev,
> Error **errp)
>       s->dma_paddr = 0;
>       s->dma_len = 0;
>       s->dma_result = ITD_DMA_RESULT_IDLE;
> +    s->dma_write_val = ITD_DMA_WRITE_VAL;
>       s->dma_armed = false;
>       s->dma_attrs_cfg = ITD_ATTRS_SET_SPACE(0, ITD_ATTRS_SPACE_NONSECURE);
>       s->dma_as = pci_device_iommu_address_space(pdev);
> @@ -280,6 +289,7 @@ static void iommu_testdev_reset(DeviceState *dev)
>       s->dma_paddr = 0;
>       s->dma_len = 0;
>       s->dma_result = ITD_DMA_RESULT_IDLE;
> +    s->dma_write_val = ITD_DMA_WRITE_VAL;
>       s->dma_armed = false;
>       s->dma_attrs_cfg = ITD_ATTRS_SET_SPACE(0, ITD_ATTRS_SPACE_NONSECURE);
>   }
> diff --git a/include/hw/misc/iommu-testdev.h b/include/hw/misc/iommu-testdev.h
> index 3383659..2f4e931 100644
> --- a/include/hw/misc/iommu-testdev.h
> +++ b/include/hw/misc/iommu-testdev.h
> @@ -81,6 +81,7 @@ enum {
>       ITD_REG_DMA_ATTRS       = 0x18,
>       ITD_REG_DMA_GPA_LO      = 0x1c,
>       ITD_REG_DMA_GPA_HI      = 0x20,
> +    ITD_REG_DMA_WRITE_VAL   = 0x24,
>       BAR0_SIZE               = 0x1000,
>   };
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI
  2026-07-27  2:28 ` [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI flavien.solt97
  2026-07-27  3:52   ` Nutty.Liu
@ 2026-07-27  6:16   ` Chao Liu
  2026-07-27  6:24   ` Chao Liu
  2 siblings, 0 replies; 9+ messages in thread
From: Chao Liu @ 2026-07-27  6:16 UTC (permalink / raw)
  To: Flavien Solt
  Cc: qemu-devel, qemu-riscv, qemu-stable, Andrew Jones, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei

Hi Flavien,

The code change matches the current AIA requirement: the notice MSI must
be sent after the MRIF update regardless of the interrupt-enable bit.
Andrew's v1 requests to wrap the commit message, retain the notification
comment, and add tests are addressed in v3.

However, the transport corruption reported on v2 is still present in v3.
`b4 am` retrieves 2/3 with this hunk header split:

    @@ -788,19 +788,6 @@ static MemTxResult
    riscv_iommu_msi_write(RISCVIOMMUState *s,

The continuation has no diff prefix, so both `git apply --check` and
`checkpatch.pl` report a corrupt/line-wrapped patch. Patch 1/3 also has
four similarly wrapped hunk headers, so the posted series cannot be
applied.

For review, I mechanically joined only those five hunk headers. After
that, all three patches pass checkpatch, the riscv64-softmmu build
succeeds, and qtest-riscv64/iommu-riscv-test passes all six subtests,
including both new MRIF notice cases.

Please resend without body reflow (for example with git send-email or
b4 send), and verify the posted copy from lore using `b4 am`. You may
also want to restore Daniel's Reviewed-by from v1, which is missing from
2/3.

With the transport issue fixed, for this patch:

Reviewed-by: Chao Liu <chao.liu@processmission.com>
Tested-by: Chao Liu <chao.liu@processmission.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI
  2026-07-27  2:28 ` [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI flavien.solt97
  2026-07-27  3:52   ` Nutty.Liu
  2026-07-27  6:16   ` Chao Liu
@ 2026-07-27  6:24   ` Chao Liu
  2 siblings, 0 replies; 9+ messages in thread
From: Chao Liu @ 2026-07-27  6:24 UTC (permalink / raw)
  To: flavien.solt97
  Cc: qemu-devel, qemu-riscv, qemu-stable, Andrew Jones, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei

On Sun, Jul 26, 2026 at 07:28:21PM +0800, flavien.solt97@gmail.com wrote:
> From 42f759d7e7f4eca064638622d52aa38be11b956b Mon Sep 17 00:00:00 2001
> From: Flavien Solt <flavien.solt97@gmail.com>
> Date: Sun, 26 Jul 2026 17:52:03 +0800
> Subject: [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI
> 
> The AIA specification requires an IOMMU to send the configured notice
> MSI after storing an MSI to an MRIF, even when the corresponding
> interrupt-enable bit is clear.
> 
> riscv_iommu_msi_write() currently reads the MRIF interrupt-enable
> doubleword and suppresses the notice MSI when the matching bit is zero.
> This makes notice delivery depend on a bit that AIA requires the IOMMU
> to ignore.
> 
> Remove the enable-word read and send the notice MSI unconditionally
> after updating the MRIF pending bit.
> 
> Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
> Cc: qemu-stable@nongnu.org
> Reviewed-by: Andrew Jones <andrew.jones@oss.qualcomm.com>
> Signed-off-by: Flavien Solt <flavien.solt97@gmail.com>
Reviewed-by: Chao Liu <chao.liu@processmission.com>

Thanks,
Chao

> ---
>  hw/riscv/riscv-iommu.c | 13 -------------
>  1 file changed, 13 deletions(-)
> 
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index f6865d1..2bbac30 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -788,19 +788,6 @@ static MemTxResult
> riscv_iommu_msi_write(RISCVIOMMUState *s,
>          goto err;
>      }
> 
> -    /* Get MRIF enable bits */
> -    addr = addr + sizeof(intn);
> -    res = dma_memory_read(s->target_as, addr, &intn, sizeof(intn), attrs);
> -    if (res != MEMTX_OK) {
> -        cause = RISCV_IOMMU_FQ_CAUSE_MSI_LOAD_FAULT;
> -        goto err;
> -    }
> -
> -    if (!(intn & data)) {
> -        /* notification disabled, MRIF update completed. */
> -        return MEMTX_OK;
> -    }
> -
>      /* Send notification message */
>      addr = PPN_PHYS(get_field(pte[1], RISCV_IOMMU_MSI_MRIF_NPPN));
>      n190 = get_field(pte[1], RISCV_IOMMU_MSI_MRIF_NID) |
> -- 
> 2.54.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests
  2026-07-27  2:28 ` [PATCH v3 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests flavien.solt97
@ 2026-07-27  6:25   ` Chao Liu
  0 siblings, 0 replies; 9+ messages in thread
From: Chao Liu @ 2026-07-27  6:25 UTC (permalink / raw)
  To: flavien.solt97
  Cc: qemu-devel, qemu-riscv, Andrew Jones, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei,
	Fabiano Rosas, Laurent Vivier, Paolo Bonzini

On Sun, Jul 26, 2026 at 07:28:27PM +0800, flavien.solt97@gmail.com wrote:
> From a13bfa64b84ac70c9e257253616ce650fc3e794b Mon Sep 17 00:00:00 2001
> From: Flavien Solt <flavien.solt97@gmail.com>
> Date: Sun, 26 Jul 2026 17:54:04 +0800
> Subject: [PATCH v3 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests
> 
> Exercise MRIF-mode MSI writes through iommu-testdev with the destination
> interrupt-enable bit both clear and set. Each case requires the pending
> bit to be stored plus the configured notice ID to reach guest memory.
> 
> The enable-clear case regresses the notice suppression fixed by the
> previous patch. The enable-set case provides a control for the existing
> path.
> 
> Signed-off-by: Flavien Solt <flavien.solt97@gmail.com>
Reviewed-by: Chao Liu <chao.liu@processmission.com>

Thanks,
Chao

> ---
>  tests/qtest/iommu-riscv-test.c | 102 +++++++++++++++++++++++++++++++++
>  1 file changed, 102 insertions(+)
> 
> diff --git a/tests/qtest/iommu-riscv-test.c b/tests/qtest/iommu-riscv-test.c
> index 2638024..85f79ea 100644
> --- a/tests/qtest/iommu-riscv-test.c
> +++ b/tests/qtest/iommu-riscv-test.c
> @@ -14,6 +14,7 @@
>  #include "hw/pci/pci_regs.h"
>  #include "hw/misc/iommu-testdev.h"
>  #include "hw/riscv/riscv-iommu-bits.h"
> +#include "libqos/qos-iommu-testdev.h"
>  #include "libqos/qos-riscv-iommu.h"
>  #include "libqos/riscv-iommu.h"
> 
> @@ -26,6 +27,13 @@
>  #define RISCV_BUS_MMIO_LIMIT       0x80000000
>  #define RISCV_ECAM_ALLOC_PTR       0x30000000
> 
> +#define RISCV_MRIF_MSI_IOVA        0x00000000fee00000ull
> +#define RISCV_MRIF_MSI_PT_GPA      (QRIOMMU_SPACE_OFFS + 0x00030000ull)
> +#define RISCV_MRIF_BASE_GPA        (QRIOMMU_SPACE_OFFS + 0x00031000ull)
> +#define RISCV_MRIF_NOTICE_GPA      (QRIOMMU_SPACE_OFFS + 0x00032000ull)
> +#define RISCV_MRIF_INTID           5u
> +#define RISCV_MRIF_NOTICE_ID       0x12du
> +
>  typedef struct RiscvIommuTestState {
>      QTestState *qts;
>      QGenericPCIBus gbus;
> @@ -264,6 +272,96 @@ static void test_riscv_iommu_nested(void)
>      run_riscv_iommu_translation(&cfg);
>  }
> 
> +static void riscv_iommu_setup_mrif_context(RiscvIommuTestState *state)
> +{
> +    uint64_t dc_addr;
> +    uint64_t msiptp;
> +    uint64_t pte0;
> +    uint64_t pte1;
> +
> +    qtest_memset(state->qts, QRIOMMU_SPACE_OFFS + QRIOMMU_DDT_BASE, 0,
> +                 0x1000);
> +    qtest_memset(state->qts, RISCV_MRIF_MSI_PT_GPA, 0, 0x1000);
> +    qtest_memset(state->qts, RISCV_MRIF_BASE_GPA, 0, 0x1000);
> +    qtest_memset(state->qts, RISCV_MRIF_NOTICE_GPA, 0, 4);
> +
> +    dc_addr = QRIOMMU_SPACE_OFFS + QRIOMMU_DDT_BASE +
> +              state->testdev->devfn * sizeof(struct riscv_iommu_dc);
> +
> +    msiptp = (RISCV_MRIF_MSI_PT_GPA >> 12) |
> +             ((uint64_t)RISCV_IOMMU_DC_MSIPTP_MODE_FLAT << 60);
> +
> +    qtest_writeq(state->qts, dc_addr + 0, RISCV_IOMMU_DC_TC_V);
> +    qtest_writeq(state->qts, dc_addr + 8, 0);
> +    qtest_writeq(state->qts, dc_addr + 16, 0);
> +    qtest_writeq(state->qts, dc_addr + 24, 0);
> +    qtest_writeq(state->qts, dc_addr + 32, msiptp);
> +    qtest_writeq(state->qts, dc_addr + 40, 0);
> +    qtest_writeq(state->qts, dc_addr + 48, RISCV_MRIF_MSI_IOVA >> 12);
> +    qtest_writeq(state->qts, dc_addr + 56, 0);
> +
> +    pte0 = RISCV_IOMMU_MSI_PTE_V |
> +           ((uint64_t)RISCV_IOMMU_MSI_PTE_M_MRIF << 1) |
> +           ((RISCV_MRIF_BASE_GPA >> 9) << 7);
> +    pte1 = ((RISCV_MRIF_NOTICE_GPA >> 12) << 10) | RISCV_MRIF_NOTICE_ID;
> +
> +    qtest_writeq(state->qts, RISCV_MRIF_MSI_PT_GPA, pte0);
> +    qtest_writeq(state->qts, RISCV_MRIF_MSI_PT_GPA + 8, pte1);
> +
> +    qriommu_program_regs(state->qts, state->iommu_base);
> +}
> +
> +static void run_riscv_iommu_mrif_notice(bool enable_bit)
> +{
> +    RiscvIommuTestState state = { 0 };
> +    uint64_t pending;
> +    uint64_t enabled;
> +    uint32_t notice;
> +    uint32_t dma_result;
> +
> +    if (!riscv_iommu_test_setup(&state)) {
> +        return;
> +    }
> +
> +    riscv_iommu_check(state.qts, state.iommu_base, QRIOMMU_TM_BARE);
> +    riscv_iommu_setup_mrif_context(&state);
> +
> +    enabled = enable_bit ? (1ull << RISCV_MRIF_INTID) : 0;
> +    qtest_writeq(state.qts, RISCV_MRIF_BASE_GPA + 8, enabled);
> +    qpci_io_writel(state.testdev, state.testdev_bar, ITD_REG_DMA_WRITE_VAL,
> +                   RISCV_MRIF_INTID);
> +
> +    dma_result = qos_iommu_testdev_trigger_dma(
> +        state.testdev, state.testdev_bar, RISCV_MRIF_MSI_IOVA,
> +        RISCV_MRIF_NOTICE_GPA, DMA_LEN, qriommu_build_dma_attrs());
> +
> +    pending = qtest_readq(state.qts, RISCV_MRIF_BASE_GPA);
> +    notice = qtest_readl(state.qts, RISCV_MRIF_NOTICE_GPA);
> +
> +    g_test_message("MRIF notice: enable=%u pending=0x%" PRIx64
> +                   " notice=0x%x", enable_bit, pending, notice);
> +
> +    /*
> +     * Interrupt remapping consumes the original DMA write; the generic
> +     * test device cannot read it back from the supplied physical address.
> +     */
> +    g_assert_cmpuint(dma_result, ==, ITD_DMA_ERR_MISMATCH);
> +    g_assert_cmpuint(pending & (1ull << RISCV_MRIF_INTID), !=, 0);
> +    g_assert_cmpuint(notice, ==, RISCV_MRIF_NOTICE_ID);
> +
> +    riscv_iommu_test_teardown(&state);
> +}
> +
> +static void test_riscv_iommu_mrif_notice_enable_clear(void)
> +{
> +    run_riscv_iommu_mrif_notice(false);
> +}
> +
> +static void test_riscv_iommu_mrif_notice_enable_set(void)
> +{
> +    run_riscv_iommu_mrif_notice(true);
> +}
> +
>  int main(int argc, char **argv)
>  {
>      g_test_init(&argc, &argv, NULL);
> @@ -275,5 +373,9 @@ int main(int argc, char **argv)
>                     test_riscv_iommu_g_stage_only);
>      qtest_add_func("/iommu-testdev/translation/ns-nested",
>                     test_riscv_iommu_nested);
> +    qtest_add_func("/iommu-testdev/mrif-notice/enable-clear",
> +                   test_riscv_iommu_mrif_notice_enable_clear);
> +    qtest_add_func("/iommu-testdev/mrif-notice/enable-set",
> +                   test_riscv_iommu_mrif_notice_enable_set);
>      return g_test_run();
>  }
> -- 
> 2.54.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-07-27  6:25 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27  2:27 [PATCH v3 0/3] riscv-iommu: always send MRIF notice MSI flavien.solt97
2026-07-27  2:28 ` [PATCH v3 1/3] hw/misc/iommu-testdev: support PCI MSI test writes flavien.solt97
2026-07-27  4:11   ` Nutty.Liu
2026-07-27  2:28 ` [PATCH v3 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI flavien.solt97
2026-07-27  3:52   ` Nutty.Liu
2026-07-27  6:16   ` Chao Liu
2026-07-27  6:24   ` Chao Liu
2026-07-27  2:28 ` [PATCH v3 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests flavien.solt97
2026-07-27  6:25   ` Chao Liu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.