* [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
` (3 more replies)
0 siblings, 4 replies; 8+ 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] 8+ 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-15 13:36 ` Jason Gunthorpe
2026-05-13 21:52 ` [PATCH 2/3] iommu/io-pgtable-arm: Rework to use the iommu-pages API Mostafa Saleh
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ 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] 8+ 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-15 13:54 ` Jason Gunthorpe
2026-05-13 21:52 ` [PATCH 3/3] iommu/io-pgtable-arm: Use address conversion consistently Mostafa Saleh
2026-05-19 9:04 ` [PATCH 0/3] iommu/io-pgtable-arm: iommu-pages and cleanup Jörg Rödel
3 siblings, 1 reply; 8+ 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] 8+ 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
2026-05-15 13:33 ` Jason Gunthorpe
2026-05-19 9:04 ` [PATCH 0/3] iommu/io-pgtable-arm: iommu-pages and cleanup Jörg Rödel
3 siblings, 1 reply; 8+ 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] 8+ messages in thread
* Re: [PATCH 3/3] iommu/io-pgtable-arm: Use address conversion consistently
2026-05-13 21:52 ` [PATCH 3/3] iommu/io-pgtable-arm: Use address conversion consistently Mostafa Saleh
@ 2026-05-15 13:33 ` Jason Gunthorpe
0 siblings, 0 replies; 8+ messages in thread
From: Jason Gunthorpe @ 2026-05-15 13:33 UTC (permalink / raw)
To: Mostafa Saleh
Cc: iommu, linux-arm-kernel, linux-kernel, robin.murphy, will, joro
On Wed, May 13, 2026 at 09:52:03PM +0000, Mostafa Saleh wrote:
> 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(-)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/3] iommu/io-pgtable-arm: Use consistent sizes for page allocation and freeing
2026-05-13 21:52 ` [PATCH 1/3] iommu/io-pgtable-arm: Use consistent sizes for page allocation and freeing Mostafa Saleh
@ 2026-05-15 13:36 ` Jason Gunthorpe
0 siblings, 0 replies; 8+ messages in thread
From: Jason Gunthorpe @ 2026-05-15 13:36 UTC (permalink / raw)
To: Mostafa Saleh
Cc: iommu, linux-arm-kernel, linux-kernel, robin.murphy, will, joro
On Wed, May 13, 2026 at 09:52:01PM +0000, Mostafa Saleh wrote:
> 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(-)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
This is similar to how iommupt works, pt_top_memsize_lg2() rounds up
the top table size to the alignment minimum and we just dma map
flush/etc the larger size everwhere.
Jason
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] iommu/io-pgtable-arm: Rework to use the iommu-pages API
2026-05-13 21:52 ` [PATCH 2/3] iommu/io-pgtable-arm: Rework to use the iommu-pages API Mostafa Saleh
@ 2026-05-15 13:54 ` Jason Gunthorpe
0 siblings, 0 replies; 8+ messages in thread
From: Jason Gunthorpe @ 2026-05-15 13:54 UTC (permalink / raw)
To: Mostafa Saleh
Cc: iommu, linux-arm-kernel, linux-kernel, robin.murphy, will, joro
On Wed, May 13, 2026 at 09:52:02PM +0000, Mostafa Saleh wrote:
> 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(-)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
I feel the setup for incoherent walk for panthor is kind of sketchy,
if you select incoherent walk and pass in a random GPU driver struct
device there are alot of assumptions suddenly to know the dma API is
doing the right thing..
Jason
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 0/3] iommu/io-pgtable-arm: iommu-pages and cleanup
2026-05-13 21:52 [PATCH 0/3] iommu/io-pgtable-arm: iommu-pages and cleanup Mostafa Saleh
` (2 preceding siblings ...)
2026-05-13 21:52 ` [PATCH 3/3] iommu/io-pgtable-arm: Use address conversion consistently Mostafa Saleh
@ 2026-05-19 9:04 ` Jörg Rödel
3 siblings, 0 replies; 8+ messages in thread
From: Jörg Rödel @ 2026-05-19 9:04 UTC (permalink / raw)
To: Mostafa Saleh
Cc: iommu, linux-arm-kernel, linux-kernel, robin.murphy, will, jgg
On Wed, May 13, 2026 at 09:52:00PM +0000, Mostafa Saleh wrote:
> 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(-)
Applied, thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-05-19 9:04 UTC | newest]
Thread overview: 8+ 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-15 13:36 ` Jason Gunthorpe
2026-05-13 21:52 ` [PATCH 2/3] iommu/io-pgtable-arm: Rework to use the iommu-pages API Mostafa Saleh
2026-05-15 13:54 ` Jason Gunthorpe
2026-05-13 21:52 ` [PATCH 3/3] iommu/io-pgtable-arm: Use address conversion consistently Mostafa Saleh
2026-05-15 13:33 ` Jason Gunthorpe
2026-05-19 9:04 ` [PATCH 0/3] iommu/io-pgtable-arm: iommu-pages and cleanup Jörg Rödel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.