From: Junjie Cao <[email protected]> iommu-intel-test.c keeps the iommu-testdev PCI setup (save_fn(), setup_qtest_pci_device()) and the VT-d command-line / capability helpers (qvtd_iommu_args(), qvtd_check_caps()) as file-local statics. A second Intel IOMMU test would have to copy them, which defeats the purpose of the shared qos-intel-iommu module.
Move them into qos-intel-iommu so sibling tests can reuse them: save_fn() becomes qvtd_save_pci_dev() and setup_qtest_pci_device() becomes qvtd_setup_qtest_pci_device(); qvtd_iommu_args() and qvtd_check_caps() keep their names. No functional change: iommu-intel-test now calls the public qvtd_setup_qtest_pci_device() instead of its file-local copy. Signed-off-by: Junjie Cao <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Message-ID: <[email protected]> --- tests/qtest/libqos/qos-intel-iommu.h | 23 ++++++++ tests/qtest/iommu-intel-test.c | 78 +--------------------------- tests/qtest/libqos/qos-intel-iommu.c | 77 +++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 77 deletions(-) diff --git a/tests/qtest/libqos/qos-intel-iommu.h b/tests/qtest/libqos/qos-intel-iommu.h index c6cacc5c3f..dd6f920464 100644 --- a/tests/qtest/libqos/qos-intel-iommu.h +++ b/tests/qtest/libqos/qos-intel-iommu.h @@ -182,4 +182,27 @@ void qvtd_run_translation_case(QTestState *qts, QPCIDevice *dev, QPCIBar bar, uint64_t iommu_base, const QVTDTestConfig *cfg); +/* + * qvtd_iommu_args - Build the -device intel-iommu command-line fragment + * for the requested translation mode. + */ +const char *qvtd_iommu_args(QVTDTransMode mode); + +/* + * qvtd_check_caps - Check whether the running QEMU exposes the ECAP bits + * required by @mode. Calls g_test_skip() and returns + * false when a required capability is missing. + */ +bool qvtd_check_caps(QTestState *qts, QVTDTransMode mode); + +/* + * qvtd_setup_qtest_pci_device - Create a QPCIBus, locate the iommu-testdev + * PCI function, enable it and map BAR0. + * + * On success, *pcibus and *bar are populated and the returned QPCIDevice + * must be released by the caller via g_free(). + */ +QPCIDevice *qvtd_setup_qtest_pci_device(QTestState *qts, QPCIBus **pcibus, + QPCIBar *bar); + #endif /* QTEST_LIBQOS_INTEL_IOMMU_H */ diff --git a/tests/qtest/iommu-intel-test.c b/tests/qtest/iommu-intel-test.c index 703bbfef73..c2744def6f 100644 --- a/tests/qtest/iommu-intel-test.c +++ b/tests/qtest/iommu-intel-test.c @@ -24,82 +24,6 @@ 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,scalable-mode=on,fsts=on "; - case QVTD_TM_SCALABLE_PT: - case QVTD_TM_SCALABLE_SLT: - return "-device intel-iommu,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; @@ -124,7 +48,7 @@ static void run_intel_iommu_translation(const QVTDTestConfig *cfg) } /* Setup and configure IOMMU-testdev PCI device */ - dev = setup_qtest_pci_device(qts, &pcibus, &bar); + dev = qvtd_setup_qtest_pci_device(qts, &pcibus, &bar); g_assert(dev); g_test_message("### Intel IOMMU translation mode=%d ###", cfg->trans_mode); diff --git a/tests/qtest/libqos/qos-intel-iommu.c b/tests/qtest/libqos/qos-intel-iommu.c index f8ca4c871b..4095ac0917 100644 --- a/tests/qtest/libqos/qos-intel-iommu.c +++ b/tests/qtest/libqos/qos-intel-iommu.c @@ -11,6 +11,7 @@ #include "qemu/osdep.h" #include "hw/i386/intel_iommu_internal.h" #include "tests/qtest/libqos/pci.h" +#include "tests/qtest/libqos/pci-pc.h" #include "qos-iommu-testdev.h" #include "qos-intel-iommu.h" @@ -452,3 +453,79 @@ void qvtd_run_translation_case(QTestState *qts, QPCIDevice *dev, } } } + +const char *qvtd_iommu_args(QVTDTransMode mode) +{ + switch (mode) { + case QVTD_TM_SCALABLE_FLT: + return "-device intel-iommu,scalable-mode=on,fsts=on "; + case QVTD_TM_SCALABLE_PT: + case QVTD_TM_SCALABLE_SLT: + return "-device intel-iommu,scalable-mode=on "; + default: + return "-device intel-iommu "; + } +} + +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 qvtd_save_pci_dev(QPCIDevice *dev, int devfn, void *data) +{ + QPCIDevice **pdev = (QPCIDevice **)data; + + *pdev = dev; +} + +QPCIDevice *qvtd_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, qvtd_save_pci_dev, &dev); + + g_assert(dev); + qpci_device_enable(dev); + *bar = qpci_iomap(dev, 0, NULL); + g_assert_false(bar->is_io); + + return dev; +} -- MST
