From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B4328CAC5A7 for ; Mon, 22 Sep 2025 09:00:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=mi6TD8VyLf+L2Nc6qgjtgNBQkwWi+DuvkEzgMSAI6jo=; b=2O7oRI8B2vcTeK3fwf3+UpHNKX 2OjAJicEnHehrzzh6fxU5y0GiCOKB1ErwQu1TVGenPz8A8Ce6wzoao2DIHz+WMpBnFj8VKGoPXY/F asOHtJXmbNm0t8JtCxwiRV8OAu/MPCzTdXdTKbFPNYi//+xfzSKmsBdZXoQkpwWHQKEON7VjBfvly HdD4/8kxQOYcbLa+JujnA1CbCv1C4+DrG6I6A9tTTdjnUBUcoumNGlQbbR566KSrv3QqDGVafajKL pXWBJsvEh2diledewuz+MtK7j9BE9CSG31o+dwSf2TU2a7UxAThwOqdJ3eBChU5P9g88AMy7wgMKY D4Iu0kIw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1v0cPA-00000009ouu-253m; Mon, 22 Sep 2025 09:00:16 +0000 Received: from mail-wm1-x349.google.com ([2a00:1450:4864:20::349]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1v0cP5-00000009oqo-2YOl for linux-arm-kernel@lists.infradead.org; Mon, 22 Sep 2025 09:00:12 +0000 Received: by mail-wm1-x349.google.com with SMTP id 5b1f17b1804b1-46da436df64so3350125e9.0 for ; Mon, 22 Sep 2025 02:00:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758531609; x=1759136409; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=mi6TD8VyLf+L2Nc6qgjtgNBQkwWi+DuvkEzgMSAI6jo=; b=30G5lHMTp5Pn9V9uilIJlewkKGIHPmHuQSL1kNNrDxIRCQfxUbxDJRakCHY9HZ5ogi Au058qHtwk3eKSOwuULzllM+cfmJK3lH8FFYEOfV0J7co+UQ3V7fBw2KakJQkibv2mqL 1HiwcdYu0ofhCCrpnvkX1xXhiN/ZLt78U91XBjvQzVqE27ZftTcNWoXwnyf1zPiuAtRH Efou4ObnXWHT9ORCjSpsj5XqXgA9+T1GzqTt4gvqGHEETh/kbxa8ey4SUlBY9yT1PeDQ Pm132b3YYkJSmv/KMcnkeVLs4FnakSWoINJ9sbWNmq9cOF9J3EcZiSa0DfdfMM0e0EVZ /tVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758531609; x=1759136409; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mi6TD8VyLf+L2Nc6qgjtgNBQkwWi+DuvkEzgMSAI6jo=; b=BaI8rPCZceq0tmWMIrg/fxFunABeMhaV/N9SGSMaNoGu/WuJ2dDAv16Upi3nk0t/HI icKGValD/q9k0GTnu8EAiIuxFF/7HOVCiQ2GQJaWq5ifgkcx6tUSWDRuCsl5lijn3hOZ 5zDG+YaONXn9uamY1C0R6uc2LbGORFVHZ7y1J4RJOIJ+s9gDOQ1ctmRvcoPFSFkxjUek RoQ/fuuD3hMoTSjBS9IlJT29JJ6bY23MxPLak4rp6o3/Qi5ZZmoAI7emhCEcM6/xiC1c OcveHP3k+EVxitThsoCz2jM+qe7ZHmqRdCXe53+HJB+XhF0PhmLvQVbDsmTFjiywX6yK cAyg== X-Forwarded-Encrypted: i=1; AJvYcCXmSgsCnTNZCQ+z8PYyWGGkolci91xrhMDQxwBZDLBiw5yjVVWfiOnHCLaQGmwOwmHWtdcxdG6KBmq+mQhXPXYp@lists.infradead.org X-Gm-Message-State: AOJu0Yw/WZV9vjEecIyOrcw+7pOVQsD9zQRQn+FgU8ysCc22hS8R1VWT 3/eETwjMPhKee0kBDNGwjoYCJypl+0ChmUKeoCiEHh5m5FTpAX9nUxXBZ3FEUHaZ7FaQaQx7lFz v4nBxLvua4t9jOA== X-Google-Smtp-Source: AGHT+IHEl5s+QPaPzGfgCuRqhCMt6KCfe3mA0A/82HtqGagB0IP7AhZDyC3DDVBt3JAEbplLYzuZt2vDDFw8ww== X-Received: from wmtk8.prod.google.com ([2002:a05:600c:c4a8:b0:45b:885a:402d]) (user=smostafa job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4f44:b0:46d:996b:8291 with SMTP id 5b1f17b1804b1-46d996b8960mr13252115e9.34.1758531609366; Mon, 22 Sep 2025 02:00:09 -0700 (PDT) Date: Mon, 22 Sep 2025 08:59:28 +0000 In-Reply-To: <20250922090003.686704-1-smostafa@google.com> Mime-Version: 1.0 References: <20250922090003.686704-1-smostafa@google.com> X-Mailer: git-send-email 2.51.0.534.gc79095c0ca-goog Message-ID: <20250922090003.686704-5-smostafa@google.com> Subject: [PATCH v4 4/4] iommu/io-pgtable-arm-selftests: Use KUnit From: Mostafa Saleh To: iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: robin.murphy@arm.com, will@kernel.org, joro@8bytes.org, jgg@ziepe.ca, praan@google.com, Mostafa Saleh , Jason Gunthorpe Content-Type: text/plain; charset="UTF-8" X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250922_020011_696417_6809D2D4 X-CRM114-Status: GOOD ( 21.73 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Integrate the selftests as part of kunit. Now instead of the test only being run at boot, it can run: - With CONFIG_IOMMU_IO_PGTABLE_LPAE_KUNIT_TEST=y It will automatically run at boot as before. - Otherwise with CONFIG_IOMMU_IO_PGTABLE_KUNIT_TEST=m: 1) on module load: Once the module load the self test will run # modprobe io-pgtable-arm-selftests 2) debugfs With CONFIG_KUNIT_DEBUGFS=y You can run the test with # echo 1 > /sys/kernel/debug/kunit/io-pgtable-arm-test/run 3) Using kunit.py You can also use the helper script which uses Qemu in the background # ./tools/testing/kunit/kunit.py run --build_dir build_kunit_arm64 --arch arm64 \ --make_options LLVM=1 --kunitconfig ./kunit/kunitconfig [18:01:09] ============= io-pgtable-arm-test (1 subtest) ============== [18:01:09] [PASSED] arm_lpae_do_selftests [18:01:09] =============== [PASSED] io-pgtable-arm-test =============== [18:01:09] ============================================================ Suggested-by: Jason Gunthorpe Reviewed-by: Jason Gunthorpe Signed-off-by: Mostafa Saleh --- drivers/iommu/Kconfig | 11 ++-- drivers/iommu/Makefile | 2 +- drivers/iommu/io-pgtable-arm-selftests.c | 82 +++++++++++++----------- 3 files changed, 51 insertions(+), 44 deletions(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 553522ef3ca9..d50685433347 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -40,12 +40,13 @@ config IOMMU_IO_PGTABLE_LPAE sizes at both stage-1 and stage-2, as well as address spaces up to 48-bits in size. -config IOMMU_IO_PGTABLE_LPAE_SELFTEST - tristate "LPAE selftests" - depends on IOMMU_IO_PGTABLE_LPAE +config IOMMU_IO_PGTABLE_LPAE_KUNIT_TEST + tristate "KUnit tests for LPAE" + depends on IOMMU_IO_PGTABLE_LPAE && KUNIT + default KUNIT_ALL_TESTS help - Enable self-tests for LPAE page table allocator. This performs - a series of page-table consistency checks during boot. + Enable kunit tests for LPAE page table allocator. This performs + a series of page-table consistency checks. If unsure, say N here. diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 5250a2eea13f..ac3851570303 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o -obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST) += io-pgtable-arm-selftests.o +obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE_KUNIT_TEST) += io-pgtable-arm-selftests.o obj-$(CONFIG_IOMMU_IO_PGTABLE_DART) += io-pgtable-dart.o obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o diff --git a/drivers/iommu/io-pgtable-arm-selftests.c b/drivers/iommu/io-pgtable-arm-selftests.c index 50350e88d9b4..fc18bd54a315 100644 --- a/drivers/iommu/io-pgtable-arm-selftests.c +++ b/drivers/iommu/io-pgtable-arm-selftests.c @@ -6,7 +6,8 @@ * * Author: Will Deacon */ -#include +#include +#include #include #include #include @@ -48,13 +49,14 @@ static void arm_lpae_dump_ops(struct io_pgtable_ops *ops) cfg->pgsize_bitmap, cfg->ias, cfg->oas); } -#define __FAIL(ops, i) ({ \ - WARN(1, "selftest: test failed for fmt idx %d\n", (i)); \ - arm_lpae_dump_ops(ops); \ - -EFAULT; \ +#define __FAIL(test, ops, i) ({ \ + KUNIT_FAIL(test, ""); \ + kunit_err(test, "selftest: test failed for fmt idx %d\n", (i)); \ + arm_lpae_dump_ops(ops); \ + -EFAULT; \ }) -static int arm_lpae_run_tests(struct io_pgtable_cfg *cfg) +static int arm_lpae_run_tests(struct kunit *test, struct io_pgtable_cfg *cfg) { static const enum io_pgtable_fmt fmts[] = { ARM_64_LPAE_S1, @@ -70,7 +72,7 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *cfg) cfg_cookie = cfg; ops = alloc_io_pgtable_ops(fmts[i], cfg, cfg); if (!ops) { - pr_err("selftest: failed to allocate io pgtable ops\n"); + kunit_err(test, "selftest: failed to allocate io pgtable ops\n"); return -ENOMEM; } @@ -79,13 +81,13 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *cfg) * Empty page tables shouldn't provide any translations. */ if (ops->iova_to_phys(ops, 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); if (ops->iova_to_phys(ops, SZ_1G + 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); if (ops->iova_to_phys(ops, SZ_2G + 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); /* * Distinct mappings of different granule sizes. @@ -98,16 +100,16 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *cfg) IOMMU_READ | IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_CACHE, GFP_KERNEL, &mapped)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); /* Overlapping mappings */ if (!ops->map_pages(ops, iova, iova + size, size, 1, IOMMU_READ | IOMMU_NOEXEC, GFP_KERNEL, &mapped)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); if (ops->iova_to_phys(ops, iova + 42) != (iova + 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); iova += SZ_1G; } @@ -118,18 +120,18 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *cfg) size = 1UL << j; if (ops->unmap_pages(ops, iova, size, 1, NULL) != size) - return __FAIL(ops, i); + return __FAIL(test, ops, i); if (ops->iova_to_phys(ops, iova + 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); /* Remap full block */ if (ops->map_pages(ops, iova, iova, size, 1, IOMMU_WRITE, GFP_KERNEL, &mapped)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); if (ops->iova_to_phys(ops, iova + 42) != (iova + 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); iova += SZ_1G; } @@ -145,11 +147,11 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *cfg) IOMMU_READ | IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_CACHE, GFP_KERNEL, &mapped)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); if (mapped != size) - return __FAIL(ops, i); + return __FAIL(test, ops, i); if (ops->unmap_pages(ops, iova, size, 1, NULL) != size) - return __FAIL(ops, i); + return __FAIL(test, ops, i); free_io_pgtable_ops(ops); } @@ -157,7 +159,7 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *cfg) return 0; } -static int arm_lpae_do_selftests(void) +static void arm_lpae_do_selftests(struct kunit *test) { static const unsigned long pgsize[] = { SZ_4K | SZ_2M | SZ_1G, @@ -170,18 +172,19 @@ static int arm_lpae_do_selftests(void) }; int i, j, k, pass = 0, fail = 0; - struct faux_device *dev; + struct device *dev; struct io_pgtable_cfg cfg = { .tlb = &dummy_tlb_ops, .coherent_walk = true, .quirks = IO_PGTABLE_QUIRK_NO_WARN, }; - dev = faux_device_create("io-pgtable-test", NULL, 0); - if (!dev) - return -ENOMEM; + dev = kunit_device_register(test, "io-pgtable-test"); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev); + if (IS_ERR_OR_NULL(dev)) + return; - cfg.iommu_dev = &dev->dev; + cfg.iommu_dev = dev; for (i = 0; i < ARRAY_SIZE(pgsize); ++i) { for (j = 0; j < ARRAY_SIZE(address_size); ++j) { @@ -190,9 +193,9 @@ static int arm_lpae_do_selftests(void) cfg.pgsize_bitmap = pgsize[i]; cfg.ias = address_size[k]; cfg.oas = address_size[j]; - pr_info("selftest: pgsize_bitmap 0x%08lx, IAS %u OAS %u\n", - pgsize[i], cfg.ias, cfg.oas); - if (arm_lpae_run_tests(&cfg)) + kunit_info(test, "selftest: pgsize_bitmap 0x%08lx, IAS %u OAS %u\n", + pgsize[i], cfg.ias, cfg.oas); + if (arm_lpae_run_tests(test, &cfg)) fail++; else pass++; @@ -200,17 +203,20 @@ static int arm_lpae_do_selftests(void) } } - pr_info("selftest: completed with %d PASS %d FAIL\n", pass, fail); - faux_device_destroy(dev); - - return fail ? -EFAULT : 0; + kunit_info(test, "selftest: completed with %d PASS %d FAIL\n", pass, fail); } -static void arm_lpae_exit_selftests(void) -{ -} +static struct kunit_case io_pgtable_arm_test_cases[] = { + KUNIT_CASE(arm_lpae_do_selftests), + {}, +}; + +static struct kunit_suite io_pgtable_arm_test = { + .name = "io-pgtable-arm-test", + .test_cases = io_pgtable_arm_test_cases, +}; + +kunit_test_suite(io_pgtable_arm_test); -subsys_initcall(arm_lpae_do_selftests); -module_exit(arm_lpae_exit_selftests); MODULE_DESCRIPTION("io-pgtable-arm library selftest"); MODULE_LICENSE("GPL"); -- 2.51.0.534.gc79095c0ca-goog