From nobody Thu Oct 2 07:46:25 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D38319DF4A for ; Fri, 19 Sep 2025 13:33:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758288803; cv=none; b=V09fL4a5QFpVeyThE/mhc8cgB9Nt2bBUNCBW/0tBQlE3+RRMiHUPG9Iz52xP8Avvpe+7L0+bC3Ekx6c9m71anfHa3bI7f/r1yTONsJxBdbDYrdw3CiXgD7sjJyxO7bYNwBpHTZxMvuCI4VwGN8dCXBH4UcYATE6DaT5b7GZP950= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758288803; c=relaxed/simple; bh=IkvFohIT4Wev3CJlOkrieSRHtDFSjhkdcyilBtxGyoQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=uVqJwC8HqgDsqeZeNBPL82m1McWQkCrEi4qcD8SR4dzWzG1+KqPHUCr68Iz9FZKuU1bRdOEu5jANPD2lfQ4RK9K6uzaCdxEvfxev2e8nrWFaugd2KhFc8DynucHo80HvxZxU+9E0Pz6cIWfddKJ58zRXHzpuXVM/y/h3EZO2FVk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Xa4ywCLl; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Xa4ywCLl" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-45df7e734e0so23812335e9.0 for ; Fri, 19 Sep 2025 06:33:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758288800; x=1758893600; darn=vger.kernel.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=dta3w9x0Kzr2/YC3aAI2cLcS4FTvsApb1bOklp+8AkE=; b=Xa4ywCLl86yWPUeJdN5ghDcWRjS/G+pHFrSE6kd4/NEFgAo43CassgsPk009F3R5dl XJznGdrFedbNSLuVGN5xMdSVSPFKEquN5qqxVQ15XFoGCUrUM9rv/KAIDj4hOe7Chfwi 1wPQALS7dVuQHejyDcxo5R6D6oeKyLva8+m1eF0/DvoW38L2F+FtiYeKGz2lnF3iHs1C MH7nEX/OvXXPz8lB4U73rWB5+kq258CKZakggOH1a86Nx9lR5ho8ukap/vqDRQGqDBcJ TPmZxyJzW4dkpVReTihRll63MEyVXNaa4quM5EpPvqcG7iLmZQ7dRWbsHczLkjXJJm00 eD8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758288800; x=1758893600; 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=dta3w9x0Kzr2/YC3aAI2cLcS4FTvsApb1bOklp+8AkE=; b=e0x2VcIawpnPEaJHxxrHOzxNnAGDHQnCjetg1MYglfPx+aUI9JTNRRHjh6Wey7OglT RI6Kw/BF/dYVvtnKT+RDjAyaP/VR1hfEM8SI4VDWmeY7nFFLBzIycGoLU0Qwv4HS5xXk yMx2bINjq5Efgi365oBF8t0p1wUd31+7ppBfnY9HN4G6QMt7dTbhiJnIOutH6qxIbU0N n8hKUKByK9p4Q1JTq7mnRJrcmE9OsajufJXqYxDv0ZoyP6RhkSQ/iLp3kHIV8xxLgPKB zfgrRM4yTVl7g85g6kN+tyTJwjVTB1syQO7MrBuH0xhf5UM5oY3CsG+78uM+CqKpdstp 9S9w== X-Forwarded-Encrypted: i=1; AJvYcCW2Mb7FpM/99YlKWfo3iYREH7vnO40A6cpVrqd04dAtUadvG00zaRvpbEccUDQitqaoCX+1D1J65ldGm3g=@vger.kernel.org X-Gm-Message-State: AOJu0YxAY4zxPFiD6PVpo0Dzrs5LEyAcdpiwSm/p/YGpgsqcpfNFROnL TloUxou4WNa09nouSc428jrBDz02GKY/RJwy6mFlBFdmlzK7b9kYuaIgbJeAaT6D0bUmhIQgQsU RES7lr1yPHgVpkQ== X-Google-Smtp-Source: AGHT+IEfxiQvwNODoSv0Q8MyC2iij/p4VeQe4Qd7UQdXLmJ90VPgVJBy+TPvBsuyLaP4UaVBUz+AHld+iqa7Dg== X-Received: from wmbdr20.prod.google.com ([2002:a05:600c:6094:b0:45c:b62f:ca0d]) (user=smostafa job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:450a:b0:45e:8e:28bf with SMTP id 5b1f17b1804b1-467eb231105mr25807885e9.28.1758288800565; Fri, 19 Sep 2025 06:33:20 -0700 (PDT) Date: Fri, 19 Sep 2025 13:33:10 +0000 In-Reply-To: <20250919133316.2741279-1-smostafa@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250919133316.2741279-1-smostafa@google.com> X-Mailer: git-send-email 2.51.0.534.gc79095c0ca-goog Message-ID: <20250919133316.2741279-2-smostafa@google.com> Subject: [PATCH v3 1/4] iommu/io-pgtable-arm: Simplify error prints for selftests 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 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" At the moment, if the self test fails it prints a lot of information about the page table (size, levels...) this requires access to many internals, which has to be exposed in the next patch moving the tests out. Instead, we can simplify the print, using ias, oas, pgsize_bitmap and fmt is enough to identify the failed case, and the rest can be deduced from the code. Signed-off-by: Mostafa Saleh --- drivers/iommu/io-pgtable-arm.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 7e8e2216c294..00218af5d5f7 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -1299,14 +1299,10 @@ static const struct iommu_flush_ops dummy_tlb_ops _= _initconst =3D { =20 static void __init arm_lpae_dump_ops(struct io_pgtable_ops *ops) { - struct arm_lpae_io_pgtable *data =3D io_pgtable_ops_to_data(ops); - struct io_pgtable_cfg *cfg =3D &data->iop.cfg; + struct io_pgtable_cfg *cfg =3D &io_pgtable_ops_to_pgtable(ops)->cfg; =20 - pr_err("cfg: pgsize_bitmap 0x%lx, ias %u-bit\n", - cfg->pgsize_bitmap, cfg->ias); - pr_err("data: %d levels, 0x%zx pgd_size, %u pg_shift, %u bits_per_level, = pgd @ %p\n", - ARM_LPAE_MAX_LEVELS - data->start_level, ARM_LPAE_PGD_SIZE(data), - ilog2(ARM_LPAE_GRANULE(data)), data->bits_per_level, data->pgd); + pr_err("cfg: pgsize_bitmap 0x%lx, ias %u-bit oas %u-bit\n", + cfg->pgsize_bitmap, cfg->ias, cfg->oas); } =20 #define __FAIL(ops, i) ({ \ --=20 2.51.0.534.gc79095c0ca-goog From nobody Thu Oct 2 07:46:25 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3EF652ECE95 for ; Fri, 19 Sep 2025 13:33:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758288805; cv=none; b=V8R/6nHAt3DMVRzve/ZUosTTWo1HcWqr2O3Tf+6pRCBGW45FtbcIM6a7jxBDsKKIq/mw+A6vkm+uHcwtwKwN4OL5/2JITtebTUB/TCt57znBBd/8QGFMZLeeN89rADf723NkEhI2RLxDIzr2VmLb+dmwDhYiANWjZ4BLHJ1VqZQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758288805; c=relaxed/simple; bh=vYUS3dI9XgT7DB9opuiZ1Byrj34GtobBqgcS9r1zFWc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=SO6a8yEjO5LolRPZp7lAoaI4HxiIYkbx8/h8mmNYmDmvJeKR+SxCqadhiXYQ/Mu2DZxzcqU5wO610xqTCFH0oyPAEjHswppGrgQxw4TAI6oukNX2sAg2lpV+KGLGjZ09db7099ld5GNsEGwBSD/qcEoAIqyIVg/0rLCNnWO6vNg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=I5KNY1ph; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="I5KNY1ph" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3ee888281c3so817697f8f.3 for ; Fri, 19 Sep 2025 06:33:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758288801; x=1758893601; darn=vger.kernel.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=gDG1lzvpcDhJhbEFYfIq80tGXsnz1MaPskEEqdr6vp0=; b=I5KNY1phNt3USg2DyRCWgqrIjuvFAVFajYQ9dwOm5aNOtPTS2YABN6RH08uBmbgc50 Tfp6L3m4CwscgDGSdiH0SptyyELlJEg8ksbJbht+sQNIL5+6YQ6BGwALiG0Dx3mN8lin q+MqFpUQbr7PfxEALnIf151Zd7aYgxEH7nKIB5FW3h/2popDFb+dCFN9w9+tM4EkjPeY ywXJSt/Ct1/+v27/P3mEUU5B3oxxpFBA9lWAte2tokgCHgFusOVarJ8ehvH0Tp1//TGU sAV80Cyh7G6ydEkxGm5DoWHRrBvzkH+4nPyPSAGjsp71GO0Ho2kTL5CPgOPJGTnqNsLZ YYgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758288801; x=1758893601; 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=gDG1lzvpcDhJhbEFYfIq80tGXsnz1MaPskEEqdr6vp0=; b=QcDFBYiejvayO3nL/KDkHP6m/hzzdRPCy+ASp0c5fX0Myw2TGDjENmBg1NVtTrlwD7 /NgPdJvWcovDEOAFS5tzw+Eybawdbl4F/uPBMK0rRJUbMw/DrFQtWiqH3DcvC6efoI9m WqqfHU3vU53K9HDJ5N/kqFcJmBOG511zkpbGUTMadbtYngP9yXGGzOBBO9y8eozwUt4M BhMXFmrAfeY1EMba/gt1d6ABVXVRmtjRzKuqCJmzis2/5nN7EeWx7/G1s+sXDR15SQA4 pAnvGWLPY+qa9EvLBuFnvfNYiQhJ/oqYKc7SZ+yRdScUeYqr4H1D0m6XX9EDFNV02S2c BaLA== X-Forwarded-Encrypted: i=1; AJvYcCWJe+/ehnlVUItcXMBeP222QC9olYzo0PQzCBui3JAy6LDPgaTh0txubgNHBqhXt+d7WVhGJSoENqK+DqY=@vger.kernel.org X-Gm-Message-State: AOJu0YyCTw20g1kHkuJC6e699fMa62XOf2VYDORGU69ukGO9CtpPbjnC q6sAm62cSRvqb19bkxHT2awCyChj78WOn+/ltTdubZ1q2zp7ir/EIJIqW9rvKjsw7vw+eLfw802 pbo6kLDaHlD8Nig== X-Google-Smtp-Source: AGHT+IEA3wbXjckbVprhquwu1f9p3GkdjRSMj1EJRcToZghtt4tIZs82OMfdDy4Mq9NH3Zl2PvgmzaeZXLAooQ== X-Received: from wmbhc7.prod.google.com ([2002:a05:600c:8707:b0:45b:6199:5f39]) (user=smostafa job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:178a:b0:3c7:36f3:c352 with SMTP id ffacd0b85a97d-3ee86d6cd65mr2686938f8f.59.1758288801693; Fri, 19 Sep 2025 06:33:21 -0700 (PDT) Date: Fri, 19 Sep 2025 13:33:11 +0000 In-Reply-To: <20250919133316.2741279-1-smostafa@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250919133316.2741279-1-smostafa@google.com> X-Mailer: git-send-email 2.51.0.534.gc79095c0ca-goog Message-ID: <20250919133316.2741279-3-smostafa@google.com> Subject: [PATCH v3 2/4] iommu/io-pgtable-arm: Move selftests to a separate file 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 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Clean up the io-pgtable-arm library by moving the selftests out. Next the tests will be registered with kunit. This is useful also to factor out kernel specific code out, so it can compiled as part of the hypervisor object. Signed-off-by: Mostafa Saleh --- drivers/iommu/Makefile | 1 + drivers/iommu/io-pgtable-arm-selftests.c | 208 +++++++++++++++++++++++ drivers/iommu/io-pgtable-arm.c | 200 ---------------------- 3 files changed, 209 insertions(+), 200 deletions(-) create mode 100644 drivers/iommu/io-pgtable-arm-selftests.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 355294fa9033..5250a2eea13f 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_IOMMU_DMA) +=3D dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) +=3D io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) +=3D io-pgtable-arm-v7s.o obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) +=3D io-pgtable-arm.o +obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST) +=3D io-pgtable-arm-selftests= .o obj-$(CONFIG_IOMMU_IO_PGTABLE_DART) +=3D io-pgtable-dart.o obj-$(CONFIG_IOMMU_IOVA) +=3D iova.o obj-$(CONFIG_OF_IOMMU) +=3D of_iommu.o diff --git a/drivers/iommu/io-pgtable-arm-selftests.c b/drivers/iommu/io-pg= table-arm-selftests.c new file mode 100644 index 000000000000..17f48216647c --- /dev/null +++ b/drivers/iommu/io-pgtable-arm-selftests.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * CPU-agnostic ARM page table allocator. + * + * Copyright (C) 2014 ARM Limited + * + * Author: Will Deacon + */ +#include +#include +#include +#include + +#include "io-pgtable-arm.h" + +static struct io_pgtable_cfg *cfg_cookie __initdata; + +static void __init dummy_tlb_flush_all(void *cookie) +{ + WARN_ON(cookie !=3D cfg_cookie); +} + +static void __init dummy_tlb_flush(unsigned long iova, size_t size, + size_t granule, void *cookie) +{ + WARN_ON(cookie !=3D cfg_cookie); + WARN_ON(!(size & cfg_cookie->pgsize_bitmap)); +} + +static void __init dummy_tlb_add_page(struct iommu_iotlb_gather *gather, + unsigned long iova, size_t granule, + void *cookie) +{ + dummy_tlb_flush(iova, granule, granule, cookie); +} + +static const struct iommu_flush_ops dummy_tlb_ops __initconst =3D { + .tlb_flush_all =3D dummy_tlb_flush_all, + .tlb_flush_walk =3D dummy_tlb_flush, + .tlb_add_page =3D dummy_tlb_add_page, +}; + +static void __init arm_lpae_dump_ops(struct io_pgtable_ops *ops) +{ + struct io_pgtable_cfg *cfg =3D &io_pgtable_ops_to_pgtable(ops)->cfg; + + pr_err("cfg: pgsize_bitmap 0x%lx, ias %u-bit oas %u-bit\n", + 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; \ +}) + +static int __init arm_lpae_run_tests(struct io_pgtable_cfg *cfg) +{ + static const enum io_pgtable_fmt fmts[] __initconst =3D { + ARM_64_LPAE_S1, + ARM_64_LPAE_S2, + }; + + int i, j; + unsigned long iova; + size_t size, mapped; + struct io_pgtable_ops *ops; + + for (i =3D 0; i < ARRAY_SIZE(fmts); ++i) { + cfg_cookie =3D cfg; + ops =3D alloc_io_pgtable_ops(fmts[i], cfg, cfg); + if (!ops) { + pr_err("selftest: failed to allocate io pgtable ops\n"); + return -ENOMEM; + } + + /* + * Initial sanity checks. + * Empty page tables shouldn't provide any translations. + */ + if (ops->iova_to_phys(ops, 42)) + return __FAIL(ops, i); + + if (ops->iova_to_phys(ops, SZ_1G + 42)) + return __FAIL(ops, i); + + if (ops->iova_to_phys(ops, SZ_2G + 42)) + return __FAIL(ops, i); + + /* + * Distinct mappings of different granule sizes. + */ + iova =3D 0; + for_each_set_bit(j, &cfg->pgsize_bitmap, BITS_PER_LONG) { + size =3D 1UL << j; + + if (ops->map_pages(ops, iova, iova, size, 1, + IOMMU_READ | IOMMU_WRITE | + IOMMU_NOEXEC | IOMMU_CACHE, + GFP_KERNEL, &mapped)) + return __FAIL(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); + + if (ops->iova_to_phys(ops, iova + 42) !=3D (iova + 42)) + return __FAIL(ops, i); + + iova +=3D SZ_1G; + } + + /* Full unmap */ + iova =3D 0; + for_each_set_bit(j, &cfg->pgsize_bitmap, BITS_PER_LONG) { + size =3D 1UL << j; + + if (ops->unmap_pages(ops, iova, size, 1, NULL) !=3D size) + return __FAIL(ops, i); + + if (ops->iova_to_phys(ops, iova + 42)) + return __FAIL(ops, i); + + /* Remap full block */ + if (ops->map_pages(ops, iova, iova, size, 1, + IOMMU_WRITE, GFP_KERNEL, &mapped)) + return __FAIL(ops, i); + + if (ops->iova_to_phys(ops, iova + 42) !=3D (iova + 42)) + return __FAIL(ops, i); + + iova +=3D SZ_1G; + } + + /* + * Map/unmap the last largest supported page of the IAS, this can + * trigger corner cases in the concatednated page tables. + */ + mapped =3D 0; + size =3D 1UL << __fls(cfg->pgsize_bitmap); + iova =3D (1UL << cfg->ias) - size; + if (ops->map_pages(ops, iova, iova, size, 1, + IOMMU_READ | IOMMU_WRITE | + IOMMU_NOEXEC | IOMMU_CACHE, + GFP_KERNEL, &mapped)) + return __FAIL(ops, i); + if (mapped !=3D size) + return __FAIL(ops, i); + if (ops->unmap_pages(ops, iova, size, 1, NULL) !=3D size) + return __FAIL(ops, i); + + free_io_pgtable_ops(ops); + } + + return 0; +} + +static int __init arm_lpae_do_selftests(void) +{ + static const unsigned long pgsize[] __initconst =3D { + SZ_4K | SZ_2M | SZ_1G, + SZ_16K | SZ_32M, + SZ_64K | SZ_512M, + }; + + static const unsigned int address_size[] __initconst =3D { + 32, 36, 40, 42, 44, 48, + }; + + int i, j, k, pass =3D 0, fail =3D 0; + struct faux_device *dev; + struct io_pgtable_cfg cfg =3D { + .tlb =3D &dummy_tlb_ops, + .coherent_walk =3D true, + .quirks =3D IO_PGTABLE_QUIRK_NO_WARN, + }; + + dev =3D faux_device_create("io-pgtable-test", NULL, 0); + if (!dev) + return -ENOMEM; + + cfg.iommu_dev =3D &dev->dev; + + for (i =3D 0; i < ARRAY_SIZE(pgsize); ++i) { + for (j =3D 0; j < ARRAY_SIZE(address_size); ++j) { + /* Don't use ias > oas as it is not valid for stage-2. */ + for (k =3D 0; k <=3D j; ++k) { + cfg.pgsize_bitmap =3D pgsize[i]; + cfg.ias =3D address_size[k]; + cfg.oas =3D 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)) + fail++; + else + pass++; + } + } + } + + pr_info("selftest: completed with %d PASS %d FAIL\n", pass, fail); + faux_device_destroy(dev); + + return fail ? -EFAULT : 0; +} +subsys_initcall(arm_lpae_do_selftests); diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 00218af5d5f7..aed18b3d277f 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -12,10 +12,7 @@ #include #include #include -#include -#include #include -#include #include #include =20 @@ -1267,200 +1264,3 @@ struct io_pgtable_init_fns io_pgtable_arm_mali_lpae= _init_fns =3D { .alloc =3D arm_mali_lpae_alloc_pgtable, .free =3D arm_lpae_free_pgtable, }; - -#ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST - -static struct io_pgtable_cfg *cfg_cookie __initdata; - -static void __init dummy_tlb_flush_all(void *cookie) -{ - WARN_ON(cookie !=3D cfg_cookie); -} - -static void __init dummy_tlb_flush(unsigned long iova, size_t size, - size_t granule, void *cookie) -{ - WARN_ON(cookie !=3D cfg_cookie); - WARN_ON(!(size & cfg_cookie->pgsize_bitmap)); -} - -static void __init dummy_tlb_add_page(struct iommu_iotlb_gather *gather, - unsigned long iova, size_t granule, - void *cookie) -{ - dummy_tlb_flush(iova, granule, granule, cookie); -} - -static const struct iommu_flush_ops dummy_tlb_ops __initconst =3D { - .tlb_flush_all =3D dummy_tlb_flush_all, - .tlb_flush_walk =3D dummy_tlb_flush, - .tlb_add_page =3D dummy_tlb_add_page, -}; - -static void __init arm_lpae_dump_ops(struct io_pgtable_ops *ops) -{ - struct io_pgtable_cfg *cfg =3D &io_pgtable_ops_to_pgtable(ops)->cfg; - - pr_err("cfg: pgsize_bitmap 0x%lx, ias %u-bit oas %u-bit\n", - 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; \ -}) - -static int __init arm_lpae_run_tests(struct io_pgtable_cfg *cfg) -{ - static const enum io_pgtable_fmt fmts[] __initconst =3D { - ARM_64_LPAE_S1, - ARM_64_LPAE_S2, - }; - - int i, j; - unsigned long iova; - size_t size, mapped; - struct io_pgtable_ops *ops; - - for (i =3D 0; i < ARRAY_SIZE(fmts); ++i) { - cfg_cookie =3D cfg; - ops =3D alloc_io_pgtable_ops(fmts[i], cfg, cfg); - if (!ops) { - pr_err("selftest: failed to allocate io pgtable ops\n"); - return -ENOMEM; - } - - /* - * Initial sanity checks. - * Empty page tables shouldn't provide any translations. - */ - if (ops->iova_to_phys(ops, 42)) - return __FAIL(ops, i); - - if (ops->iova_to_phys(ops, SZ_1G + 42)) - return __FAIL(ops, i); - - if (ops->iova_to_phys(ops, SZ_2G + 42)) - return __FAIL(ops, i); - - /* - * Distinct mappings of different granule sizes. - */ - iova =3D 0; - for_each_set_bit(j, &cfg->pgsize_bitmap, BITS_PER_LONG) { - size =3D 1UL << j; - - if (ops->map_pages(ops, iova, iova, size, 1, - IOMMU_READ | IOMMU_WRITE | - IOMMU_NOEXEC | IOMMU_CACHE, - GFP_KERNEL, &mapped)) - return __FAIL(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); - - if (ops->iova_to_phys(ops, iova + 42) !=3D (iova + 42)) - return __FAIL(ops, i); - - iova +=3D SZ_1G; - } - - /* Full unmap */ - iova =3D 0; - for_each_set_bit(j, &cfg->pgsize_bitmap, BITS_PER_LONG) { - size =3D 1UL << j; - - if (ops->unmap_pages(ops, iova, size, 1, NULL) !=3D size) - return __FAIL(ops, i); - - if (ops->iova_to_phys(ops, iova + 42)) - return __FAIL(ops, i); - - /* Remap full block */ - if (ops->map_pages(ops, iova, iova, size, 1, - IOMMU_WRITE, GFP_KERNEL, &mapped)) - return __FAIL(ops, i); - - if (ops->iova_to_phys(ops, iova + 42) !=3D (iova + 42)) - return __FAIL(ops, i); - - iova +=3D SZ_1G; - } - - /* - * Map/unmap the last largest supported page of the IAS, this can - * trigger corner cases in the concatednated page tables. - */ - mapped =3D 0; - size =3D 1UL << __fls(cfg->pgsize_bitmap); - iova =3D (1UL << cfg->ias) - size; - if (ops->map_pages(ops, iova, iova, size, 1, - IOMMU_READ | IOMMU_WRITE | - IOMMU_NOEXEC | IOMMU_CACHE, - GFP_KERNEL, &mapped)) - return __FAIL(ops, i); - if (mapped !=3D size) - return __FAIL(ops, i); - if (ops->unmap_pages(ops, iova, size, 1, NULL) !=3D size) - return __FAIL(ops, i); - - free_io_pgtable_ops(ops); - } - - return 0; -} - -static int __init arm_lpae_do_selftests(void) -{ - static const unsigned long pgsize[] __initconst =3D { - SZ_4K | SZ_2M | SZ_1G, - SZ_16K | SZ_32M, - SZ_64K | SZ_512M, - }; - - static const unsigned int address_size[] __initconst =3D { - 32, 36, 40, 42, 44, 48, - }; - - int i, j, k, pass =3D 0, fail =3D 0; - struct faux_device *dev; - struct io_pgtable_cfg cfg =3D { - .tlb =3D &dummy_tlb_ops, - .coherent_walk =3D true, - .quirks =3D IO_PGTABLE_QUIRK_NO_WARN, - }; - - dev =3D faux_device_create("io-pgtable-test", NULL, 0); - if (!dev) - return -ENOMEM; - - cfg.iommu_dev =3D &dev->dev; - - for (i =3D 0; i < ARRAY_SIZE(pgsize); ++i) { - for (j =3D 0; j < ARRAY_SIZE(address_size); ++j) { - /* Don't use ias > oas as it is not valid for stage-2. */ - for (k =3D 0; k <=3D j; ++k) { - cfg.pgsize_bitmap =3D pgsize[i]; - cfg.ias =3D address_size[k]; - cfg.oas =3D 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)) - fail++; - else - pass++; - } - } - } - - pr_info("selftest: completed with %d PASS %d FAIL\n", pass, fail); - faux_device_destroy(dev); - - return fail ? -EFAULT : 0; -} -subsys_initcall(arm_lpae_do_selftests); -#endif --=20 2.51.0.534.gc79095c0ca-goog From nobody Thu Oct 2 07:46:25 2025 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A6B7830F94F for ; Fri, 19 Sep 2025 13:33:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758288806; cv=none; b=fZ7ZcUcqB0MxvGUMnHEy0NB9wIbEtTjVO7Fgbm2i++qu8Q5U5+cWZ6r+i1FjV5oqsQB9u3t2/IPm5Kk2u7g2MFihGasnPgPjErdu89sPSb+0FT907jwmQZCk6QSl6JmBV+YEUim6SVbcFt2odvrlXucW5D1nZKtVIhWzVm7w2lM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758288806; c=relaxed/simple; bh=7oXYl5Po4AjfBd/5rYjBxuYp+0gnhDH956S33u0vZDA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qBgCdgJUN6kVjKUBZlCVt0R5OXCDWCY9KAIN4uWfe8mZKviK8M9Shyc83QQevpFVCMiLiO4tRvD2LODc1jKHJMlwASckTnuu3MfLw9Gjy4WQl+qwOeIE57cHMXOFcRx9QnKUW5ZJ7I4Tm6y+SA7t6xS758E9+m2qRJS1I25BJ20= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=OFZ4urbM; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="OFZ4urbM" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45b9a856d58so17157745e9.0 for ; Fri, 19 Sep 2025 06:33:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758288803; x=1758893603; darn=vger.kernel.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=v+B9Rd0QSKX3f0a8GqzDwyxDt6n7MbipsBAu2cM0NNI=; b=OFZ4urbMJNa5d4cd56Os67V9LzAPs5uLoqJs05/sXa2xnOUq1vZTHh29DTNKwjIbnL MaMpN7dz5vmrepS+iW0LD962FTRvGq4mDlyVlYrLcVVqhDJ20F610DNcxd5CUH0qjQ67 0B696/x43XR9T/9PmtHK65bWJoSIFcS/7yZHRwvvn8JU1fd7IPV0dIDDA07PCOOvm2G2 jt8nADDqUbrE7eAF+Fn/70aLYuoRw8/fhFIt27UnkjezByTrVurYE7Cu2aj4puoGCB0t GphkorWhWGwYkjYcdDo3IMURRF58D0bRnxXtqZbykPZRsldoNuLyVLbcQmtwIrEKOYpe Yrrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758288803; x=1758893603; 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=v+B9Rd0QSKX3f0a8GqzDwyxDt6n7MbipsBAu2cM0NNI=; b=JpMc/9hWHAN0bFSt4kShim6Ng/1gndTA54nmSK0wgWHoEF6x0WbFp7UzgnMoqYokTn V7Dxy3yAW9X3Mndgos1u89MUcxdN5Bplgv7f5RAgk4e9UALp2d6wdzU0KlmldBvjyZyY J1Tk55smM9tI7sIf1wN//ZKYlPnUfq7pF9yVAWpf5Yt31BjMvVYEDPnEAChnEc4xVtI7 TZRwiC3BWYd0eCacsaJfuolHA9x16wVatMoxgaQJsbe1Xv6b1nMPCBcE2MqA2c7xPSHe NDwFTGQLO98sTgXOjpzx78lWEkbio5mbcTM8DqvOURNvHo646klWyyef5HcK9hBRS0ft NY2A== X-Forwarded-Encrypted: i=1; AJvYcCX5uhPtHTZtA/AjTC5PjdMKpXqqmTxXV1mPrbsfobIWbDcIfNqfZFVWCPD9zKoFDwRaR085hI7v37bOZqU=@vger.kernel.org X-Gm-Message-State: AOJu0YzzL9uNPpCF6riIsTi3r86aLJ3VpQMG9njOBiZylUUOkORFAgqj 4nfVzYZMlvjJjkcedNZkoH+Sp2hqdXZUe9ZwojYmwC/RXMSkRMk5mPkfLknDPurxH+jUyOQVdw3 PPAkRmPs18v1kng== X-Google-Smtp-Source: AGHT+IHgv9Oc1Q90zGIOvBR/gtnADwG6axckvKn1MbwYC6fQkHZhHVTfgauS5SWZ9dYzPTFs0YjJunsuQ96/hQ== X-Received: from wmbeq6.prod.google.com ([2002:a05:600c:8486:b0:45d:e59b:2eb0]) (user=smostafa job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3595:b0:458:bf0a:6061 with SMTP id 5b1f17b1804b1-467f00c5fd6mr42464245e9.24.1758288803025; Fri, 19 Sep 2025 06:33:23 -0700 (PDT) Date: Fri, 19 Sep 2025 13:33:12 +0000 In-Reply-To: <20250919133316.2741279-1-smostafa@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250919133316.2741279-1-smostafa@google.com> X-Mailer: git-send-email 2.51.0.534.gc79095c0ca-goog Message-ID: <20250919133316.2741279-4-smostafa@google.com> Subject: [PATCH v3 3/4] iommu/io-pgtable-arm-selftests: Modularize the test 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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Remove the __init constraint, as the test will be converted to KUnit, it can run on-demand after later. Also, as KUnit can be a module, make this test modular. Reviewed-by: Jason Gunthorpe Signed-off-by: Mostafa Saleh --- drivers/iommu/Kconfig | 2 +- drivers/iommu/io-pgtable-arm-selftests.c | 34 +++++++++++++++--------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 70d29b14d851..553522ef3ca9 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -41,7 +41,7 @@ config IOMMU_IO_PGTABLE_LPAE up to 48-bits in size. =20 config IOMMU_IO_PGTABLE_LPAE_SELFTEST - bool "LPAE selftests" + tristate "LPAE selftests" depends on IOMMU_IO_PGTABLE_LPAE help Enable self-tests for LPAE page table allocator. This performs diff --git a/drivers/iommu/io-pgtable-arm-selftests.c b/drivers/iommu/io-pg= table-arm-selftests.c index 17f48216647c..4c3dee4ba895 100644 --- a/drivers/iommu/io-pgtable-arm-selftests.c +++ b/drivers/iommu/io-pgtable-arm-selftests.c @@ -13,28 +13,28 @@ =20 #include "io-pgtable-arm.h" =20 -static struct io_pgtable_cfg *cfg_cookie __initdata; +static struct io_pgtable_cfg *cfg_cookie; =20 -static void __init dummy_tlb_flush_all(void *cookie) +static void dummy_tlb_flush_all(void *cookie) { WARN_ON(cookie !=3D cfg_cookie); } =20 -static void __init dummy_tlb_flush(unsigned long iova, size_t size, - size_t granule, void *cookie) +static void dummy_tlb_flush(unsigned long iova, size_t size, + size_t granule, void *cookie) { WARN_ON(cookie !=3D cfg_cookie); WARN_ON(!(size & cfg_cookie->pgsize_bitmap)); } =20 -static void __init dummy_tlb_add_page(struct iommu_iotlb_gather *gather, - unsigned long iova, size_t granule, - void *cookie) +static void dummy_tlb_add_page(struct iommu_iotlb_gather *gather, + unsigned long iova, size_t granule, + void *cookie) { dummy_tlb_flush(iova, granule, granule, cookie); } =20 -static const struct iommu_flush_ops dummy_tlb_ops __initconst =3D { +static const struct iommu_flush_ops dummy_tlb_ops =3D { .tlb_flush_all =3D dummy_tlb_flush_all, .tlb_flush_walk =3D dummy_tlb_flush, .tlb_add_page =3D dummy_tlb_add_page, @@ -54,9 +54,9 @@ static void __init arm_lpae_dump_ops(struct io_pgtable_op= s *ops) -EFAULT; \ }) =20 -static int __init arm_lpae_run_tests(struct io_pgtable_cfg *cfg) +static int arm_lpae_run_tests(struct io_pgtable_cfg *cfg) { - static const enum io_pgtable_fmt fmts[] __initconst =3D { + static const enum io_pgtable_fmt fmts[] =3D { ARM_64_LPAE_S1, ARM_64_LPAE_S2, }; @@ -157,15 +157,15 @@ static int __init arm_lpae_run_tests(struct io_pgtabl= e_cfg *cfg) return 0; } =20 -static int __init arm_lpae_do_selftests(void) +static int arm_lpae_do_selftests(void) { - static const unsigned long pgsize[] __initconst =3D { + static const unsigned long pgsize[] =3D { SZ_4K | SZ_2M | SZ_1G, SZ_16K | SZ_32M, SZ_64K | SZ_512M, }; =20 - static const unsigned int address_size[] __initconst =3D { + static const unsigned int address_size[] =3D { 32, 36, 40, 42, 44, 48, }; =20 @@ -205,4 +205,12 @@ static int __init arm_lpae_do_selftests(void) =20 return fail ? -EFAULT : 0; } + +static void arm_lpae_exit_selftests(void) +{ +} + subsys_initcall(arm_lpae_do_selftests); +module_exit(arm_lpae_exit_selftests); +MODULE_DESCRIPTION("io-pgtable-arm library selftest"); +MODULE_LICENSE("GPL"); --=20 2.51.0.534.gc79095c0ca-goog From nobody Thu Oct 2 07:46:25 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D7533126A7 for ; Fri, 19 Sep 2025 13:33:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758288810; cv=none; b=gU3sakKUcGnDQL2qwvwZiBDB1uD+rljhEgvuJr7iw04Ry2Bj4ia991GsG1UJmjrONSULOYXli4APyR5wPUk8p+lWhyZc6PdUPtkhTN2D9oK1YENB1INXPT89n3huBrIml9ineT61rU3A9cVlR/AMf2SX27j30YMr1QjxphX4zXY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758288810; c=relaxed/simple; bh=TyW+eoxhdQX3K1kZzdswB4GMFpfu8E/GUU5PJAgxrb0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=i+e3lIgoLUhZGowa4tkGAw3isWnPBtZY6CQriGIZ2KAW4gWcRlLsGcJlYlP7Fjw5Rbq3d3Cbze2yyqu6QHugsM1d3H9trdSUyPM4ZohmPISjH1AJ1wV5+XpcbL3uEU+0pm5ZtJWzfdn15Xs8R+t+/tJeJsyzZGXU/9DVp4mrxfk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=AbQywyRX; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="AbQywyRX" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3eae869cb3fso1532265f8f.0 for ; Fri, 19 Sep 2025 06:33:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758288806; x=1758893606; darn=vger.kernel.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=DP/Bm+5e3mSkOukBBhCRTkrnvruqWsZSDU04xkfK8rg=; b=AbQywyRXmWloyWT8nXFcs+QqICkFIjSUcHQ8gZYkvEjvkIj9mHEh7YNsvXEomKVai9 rLGN68yeqxsR3csl3Hut1I9cm/rLA3Xcdocfy73wVJLI3pEmqFRmqOmkKCeWroTbzC4K JKgCt1usP+iyxqAdsr2Yvs8Fci3mm/nQff2rGHNVtA07ZxatC4ylNOiHBsQDn85kEVid lZEwm6Sebt1kgx/Lt5nn7WhwY8HyX3u4cbjou4fc0x5Gs+d3Izr9w/XQrB6y+wFTTcWa tQbH0wSFGGoDDfbi3NyLSQebtWnaYX6lZqj7WbJipH0A3JLuoCuiKKYXboatCxyKCnZq L2Ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758288806; x=1758893606; 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=DP/Bm+5e3mSkOukBBhCRTkrnvruqWsZSDU04xkfK8rg=; b=bwBnSgTEh2YOEiAMi09qrBk7nZUyRY59Pqn8nFJ0fG8tzYsRsVxs0lJX7LQxCdGR0y Tox6i2e/CkHhaMrE+kJH4IjuduRUIs39ZTwDVwiBhQO7ryFLPCDqGhLg5+I/S5CnyJ7N Pm2w0DNu4yba3pdQuDlbp6B/SnleWcMakICLgRwzZ09Zdg/CqjO1pW2sGgWyhJOdtk1L zKvcMLuGVc5m6NojkqZlddnsZef/yT/GlZluNWAc6oaymawqVAOk/kgSWp9dtjpLFXI/ SRgHny1kog2K0umEUj3Gs7gbqYn5yPPWQPCoGqqLJkYihJH7mqEhaEaQv7LrofB0wgCx fXBg== X-Forwarded-Encrypted: i=1; AJvYcCWKlTd4JFl/ennG28EHpk9GanSfePL+jHWa8eGFbms4T+QpXon14qkE0HHmUzAo6MuTeEu5PS1BwRTVTcM=@vger.kernel.org X-Gm-Message-State: AOJu0Ywan8HanGQi2woIk6+g+H0+L5Yu8Ebq7Gc8vaJ9bQa51j9UnEZa dDrih5Df6Atu6DAhPNFNreG0PF4fCLCC1bPdbxliLzofuyntKr6ciJGXvRhJa4snU+Qm1LDuH/6 UlF9yd7gFeyJ0vg== X-Google-Smtp-Source: AGHT+IGfd9H6PFBnWGC9u0o/DJ1VDVi6YMq0gft0vsd6mTOo7SapURN04FyPK7q0T/gUAS8fpfu5CNP10jZbcQ== X-Received: from wrbgv25.prod.google.com ([2002:a05:6000:4619:b0:3ec:df9b:56a4]) (user=smostafa job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:400c:b0:3ea:9042:e682 with SMTP id ffacd0b85a97d-3ee7c55430amr2660786f8f.11.1758288806436; Fri, 19 Sep 2025 06:33:26 -0700 (PDT) Date: Fri, 19 Sep 2025 13:33:13 +0000 In-Reply-To: <20250919133316.2741279-1-smostafa@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250919133316.2741279-1-smostafa@google.com> X-Mailer: git-send-email 2.51.0.534.gc79095c0ca-goog Message-ID: <20250919133316.2741279-5-smostafa@google.com> Subject: [PATCH v3 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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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=3Dy It will automatically run at boot as before. - Otherwise with CONFIG_IOMMU_IO_PGTABLE_KUNIT_TEST=3Dm: 1) on module load: Once the module load the self test will run # modprobe io-pgtable-arm-selftests 2) debugfs With CONFIG_KUNIT_DEBUGFS=3Dy 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 --a= rch arm64 \ --make_options LLVM=3D1 --kunitconfig ./kunit/kunitconfig [18:01:09] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D io-pgtable-arm-tes= t (1 subtest) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [18:01:09] [PASSED] arm_lpae_do_selftests [18:01:09] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [PASSED] io-= pgtable-arm-test =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [18:01:09] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Suggested-by: Jason Gunthorpe Reviewed-by: Jason Gunthorpe Signed-off-by: Mostafa Saleh --- drivers/iommu/Kconfig | 10 +-- drivers/iommu/Makefile | 2 +- drivers/iommu/io-pgtable-arm-selftests.c | 82 +++++++++++++----------- 3 files changed, 51 insertions(+), 43 deletions(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 553522ef3ca9..f7e80c3c1f2a 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -40,12 +40,14 @@ config IOMMU_IO_PGTABLE_LPAE sizes at both stage-1 and stage-2, as well as address spaces up to 48-bits in size. =20 -config IOMMU_IO_PGTABLE_LPAE_SELFTEST +config IOMMU_IO_PGTABLE_LPAE_KUNIT_TEST tristate "LPAE selftests" - depends on IOMMU_IO_PGTABLE_LPAE + select IOMMU_IO_PGTABLE_LPAE + depends on 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. =20 If unsure, say N here. =20 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) +=3D dma-iommu.o obj-$(CONFIG_IOMMU_IO_PGTABLE) +=3D io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) +=3D io-pgtable-arm-v7s.o obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) +=3D io-pgtable-arm.o -obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST) +=3D io-pgtable-arm-selftests= .o +obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE_KUNIT_TEST) +=3D io-pgtable-arm-selftes= ts.o obj-$(CONFIG_IOMMU_IO_PGTABLE_DART) +=3D io-pgtable-dart.o obj-$(CONFIG_IOMMU_IOVA) +=3D iova.o obj-$(CONFIG_OF_IOMMU) +=3D of_iommu.o diff --git a/drivers/iommu/io-pgtable-arm-selftests.c b/drivers/iommu/io-pg= table-arm-selftests.c index 4c3dee4ba895..9d9acb91d823 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 __init arm_lpae_dump_ops(struct io_pgtable_= ops *ops) cfg->pgsize_bitmap, cfg->ias, cfg->oas); } =20 -#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; \ }) =20 -static int arm_lpae_run_tests(struct io_pgtable_cfg *cfg) +static int arm_lpae_run_tests(struct kunit *test, struct io_pgtable_cfg *c= fg) { static const enum io_pgtable_fmt fmts[] =3D { ARM_64_LPAE_S1, @@ -70,7 +72,7 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *cfg) cfg_cookie =3D cfg; ops =3D 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; } =20 @@ -79,13 +81,13 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *cf= g) * Empty page tables shouldn't provide any translations. */ if (ops->iova_to_phys(ops, 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); =20 if (ops->iova_to_phys(ops, SZ_1G + 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); =20 if (ops->iova_to_phys(ops, SZ_2G + 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); =20 /* * Distinct mappings of different granule sizes. @@ -98,16 +100,16 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *c= fg) IOMMU_READ | IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_CACHE, GFP_KERNEL, &mapped)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); =20 /* 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); =20 if (ops->iova_to_phys(ops, iova + 42) !=3D (iova + 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); =20 iova +=3D SZ_1G; } @@ -118,18 +120,18 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *= cfg) size =3D 1UL << j; =20 if (ops->unmap_pages(ops, iova, size, 1, NULL) !=3D size) - return __FAIL(ops, i); + return __FAIL(test, ops, i); =20 if (ops->iova_to_phys(ops, iova + 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); =20 /* 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); =20 if (ops->iova_to_phys(ops, iova + 42) !=3D (iova + 42)) - return __FAIL(ops, i); + return __FAIL(test, ops, i); =20 iova +=3D 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 !=3D size) - return __FAIL(ops, i); + return __FAIL(test, ops, i); if (ops->unmap_pages(ops, iova, size, 1, NULL) !=3D size) - return __FAIL(ops, i); + return __FAIL(test, ops, i); =20 free_io_pgtable_ops(ops); } @@ -157,7 +159,7 @@ static int arm_lpae_run_tests(struct io_pgtable_cfg *cf= g) return 0; } =20 -static int arm_lpae_do_selftests(void) +static void arm_lpae_do_selftests(struct kunit *test) { static const unsigned long pgsize[] =3D { SZ_4K | SZ_2M | SZ_1G, @@ -170,18 +172,19 @@ static int arm_lpae_do_selftests(void) }; =20 int i, j, k, pass =3D 0, fail =3D 0; - struct faux_device *dev; + struct device *dev; struct io_pgtable_cfg cfg =3D { .tlb =3D &dummy_tlb_ops, .coherent_walk =3D true, .quirks =3D IO_PGTABLE_QUIRK_NO_WARN, }; =20 - dev =3D faux_device_create("io-pgtable-test", NULL, 0); - if (!dev) - return -ENOMEM; + dev =3D kunit_device_register(test, "io-pgtable-test"); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev); + if (IS_ERR_OR_NULL(dev)) + return; =20 - cfg.iommu_dev =3D &dev->dev; + cfg.iommu_dev =3D dev; =20 for (i =3D 0; i < ARRAY_SIZE(pgsize); ++i) { for (j =3D 0; j < ARRAY_SIZE(address_size); ++j) { @@ -190,9 +193,9 @@ static int arm_lpae_do_selftests(void) cfg.pgsize_bitmap =3D pgsize[i]; cfg.ias =3D address_size[k]; cfg.oas =3D 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) } } =20 - 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= ); } =20 -static void arm_lpae_exit_selftests(void) -{ -} +static struct kunit_case io_pgtable_arm_test_cases[] =3D { + KUNIT_CASE(arm_lpae_do_selftests), + {}, +}; + +static struct kunit_suite io_pgtable_arm_test =3D { + .name =3D "io-pgtable-arm-test", + .test_cases =3D io_pgtable_arm_test_cases, +}; + +kunit_test_suite(io_pgtable_arm_test); =20 -subsys_initcall(arm_lpae_do_selftests); -module_exit(arm_lpae_exit_selftests); MODULE_DESCRIPTION("io-pgtable-arm library selftest"); MODULE_LICENSE("GPL"); --=20 2.51.0.534.gc79095c0ca-goog