From: Chao Liu <chao.liu.zevorn@gmail.com>
To: Fengyuan Yu <15fengyuan@gmail.com>
Cc: Fabiano Rosas <farosas@suse.de>,
Laurent Vivier <lvivier@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Tao Tang <tangtao1634@phytium.com.cn>,
qemu-devel@nongnu.org
Subject: Re: [PATCH RFC v1 2/2] tests/qtest: Add Intel IOMMU bare-metal test
Date: Wed, 4 Feb 2026 15:43:37 +0800 [thread overview]
Message-ID: <aYL4qVS1IEbcoPL2@ZEVORN-PC> (raw)
In-Reply-To: <89909ddad9c2b887056344bb93e5407e3639980d.1770172615.git.15fengyuan@gmail.com>
Hi Fengyuan,
On Wed, Feb 04, 2026 at 11:06:20AM +0800, Fengyuan Yu wrote:
> Add a qtest suite for the Intel IOMMU (VT-d) device on the Q35 machine.
> The test exercises pass-through and translated translation modes using
> iommu-testdev and the qos-intel-iommu helpers.
>
> The test validates:
> - Root Entry Table and Context Entry Table configuration
> - 4-level page table walks for 48-bit address translation
> - Pass-through mode (identity mapping)
> - Translated mode with complete IOVA-to-PA translation
> - DMA transaction execution with memory content verification
>
Good commit message.
> Signed-off-by: Fengyuan Yu <15fengyuan@gmail.com>
> ---
> tests/qtest/iommu-intel-test.c | 137 +++++++++++++++++++++++++++++++++
> tests/qtest/meson.build | 2 +
> 2 files changed, 139 insertions(+)
> create mode 100644 tests/qtest/iommu-intel-test.c
>
> diff --git a/tests/qtest/iommu-intel-test.c b/tests/qtest/iommu-intel-test.c
> new file mode 100644
> index 0000000000..9f631be2c5
> --- /dev/null
> +++ b/tests/qtest/iommu-intel-test.c
> @@ -0,0 +1,137 @@
> +/*
> + * QTest for Intel IOMMU (VT-d) with iommu-testdev
> + *
> + * This QTest file is used to test the Intel IOMMU with iommu-testdev so that
> + * we can test VT-d without any guest kernel or firmware.
> + *
> + * Copyright (c) 2026 Fengyuan Yu <15fengyuan@gmail.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "libqtest.h"
> +#include "libqos/pci.h"
> +#include "libqos/pci-pc.h"
> +#include "hw/pci/pci_regs.h"
> +#include "hw/misc/iommu-testdev.h"
> +#include "libqos/qos-intel-iommu.h"
> +
> +#define DMA_LEN 4
> +
> +/* Test configurations for different Intel IOMMU modes */
> +static const QVTDTestConfig base_test_configs[] = {
> + {
> + .trans_mode = QVTD_TM_LEGACY_PT,
> + .dma_iova = 0x10100000, /* Use address in guest RAM range (inside 512MB) */
> + .dma_pa = 0x10100000,
> + .dma_len = DMA_LEN,
> + .expected_result = 0,
> + .domain_id = 1,
> + },
> + {
> + .trans_mode = QVTD_TM_LEGACY_TRANS,
> + .dma_iova = QVTD_TEST_IOVA,
> + .dma_pa = QVTD_TEST_PA,
> + .dma_len = DMA_LEN,
> + .expected_result = 0,
> + .domain_id = 1,
> + },
> +};
> +
> +static QPCIDevice *setup_qtest_pci_device(QTestState *qts, QPCIBus **pcibus,
> + QPCIBar *bar)
> +{
> + uint16_t vid, did;
> + QPCIDevice *dev = NULL;
> + int device_count = 0;
> +
> + *pcibus = qpci_new_pc(qts, NULL);
> + g_assert(*pcibus != NULL);
> +
> + g_test_message("Scanning PCI bus for iommu-testdev (vendor:device = 0x%04x:0x%04x)...",
> + IOMMU_TESTDEV_VENDOR_ID, IOMMU_TESTDEV_DEVICE_ID);
> +
> + /* Find device by vendor/device ID to avoid slot surprises. */
> + for (int s = 0; s < 32 && !dev; s++) {
> + for (int fn = 0; fn < 8 && !dev; fn++) {
> + QPCIDevice *cand = qpci_device_find(*pcibus, QPCI_DEVFN(s, fn));
> + if (!cand) {
> + continue;
> + }
> + vid = qpci_config_readw(cand, PCI_VENDOR_ID);
> + did = qpci_config_readw(cand, PCI_DEVICE_ID);
> +
> + device_count++;
> + g_test_message(" Found PCI device at %02x:%x - vendor:device = 0x%04x:0x%04x",
> + s, fn, vid, did);
> +
> + if (vid == IOMMU_TESTDEV_VENDOR_ID &&
> + did == IOMMU_TESTDEV_DEVICE_ID) {
> + dev = cand;
> + g_test_message("Found iommu-testdev! devfn: 0x%x", cand->devfn);
> + } else {
> + g_free(cand);
> + }
> + }
> + }
> +
This manual PCI bus scanning is verbose. The SMMUv3 test uses
qpci_device_foreach() which is more concise:
qpci_device_foreach(&gbus->bus, IOMMU_TESTDEV_VENDOR_ID,
IOMMU_TESTDEV_DEVICE_ID, save_fn, &dev);
See iommu-smmuv3-test.c for reference.
> + if (!dev) {
> + g_test_message("ERROR: iommu-testdev not found after scanning %d PCI devices", device_count);
> + g_test_message("Expected vendor:device = 0x%04x:0x%04x (PCI_VENDOR_ID_REDHAT:PCI_DEVICE_ID_REDHAT_TEST)",
> + IOMMU_TESTDEV_VENDOR_ID, IOMMU_TESTDEV_DEVICE_ID);
> + qpci_free_pc(*pcibus);
> + *pcibus = NULL;
> + g_test_skip("iommu-testdev not found on PCI bus - device may not be compiled or registered");
> + return NULL;
> + }
> +
> + /* Enable device - iommu-testdev only uses MMIO, not I/O ports */
> + uint16_t cmd = qpci_config_readw(dev, PCI_COMMAND);
> + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
> + qpci_config_writew(dev, PCI_COMMAND, cmd);
> +
> + *bar = qpci_iomap(dev, 0, NULL);
> + g_assert_false(bar->is_io);
> +
> + return dev;
> +}
> +
> +static void test_intel_iommu_translation(void)
> +{
> + QTestState *qts;
> + QPCIBus *pcibus;
> + QPCIDevice *dev;
> + QPCIBar bar;
> +
Please add a machine availability check before qtest_init(), similar to
what the SMMUv3 test does:
if (!qtest_has_machine("q35")) {
g_test_skip("q35 machine not available");
return;
}
> + /* Initialize QEMU environment for Intel IOMMU testing */
> + qts = qtest_init("-machine q35,kernel-irqchip=split "
> + "-accel tcg "
> + "-device intel-iommu,pt=on,aw-bits=48 "
> + "-device iommu-testdev,bus=pcie.0,addr=0x4 "
> + "-m 512");
> +
> + /* Setup and configure PCI device */
> + dev = setup_qtest_pci_device(qts, &pcibus, &bar);
> + if (!dev) {
> + qtest_quit(qts);
> + return;
> + }
> +
> + /* Run the translation tests */
> + g_test_message("### Starting Intel IOMMU translation tests...###");
> + qvtd_translation_batch(base_test_configs, ARRAY_SIZE(base_test_configs),
> + qts, dev, bar, Q35_IOMMU_BASE);
> + g_test_message("### Intel IOMMU translation tests completed successfully! ###");
> +
> + g_free(dev);
> + qpci_free_pc(pcibus);
> + qtest_quit(qts);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + g_test_init(&argc, &argv, NULL);
> + qtest_add_func("/iommu-testdev/intel-translation", test_intel_iommu_translation);
The test path naming differs from the SMMUv3 convention. For consistency,
consider splitting into separate test functions and using paths like:
qtest_add_func("/iommu-testdev/intel/legacy-pt", test_intel_legacy_pt);
qtest_add_func("/iommu-testdev/intel/legacy-trans", test_intel_legacy_trans);
This makes it easier to run individual test cases and debug failures.
> + return g_test_run();
> +}
Missing newline at end of file. Please run scripts/checkpatch.pl check
it.
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index e2d2e68092..344e836300 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -95,6 +95,8 @@ qtests_i386 = \
> (config_all_devices.has_key('CONFIG_SDHCI_PCI') ? ['fuzz-sdcard-test'] : []) + \
> (config_all_devices.has_key('CONFIG_ESP_PCI') ? ['am53c974-test'] : []) + \
> (config_all_devices.has_key('CONFIG_VTD') ? ['intel-iommu-test'] : []) + \
> + (config_all_devices.has_key('CONFIG_VTD') and
> + config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') ? ['iommu-intel-test'] : []) + \
> (host_os != 'windows' and \
> config_all_devices.has_key('CONFIG_ACPI_ERST') ? ['erst-test'] : []) + \
> (config_all_devices.has_key('CONFIG_PCIE_PORT') and \
> --
> 2.39.5
>
One more thing: the MAINTAINERS entry in patch 1/2 only adds the libqos
files. Please also add to 'X86 general architecture support':
F: tests/qtest/iommu-intel-test.c
to the IOMMU section.
Overall, this is a nice addition to the IOMMU testing infrastructure.
Thanks,
Chao
next prev parent reply other threads:[~2026-02-04 7:44 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-04 3:06 [PATCH RFC v1 0/2] tests/qtest: Add Intel IOMMU bare-metal test using iommu-testdev Fengyuan Yu
2026-02-04 3:06 ` [PATCH RFC v1 1/2] tests/qtest/libqos: Add Intel IOMMU helper library Fengyuan Yu
2026-02-04 7:31 ` Chao Liu
2026-02-05 9:20 ` Fengyuan
2026-02-04 3:06 ` [PATCH RFC v1 2/2] tests/qtest: Add Intel IOMMU bare-metal test Fengyuan Yu
2026-02-04 7:43 ` Chao Liu [this message]
2026-02-05 9:18 ` Fengyuan
2026-02-04 13:14 ` [PATCH RFC v1 0/2] tests/qtest: Add Intel IOMMU bare-metal test using iommu-testdev Tao Tang
2026-02-05 9:35 ` Fengyuan
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=aYL4qVS1IEbcoPL2@ZEVORN-PC \
--to=chao.liu.zevorn@gmail.com \
--cc=15fengyuan@gmail.com \
--cc=farosas@suse.de \
--cc=lvivier@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=tangtao1634@phytium.com.cn \
/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 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.