* [PATCH 0/3] iommu/io-pgtable-arm: iommu-pages and cleanup
@ 2026-05-13 21:52 Mostafa Saleh
2026-05-13 21:52 ` [PATCH 1/3] iommu/io-pgtable-arm: Use consistent sizes for page allocation and freeing Mostafa Saleh
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Mostafa Saleh @ 2026-05-13 21:52 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: robin.murphy, will, joro, jgg, Mostafa Saleh
This is a small cleanup coming from the pKVM SMMUv3 support [1].
However, they are not pKVM specific and useful in general.
The first patch is to fix a theoretical issues with alloc/free size.
The second patch is the main one to convert the code to iommu-pages.
The third patch is a cleanup to use address conversion consistently.
[1] https://lore.kernel.org/linux-iommu/20260501111928.259252-1-smostafa@google.com/
Mostafa Saleh (3):
iommu/io-pgtable-arm: Use consistent sizes for page allocation and
freeing
iommu/io-pgtable-arm: Rework to use the iommu-pages API
iommu/io-pgtable-arm: Use address conversion consistently
drivers/iommu/io-pgtable-arm.c | 88 +++++++++++++++++++++++-----------
1 file changed, 61 insertions(+), 27 deletions(-)
--
2.54.0.563.g4f69b47b94-goog
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] iommu/io-pgtable-arm: Use consistent sizes for page allocation and freeing
2026-05-13 21:52 [PATCH 0/3] iommu/io-pgtable-arm: iommu-pages and cleanup Mostafa Saleh
@ 2026-05-13 21:52 ` Mostafa Saleh
2026-05-13 21:52 ` [PATCH 2/3] iommu/io-pgtable-arm: Rework to use the iommu-pages API Mostafa Saleh
2026-05-13 21:52 ` [PATCH 3/3] iommu/io-pgtable-arm: Use address conversion consistently Mostafa Saleh
2 siblings, 0 replies; 4+ messages in thread
From: Mostafa Saleh @ 2026-05-13 21:52 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: robin.murphy, will, joro, jgg, Mostafa Saleh
At the moment we use alloc_size to allocate memory but then there
is a logical error where we just size in the error and free path,
which might be smaller.
Also we size to do DMA-API operations, which is OK, but confusing.
Instead of this error-prone handling, just set size to alloc_size
and use it everywhere.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
drivers/iommu/io-pgtable-arm.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 0208e5897c29..0cbe545c491d 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -253,7 +253,6 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
void *cookie)
{
struct device *dev = cfg->iommu_dev;
- size_t alloc_size;
dma_addr_t dma;
void *pages;
@@ -261,12 +260,11 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
* For very small starting-level translation tables the HW requires a
* minimum alignment of at least 64 to cover all cases.
*/
- alloc_size = max(size, 64);
+ size = max(size, 64);
if (cfg->alloc)
- pages = cfg->alloc(cookie, alloc_size, gfp);
+ pages = cfg->alloc(cookie, size, gfp);
else
- pages = iommu_alloc_pages_node_sz(dev_to_node(dev), gfp,
- alloc_size);
+ pages = iommu_alloc_pages_node_sz(dev_to_node(dev), gfp, size);
if (!pages)
return NULL;
@@ -303,6 +301,9 @@ static void __arm_lpae_free_pages(void *pages, size_t size,
struct io_pgtable_cfg *cfg,
void *cookie)
{
+ /* See __arm_lpae_alloc_pages(). */
+ size = max(size, 64);
+
if (!cfg->coherent_walk)
dma_unmap_single(cfg->iommu_dev, __arm_lpae_dma_addr(pages),
size, DMA_TO_DEVICE);
--
2.54.0.563.g4f69b47b94-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] iommu/io-pgtable-arm: Rework to use the iommu-pages API
2026-05-13 21:52 [PATCH 0/3] iommu/io-pgtable-arm: iommu-pages and cleanup Mostafa Saleh
2026-05-13 21:52 ` [PATCH 1/3] iommu/io-pgtable-arm: Use consistent sizes for page allocation and freeing Mostafa Saleh
@ 2026-05-13 21:52 ` Mostafa Saleh
2026-05-13 21:52 ` [PATCH 3/3] iommu/io-pgtable-arm: Use address conversion consistently Mostafa Saleh
2 siblings, 0 replies; 4+ messages in thread
From: Mostafa Saleh @ 2026-05-13 21:52 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: robin.murphy, will, joro, jgg, Mostafa Saleh
Update the io-pgtable-arm allocator to use the iommu-pages API.
Replace the DMA API usage from __arm_lpae_alloc_pages() with
iommu_pages_start_incoherent() and from __arm_lpae_free_pages() with
iommu_pages_free_incoherent().
Since the iommu-pages API relies on metadata stored in the struct page
during iommu_alloc_pages_node_sz(), it cannot be used safely with memory
allocated via the custom cfg->alloc (which may not be backed by pages).
So, isolate that logic and keep it as it.
Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
drivers/iommu/io-pgtable-arm.c | 79 ++++++++++++++++++++++++----------
1 file changed, 56 insertions(+), 23 deletions(-)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 0cbe545c491d..86b23aa04324 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -248,24 +248,15 @@ static dma_addr_t __arm_lpae_dma_addr(void *pages)
return (dma_addr_t)virt_to_phys(pages);
}
-static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
- struct io_pgtable_cfg *cfg,
- void *cookie)
+static void *__arm_lpae_cfg_alloc(size_t size, gfp_t gfp,
+ struct io_pgtable_cfg *cfg,
+ void *cookie)
{
struct device *dev = cfg->iommu_dev;
dma_addr_t dma;
void *pages;
- /*
- * For very small starting-level translation tables the HW requires a
- * minimum alignment of at least 64 to cover all cases.
- */
- size = max(size, 64);
- if (cfg->alloc)
- pages = cfg->alloc(cookie, size, gfp);
- else
- pages = iommu_alloc_pages_node_sz(dev_to_node(dev), gfp, size);
-
+ pages = cfg->alloc(cookie, size, gfp);
if (!pages)
return NULL;
@@ -289,14 +280,55 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
dma_unmap_single(dev, dma, size, DMA_TO_DEVICE);
out_free:
- if (cfg->free)
- cfg->free(cookie, pages, size);
- else
- iommu_free_pages(pages);
-
+ cfg->free(cookie, pages, size);
return NULL;
}
+static void __arm_lpae_cfg_free(void *pages, size_t size,
+ struct io_pgtable_cfg *cfg,
+ void *cookie)
+{
+ if (!cfg->coherent_walk)
+ dma_unmap_single(cfg->iommu_dev, __arm_lpae_dma_addr(pages),
+ size, DMA_TO_DEVICE);
+
+ cfg->free(cookie, pages, size);
+}
+
+static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
+ struct io_pgtable_cfg *cfg,
+ void *cookie)
+{
+ struct device *dev = cfg->iommu_dev;
+ void *pages;
+
+ /*
+ * For very small starting-level translation tables the HW requires a
+ * minimum alignment of at least 64 to cover all cases.
+ */
+ size = max(size, 64);
+
+ if (cfg->alloc)
+ return __arm_lpae_cfg_alloc(size, gfp, cfg, cookie);
+
+ pages = iommu_alloc_pages_node_sz(dev_to_node(dev), gfp, size);
+ if (!pages)
+ return NULL;
+
+ if (!cfg->coherent_walk) {
+ int ret = iommu_pages_start_incoherent(pages, dev);
+
+ if (ret) {
+ if (ret == -EOPNOTSUPP)
+ dev_err(dev, "Cannot accommodate DMA translation for IOMMU page tables\n");
+ iommu_free_pages(pages);
+ return NULL;
+ }
+ }
+
+ return pages;
+}
+
static void __arm_lpae_free_pages(void *pages, size_t size,
struct io_pgtable_cfg *cfg,
void *cookie)
@@ -304,12 +336,13 @@ static void __arm_lpae_free_pages(void *pages, size_t size,
/* See __arm_lpae_alloc_pages(). */
size = max(size, 64);
- if (!cfg->coherent_walk)
- dma_unmap_single(cfg->iommu_dev, __arm_lpae_dma_addr(pages),
- size, DMA_TO_DEVICE);
+ if (cfg->free) {
+ __arm_lpae_cfg_free(pages, size, cfg, cookie);
+ return;
+ }
- if (cfg->free)
- cfg->free(cookie, pages, size);
+ if (!cfg->coherent_walk)
+ iommu_pages_free_incoherent(pages, cfg->iommu_dev);
else
iommu_free_pages(pages);
}
--
2.54.0.563.g4f69b47b94-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] iommu/io-pgtable-arm: Use address conversion consistently
2026-05-13 21:52 [PATCH 0/3] iommu/io-pgtable-arm: iommu-pages and cleanup Mostafa Saleh
2026-05-13 21:52 ` [PATCH 1/3] iommu/io-pgtable-arm: Use consistent sizes for page allocation and freeing Mostafa Saleh
2026-05-13 21:52 ` [PATCH 2/3] iommu/io-pgtable-arm: Rework to use the iommu-pages API Mostafa Saleh
@ 2026-05-13 21:52 ` Mostafa Saleh
2 siblings, 0 replies; 4+ messages in thread
From: Mostafa Saleh @ 2026-05-13 21:52 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: robin.murphy, will, joro, jgg, Mostafa Saleh
Use consistent address conversions in the driver:
- virt_to_phys(): For all virtual to physical address conversion,
convert __pa users as we don’t need to rely on it type casting.
- phys_to_virt(): For all physical to virtual address conversion,
similarly, convert __va users.
That changes nothing at all. However, it will be useful when
compiling this file for the KVM hypervisor as it can cleanly
replace virt_to_phys/phys_to_virt
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
drivers/iommu/io-pgtable-arm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 86b23aa04324..476c0e25631a 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -143,7 +143,7 @@
#define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC 0x8DULL
/* IOPTE accessors */
-#define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d))
+#define iopte_deref(pte, d) phys_to_virt(iopte_to_paddr(pte, d))
#define iopte_type(pte) \
(((pte) >> ARM_LPAE_PTE_TYPE_SHIFT) & ARM_LPAE_PTE_TYPE_MASK)
@@ -429,7 +429,7 @@ static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table,
arm_lpae_iopte old, new;
struct io_pgtable_cfg *cfg = &data->iop.cfg;
- new = paddr_to_iopte(__pa(table), data) | ARM_LPAE_PTE_TYPE_TABLE;
+ new = paddr_to_iopte(virt_to_phys(table), data) | ARM_LPAE_PTE_TYPE_TABLE;
if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
new |= ARM_LPAE_PTE_NSTABLE;
--
2.54.0.563.g4f69b47b94-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-05-13 21:53 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-13 21:52 [PATCH 0/3] iommu/io-pgtable-arm: iommu-pages and cleanup Mostafa Saleh
2026-05-13 21:52 ` [PATCH 1/3] iommu/io-pgtable-arm: Use consistent sizes for page allocation and freeing Mostafa Saleh
2026-05-13 21:52 ` [PATCH 2/3] iommu/io-pgtable-arm: Rework to use the iommu-pages API Mostafa Saleh
2026-05-13 21:52 ` [PATCH 3/3] iommu/io-pgtable-arm: Use address conversion consistently Mostafa Saleh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox