[PATCH v4] iommu/io-pgtable-arm: Add support for contiguous hint bit
Daniel Mentz
danielmentz at google.com
Tue Sep 8 09:36:35 PDT 2026
On Sun, Aug 30, 2026 at 12:43 PM Daniel Mentz <danielmentz at google.com> wrote:
> > >>>> +/*
> > >>>> + * Install num_entries leaf entries starting at ptep (index map_idx_start
> > >>>> + * within the current table), tagging arm_lpae_num_cont()-sized groups with
> > >>>> + * the contiguous hint where both idx and paddr are aligned to the group
> > >>>> + * size. Entries in a misaligned group are installed without the hint.
> > >>>> + *
> > >>>> + * idx and paddr both advance by block_size per entry, so their alignment
> > >>>> + * relative to the group size is invariant across a run of entries within
> > >>>> + * this call: once a group qualifies (or fails to), every later whole group
> > >>>> + * does too, up to num_entries. This merges each such run into a single
> > >>>> + * arm_lpae_init_pte() call instead of one call per group.
> > >>>> + */
> > >>>
> > >>> Can you provide an example for when this function installs descriptors
> > >>> where the contiguous bit is only set on a subset of them. I would
> > >>> assume that the contiguous bit is either set for all descriptors or
> > >>> none of them.
> > >>>
> > >>
> > >> That assumption doesn't hold in general -- it's only true when the
> > >> map request happens to start and end on a cont_size boundary. For an
> > >> arbitrary map_pages() call it usually doesn't.
> > >
> > > I believe you won't see arbitrary map_pages() calls. I understand that
> > > these calls are exclusively coming from __iommu_map_domain_pgtbl()
> > > which uses iommu_pgsize() to determine optimal page sizes.
> > >
> > >> Example, 4K granule (num_cont = 16, cont_size = 64K),
> > >> iova = paddr = 0x1000, pgcount = 34:
> > >>
> > >> - idx 1..15 (off != 0, misaligned prefix): installed plain
> > >> - idx 16..31 (off == 0, paddr now 64K-aligned): installed w/ CONT
> > >> - idx 32..34 (off == 0, remaining < num_cont): installed plain
> > >
> > > In the example you provided, I expect that you'll receive three
> > > separate calls from __iommu_map_domain_pgtbl:
> > > * idx 1..15 with pgsize 4KB
> > > * one call with pgsize 64KB
> > > * idx 32..34 with pgsize 4KB
> > >
> > > If I took your argument further, I could argue that we'd also have to
> > > check if we can put down a block mapping if iova = paddr = 0x0 and
> > > pgcount = 512, but we're not doing that either.
> > >
> > > Could you provide the input parameters to the iommu_map() call that
> > > resulted in the parameters you provided i.e. iova = paddr = 0x1000,
> > > pgcount = 34:
> > >
> >
> > You're right -- for the iommu_map()/__iommu_map_domain_pgtbl() path, iommu_pgsize()
> > already splits the request at the boundaries you describe before install_leaf() ever
> > sees it, so install_leaf() doesn't need to handle a mixed prefix/CONT-group/suffix
> > chunk for that caller.
> >
> > That said, install_leaf() is shared by other callers that reach it through
> > ops->map_pages() directly, without going through iommu_pgsize(). panthor_vm_map_pages()
> > (drivers/gpu/drm/panthor/panthor_mmu.c) is one -- it allocates its io_pgtable_ops via
> > alloc_io_pgtable_ops(ARM_64_LPAE_S1, ...), same as any other LPAE consumer, but does its
> > own chunking with a local get_pgsize() that only ever returns SZ_4K or SZ_2M, with no
> > notion of the 64K/32M CONT boundaries. That can hand install_leaf() exactly the mixed
> > iova=paddr=0x1000, pgcount=34 shape in a single call (panfrost's map loop uses the same
> > get_pgsize() and hits the same case). So the prefix/aligned-group/suffix handling in
> > install_leaf() is still needed for that path.
>
> Maybe other people can chime in here, but I feel, from an API
> perspective, we should have only one way to make of use iopgtable. I
> think we should just mandate that users honor the updated value for
> pgtbl_cfg.pgsize_bitmap (and pgtbl_cfg.ias) after the
> alloc_io_pgtable_ops() call and then choose page sizes appropriately.
> Otherwise, we end up with two pieces of code in the kernel solving the
> same problem. panthor_mmu won't be able to take advantage of the
> contiguous bit until it gets updated accordingly, and that's ok.
On this note, I want to point out that I tried something similar in
2025 (see https://lore.kernel.org/linux-iommu/20250430231924.1481493-1-danielmentz@google.com/).
The feedback I received from Jason at the time was:
"Wouldn't it be better to use the pgsize_bitmap and rely on the core
code to indicate that a contiguous page size is being used, so it can
trivially set the PTE bit without doing all this extra work?"
More information about the linux-arm-kernel
mailing list