[PATCH v5 2/4] armv8: mmu: teach the pagetable dumper to show explicit FAULT maps

Casey Connolly casey.connolly at linaro.org
Tue May 26 16:10:45 CEST 2026



On 25/05/2026 13:35, Ilias Apalodimas wrote:
> On Mon, 18 May 2026 at 12:00, Casey Connolly <casey.connolly at linaro.org> wrote:
>>
>> When a region is explicitly unmapped (like with
>> mmu_change_region_attr(.... PTE_TYPE_FAULT)) the address translation
>> still remains but won't be used since the region is marked invalid.
>> Print these regions when we dump the pagetable to help with debugging.
>>
>> Signed-off-by: Casey Connolly <casey.connolly at linaro.org>
>> ---
>>  arch/arm/cpu/armv8/cache_v8.c | 8 ++++++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
>> index 97a1c39ed268..2800ba57a464 100644
>> --- a/arch/arm/cpu/armv8/cache_v8.c
>> +++ b/arch/arm/cpu/armv8/cache_v8.c
>> @@ -533,9 +533,9 @@ static void __pagetable_walk(u64 addr, u64 tcr, int level, pte_walker_cb_t cb, v
>>
>>                 if (exit)
>>                         return;
>>
>> -               if (pte_type(&pte) == PTE_TYPE_FAULT)
>> +               if (!pte)
>>                         continue;
>>
>>                 attrs = pte & ALL_ATTRS;
>>                 /* If we're currently inside a block or set of pages */
>> @@ -572,9 +572,9 @@ static void __pagetable_walk(u64 addr, u64 tcr, int level, pte_walker_cb_t cb, v
>>
>>                         /* Go down a level */
>>                         __pagetable_walk(_addr, tcr, level + 1, cb, priv);
>>                         state[level] = WALKER_STATE_START;
>> -               } else if (pte_type(&pte) == PTE_TYPE_BLOCK || pte_type(&pte) == PTE_TYPE_PAGE) {
>> +               } else {
>>                         /* We foud a block or page, start walking */
>>                         entry_start = pte;
>>                         state[level] = WALKER_STATE_REGION;
>>                 }
>> @@ -707,8 +707,12 @@ static bool pagetable_print_entry(u64 start_attrs, u64 end, int va_bits, int lev
>>  {
>>         u64 _addr = start_attrs & GENMASK_ULL(va_bits, PAGE_SHIFT);
>>         int indent = va_bits < 39 ? level - 1 : level;
>>
>> +       /* Ignore empty blocks */
>> +       if (!start_attrs)
>> +               return false;
> 
> I am not sure I am following this one. This one get the value of
> TTBR_ELx. What are we trying to prevent? Perhaps we should move the
> check to walk_pagetable()?

Not sure what you mean about TTBR_ELx here. I think you're right that it
should be moved, I think I added it because I hit a case where there was
a table with no blocks in it (which obviously should never happen if the
mmu code is working properly).

I can just drop it then if we see empty FAULT mappings from address 0
with a size of 1 granule we know there's a bug in the MMU code :D


> 
> Cheers
> /Ilias
>> +
>>         printf("%*s", indent * 2, "");
>>         if (PTE_IS_TABLE(start_attrs, level))
>>                 printf("[%#016llx]%19s", _addr, "");
>>         else
>>
>> --
>> 2.53.0
>>

-- 
// Casey (she/her)



More information about the U-Boot mailing list