diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2014-05-19 15:13:47 -0400 |
---|---|---|
committer | Jiri Olsa <jolsa@kernel.org> | 2014-06-09 06:21:04 -0400 |
commit | f972eb63b1003fae68d7b7e9b674d4ba5db681c2 (patch) | |
tree | 55e61b866ebfaeefd44ac32bb3e855604f538048 /kernel | |
parent | e646fe730a324098a718f1c9b2f349efb99d5457 (diff) |
perf: Pass protection and flags bits through mmap2 interface
The mmap2 interface was missing the protection and flags bits needed to
accurately determine if a mmap memory area was shared or private and
if it was readable or not.
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
[tweaked patch to compile and wrote changelog]
Signed-off-by: Don Zickus <dzickus@redhat.com>
Link: http://lkml.kernel.org/r/1400526833-141779-2-git-send-email-dzickus@redhat.com
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/events/core.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 7da5e561e89a..eea1955c7868 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/mm_types.h> | 40 | #include <linux/mm_types.h> |
41 | #include <linux/cgroup.h> | 41 | #include <linux/cgroup.h> |
42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
43 | #include <linux/mman.h> | ||
43 | 44 | ||
44 | #include "internal.h" | 45 | #include "internal.h" |
45 | 46 | ||
@@ -5127,6 +5128,7 @@ struct perf_mmap_event { | |||
5127 | int maj, min; | 5128 | int maj, min; |
5128 | u64 ino; | 5129 | u64 ino; |
5129 | u64 ino_generation; | 5130 | u64 ino_generation; |
5131 | u32 prot, flags; | ||
5130 | 5132 | ||
5131 | struct { | 5133 | struct { |
5132 | struct perf_event_header header; | 5134 | struct perf_event_header header; |
@@ -5168,6 +5170,8 @@ static void perf_event_mmap_output(struct perf_event *event, | |||
5168 | mmap_event->event_id.header.size += sizeof(mmap_event->min); | 5170 | mmap_event->event_id.header.size += sizeof(mmap_event->min); |
5169 | mmap_event->event_id.header.size += sizeof(mmap_event->ino); | 5171 | mmap_event->event_id.header.size += sizeof(mmap_event->ino); |
5170 | mmap_event->event_id.header.size += sizeof(mmap_event->ino_generation); | 5172 | mmap_event->event_id.header.size += sizeof(mmap_event->ino_generation); |
5173 | mmap_event->event_id.header.size += sizeof(mmap_event->prot); | ||
5174 | mmap_event->event_id.header.size += sizeof(mmap_event->flags); | ||
5171 | } | 5175 | } |
5172 | 5176 | ||
5173 | perf_event_header__init_id(&mmap_event->event_id.header, &sample, event); | 5177 | perf_event_header__init_id(&mmap_event->event_id.header, &sample, event); |
@@ -5186,6 +5190,8 @@ static void perf_event_mmap_output(struct perf_event *event, | |||
5186 | perf_output_put(&handle, mmap_event->min); | 5190 | perf_output_put(&handle, mmap_event->min); |
5187 | perf_output_put(&handle, mmap_event->ino); | 5191 | perf_output_put(&handle, mmap_event->ino); |
5188 | perf_output_put(&handle, mmap_event->ino_generation); | 5192 | perf_output_put(&handle, mmap_event->ino_generation); |
5193 | perf_output_put(&handle, mmap_event->prot); | ||
5194 | perf_output_put(&handle, mmap_event->flags); | ||
5189 | } | 5195 | } |
5190 | 5196 | ||
5191 | __output_copy(&handle, mmap_event->file_name, | 5197 | __output_copy(&handle, mmap_event->file_name, |
@@ -5204,6 +5210,7 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | |||
5204 | struct file *file = vma->vm_file; | 5210 | struct file *file = vma->vm_file; |
5205 | int maj = 0, min = 0; | 5211 | int maj = 0, min = 0; |
5206 | u64 ino = 0, gen = 0; | 5212 | u64 ino = 0, gen = 0; |
5213 | u32 prot = 0, flags = 0; | ||
5207 | unsigned int size; | 5214 | unsigned int size; |
5208 | char tmp[16]; | 5215 | char tmp[16]; |
5209 | char *buf = NULL; | 5216 | char *buf = NULL; |
@@ -5234,6 +5241,28 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | |||
5234 | gen = inode->i_generation; | 5241 | gen = inode->i_generation; |
5235 | maj = MAJOR(dev); | 5242 | maj = MAJOR(dev); |
5236 | min = MINOR(dev); | 5243 | min = MINOR(dev); |
5244 | |||
5245 | if (vma->vm_flags & VM_READ) | ||
5246 | prot |= PROT_READ; | ||
5247 | if (vma->vm_flags & VM_WRITE) | ||
5248 | prot |= PROT_WRITE; | ||
5249 | if (vma->vm_flags & VM_EXEC) | ||
5250 | prot |= PROT_EXEC; | ||
5251 | |||
5252 | if (vma->vm_flags & VM_MAYSHARE) | ||
5253 | flags = MAP_SHARED; | ||
5254 | else | ||
5255 | flags = MAP_PRIVATE; | ||
5256 | |||
5257 | if (vma->vm_flags & VM_DENYWRITE) | ||
5258 | flags |= MAP_DENYWRITE; | ||
5259 | if (vma->vm_flags & VM_MAYEXEC) | ||
5260 | flags |= MAP_EXECUTABLE; | ||
5261 | if (vma->vm_flags & VM_LOCKED) | ||
5262 | flags |= MAP_LOCKED; | ||
5263 | if (vma->vm_flags & VM_HUGETLB) | ||
5264 | flags |= MAP_HUGETLB; | ||
5265 | |||
5237 | goto got_name; | 5266 | goto got_name; |
5238 | } else { | 5267 | } else { |
5239 | name = (char *)arch_vma_name(vma); | 5268 | name = (char *)arch_vma_name(vma); |
@@ -5274,6 +5303,8 @@ got_name: | |||
5274 | mmap_event->min = min; | 5303 | mmap_event->min = min; |
5275 | mmap_event->ino = ino; | 5304 | mmap_event->ino = ino; |
5276 | mmap_event->ino_generation = gen; | 5305 | mmap_event->ino_generation = gen; |
5306 | mmap_event->prot = prot; | ||
5307 | mmap_event->flags = flags; | ||
5277 | 5308 | ||
5278 | if (!(vma->vm_flags & VM_EXEC)) | 5309 | if (!(vma->vm_flags & VM_EXEC)) |
5279 | mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA; | 5310 | mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA; |
@@ -5314,6 +5345,8 @@ void perf_event_mmap(struct vm_area_struct *vma) | |||
5314 | /* .min (attr_mmap2 only) */ | 5345 | /* .min (attr_mmap2 only) */ |
5315 | /* .ino (attr_mmap2 only) */ | 5346 | /* .ino (attr_mmap2 only) */ |
5316 | /* .ino_generation (attr_mmap2 only) */ | 5347 | /* .ino_generation (attr_mmap2 only) */ |
5348 | /* .prot (attr_mmap2 only) */ | ||
5349 | /* .flags (attr_mmap2 only) */ | ||
5317 | }; | 5350 | }; |
5318 | 5351 | ||
5319 | perf_event_mmap_event(&mmap_event); | 5352 | perf_event_mmap_event(&mmap_event); |