47 lines
1.7 KiB
Diff
47 lines
1.7 KiB
Diff
|
From: Pekka Enberg <penberg@kernel.org>
|
||
|
Date: Mon, 8 Nov 2010 19:29:07 +0000 (+0200)
|
||
|
Subject: perf_events: Fix perf_counter_mmap() hook in mprotect()
|
||
|
X-Git-Tag: v2.6.37-rc2~72
|
||
|
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=63bfd7384b119409685a17d5c58f0b56e5dc03da
|
||
|
|
||
|
perf_events: Fix perf_counter_mmap() hook in mprotect()
|
||
|
|
||
|
As pointed out by Linus, commit dab5855 ("perf_counter: Add mmap event hooks to
|
||
|
mprotect()") is fundamentally wrong as mprotect_fixup() can free 'vma' due to
|
||
|
merging. Fix the problem by moving perf_event_mmap() hook to
|
||
|
mprotect_fixup().
|
||
|
|
||
|
Note: there's another successful return path from mprotect_fixup() if old
|
||
|
flags equal to new flags. We don't, however, need to call
|
||
|
perf_event_mmap() there because 'perf' already knows the VMA is
|
||
|
executable.
|
||
|
|
||
|
Reported-by: Dave Jones <davej@redhat.com>
|
||
|
Analyzed-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||
|
Cc: Ingo Molnar <mingo@elte.hu>
|
||
|
Reviewed-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
||
|
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||
|
---
|
||
|
|
||
|
diff --git a/mm/mprotect.c b/mm/mprotect.c
|
||
|
index 2d1bf7c..4c51338 100644
|
||
|
--- a/mm/mprotect.c
|
||
|
+++ b/mm/mprotect.c
|
||
|
@@ -211,6 +211,7 @@ success:
|
||
|
mmu_notifier_invalidate_range_end(mm, start, end);
|
||
|
vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
|
||
|
vm_stat_account(mm, newflags, vma->vm_file, nrpages);
|
||
|
+ perf_event_mmap(vma);
|
||
|
return 0;
|
||
|
|
||
|
fail:
|
||
|
@@ -299,7 +300,6 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
|
||
|
error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
|
||
|
if (error)
|
||
|
goto out;
|
||
|
- perf_event_mmap(vma);
|
||
|
nstart = tmp;
|
||
|
|
||
|
if (nstart < prev->vm_end)
|