Patch "perf/x86: Fix RDPMC vs. mm_struct tracking" has been added to the 4.12-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
perf/x86: Fix RDPMC vs. mm_struct tracking
to the 4.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
perf-x86-fix-rdpmc-vs.-mm_struct-tracking.patch
and it can be found in the queue-4.12 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
bfe334924ccd9f4a53f30240c03cf2f43f5b2df1Mon Sep 17 00:00:00 2001
From: Peter Zijlstra <[email protected]>
Date: Wed, 2 Aug 2017 19:39:30 +0200
Subject: perf/x86: Fix RDPMC vs. mm_struct tracking
From: Peter Zijlstra <[email protected]>
commit bfe334924ccd9f4a53f30240c03cf2f43f5b2df1 upstream.
Vince reported the following rdpmc() testcase failure:
Quoted 8 lines
Failing test case:
fd=perf_event_open(); addr=mmap(fd); exec() // without closing or unmapping the event fd=perf_event_open(); addr=mmap(fd); rdpmc() // GPFs due to rdpmc being disabled
The problem is of course that exec() plays tricks with what is current->mm, only destroying the old mappings after having installed the new mm.
Fix this confusion by passing along vma->vm_mm instead of relying on current->mm.
--- arch/x86/events/core.c | 16 +++++++--------- include/linux/perf_event.h | 4 ++-- kernel/events/core.c | 6 +++--- 3 files changed, 12 insertions(+), 14 deletions(-)
arch/x86/events/core.c +7 -9
@@ -2105,7 +2105,7 @@ static void refresh_pce(void *ignored)load_mm_cr4 (current->active_mm); } -static void x86_pmu_event_mapped (struct perf_event *event) +static void x86_pmu_event_mapped (struct perf_event *event,struct mm_struct *mm) {if (!(event->hw.flags &PERF_X86_EVENT_RDPMC_ALLOWED ))return ;
@@ -2120,22 +2120,20 @@ static void x86_pmu_event_mapped(struct* For now, this can't happen because all callers hold mmap_sem * for write. If this changes, we'll need a different solution. */ -lockdep_assert_held_exclusive (¤t->mm->mmap_sem); +lockdep_assert_held_exclusive (&mm->mmap_sem); -if (atomic_inc_return (¤t->mm->context.perf_rdpmc_allowed) ==1 ) -on_each_cpu_mask (mm_cpumask (current->mm), refresh_pce,NULL ,1 ); +if (atomic_inc_return (&mm->context.perf_rdpmc_allowed) ==1 ) +on_each_cpu_mask (mm_cpumask (mm), refresh_pce,NULL ,1 ); } -static void x86_pmu_event_unmapped (struct perf_event *event) +static void x86_pmu_event_unmapped (struct perf_event *event,struct mm_struct *mm) { -if (!current->mm) -return ;if (!(event->hw.flags &PERF_X86_EVENT_RDPMC_ALLOWED ))return ; -if (atomic_dec_and_test (¤t->mm->context.perf_rdpmc_allowed)) -on_each_cpu_mask (mm_cpumask (current->mm), refresh_pce,NULL ,1 ); +if (atomic_dec_and_test (&mm->context.perf_rdpmc_allowed)) +on_each_cpu_mask (mm_cpumask (mm), refresh_pce,NULL ,1 ); }static int x86_pmu_event_idx (struct perf_event *event)
include/linux/perf_event.h +2 -2
@@ -310,8 +310,8 @@ struct pmu {* Notification that the event was mapped or unmapped. Called * in the context of the mapping task. */ -void (*event_mapped) (struct perf_event *event);/*optional*/ -void (*event_unmapped) (struct perf_event *event);/*optional*/ +void (*event_mapped) (struct perf_event *event,struct mm_struct *mm);/* optional */ +void (*event_unmapped) (struct perf_event *event,struct mm_struct *mm);/* optional */ /* * Flags for ->add()/->del()/ ->start()/->stop(). There are
kernel/events/core.c +3 -3
@@ -5084,7 +5084,7 @@ static void perf_mmap_open(struct vm_areatomic_inc (&event->rb->aux_mmap_count);if (event->pmu->event_mapped) - event->pmu->event_mapped (event); + event->pmu->event_mapped (event, vma->vm_mm); }static void perf_pmu_output_stop (struct perf_event *event);
@@ -5107,7 +5107,7 @@ static void perf_mmap_close(struct vm_arunsigned long size =perf_data_size (rb);if (event->pmu->event_unmapped) - event->pmu->event_unmapped (event); + event->pmu->event_unmapped (event, vma->vm_mm);/* * rb->aux_mmap_count will always drop before rb->mmap_count and
@@ -5405,7 +5405,7 @@ aux_unlock: vma->vm_ops = &perf_mmap_vmops;if (event->pmu->event_mapped) - event->pmu->event_mapped (event); + event->pmu->event_mapped (event, vma->vm_mm);return ret; }
Patches currently in stable-queue which might be from [email protected] are
queue-4.12/x86-asm-64-clear-ac-on-nmi-entries.patch queue-4.12/kernel-watchdog-prevent-false-positives-with-turbo-modes.patch queue-4.12/perf-x86-fix-rdpmc-vs.-mm_struct-tracking.patch