diff options
author | Ingo Molnar <mingo@kernel.org> | 2016-09-23 07:20:33 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-09-23 07:20:33 +0200 |
commit | 739f1bcd045f473d79358aac94439722d41a2650 (patch) | |
tree | a8cfdff0a9b798acb618ba2b79861af723b217db /arch/x86/events/intel/pt.c | |
parent | 89f1c2c59c4aef8e26edbc7db5175e6ffb0e9ec7 (diff) | |
parent | 3bf6215a1b30db7df6083c708caab3fe1a8e8abe (diff) | |
download | lwn-739f1bcd045f473d79358aac94439722d41a2650.tar.gz lwn-739f1bcd045f473d79358aac94439722d41a2650.zip |
Merge branch 'perf/urgent' into perf/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/events/intel/pt.c')
-rw-r--r-- | arch/x86/events/intel/pt.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 18d18fdda93d..c5047b8f777b 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -1096,6 +1096,11 @@ static void pt_addr_filters_fini(struct perf_event *event) event->hw.addr_filters = NULL; } +static inline bool valid_kernel_ip(unsigned long ip) +{ + return virt_addr_valid(ip) && kernel_ip(ip); +} + static int pt_event_addr_filters_validate(struct list_head *filters) { struct perf_addr_filter *filter; @@ -1103,11 +1108,16 @@ static int pt_event_addr_filters_validate(struct list_head *filters) list_for_each_entry(filter, filters, entry) { /* PT doesn't support single address triggers */ - if (!filter->range) + if (!filter->range || !filter->size) return -EOPNOTSUPP; - if (!filter->inode && !kernel_ip(filter->offset)) - return -EINVAL; + if (!filter->inode) { + if (!valid_kernel_ip(filter->offset)) + return -EINVAL; + + if (!valid_kernel_ip(filter->offset + filter->size)) + return -EINVAL; + } if (++range > pt_cap_get(PT_CAP_num_address_ranges)) return -EOPNOTSUPP; @@ -1133,7 +1143,7 @@ static void pt_event_addr_filters_sync(struct perf_event *event) } else { /* apply the offset */ msr_a = filter->offset + offs[range]; - msr_b = filter->size + msr_a; + msr_b = filter->size + msr_a - 1; } filters->filter[range].msr_a = msr_a; |