[PATCH v3 1/6] arm64: make huge_ptep_get handled unaligned addresses

Dev Jain dev.jain at arm.com
Mon Jul 6 03:52:25 PDT 2026



On 06/07/26 2:15 pm, David Hildenbrand (Arm) wrote:
> On 7/5/26 10:08, Dev Jain wrote:
>>
>>
>> On 05/07/26 1:05 pm, Andrew Morton wrote:
>>> On Fri,  3 Jul 2026 11:41:54 +0000 Dev Jain <dev.jain at arm.com> wrote:
>>>
>>>> huge_ptep_get() can be handed a virtual address pointing to the middle of
>>>> a contpmd/contpte mapped hugetlb folio (examples of callers are
>>>> pagemap_hugetlb_range, page_mapped_in_vma).
>>>>
>>>> The arm64 helper rewalks the pgtables in find_num_contig to answer whether
>>>> the huge pte we have maps a contpmd or a contpte hugetlb folio, and
>>>> returns CONT_PMDS or CONT_PTES, so that it can collect a/d bits over the
>>>> contiguous ptes. We can falsely return CONT_PTES instead of CONT_PMDS
>>>> if the addr is not aligned.
>>>>
>>>> Fix this by aligning the pmdp pointer down to a contpmd base before
>>>> checking equality with the passed huge pte pointer, to correctly answer
>>>> whether the huge pte is the base of a contpmd block.
>>>>
>>>> Fixes: 29cb80519689 ("arm64: hugetlb: Cleanup huge_pte size discovery mechanisms")
>>>> Cc: stable at vger.kernel.org
>>>
>>> Please describe the userspace-visible effects of bugs when fixing them.
>>> Particularly when cc:stable is proposed.  Thanks.
>>
>> Forgot for this one. It should be, on systems where CONT_PTES != CONT_PMDS
>> (meaning page size is 16K) we could collect excess a/d bit state, meaning
>> extra work for the kernel.
> 
> Even worse, right? We could walk 128 entries, when we really should just walk 16
> (IIRC) entries, possibly reading garbage or even worse, into a memory hole at
> the end of memory?

Hmm I was thinking that the checks pte_dirty() and pte_young() wouldn't care whether
the pte is garbage. But, we could actually dereference a ptep pointer not having
backing memory at all.

Does the following sound good?

"On systems where CONT_PTES != CONT_PMDS (meaning page size is 16K), we could collect
excess a/d bit state, meaning extra work for the kernel. Even worse, we may iterate
beyond the PTE table and dereference a garbage ptep pointer to access physical
memory we don't own. Since the ptep pointer is a linear map address, we may run off
the end of the linear map, dereference a VA not mapped into the kernel pgtables and
cause kernel panic."

Although I checked on arm64, there is no case in which there is a hole after the
linear map, but still that assumption shouldn't be made.


> 




More information about the linux-arm-kernel mailing list