diff options
Diffstat (limited to 'kernel/events/core.c')
-rw-r--r-- | kernel/events/core.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 5fa58e4cffac..a33d9a2bcbd7 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 | ||
@@ -5128,6 +5129,7 @@ struct perf_mmap_event { | |||
5128 | int maj, min; | 5129 | int maj, min; |
5129 | u64 ino; | 5130 | u64 ino; |
5130 | u64 ino_generation; | 5131 | u64 ino_generation; |
5132 | u32 prot, flags; | ||
5131 | 5133 | ||
5132 | struct { | 5134 | struct { |
5133 | struct perf_event_header header; | 5135 | struct perf_event_header header; |
@@ -5169,6 +5171,8 @@ static void perf_event_mmap_output(struct perf_event *event, | |||
5169 | mmap_event->event_id.header.size += sizeof(mmap_event->min); | 5171 | mmap_event->event_id.header.size += sizeof(mmap_event->min); |
5170 | mmap_event->event_id.header.size += sizeof(mmap_event->ino); | 5172 | mmap_event->event_id.header.size += sizeof(mmap_event->ino); |
5171 | mmap_event->event_id.header.size += sizeof(mmap_event->ino_generation); | 5173 | mmap_event->event_id.header.size += sizeof(mmap_event->ino_generation); |
5174 | mmap_event->event_id.header.size += sizeof(mmap_event->prot); | ||
5175 | mmap_event->event_id.header.size += sizeof(mmap_event->flags); | ||
5172 | } | 5176 | } |
5173 | 5177 | ||
5174 | perf_event_header__init_id(&mmap_event->event_id.header, &sample, event); | 5178 | perf_event_header__init_id(&mmap_event->event_id.header, &sample, event); |
@@ -5187,6 +5191,8 @@ static void perf_event_mmap_output(struct perf_event *event, | |||
5187 | perf_output_put(&handle, mmap_event->min); | 5191 | perf_output_put(&handle, mmap_event->min); |
5188 | perf_output_put(&handle, mmap_event->ino); | 5192 | perf_output_put(&handle, mmap_event->ino); |
5189 | perf_output_put(&handle, mmap_event->ino_generation); | 5193 | perf_output_put(&handle, mmap_event->ino_generation); |
5194 | perf_output_put(&handle, mmap_event->prot); | ||
5195 | perf_output_put(&handle, mmap_event->flags); | ||
5190 | } | 5196 | } |
5191 | 5197 | ||
5192 | __output_copy(&handle, mmap_event->file_name, | 5198 | __output_copy(&handle, mmap_event->file_name, |
@@ -5205,6 +5211,7 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | |||
5205 | struct file *file = vma->vm_file; | 5211 | struct file *file = vma->vm_file; |
5206 | int maj = 0, min = 0; | 5212 | int maj = 0, min = 0; |
5207 | u64 ino = 0, gen = 0; | 5213 | u64 ino = 0, gen = 0; |
5214 | u32 prot = 0, flags = 0; | ||
5208 | unsigned int size; | 5215 | unsigned int size; |
5209 | char tmp[16]; | 5216 | char tmp[16]; |
5210 | char *buf = NULL; | 5217 | char *buf = NULL; |
@@ -5235,6 +5242,28 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | |||
5235 | gen = inode->i_generation; | 5242 | gen = inode->i_generation; |
5236 | maj = MAJOR(dev); | 5243 | maj = MAJOR(dev); |
5237 | min = MINOR(dev); | 5244 | min = MINOR(dev); |
5245 | |||
5246 | if (vma->vm_flags & VM_READ) | ||
5247 | prot |= PROT_READ; | ||
5248 | if (vma->vm_flags & VM_WRITE) | ||
5249 | prot |= PROT_WRITE; | ||
5250 | if (vma->vm_flags & VM_EXEC) | ||
5251 | prot |= PROT_EXEC; | ||
5252 | |||
5253 | if (vma->vm_flags & VM_MAYSHARE) | ||
5254 | flags = MAP_SHARED; | ||
5255 | else | ||
5256 | flags = MAP_PRIVATE; | ||
5257 | |||
5258 | if (vma->vm_flags & VM_DENYWRITE) | ||
5259 | flags |= MAP_DENYWRITE; | ||
5260 | if (vma->vm_flags & VM_MAYEXEC) | ||
5261 | flags |= MAP_EXECUTABLE; | ||
5262 | if (vma->vm_flags & VM_LOCKED) | ||
5263 | flags |= MAP_LOCKED; | ||
5264 | if (vma->vm_flags & VM_HUGETLB) | ||
5265 | flags |= MAP_HUGETLB; | ||
5266 | |||
5238 | goto got_name; | 5267 | goto got_name; |
5239 | } else { | 5268 | } else { |
5240 | name = (char *)arch_vma_name(vma); | 5269 | name = (char *)arch_vma_name(vma); |
@@ -5275,6 +5304,8 @@ got_name: | |||
5275 | mmap_event->min = min; | 5304 | mmap_event->min = min; |
5276 | mmap_event->ino = ino; | 5305 | mmap_event->ino = ino; |
5277 | mmap_event->ino_generation = gen; | 5306 | mmap_event->ino_generation = gen; |
5307 | mmap_event->prot = prot; | ||
5308 | mmap_event->flags = flags; | ||
5278 | 5309 | ||
5279 | if (!(vma->vm_flags & VM_EXEC)) | 5310 | if (!(vma->vm_flags & VM_EXEC)) |
5280 | mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA; | 5311 | mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA; |
@@ -5315,6 +5346,8 @@ void perf_event_mmap(struct vm_area_struct *vma) | |||
5315 | /* .min (attr_mmap2 only) */ | 5346 | /* .min (attr_mmap2 only) */ |
5316 | /* .ino (attr_mmap2 only) */ | 5347 | /* .ino (attr_mmap2 only) */ |
5317 | /* .ino_generation (attr_mmap2 only) */ | 5348 | /* .ino_generation (attr_mmap2 only) */ |
5349 | /* .prot (attr_mmap2 only) */ | ||
5350 | /* .flags (attr_mmap2 only) */ | ||
5318 | }; | 5351 | }; |
5319 | 5352 | ||
5320 | perf_event_mmap_event(&mmap_event); | 5353 | perf_event_mmap_event(&mmap_event); |
@@ -6897,10 +6930,6 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, | |||
6897 | if (ret) | 6930 | if (ret) |
6898 | return -EFAULT; | 6931 | return -EFAULT; |
6899 | 6932 | ||
6900 | /* disabled for now */ | ||
6901 | if (attr->mmap2) | ||
6902 | return -EINVAL; | ||
6903 | |||
6904 | if (attr->__reserved_1) | 6933 | if (attr->__reserved_1) |
6905 | return -EINVAL; | 6934 | return -EINVAL; |
6906 | 6935 | ||