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 | |
| 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>
| -rw-r--r-- | include/uapi/linux/perf_event.h | 1 | ||||
| -rw-r--r-- | kernel/events/core.c | 33 |
2 files changed, 34 insertions, 0 deletions
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index 5312fae47218..9269de254874 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h | |||
| @@ -705,6 +705,7 @@ enum perf_event_type { | |||
| 705 | * u32 min; | 705 | * u32 min; |
| 706 | * u64 ino; | 706 | * u64 ino; |
| 707 | * u64 ino_generation; | 707 | * u64 ino_generation; |
| 708 | * u32 prot, flags; | ||
| 708 | * char filename[]; | 709 | * char filename[]; |
| 709 | * struct sample_id sample_id; | 710 | * struct sample_id sample_id; |
| 710 | * }; | 711 | * }; |
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); |
