From 13ba0aec9c83e0a060ca976eace71414d4b1ca8d Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Fri, 4 Oct 2024 16:00:19 -0700 Subject: [PATCH] ANDROID: 16K: Fixup perf_mmap check for metadata page perf_mmap() expects a power of 2 number of pages plus 1 additional page. In the emulated __PAGE_SIZE case, the one extra page is actually (__PAGE_SIZE / PAGE_SIZE) number of 4KiB pages in the kernel. See MMAP layout in perf_event_open(): The mmap size should be 1+2^n pages, where the first page is a metadata page (struct perf_event_mmap_page) that contains various bits of information such as where the ring-buffer head is. [1] Also update perf_event_mmap_kb's default value to reflect this; i.e 512KiB + sizeof 1 page in KiB (__PAGE_SIZE/1024) [1] https://man7.org/linux/man-pages/man2/perf_event_open.2.html Bug: 383389337 Bug: 366098040 Test: atest vts_ltp_test_x86_64 Change-Id: I475e3c9ed896d8e3735681b1143e31c62ed20359 Signed-off-by: Kalesh Singh --- kernel/events/core.c | 5 +++-- mm/page_size_compat.c | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 01cc0f41b411..9bdc322273fd 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -6628,7 +6629,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) vma_size = vma->vm_end - vma->vm_start; if (vma->vm_pgoff == 0) { - nr_pages = (vma_size / PAGE_SIZE) - 1; + nr_pages = (vma_size / PAGE_SIZE) - (__PAGE_SIZE / PAGE_SIZE); } else { /* * AUX area mapping: if rb->aux_nr_pages != 0, it's already @@ -6699,7 +6700,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) if (nr_pages != 0 && !is_power_of_2(nr_pages)) return -EINVAL; - if (vma_size != PAGE_SIZE * (1 + nr_pages)) + if (vma_size != PAGE_SIZE * ((__PAGE_SIZE / PAGE_SIZE) + nr_pages)) return -EINVAL; WARN_ON_ONCE(event->ctx->parent_ctx); diff --git a/mm/page_size_compat.c b/mm/page_size_compat.c index 3b2b9f52a42e..716f59f25518 100644 --- a/mm/page_size_compat.c +++ b/mm/page_size_compat.c @@ -13,6 +13,7 @@ #include #include #include +#include #define MIN_PAGE_SHIFT_COMPAT (PAGE_SHIFT + 1) #define MAX_PAGE_SHIFT_COMPAT 16 /* Max of 64KB */ @@ -315,3 +316,15 @@ free_magic: return error; } + +static int __init init_sysctl_perf_event_mlock(void) +{ + if (!static_branch_unlikely(&page_shift_compat_enabled)) + return 0; + + /* Minimum for 512 kiB + 1 user control page */ + sysctl_perf_event_mlock = 512 + (__PAGE_SIZE / 1024); /* 'free' kiB per user */ + + return 0; +} +core_initcall(init_sysctl_perf_event_mlock);