Remove get_data_vma() which made a copy of the original VMA containing padding and modified vm_end to exclude the trailing padding (if any). Avoid this copy to avoid races due to stale data relating to vma->vm_file. Instead use VMA_PAD_START(vma) directly to get the correct end excluding padding if any. Add additional check to verify the padding VMA is as expected and also check for allocation failure of the pad VMA. ELFs with padding can be loaded from tmpfs. For simplicity swapped out shmem accounting in smaps, skips the fast path for read only files and walks the page table with the range adjusted for padding. Example output: ===== Maps ===== 7ff6306c2000-7ff6306c3000 r--p 00000000 fe:09 1912 /system/lib64/bootstrap/libdl.so 7ff6306c3000-7ff6306c6000 ---p 00000000 00:00 0 [page size compat] 7ff6306c6000-7ff6306c7000 r-xp 00004000 fe:09 1912 /system/lib64/bootstrap/libdl.so 7ff6306c7000-7ff6306ca000 ---p 00000000 00:00 0 [page size compat] 7ff6306ca000-7ff6306cb000 r--p 00008000 fe:09 1912 /system/lib64/bootstrap/libdl.so ===== Smaps ===== 7ff6306c2000-7ff6306c3000 r--p 00000000 fe:09 1912 /system/lib64/bootstrap/libdl.so Size: 4 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Rss: 4 kB Pss: 0 kB Pss_Dirty: 0 kB Shared_Clean: 4 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 0 kB Referenced: 4 kB Anonymous: 0 kB KSM: 0 kB LazyFree: 0 kB AnonHugePages: 0 kB ShmemPmdMapped: 0 kB FilePmdMapped: 0 kB Shared_Hugetlb: 0 kB Private_Hugetlb: 0 kB Swap: 0 kB SwapPss: 0 kB Locked: 0 kB THPeligible: 0 VmFlags: rd mr mw me ?? 7ff6306c3000-7ff6306c6000 ---p 00000000 00:00 0 [page size compat] Size: 12 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Rss: 0 kB Pss: 0 kB Pss_Dirty: 0 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 0 kB Referenced: 0 kB Anonymous: 0 kB KSM: 0 kB LazyFree: 0 kB AnonHugePages: 0 kB ShmemPmdMapped: 0 kB FilePmdMapped: 0 kB Shared_Hugetlb: 0 kB Private_Hugetlb: 0 kB Swap: 0 kB SwapPss: 0 kB Locked: 0 kB THPeligible: 0 VmFlags: mr mw me 7ff6306c6000-7ff6306c7000 r-xp 00004000 fe:09 1912 /system/lib64/bootstrap/libdl.so Size: 4 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Rss: 4 kB Pss: 0 kB Pss_Dirty: 0 kB Shared_Clean: 4 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 0 kB Referenced: 4 kB Anonymous: 0 kB KSM: 0 kB LazyFree: 0 kB AnonHugePages: 0 kB ShmemPmdMapped: 0 kB FilePmdMapped: 0 kB Shared_Hugetlb: 0 kB Private_Hugetlb: 0 kB Swap: 0 kB SwapPss: 0 kB Locked: 0 kB THPeligible: 0 VmFlags: rd ex mr mw me ?? 7ff6306c7000-7ff6306ca000 ---p 00000000 00:00 0 [page size compat] Size: 12 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Rss: 0 kB Pss: 0 kB Pss_Dirty: 0 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 0 kB Referenced: 0 kB Anonymous: 0 kB KSM: 0 kB LazyFree: 0 kB AnonHugePages: 0 kB ShmemPmdMapped: 0 kB FilePmdMapped: 0 kB Shared_Hugetlb: 0 kB Private_Hugetlb: 0 kB Swap: 0 kB SwapPss: 0 kB Locked: 0 kB THPeligible: 0 VmFlags: mr mw me 7ff6306ca000-7ff6306cb000 r--p 00008000 fe:09 1912 /system/lib64/bootstrap/libdl.so Size: 4 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Rss: 4 kB Pss: 4 kB Pss_Dirty: 4 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 4 kB Referenced: 4 kB Anonymous: 4 kB KSM: 0 kB LazyFree: 0 kB AnonHugePages: 0 kB ShmemPmdMapped: 0 kB FilePmdMapped: 0 kB Shared_Hugetlb: 0 kB Private_Hugetlb: 0 kB Swap: 0 kB SwapPss: 0 kB Locked: 0 kB THPeligible: 0 VmFlags: rd mr mw me ac Bug: 383389169 Bug: 409239984 Change-Id: Ic54e89571276db62ffc01681e7ca8986bb1ca7c4 Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
77 lines
2.1 KiB
C
77 lines
2.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_PAGE_SIZE_MIGRATION_H
|
|
#define _LINUX_PAGE_SIZE_MIGRATION_H
|
|
|
|
/*
|
|
* Page Size Migration
|
|
*
|
|
* Copyright (c) 2024, Google LLC.
|
|
* Author: Kalesh Singh <kaleshsingh@goole.com>
|
|
*
|
|
* This file contains the APIs for mitigations to ensure
|
|
* app compatibility during the transition from 4kB to 16kB
|
|
* page size in Android.
|
|
*/
|
|
|
|
#include <linux/pgsize_migration_inline.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/mm.h>
|
|
|
|
#if PAGE_SIZE == SZ_4K && defined(CONFIG_64BIT)
|
|
extern void vma_set_pad_pages(struct vm_area_struct *vma,
|
|
unsigned long nr_pages);
|
|
|
|
extern unsigned long vma_pad_pages(struct vm_area_struct *vma);
|
|
|
|
extern void madvise_vma_pad_pages(struct vm_area_struct *vma,
|
|
unsigned long start, unsigned long end);
|
|
|
|
extern void show_map_pad_vma(struct vm_area_struct *vma,
|
|
struct seq_file *m, void *func, bool smaps);
|
|
|
|
extern void split_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *new,
|
|
unsigned long addr, int new_below);
|
|
|
|
extern bool is_mergable_pad_vma(struct vm_area_struct *vma,
|
|
unsigned long vm_flags);
|
|
|
|
extern unsigned long vma_data_pages(struct vm_area_struct *vma);
|
|
#else /* PAGE_SIZE != SZ_4K || !defined(CONFIG_64BIT) */
|
|
static inline void vma_set_pad_pages(struct vm_area_struct *vma,
|
|
unsigned long nr_pages)
|
|
{
|
|
}
|
|
|
|
static inline unsigned long vma_pad_pages(struct vm_area_struct *vma)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void madvise_vma_pad_pages(struct vm_area_struct *vma,
|
|
unsigned long start, unsigned long end)
|
|
{
|
|
}
|
|
|
|
static inline void show_map_pad_vma(struct vm_area_struct *vma,
|
|
struct seq_file *m, void *func, bool smaps)
|
|
{
|
|
}
|
|
|
|
static inline void split_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *new,
|
|
unsigned long addr, int new_below)
|
|
{
|
|
}
|
|
|
|
static inline bool is_mergable_pad_vma(struct vm_area_struct *vma,
|
|
unsigned long vm_flags)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
static inline unsigned long vma_data_pages(struct vm_area_struct *vma)
|
|
{
|
|
return vma_pages(vma);
|
|
}
|
|
#endif /* PAGE_SIZE == SZ_4K && defined(CONFIG_64BIT) */
|
|
#endif /* _LINUX_PAGE_SIZE_MIGRATION_H */
|