On 11/26/25 7:45 AM, Tao Tang wrote:
Introduce qos-smmuv3, a reusable library for SMMUv3-related qtest
operations. This module encapsulates common tasks like:

- SMMUv3 initialization (enabling, configuring command/event queues)
- Stream Table Entry (STE) and Context Descriptor (CD) setup
- Multi-level page table construction (L0-L3 for 4KB granules)
- Support for Stage 1, Stage 2, and nested translation modes
- Could be easily extended to support multi-space testing infrastructure
     (Non-Secure, Secure, Root, Realm)

The library provides high-level abstractions that allow test code to
focus on IOMMU behavior validation rather than low-level register
manipulation and page table encoding. Key features include:

- Automatic memory allocation for translation structures with proper
     alignment
- Helper functions to build valid STEs/CDs for different translation
     scenarios
- Page table walkers that handle address offset calculations per
     security space
- Command queue management for SMMU configuration commands

This infrastructure is designed to be used by iommu-testdev-based tests
and future SMMUv3 test suites, reducing code duplication and improving
test maintainability.

Signed-off-by: Tao Tang <[email protected]>
---
  tests/qtest/libqos/meson.build  |   3 +
  tests/qtest/libqos/qos-smmuv3.c | 731 ++++++++++++++++++++++++++++++++
  tests/qtest/libqos/qos-smmuv3.h | 267 ++++++++++++
  3 files changed, 1001 insertions(+)
  create mode 100644 tests/qtest/libqos/qos-smmuv3.c
  create mode 100644 tests/qtest/libqos/qos-smmuv3.h


...

+
+void qsmmu_single_translation(QSMMUTestContext *ctx)
+{
+    uint32_t config_result;
+    uint32_t dma_result;
+    bool test_passed;
+
+    /* Configure SMMU translation */
+    config_result = qsmmu_setup_and_enable_translation(ctx);
+    if (config_result != 0) {
+        g_test_message("Configuration failed: mode=%u status=0x%x",
+                       ctx->config.trans_mode, config_result);
+        return;

Is that expected to silently return if we can't configure translation?

+    }
+
+    /* Trigger DMA operation */
+    dma_result = qsmmu_trigger_dma(ctx);
+    if (dma_result != 0) {
+        g_test_message("DMA failed: mode=%u result=0x%x",
+                       ctx->config.trans_mode, dma_result);
+    } else {
+        g_test_message("-> DMA succeeded: mode=%u", ctx->config.trans_mode);
+    }
+
+    /* Validate test result */
+    test_passed = qsmmu_validate_test_result(ctx);
+    g_assert_true(test_passed);
+
+    /* Clean up translation state to prepare for the next test */
+    qsmmu_cleanup_translation(ctx);
+}
+
+void qsmmu_translation_batch(const QSMMUTestConfig *configs, size_t count,
+                             QTestState *qts, QPCIDevice *dev,
+                             QPCIBar bar, uint64_t smmu_base)
+{
+    for (int i = 0; i < count; i++) {
+        /* Initialize test memory */
+        qtest_memset(qts, configs[i].dma_iova, 0x00, configs[i].dma_len);
+        /* Execute each test configuration */
+        QSMMUTestContext ctx = {
+            .qts = qts,
+            .dev = dev,
+            .bar = bar,
+            .smmu_base = smmu_base,
+            .config = configs[i],
+            .trans_status = 0,
+            .dma_result = 0,
+            .sid = dev->devfn,
+            .tx_space = qsmmu_sec_sid_to_space(configs[i].sec_sid),
+        };
+
+        qsmmu_single_translation(&ctx);
+        g_test_message("--> Test %d completed: mode=%u sec_sid=%u "
+                       "status=0x%x result=0x%x", i, configs[i].trans_mode,
+                       configs[i].sec_sid, ctx.trans_status, ctx.dma_result);
+    }
+}

What is the reason for batching operations?
We are not in a performance critical scenario for running this test, so it's probably better to have distinct calls to single_translation.

...

For the rest of the patch, which is quite consequent, congrats. It's hard to review all the setup phase here, but knowing it works with the current smmuv3 implementation, that's a good proof that it's working as expected.

Reply via email to