DEBUG: drivers: iommu: pviommu: selftest
Add a simple self test which only tests mappings tracking in the
driver.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 7c17487..a5eeb43 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -516,4 +516,10 @@
Say Y here if you intend to run this kernel as a guest.
+config PKVM_PVIOMMU_SELFTEST
+ bool "pKVM pvIOMMU selftest"
+ depends on PKVM_PVIOMMU
+ help
+ Basic test for PKVM_PVIOMMU
+
endif # IOMMU_SUPPORT
diff --git a/drivers/iommu/pkvm-pviommu.c b/drivers/iommu/pkvm-pviommu.c
index bc2ff2e..53b1c1e 100644
--- a/drivers/iommu/pkvm-pviommu.c
+++ b/drivers/iommu/pkvm-pviommu.c
@@ -9,6 +9,16 @@
#include <linux/maple_tree.h>
#include <linux/pci.h>
+
+#define ASSERT(cond) \
+ do { \
+ if (!(cond)) { \
+ pr_err("line %d: assertion failed: %s\n", \
+ __LINE__, #cond); \
+ return -1; \
+ } \
+ } while (0)
+
#define FEAUTRE_PGSIZE_BITMAP 0x1
#define DRIVER_VERSION 0x1000ULL
@@ -401,6 +411,45 @@ static struct platform_driver pkvm_pviommu_driver = {
},
};
+#if IS_ENABLED(CONFIG_PKVM_PVIOMMU_SELFTEST)
+/* Mainly test iova_to_phys and not hypervisor interface. */
+int __init __pviommu_selftest(void)
+{
+ struct pviommu_domain domain;
+
+ pr_info("pviommu selftest starting\n");
+
+ mt_init(&domain.mappings);
+
+ pviommu_domain_insert_map(&domain, 0x10000 , 0xFEFFF, 0xE0000);
+ pviommu_domain_insert_map(&domain, 0xFFF0000, 0x1EDBFFFF, 0xDEAD0000);
+ ASSERT(pviommu_domain_find(&domain, 0x10000) == 0xE0000);
+ ASSERT(pviommu_domain_find(&domain, 0x10F00) == 0xE0F00);
+ ASSERT(pviommu_domain_find(&domain, 0x1EDBFFFF) == 0xED89FFFF);
+ ASSERT(pviommu_domain_find(&domain, 0x10000000) == 0xDEAE0000);
+ ASSERT(pviommu_domain_find(&domain, 0x1FF000) == 0);
+ pviommu_domain_remove_map(&domain, 0x12000, 0x19FFF);
+ ASSERT(pviommu_domain_find(&domain, 0x11000) == 0xE1000);
+ ASSERT(pviommu_domain_find(&domain, 0x1B000) == 0xEB000);
+ ASSERT(pviommu_domain_find(&domain, 0x14000) == 0);
+
+ pviommu_domain_insert_map(&domain, 0xC00000 , 0xCFFFFF, 0xABCD000);
+ pviommu_domain_insert_map(&domain, 0xD00000 , 0xDFFFFF, 0x1000);
+ pviommu_domain_insert_map(&domain, 0xE00000, 0xEFFFFF, 0xC0FE00000);
+ ASSERT(pviommu_domain_find(&domain, 0xD00000) == 0x1000);
+ pviommu_domain_remove_map(&domain, 0xC50000, 0xE5FFFF);
+ ASSERT(pviommu_domain_find(&domain, 0xC50000) == 0);
+ ASSERT(pviommu_domain_find(&domain, 0xD10000) == 0);
+ ASSERT(pviommu_domain_find(&domain, 0xE60000) == 0xC0FE60000);
+ ASSERT(pviommu_domain_find(&domain, 0xC10000) == 0xABDD000);
+
+ mtree_destroy(&domain.mappings);
+ return 0;
+}
+
+subsys_initcall(__pviommu_selftest);
+#endif
+
module_platform_driver(pkvm_pviommu_driver);
MODULE_DESCRIPTION("IOMMU API for pKVM paravirtualized IOMMU");