aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2014-05-19 15:13:47 -0400
committerJiri Olsa <jolsa@kernel.org>2014-06-09 06:21:04 -0400
commitf972eb63b1003fae68d7b7e9b674d4ba5db681c2 (patch)
tree55e61b866ebfaeefd44ac32bb3e855604f538048 /kernel
parente646fe730a324098a718f1c9b2f349efb99d5457 (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.c33
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);