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>
This commit is contained in:
parent
e646fe730a
commit
f972eb63b1
2 changed files with 34 additions and 0 deletions
|
@ -705,6 +705,7 @@ enum perf_event_type {
|
||||||
* u32 min;
|
* u32 min;
|
||||||
* u64 ino;
|
* u64 ino;
|
||||||
* u64 ino_generation;
|
* u64 ino_generation;
|
||||||
|
* u32 prot, flags;
|
||||||
* char filename[];
|
* char filename[];
|
||||||
* struct sample_id sample_id;
|
* struct sample_id sample_id;
|
||||||
* };
|
* };
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <linux/mm_types.h>
|
#include <linux/mm_types.h>
|
||||||
#include <linux/cgroup.h>
|
#include <linux/cgroup.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/mman.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -5127,6 +5128,7 @@ struct perf_mmap_event {
|
||||||
int maj, min;
|
int maj, min;
|
||||||
u64 ino;
|
u64 ino;
|
||||||
u64 ino_generation;
|
u64 ino_generation;
|
||||||
|
u32 prot, flags;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct perf_event_header header;
|
struct perf_event_header header;
|
||||||
|
@ -5168,6 +5170,8 @@ static void perf_event_mmap_output(struct perf_event *event,
|
||||||
mmap_event->event_id.header.size += sizeof(mmap_event->min);
|
mmap_event->event_id.header.size += sizeof(mmap_event->min);
|
||||||
mmap_event->event_id.header.size += sizeof(mmap_event->ino);
|
mmap_event->event_id.header.size += sizeof(mmap_event->ino);
|
||||||
mmap_event->event_id.header.size += sizeof(mmap_event->ino_generation);
|
mmap_event->event_id.header.size += sizeof(mmap_event->ino_generation);
|
||||||
|
mmap_event->event_id.header.size += sizeof(mmap_event->prot);
|
||||||
|
mmap_event->event_id.header.size += sizeof(mmap_event->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
perf_event_header__init_id(&mmap_event->event_id.header, &sample, event);
|
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,
|
||||||
perf_output_put(&handle, mmap_event->min);
|
perf_output_put(&handle, mmap_event->min);
|
||||||
perf_output_put(&handle, mmap_event->ino);
|
perf_output_put(&handle, mmap_event->ino);
|
||||||
perf_output_put(&handle, mmap_event->ino_generation);
|
perf_output_put(&handle, mmap_event->ino_generation);
|
||||||
|
perf_output_put(&handle, mmap_event->prot);
|
||||||
|
perf_output_put(&handle, mmap_event->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
__output_copy(&handle, mmap_event->file_name,
|
__output_copy(&handle, mmap_event->file_name,
|
||||||
|
@ -5204,6 +5210,7 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
|
||||||
struct file *file = vma->vm_file;
|
struct file *file = vma->vm_file;
|
||||||
int maj = 0, min = 0;
|
int maj = 0, min = 0;
|
||||||
u64 ino = 0, gen = 0;
|
u64 ino = 0, gen = 0;
|
||||||
|
u32 prot = 0, flags = 0;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
char tmp[16];
|
char tmp[16];
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
@ -5234,6 +5241,28 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
|
||||||
gen = inode->i_generation;
|
gen = inode->i_generation;
|
||||||
maj = MAJOR(dev);
|
maj = MAJOR(dev);
|
||||||
min = MINOR(dev);
|
min = MINOR(dev);
|
||||||
|
|
||||||
|
if (vma->vm_flags & VM_READ)
|
||||||
|
prot |= PROT_READ;
|
||||||
|
if (vma->vm_flags & VM_WRITE)
|
||||||
|
prot |= PROT_WRITE;
|
||||||
|
if (vma->vm_flags & VM_EXEC)
|
||||||
|
prot |= PROT_EXEC;
|
||||||
|
|
||||||
|
if (vma->vm_flags & VM_MAYSHARE)
|
||||||
|
flags = MAP_SHARED;
|
||||||
|
else
|
||||||
|
flags = MAP_PRIVATE;
|
||||||
|
|
||||||
|
if (vma->vm_flags & VM_DENYWRITE)
|
||||||
|
flags |= MAP_DENYWRITE;
|
||||||
|
if (vma->vm_flags & VM_MAYEXEC)
|
||||||
|
flags |= MAP_EXECUTABLE;
|
||||||
|
if (vma->vm_flags & VM_LOCKED)
|
||||||
|
flags |= MAP_LOCKED;
|
||||||
|
if (vma->vm_flags & VM_HUGETLB)
|
||||||
|
flags |= MAP_HUGETLB;
|
||||||
|
|
||||||
goto got_name;
|
goto got_name;
|
||||||
} else {
|
} else {
|
||||||
name = (char *)arch_vma_name(vma);
|
name = (char *)arch_vma_name(vma);
|
||||||
|
@ -5274,6 +5303,8 @@ got_name:
|
||||||
mmap_event->min = min;
|
mmap_event->min = min;
|
||||||
mmap_event->ino = ino;
|
mmap_event->ino = ino;
|
||||||
mmap_event->ino_generation = gen;
|
mmap_event->ino_generation = gen;
|
||||||
|
mmap_event->prot = prot;
|
||||||
|
mmap_event->flags = flags;
|
||||||
|
|
||||||
if (!(vma->vm_flags & VM_EXEC))
|
if (!(vma->vm_flags & VM_EXEC))
|
||||||
mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA;
|
mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA;
|
||||||
|
@ -5314,6 +5345,8 @@ void perf_event_mmap(struct vm_area_struct *vma)
|
||||||
/* .min (attr_mmap2 only) */
|
/* .min (attr_mmap2 only) */
|
||||||
/* .ino (attr_mmap2 only) */
|
/* .ino (attr_mmap2 only) */
|
||||||
/* .ino_generation (attr_mmap2 only) */
|
/* .ino_generation (attr_mmap2 only) */
|
||||||
|
/* .prot (attr_mmap2 only) */
|
||||||
|
/* .flags (attr_mmap2 only) */
|
||||||
};
|
};
|
||||||
|
|
||||||
perf_event_mmap_event(&mmap_event);
|
perf_event_mmap_event(&mmap_event);
|
||||||
|
|
Loading…
Reference in a new issue