From: Will Deacon will.deacon@arm.com
mainline inclusion from mainline-v5.1-rc3 commit 14ae42a6f0b13130a97d94d23481128961de5d38 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4A1XO CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
------------------------------------------------------------------------
Since commit 5768402fd9c6 ("perf/ring_buffer: Use high order allocations for AUX buffers optimistically"), the perf core tends to back aux buffer allocations with high-order pages with the order encoded in the PagePrivate data. The Arm SPE driver explicitly rejects such pages, causing the perf tool to fail with:
| failed to mmap with 12 (Cannot allocate memory)
In actual fact, we can simply treat these pages just like any other since the perf core takes care to populate the page array appropriately. In theory we could try to map with PMDs where possible, but for now, let's just get things working again.
Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Fixes: 5768402fd9c6 ("perf/ring_buffer: Use high order allocations for AUX buffers optimistically") Reported-by: Hanjun Guo guohanjun@huawei.com Tested-by: Hanjun Guo guohanjun@huawei.com Tested-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Qi Liu liuqi115@huawei.com Reviewed-by: Yang Jihong yangjihong1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/perf/arm_spe_pmu.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c index a11951b083307..4fb65c61c8eab 100644 --- a/drivers/perf/arm_spe_pmu.c +++ b/drivers/perf/arm_spe_pmu.c @@ -856,16 +856,8 @@ static void *arm_spe_pmu_setup_aux(struct perf_event *event, void **pages, if (!pglist) goto out_free_buf;
- for (i = 0; i < nr_pages; ++i) { - struct page *page = virt_to_page(pages[i]); - - if (PagePrivate(page)) { - pr_warn("unexpected high-order page for auxbuf!"); - goto out_free_pglist; - } - + for (i = 0; i < nr_pages; ++i) pglist[i] = virt_to_page(pages[i]); - }
buf->base = vmap(pglist, nr_pages, VM_MAP, PAGE_KERNEL); if (!buf->base)