From: Shivam Kalra Update vread_iter() to derive the vm area size from vm->nr_pages rather than get_vm_area_size(). Currently both values are equivalent, but the upcoming vrealloc() shrink functionality will free pages without reducing the virtual reservation size. After such a shrink, the old get_vm_area_size() based calculation would overestimate the mapped range, causing vread_iter() to attempt reading from unmapped addresses. Switch to vm->nr_pages now so the reader remains correct once shrink support is added. Signed-off-by: Shivam Kalra --- mm/vmalloc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 9cb3e287a1e8..65e0a23efb3b 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -4661,7 +4661,14 @@ long vread_iter(struct iov_iter *iter, const char *addr, size_t count) smp_rmb(); vaddr = (char *) va->va_start; - size = vm ? get_vm_area_size(vm) : va_size(va); + if (vm) + /* + * Cannot use get_vm_area_size() because realloc() + * may shrink the mapping and area->size may be outdated. + */ + size = vm->nr_pages << PAGE_SHIFT; + else + size = va_size(va); if (addr >= vaddr + size) goto next_va; -- 2.43.0