All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fabiano Rosas <farosas@suse.de>
To: "Fengyuan Yu" <15fengyuan@gmail.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Jason Wang" <jasowang@redhat.com>, "Yi Liu" <yi.l.liu@intel.com>,
	"Clément Mathieu--Drif" <clement.mathieu--drif@bull.com>,
	"Laurent Vivier" <lvivier@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Tao Tang" <tangtao1634@phytium.com.cn>
Cc: qemu-devel@nongnu.org, Chao Liu <chao.liu.zevorn@gmail.com>,
	Fengyuan Yu <15fengyuan@gmail.com>
Subject: Re: [PATCH v3 2/2] tests/qtest: Add Intel IOMMU bare-metal test
Date: Fri, 27 Mar 2026 12:40:03 -0300	[thread overview]
Message-ID: <87v7ehgu24.fsf@suse.de> (raw)
In-Reply-To: <ce3c44f3b07734a4f0ee43f55b21c856034af1b1.1774421649.git.15fengyuan@gmail.com>

Fengyuan Yu <15fengyuan@gmail.com> writes:

> Add a qtest suite for the Intel IOMMU (VT-d) device on the Q35 machine.
> The test exercises both Legacy and Scalable translation modes using
> iommu-testdev and the qos-intel-iommu helpers, without requiring any
> guest kernel or firmware.
>
> The test validates:
> - Legacy-mode Root Entry Table and Context Entry Table configuration
> - Scalable-mode Context Entry, PASID Directory, and PASID Table setup
> - Legacy-mode 4-level page table walks for 48-bit address translation
> - Scalable-mode second-level and first-level 4-level page table walks
> - Pass-through mode in both Legacy and Scalable modes
> - DMA transaction execution with memory content verification
>
> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Fengyuan Yu <15fengyuan@gmail.com>
> ---
>  MAINTAINERS                    |   1 +
>  tests/qtest/iommu-intel-test.c | 216 +++++++++++++++++++++++++++++++++
>  tests/qtest/meson.build        |   2 +
>  3 files changed, 219 insertions(+)
>  create mode 100644 tests/qtest/iommu-intel-test.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ba0901bf4f..420f7ab6cf 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4016,6 +4016,7 @@ F: hw/i386/intel_iommu_accel.*
>  F: include/hw/i386/intel_iommu.h
>  F: tests/functional/x86_64/test_intel_iommu.py
>  F: tests/qtest/intel-iommu-test.c
> +F: tests/qtest/iommu-intel-test.c
>  
>  AMD-Vi Emulation
>  M: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
> diff --git a/tests/qtest/iommu-intel-test.c b/tests/qtest/iommu-intel-test.c
> new file mode 100644
> index 0000000000..a52c45e298
> --- /dev/null
> +++ b/tests/qtest/iommu-intel-test.c
> @@ -0,0 +1,216 @@
> +/*
> + * 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/i386/intel_iommu_internal.h"
> +#include "hw/misc/iommu-testdev.h"
> +#include "libqos/qos-intel-iommu.h"
> +
> +#define DMA_LEN           4
> +
> +static uint64_t intel_iommu_expected_gpa(uint64_t iova)
> +{
> +    return (QVTD_PT_VAL & VTD_PAGE_MASK_4K) + (iova & 0xfff);
> +}
> +
> +static void save_fn(QPCIDevice *dev, int devfn, void *data)
> +{
> +    QPCIDevice **pdev = (QPCIDevice **) data;
> +
> +    *pdev = dev;
> +}
> +
> +static QPCIDevice *setup_qtest_pci_device(QTestState *qts, QPCIBus **pcibus,
> +                                          QPCIBar *bar)
> +{
> +    QPCIDevice *dev = NULL;
> +
> +    *pcibus = qpci_new_pc(qts, NULL);
> +    g_assert(*pcibus != NULL);
> +
> +    qpci_device_foreach(*pcibus, IOMMU_TESTDEV_VENDOR_ID,
> +                        IOMMU_TESTDEV_DEVICE_ID, save_fn, &dev);
> +
> +    g_assert(dev);
> +    qpci_device_enable(dev);
> +    *bar = qpci_iomap(dev, 0, NULL);
> +    g_assert_false(bar->is_io);
> +
> +    return dev;
> +}
> +
> +static const char *qvtd_iommu_args(QVTDTransMode mode)
> +{
> +    switch (mode) {
> +    case QVTD_TM_SCALABLE_FLT:
> +        return "-device intel-iommu,x-scalable-mode=on,x-flts=on ";
> +    case QVTD_TM_SCALABLE_PT:
> +    case QVTD_TM_SCALABLE_SLT:
> +        return "-device intel-iommu,x-scalable-mode=on ";
> +    default:
> +        return "-device intel-iommu ";
> +    }
> +}
> +
> +static bool qvtd_check_caps(QTestState *qts, QVTDTransMode mode)
> +{
> +    uint64_t ecap = qtest_readq(qts,
> +                                Q35_HOST_BRIDGE_IOMMU_ADDR + DMAR_ECAP_REG);
> +
> +    /* All scalable modes require SMTS */
> +    if (qvtd_is_scalable(mode) && !(ecap & VTD_ECAP_SMTS)) {
> +        g_test_skip("ECAP.SMTS not supported");
> +        return false;
> +    }
> +
> +    switch (mode) {
> +    case QVTD_TM_SCALABLE_PT:
> +        if (!(ecap & VTD_ECAP_PT)) {
> +            g_test_skip("ECAP.PT not supported");
> +            return false;
> +        }
> +        break;
> +    case QVTD_TM_SCALABLE_SLT:
> +        if (!(ecap & VTD_ECAP_SSTS)) {
> +            g_test_skip("ECAP.SSTS not supported");
> +            return false;
> +        }
> +        break;
> +    case QVTD_TM_SCALABLE_FLT:
> +        if (!(ecap & VTD_ECAP_FSTS)) {
> +            g_test_skip("ECAP.FSTS not supported");
> +            return false;
> +        }
> +        break;
> +    default:
> +        break;
> +    }
> +
> +    return true;
> +}
> +
> +static void run_intel_iommu_translation(const QVTDTestConfig *cfg)
> +{
> +    QTestState *qts;
> +    QPCIBus *pcibus;
> +    QPCIDevice *dev;
> +    QPCIBar bar;
> +
> +    if (!qtest_has_machine("q35")) {
> +        g_test_skip("q35 machine not available");
> +        return;
> +    }
> +
> +    /* Initialize QEMU environment for Intel IOMMU testing */
> +    qts = qtest_initf("-machine q35 -smp 1 -m 512 -net none "
> +                      "%s -device iommu-testdev",
> +                      qvtd_iommu_args(cfg->trans_mode));
> +
> +    /* Check CAP/ECAP capabilities for required translation mode */
> +    if (!qvtd_check_caps(qts, cfg->trans_mode)) {
> +        qtest_quit(qts);
> +        return;
> +    }
> +
> +    /* Setup and configure IOMMU-testdev PCI device */
> +    dev = setup_qtest_pci_device(qts, &pcibus, &bar);
> +    g_assert(dev);
> +
> +    g_test_message("### Intel IOMMU translation mode=%d ###", cfg->trans_mode);
> +    qvtd_run_translation_case(qts, dev, bar, Q35_HOST_BRIDGE_IOMMU_ADDR, cfg);
> +    g_free(dev);
> +    qpci_free_pc(pcibus);
> +    qtest_quit(qts);
> +}
> +
> +static void test_intel_iommu_legacy_pt(void)
> +{
> +    QVTDTestConfig cfg = {
> +        .trans_mode = QVTD_TM_LEGACY_PT,
> +        .dma_gpa = QVTD_IOVA,  /* pass-through: GPA == IOVA */
> +        .dma_len = DMA_LEN,
> +        .expected_result = 0,
> +    };
> +
> +    run_intel_iommu_translation(&cfg);
> +}
> +
> +static void test_intel_iommu_legacy_trans(void)
> +{
> +    QVTDTestConfig cfg = {
> +        .trans_mode = QVTD_TM_LEGACY_TRANS,
> +        .dma_gpa = intel_iommu_expected_gpa(QVTD_IOVA),
> +        .dma_len = DMA_LEN,
> +        .expected_result = 0,
> +    };
> +
> +    run_intel_iommu_translation(&cfg);
> +}
> +
> +static void test_intel_iommu_scalable_pt(void)
> +{
> +    QVTDTestConfig cfg = {
> +        .trans_mode = QVTD_TM_SCALABLE_PT,
> +        .dma_gpa = QVTD_IOVA,  /* pass-through: GPA == IOVA */
> +        .dma_len = DMA_LEN,
> +        .expected_result = 0,
> +    };
> +
> +    run_intel_iommu_translation(&cfg);
> +}
> +
> +static void test_intel_iommu_scalable_slt(void)
> +{
> +    QVTDTestConfig cfg = {
> +        .trans_mode = QVTD_TM_SCALABLE_SLT,
> +        .dma_gpa = intel_iommu_expected_gpa(QVTD_IOVA),
> +        .dma_len = DMA_LEN,
> +        .expected_result = 0,
> +    };
> +
> +    run_intel_iommu_translation(&cfg);
> +}
> +
> +static void test_intel_iommu_scalable_flt(void)
> +{
> +    QVTDTestConfig cfg = {
> +        .trans_mode = QVTD_TM_SCALABLE_FLT,
> +        .dma_gpa = intel_iommu_expected_gpa(QVTD_IOVA),
> +        .dma_len = DMA_LEN,
> +        .expected_result = 0,
> +    };
> +
> +    run_intel_iommu_translation(&cfg);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +    g_test_init(&argc, &argv, NULL);
> +
> +    /* Legacy mode tests */
> +    qtest_add_func("/iommu-testdev/intel/legacy-pt",
> +                   test_intel_iommu_legacy_pt);
> +    qtest_add_func("/iommu-testdev/intel/legacy-trans",
> +                   test_intel_iommu_legacy_trans);
> +
> +    /* Scalable mode tests */
> +    qtest_add_func("/iommu-testdev/intel/scalable-pt",
> +                   test_intel_iommu_scalable_pt);
> +    qtest_add_func("/iommu-testdev/intel/scalable-slt",
> +                   test_intel_iommu_scalable_slt);
> +    qtest_add_func("/iommu-testdev/intel/scalable-flt",
> +                   test_intel_iommu_scalable_flt);
> +
> +    return g_test_run();
> +}
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index be4fa627b5..264bce9f81 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -96,6 +96,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                                       \

Reviewed-by: Fabiano Rosas <farosas@suse.de>


  reply	other threads:[~2026-03-27 15:40 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-25  7:09 [PATCH v3 0/2] tests/qtest: Add Intel IOMMU bare-metal test using iommu-testdev Fengyuan Yu
2026-03-25  7:09 ` [PATCH v3 1/2] tests/qtest/libqos: Add Intel IOMMU helper library Fengyuan Yu
2026-03-27 15:39   ` Fabiano Rosas
2026-03-30  9:09   ` Tao Tang
2026-03-25  7:09 ` [PATCH v3 2/2] tests/qtest: Add Intel IOMMU bare-metal test Fengyuan Yu
2026-03-27 15:40   ` Fabiano Rosas [this message]
2026-03-30  9:11   ` Tao Tang

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=87v7ehgu24.fsf@suse.de \
    --to=farosas@suse.de \
    --cc=15fengyuan@gmail.com \
    --cc=chao.liu.zevorn@gmail.com \
    --cc=clement.mathieu--drif@bull.com \
    --cc=jasowang@redhat.com \
    --cc=lvivier@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=tangtao1634@phytium.com.cn \
    --cc=yi.l.liu@intel.com \
    /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.