QEMU-Riscv Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] riscv-iommu: always send MRIF notice MSI
@ 2026-07-26 12:20 flavien.solt97
  2026-07-26 12:21 ` [PATCH v2 1/3] hw/misc/iommu-testdev: support PCI MSI test writes flavien.solt97
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: flavien.solt97 @ 2026-07-26 12:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, Andrew Jones

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.

This revision includes a qtest. 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

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] 6+ messages in thread

* [PATCH v2 1/3] hw/misc/iommu-testdev: support PCI MSI test writes
  2026-07-26 12:20 [PATCH v2 0/3] riscv-iommu: always send MRIF notice MSI flavien.solt97
@ 2026-07-26 12:21 ` flavien.solt97
  2026-07-26 15:52   ` Tao Tang
  2026-07-26 12:21 ` [PATCH v2 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI flavien.solt97
  2026-07-26 12:22 ` [PATCH v2 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests flavien.solt97
  2 siblings, 1 reply; 6+ messages in thread
From: flavien.solt97 @ 2026-07-26 12:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, Andrew Jones, Tao Tang

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>
---
 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] 6+ messages in thread

* [PATCH v2 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI
  2026-07-26 12:20 [PATCH v2 0/3] riscv-iommu: always send MRIF notice MSI flavien.solt97
  2026-07-26 12:21 ` [PATCH v2 1/3] hw/misc/iommu-testdev: support PCI MSI test writes flavien.solt97
@ 2026-07-26 12:21 ` flavien.solt97
  2026-07-26 12:22 ` [PATCH v2 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests flavien.solt97
  2 siblings, 0 replies; 6+ messages in thread
From: flavien.solt97 @ 2026-07-26 12:21 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

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] 6+ messages in thread

* [PATCH v2 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests
  2026-07-26 12:20 [PATCH v2 0/3] riscv-iommu: always send MRIF notice MSI flavien.solt97
  2026-07-26 12:21 ` [PATCH v2 1/3] hw/misc/iommu-testdev: support PCI MSI test writes flavien.solt97
  2026-07-26 12:21 ` [PATCH v2 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI flavien.solt97
@ 2026-07-26 12:22 ` flavien.solt97
  2026-07-27  6:23   ` Chao Liu
  2 siblings, 1 reply; 6+ messages in thread
From: flavien.solt97 @ 2026-07-26 12:22 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

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] 6+ messages in thread

* Re: [PATCH v2 1/3] hw/misc/iommu-testdev: support PCI MSI test writes
  2026-07-26 12:21 ` [PATCH v2 1/3] hw/misc/iommu-testdev: support PCI MSI test writes flavien.solt97
@ 2026-07-26 15:52   ` Tao Tang
  0 siblings, 0 replies; 6+ messages in thread
From: Tao Tang @ 2026-07-26 15:52 UTC (permalink / raw)
  To: flavien.solt97, qemu-devel; +Cc: qemu-riscv, Andrew Jones

Hi Flavien,

On 7/26/2026 8:21 PM, flavien.solt97@gmail.com wrote:
> 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>
> ---
>   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)


hard-wrapped # 1


>
>       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,


hard-wrapped # 2


>       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,


hard-wrapped # 3


>       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)


hard-wrapped # 4


I found four hard-wrapped hunk headers. As a result, git cannot parse 
the diff:

```

git am 0001-hw-misc-iommu-testdev-support-pci-msi-test-writes.patch
Applying: hw/misc/iommu-testdev: support PCI MSI test writes
error: corrupt patch at line 27
Patch failed at 0001 hw/misc/iommu-testdev: support PCI MSI test writes
hint: Use 'git am --show-current-patch=diff' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

```


Could you please help check this?


Otherwise, looks good.

Reviewed-by: Tao Tang <tangtao1634@phytium.com.cn>


>       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] 6+ messages in thread

* Re: [PATCH v2 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests
  2026-07-26 12:22 ` [PATCH v2 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests flavien.solt97
@ 2026-07-27  6:23   ` Chao Liu
  0 siblings, 0 replies; 6+ messages in thread
From: Chao Liu @ 2026-07-27  6:23 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 05:22:00AM +0800, flavien.solt97@gmail.com wrote:
> 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] 6+ messages in thread

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

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-26 12:20 [PATCH v2 0/3] riscv-iommu: always send MRIF notice MSI flavien.solt97
2026-07-26 12:21 ` [PATCH v2 1/3] hw/misc/iommu-testdev: support PCI MSI test writes flavien.solt97
2026-07-26 15:52   ` Tao Tang
2026-07-26 12:21 ` [PATCH v2 2/3] hw/riscv/riscv-iommu.c: always send MRIF notice MSI flavien.solt97
2026-07-26 12:22 ` [PATCH v2 3/3] tests/qtest: add RISC-V IOMMU MRIF notice tests flavien.solt97
2026-07-27  6:23   ` Chao Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox