Hi Dev

Thanks for your review.

On 2026/10/30 15:14, Dev Jain wrote:
> 
> 
> On 26/10/26 1:33 pm, Hao Ge wrote:
>> commit a739e6b557af ("mm: vmalloc: WARN_ON if mapping size is not
>> PAGE_SIZE aligned") made vmap_pte_range() warn and bail out when the
>> size is not a multiple of PAGE_SIZE. That loop steps in page
> 
> Why are we checking the alignment so late into vmap_pte_range? Why not
> simply do
> 
> if (!IS_ALIGNED(addr, PAGE_SIZE) || !IS_ALIGNED(end, PAGE_SIZE))
>       return; (or return -EINVAL);
> 
> at the start of vmap_range_noflush and vunmap_range_noflush?

I think adding that check at the entry of vunmap_range_noflush()
goes against its design intent. Its job is to tear down the mappings
of the given VA range, so even when the caller passes a size that is
not page-aligned, we still have to unmap whatever is mapped within
that range.

So the patch clamps end down to the last full page and keeps
clearing. A buggy caller still gets its mapping torn down as far as
it goes, and nothing is left behind. The check here is just for
protection. 

This is just my preliminary understanding; I may be mistaken.

Thanks
Best Regards
Hao


But that's just my understanding, happy to be corrected.


> 
> 
>> multiples and stops only at addr == end; with an unaligned size addr
>> never lands on end, so the loop cannot terminate and walks off the
>> end of the page table.
>>
>> vunmap_pte_range() has the same loop without any guard, so an
>> unaligned range would clear PTEs past end without ever stopping,
>> walking off the end of the page table.
>>
>> Add the check there too. The range is clamped down to the last full
>> page rather than dropped, and the loop is skipped when nothing is
>> left, so a buggy caller still gets its PTEs cleared as far as they
>> go.
>>
>> Reported-by: Sashiko <[email protected]>
>> Signed-off-by: Hao Ge <[email protected]>
>> ---
>>  mm/vmalloc.c | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
>> index 44e0eb32708f..7131f60d1a8e 100644
>> --- a/mm/vmalloc.c
>> +++ b/mm/vmalloc.c
>> @@ -393,6 +393,11 @@ static void vunmap_pte_range(pmd_t *pmd, unsigned long 
>> addr, unsigned long end,
>>      pte_t ptent;
>>      unsigned long size = PAGE_SIZE;
>>  
>> +    if (WARN_ON_ONCE(!PAGE_ALIGNED(end - addr)))
>> +            end = addr + PAGE_ALIGN_DOWN(end - addr);
>> +    if (end == addr)
>> +            return;
>> +
>>      pte = pte_offset_kernel(pmd, addr);
>>      lazy_mmu_mode_enable();
>>  
> 

Reply via email to