[PATCH v5 4/4] armv8: mmu: fix and optimise explicitly unmapping regions

Ilias Apalodimas ilias.apalodimas at linaro.org
Mon May 25 14:53:06 CEST 2026


Hi Casey,

[...]

>
>         return NULL;
>  }
>
> +/* Checks if the current PTE is an aligned subset of the region */
>  static bool is_aligned(u64 addr, u64 size, u64 align)
>  {
> -       return !(addr & (align - 1)) && !(size & (align - 1));
> +       return !(addr & (align - 1)) && size >= align;
>  }
>
>  /* Use flag to indicate if attrs has more than d-cache attributes */
>  static u64 set_one_region(u64 start, u64 size, u64 attrs, bool flag, int level)
> @@ -1003,11 +1004,16 @@ static u64 set_one_region(u64 start, u64 size, u64 attrs, bool flag, int level)
>         int levelshift = level2shift(level);
>         u64 levelsize = 1ULL << levelshift;
>         u64 *pte = find_pte(start, level);
>
> -       /* Can we can just modify the current level block PTE? */
> +       /* Can we can just modify the current level block/page? */
>         if (is_aligned(start, size, levelsize)) {
> -               if (flag) {
> +               if (attrs == PTE_TYPE_FAULT) {
> +                       if (pte_type(pte) == PTE_TYPE_TABLE && level < 3)
> +                               *pte = 0;
> +                       else
> +                               *pte &= ~(PMD_ATTRMASK | PTE_TYPE_MASK | PTE_BLOCK_INNER_SHARE);

Looks correct now, but the umapped memory appears as 'Device-nGnRnE'.
Shouldn't we preserve whatever was there?

Thanks
/Ilias
> +               } else if (flag) {
>                         *pte &= ~PMD_ATTRMASK;
>                         *pte |= attrs & PMD_ATTRMASK;
>                 } else {
>                         *pte &= ~PMD_ATTRINDX_MASK;
> @@ -1107,8 +1113,12 @@ void mmu_change_region_attr(phys_addr_t addr, size_t size, u64 attrs)
>         flush_dcache_range(gd->arch.tlb_addr,
>                            gd->arch.tlb_addr + gd->arch.tlb_size);
>         __asm_invalidate_tlb_all();
>
> +       /* If we were unmapping a region then we have nothing to make and can return. */
> +       if (attrs == PTE_TYPE_FAULT)
> +               return;
> +
>         mmu_change_region_attr_nobreak(addr, size, attrs);
>  }
>
>  int pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
>
> --
> 2.53.0
>


More information about the U-Boot mailing list