mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 17:57:38 -04:00
mm/khugepaged: avoid underflow in madvise_collapse for sub-PMD MADV_COLLAPSE
madvise_collapse() computes the THP-aligned window:
hstart = ALIGN(start, HPAGE_PMD_SIZE); /* round up */
hend = ALIGN_DOWN(end, HPAGE_PMD_SIZE); /* round down */
The following case will cause hstart > hend, and result in underflow in
the return statement, avoid it by returning zero early when hstart > hend.
The return value is due to input is valid to madvise(), and there is
nothing to collapse.
madvise(PMD-aligned + PAGE_SIZE, PAGE_SIZE, MADV_COLLAPSE);
In addition, kmalloc_obj(), mmgrab() and lru_add_drain_all() are
unnecessary when hstart == hend, so skip these operations by returning
early too.
Link: https://lore.kernel.org/20260513055428.1664898-1-chenwandun@lixiang.com
Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Nico Pache <npache@redhat.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Zi Yan <ziy@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
08de77b1c9
commit
b89a641056
@@ -3198,6 +3198,12 @@ int madvise_collapse(struct vm_area_struct *vma, unsigned long start,
|
||||
if (!collapse_possible(vma, vma->vm_flags, TVA_FORCED_COLLAPSE))
|
||||
return -EINVAL;
|
||||
|
||||
hstart = ALIGN(start, HPAGE_PMD_SIZE);
|
||||
hend = ALIGN_DOWN(end, HPAGE_PMD_SIZE);
|
||||
|
||||
if (hstart >= hend)
|
||||
return 0;
|
||||
|
||||
cc = kmalloc_obj(*cc);
|
||||
if (!cc)
|
||||
return -ENOMEM;
|
||||
@@ -3207,9 +3213,6 @@ int madvise_collapse(struct vm_area_struct *vma, unsigned long start,
|
||||
mmgrab(mm);
|
||||
lru_add_drain_all();
|
||||
|
||||
hstart = ALIGN(start, HPAGE_PMD_SIZE);
|
||||
hend = ALIGN_DOWN(end, HPAGE_PMD_SIZE);
|
||||
|
||||
for (addr = hstart; addr < hend; addr += HPAGE_PMD_SIZE) {
|
||||
enum scan_result result = SCAN_FAIL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user