]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
tests/qtest: Add libqos iommu-testdev helpers
authorTao Tang <tangtao1634@phytium.com.cn>
Sun, 18 Jan 2026 06:52:14 +0000 (14:52 +0800)
committerPhilippe Mathieu-Daudé <philmd@linaro.org>
Tue, 20 Jan 2026 18:51:36 +0000 (19:51 +0100)
Introduce a libqos helper module for the iommu-testdev
device used by qtests. This module provides some common functions to
all IOMMU test cases using iommu-testdev.

Wire the new sources into tests/qtest/libqos/meson.build so
they are built as part of the qtest support library.

Signed-off-by: Tao Tang <tangtao1634@phytium.com.cn>
Message-ID: <20260119161112.3841386-7-tangtao1634@phytium.com.cn>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
MAINTAINERS
tests/qtest/libqos/meson.build
tests/qtest/libqos/qos-iommu-testdev.c [new file with mode: 0644]
tests/qtest/libqos/qos-iommu-testdev.h [new file with mode: 0644]

index 63a04350fb066e4ee00b5906de65cf72598d6000..cc219e39b98f5da466d73cf950265362e5ccaccb 100644 (file)
@@ -3578,6 +3578,11 @@ F: docs/devel/testing/qtest.rst
 X: tests/qtest/bios-tables-test*
 X: tests/qtest/migration-*
 
+QTest IOMMU helpers
+M: Tao Tang <tangtao1634@phytium.com.cn>
+S: Maintained
+F: tests/qtest/libqos/qos-iommu*
+
 Device Fuzzing
 M: Alexander Bulekov <alxndr@bu.edu>
 R: Paolo Bonzini <pbonzini@redhat.com>
index 1ddaf7b095bf7f4c7d65ef548961051de440ca61..9805d63a290390f440f0b78db9653d774eab029e 100644 (file)
@@ -60,6 +60,9 @@ libqos_srcs = files(
         'x86_64_pc-machine.c',
         'riscv-virt-machine.c',
         'loongarch-virt-machine.c',
+
+        # SMMU:
+        'qos-iommu-testdev.c',
 )
 
 if have_virtfs
diff --git a/tests/qtest/libqos/qos-iommu-testdev.c b/tests/qtest/libqos/qos-iommu-testdev.c
new file mode 100644 (file)
index 0000000..91718a5
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * IOMMU test device helpers for libqos qtests
+ *
+ * Copyright (c) 2026 Phytium Technology
+ *
+ * Author:
+ *  Tao Tang <tangtao1634@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "../libqtest.h"
+#include "pci.h"
+#include "qos-iommu-testdev.h"
+
+uint32_t qos_iommu_testdev_trigger_dma(QPCIDevice *dev, QPCIBar bar,
+                                       uint64_t iova, uint64_t gpa,
+                                       uint32_t len, uint32_t attrs)
+{
+    uint32_t result = ITD_DMA_RESULT_BUSY;
+
+    qpci_io_writel(dev, bar, ITD_REG_DMA_GVA_LO, (uint32_t)iova);
+    qpci_io_writel(dev, bar, ITD_REG_DMA_GVA_HI, (uint32_t)(iova >> 32));
+    qpci_io_writel(dev, bar, ITD_REG_DMA_GPA_LO, (uint32_t)gpa);
+    qpci_io_writel(dev, bar, ITD_REG_DMA_GPA_HI, (uint32_t)(gpa >> 32));
+    qpci_io_writel(dev, bar, ITD_REG_DMA_LEN, len);
+    qpci_io_writel(dev, bar, ITD_REG_DMA_ATTRS, attrs);
+
+    qpci_io_writel(dev, bar, ITD_REG_DMA_DBELL, ITD_DMA_DBELL_ARM);
+    qpci_io_readl(dev, bar, ITD_REG_DMA_TRIGGERING);
+
+    for (int i = 0; i < 1000; i++) {
+        result = qpci_io_readl(dev, bar, ITD_REG_DMA_RESULT);
+        if (result != ITD_DMA_RESULT_BUSY) {
+            break;
+        }
+        g_usleep(1000);
+    }
+
+    if (result == ITD_DMA_RESULT_BUSY) {
+        return ITD_DMA_ERR_TX_FAIL;
+    }
+
+    return result;
+}
+
+void qos_iommu_testdev_single_translation(const QOSIOMMUTestdevDmaCfg *dma,
+                                          void *opaque,
+                                          QOSIOMMUTestdevSetupFn setup_fn,
+                                          QOSIOMMUTestdevAttrsFn attrs_fn,
+                                          QOSIOMMUTestdevValidateFn validate_fn,
+                                          QOSIOMMUTestdevReportFn report_fn,
+                                          uint32_t *dma_result_out)
+{
+    uint32_t config_result;
+    uint32_t dma_result;
+    uint32_t attrs_val;
+
+    g_assert(dma);
+    g_assert(setup_fn);
+    g_assert(attrs_fn);
+
+    config_result = setup_fn(opaque);
+    g_assert_cmpuint(config_result, ==, 0);
+
+    attrs_val = attrs_fn(opaque);
+    dma_result = qos_iommu_testdev_trigger_dma(dma->dev, dma->bar,
+                                               dma->iova, dma->gpa,
+                                               dma->len, attrs_val);
+    if (dma_result_out) {
+        *dma_result_out = dma_result;
+    }
+
+    if (report_fn) {
+        report_fn(opaque, dma_result);
+    }
+
+    if (validate_fn) {
+        g_assert_true(validate_fn(opaque));
+    }
+}
diff --git a/tests/qtest/libqos/qos-iommu-testdev.h b/tests/qtest/libqos/qos-iommu-testdev.h
new file mode 100644 (file)
index 0000000..3713b89
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * IOMMU test device helpers for libqos qtests
+ *
+ * Copyright (c) 2026 Phytium Technology
+ *
+ * Author:
+ *  Tao Tang <tangtao1634@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QTEST_LIBQOS_IOMMU_TESTDEV_H
+#define QTEST_LIBQOS_IOMMU_TESTDEV_H
+
+#include "pci.h"
+#include "hw/misc/iommu-testdev.h"
+
+typedef uint32_t (*QOSIOMMUTestdevSetupFn)(void *opaque);
+typedef uint32_t (*QOSIOMMUTestdevAttrsFn)(void *opaque);
+typedef bool (*QOSIOMMUTestdevValidateFn)(void *opaque);
+typedef void (*QOSIOMMUTestdevReportFn)(void *opaque, uint32_t dma_result);
+
+typedef struct QOSIOMMUTestdevDmaCfg {
+    QPCIDevice *dev;
+    QPCIBar bar;
+    uint64_t iova;
+    uint64_t gpa;
+    uint32_t len;
+} QOSIOMMUTestdevDmaCfg;
+
+uint32_t qos_iommu_testdev_trigger_dma(QPCIDevice *dev, QPCIBar bar,
+                                       uint64_t iova, uint64_t gpa,
+                                       uint32_t len, uint32_t attrs);
+
+void qos_iommu_testdev_single_translation(const QOSIOMMUTestdevDmaCfg *dma,
+                                          void *opaque,
+                                          QOSIOMMUTestdevSetupFn setup_fn,
+                                          QOSIOMMUTestdevAttrsFn attrs_fn,
+                                          QOSIOMMUTestdevValidateFn validate_fn,
+                                          QOSIOMMUTestdevReportFn report_fn,
+                                          uint32_t *dma_result_out);
+
+#endif /* QTEST_LIBQOS_IOMMU_TESTDEV_H */