Hi Tom,

On 7/8/26 13:47, Ilias Apalodimas wrote:
Hi Akshay

On Wed, 8 Jul 2026 at 14:17, Akshay Belsare <[email protected]> wrote:

DCACHE_OFF is defined as (0 << 2) = 0, and PTE_TYPE_FAULT is defined
as (0 << 0) = 0. In mmu_set_region_dcache_behaviour(), the cache
attribute passed to set_regions() is computed as:
   attrs = PMD_ATTRINDX(option >> 2)
For DCACHE_OFF=0 this evaluates to PMD_ATTRINDX(0) = 0, which equals
PTE_TYPE_FAULT.

Commit 6468ca13ffd6f ("armv8: mmu: fix and optimise explicitly unmapping
regions") added an unmap path to set_one_region() that
triggers when attrs == PTE_TYPE_FAULT. Because DCACHE_OFF and
PTE_TYPE_FAULT share the same numerical value (0), any call to
mmu_set_region_dcache_behaviour() with DCACHE_OFF silently unmaps the
target region instead of changing its cache attributes to non-cached.

The subsequent flush_dcache_range() call at the end of
mmu_set_region_dcache_behaviour() then crashes with a Level 3
translation fault because the region it tries to flush has just been
unmapped.

The existing flag parameter already distinguishes the two callers:
  - mmu_set_region_dcache_behaviour() always passes flag=false
  - mmu_change_region_attr_nobreak() always passes flag=true, and is the
    only legitimate caller that passes PTE_TYPE_FAULT to unmap a region

Guard the unmap path with flag so that DCACHE_OFF attribute changes
take the correct else branch, which ORs in the ATTRINDX bits only,
leaving the PTE valid.

I don't really love the 'flag' attribute that distinguishes between
preserving or overwriting the permission bits...

However, this does fix an issue.

Reviewed-by: Ilias Apalodimas <[email protected]>

Can you please cherry pick this patch?

Thanks,
Michal

Reply via email to