ANDROID: 16K: skip fault-around in ELF segment padding holes Update do_fault_around() to skip the fault-around optimization when a fault occurs within the padding region of an ELF segment VMA. These padding regions are essentially holes used to satisfy ELF segment alignment requirements in Android and are not expected to be accessed under normal conditions. By verifying the fault offset against the data-backed portion of the VMA (nr_data_pages), the kernel avoids unnecessarily populating page tables for these padding holes. This ensures that fault-around only attempts to map valid file-cache pages within the segment's data range. Bug: 498369302 Bug: 498371235 Change-Id: I9ebf5159a6fcf804efe290cb9481cedb9e9651d0 Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
diff --git a/mm/memory.c b/mm/memory.c index 043cdd9..ccef6d6 100644 --- a/mm/memory.c +++ b/mm/memory.c
@@ -4666,10 +4666,19 @@ late_initcall(fault_around_debugfs); static vm_fault_t do_fault_around(struct vm_fault *vmf) { unsigned long address = vmf->address, nr_pages, mask; + pgoff_t vma_off = vmf->pgoff - vmf->vma->vm_pgoff; + pgoff_t nr_data_pages = vma_data_pages(vmf->vma); pgoff_t start_pgoff = vmf->pgoff; pgoff_t end_pgoff; int off; + /* + * Fault occurred in the padding region. There are no file-cache pages + * to map in this region, so skip fault-around. + */ + if (vma_off >= nr_data_pages) + return 0; + nr_pages = READ_ONCE(fault_around_bytes) >> PAGE_SHIFT; mask = ~(nr_pages * PAGE_SIZE - 1) & PAGE_MASK; @@ -4684,7 +4693,7 @@ static vm_fault_t do_fault_around(struct vm_fault *vmf) end_pgoff = start_pgoff - ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) + PTRS_PER_PTE - 1; - end_pgoff = min3(end_pgoff, vma_data_pages(vmf->vma) + vmf->vma->vm_pgoff - 1, + end_pgoff = min3(end_pgoff, nr_data_pages + vmf->vma->vm_pgoff - 1, start_pgoff + nr_pages - 1); if (pmd_none(*vmf->pmd)) {