diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-09-18 14:50:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-09-18 14:50:48 -0400 |
commit | 3286be94808c403a5ca6bb2830d933439315cb99 (patch) | |
tree | 2f92c4403ae1f8c1601cf82b42e5005b0106058d | |
parent | 6ffa36a59a01691cc8823ef1113e328bb84c14de (diff) | |
parent | 080fe0b790ad438fc1b61621dac37c1964ce7f35 (diff) |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Thomas Gleixner:
"A couple of small fixes to x86 perf drivers:
- Measure L2 for HW_CACHE* events on AMD
- Fix the address filter handling in the intel/pt driver
- Handle the BTS disabling at the proper place"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/amd: Make HW_CACHE_REFERENCES and HW_CACHE_MISSES measure L2
perf/x86/intel/pt: Do validate the size of a kernel address filter
perf/x86/intel/pt: Fix kernel address filter's offset validation
perf/x86/intel/pt: Fix an off-by-one in address filter configuration
perf/x86/intel: Don't disable "intel_bts" around "intel" event batching
-rw-r--r-- | arch/x86/events/amd/core.c | 4 | ||||
-rw-r--r-- | arch/x86/events/intel/core.c | 15 | ||||
-rw-r--r-- | arch/x86/events/intel/pt.c | 18 | ||||
-rw-r--r-- | arch/x86/kvm/pmu_amd.c | 4 |
4 files changed, 26 insertions, 15 deletions
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index e07a22bb9308..f5f4b3fbbbc2 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c | |||
@@ -119,8 +119,8 @@ static const u64 amd_perfmon_event_map[PERF_COUNT_HW_MAX] = | |||
119 | { | 119 | { |
120 | [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, | 120 | [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, |
121 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, | 121 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, |
122 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0080, | 122 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0x077d, |
123 | [PERF_COUNT_HW_CACHE_MISSES] = 0x0081, | 123 | [PERF_COUNT_HW_CACHE_MISSES] = 0x077e, |
124 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, | 124 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, |
125 | [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, | 125 | [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, |
126 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00d0, /* "Decoder empty" event */ | 126 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00d0, /* "Decoder empty" event */ |
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 2cbde2f449aa..4c9a79b9cd69 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c | |||
@@ -1730,9 +1730,11 @@ static __initconst const u64 knl_hw_cache_extra_regs | |||
1730 | * disabled state if called consecutively. | 1730 | * disabled state if called consecutively. |
1731 | * | 1731 | * |
1732 | * During consecutive calls, the same disable value will be written to related | 1732 | * During consecutive calls, the same disable value will be written to related |
1733 | * registers, so the PMU state remains unchanged. hw.state in | 1733 | * registers, so the PMU state remains unchanged. |
1734 | * intel_bts_disable_local will remain PERF_HES_STOPPED too in consecutive | 1734 | * |
1735 | * calls. | 1735 | * intel_bts events don't coexist with intel PMU's BTS events because of |
1736 | * x86_add_exclusive(x86_lbr_exclusive_lbr); there's no need to keep them | ||
1737 | * disabled around intel PMU's event batching etc, only inside the PMI handler. | ||
1736 | */ | 1738 | */ |
1737 | static void __intel_pmu_disable_all(void) | 1739 | static void __intel_pmu_disable_all(void) |
1738 | { | 1740 | { |
@@ -1742,8 +1744,6 @@ static void __intel_pmu_disable_all(void) | |||
1742 | 1744 | ||
1743 | if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) | 1745 | if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) |
1744 | intel_pmu_disable_bts(); | 1746 | intel_pmu_disable_bts(); |
1745 | else | ||
1746 | intel_bts_disable_local(); | ||
1747 | 1747 | ||
1748 | intel_pmu_pebs_disable_all(); | 1748 | intel_pmu_pebs_disable_all(); |
1749 | } | 1749 | } |
@@ -1771,8 +1771,7 @@ static void __intel_pmu_enable_all(int added, bool pmi) | |||
1771 | return; | 1771 | return; |
1772 | 1772 | ||
1773 | intel_pmu_enable_bts(event->hw.config); | 1773 | intel_pmu_enable_bts(event->hw.config); |
1774 | } else | 1774 | } |
1775 | intel_bts_enable_local(); | ||
1776 | } | 1775 | } |
1777 | 1776 | ||
1778 | static void intel_pmu_enable_all(int added) | 1777 | static void intel_pmu_enable_all(int added) |
@@ -2073,6 +2072,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
2073 | */ | 2072 | */ |
2074 | if (!x86_pmu.late_ack) | 2073 | if (!x86_pmu.late_ack) |
2075 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 2074 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
2075 | intel_bts_disable_local(); | ||
2076 | __intel_pmu_disable_all(); | 2076 | __intel_pmu_disable_all(); |
2077 | handled = intel_pmu_drain_bts_buffer(); | 2077 | handled = intel_pmu_drain_bts_buffer(); |
2078 | handled += intel_bts_interrupt(); | 2078 | handled += intel_bts_interrupt(); |
@@ -2172,6 +2172,7 @@ done: | |||
2172 | /* Only restore PMU state when it's active. See x86_pmu_disable(). */ | 2172 | /* Only restore PMU state when it's active. See x86_pmu_disable(). */ |
2173 | if (cpuc->enabled) | 2173 | if (cpuc->enabled) |
2174 | __intel_pmu_enable_all(0, true); | 2174 | __intel_pmu_enable_all(0, true); |
2175 | intel_bts_enable_local(); | ||
2175 | 2176 | ||
2176 | /* | 2177 | /* |
2177 | * Only unmask the NMI after the overflow counters | 2178 | * Only unmask the NMI after the overflow counters |
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 04bb5fb5a8d7..861a7d9cb60f 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c | |||
@@ -1074,6 +1074,11 @@ static void pt_addr_filters_fini(struct perf_event *event) | |||
1074 | event->hw.addr_filters = NULL; | 1074 | event->hw.addr_filters = NULL; |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | static inline bool valid_kernel_ip(unsigned long ip) | ||
1078 | { | ||
1079 | return virt_addr_valid(ip) && kernel_ip(ip); | ||
1080 | } | ||
1081 | |||
1077 | static int pt_event_addr_filters_validate(struct list_head *filters) | 1082 | static int pt_event_addr_filters_validate(struct list_head *filters) |
1078 | { | 1083 | { |
1079 | struct perf_addr_filter *filter; | 1084 | struct perf_addr_filter *filter; |
@@ -1081,11 +1086,16 @@ static int pt_event_addr_filters_validate(struct list_head *filters) | |||
1081 | 1086 | ||
1082 | list_for_each_entry(filter, filters, entry) { | 1087 | list_for_each_entry(filter, filters, entry) { |
1083 | /* PT doesn't support single address triggers */ | 1088 | /* PT doesn't support single address triggers */ |
1084 | if (!filter->range) | 1089 | if (!filter->range || !filter->size) |
1085 | return -EOPNOTSUPP; | 1090 | return -EOPNOTSUPP; |
1086 | 1091 | ||
1087 | if (!filter->inode && !kernel_ip(filter->offset)) | 1092 | if (!filter->inode) { |
1088 | return -EINVAL; | 1093 | if (!valid_kernel_ip(filter->offset)) |
1094 | return -EINVAL; | ||
1095 | |||
1096 | if (!valid_kernel_ip(filter->offset + filter->size)) | ||
1097 | return -EINVAL; | ||
1098 | } | ||
1089 | 1099 | ||
1090 | if (++range > pt_cap_get(PT_CAP_num_address_ranges)) | 1100 | if (++range > pt_cap_get(PT_CAP_num_address_ranges)) |
1091 | return -EOPNOTSUPP; | 1101 | return -EOPNOTSUPP; |
@@ -1111,7 +1121,7 @@ static void pt_event_addr_filters_sync(struct perf_event *event) | |||
1111 | } else { | 1121 | } else { |
1112 | /* apply the offset */ | 1122 | /* apply the offset */ |
1113 | msr_a = filter->offset + offs[range]; | 1123 | msr_a = filter->offset + offs[range]; |
1114 | msr_b = filter->size + msr_a; | 1124 | msr_b = filter->size + msr_a - 1; |
1115 | } | 1125 | } |
1116 | 1126 | ||
1117 | filters->filter[range].msr_a = msr_a; | 1127 | filters->filter[range].msr_a = msr_a; |
diff --git a/arch/x86/kvm/pmu_amd.c b/arch/x86/kvm/pmu_amd.c index 39b91127ef07..cd944435dfbd 100644 --- a/arch/x86/kvm/pmu_amd.c +++ b/arch/x86/kvm/pmu_amd.c | |||
@@ -23,8 +23,8 @@ | |||
23 | static struct kvm_event_hw_type_mapping amd_event_mapping[] = { | 23 | static struct kvm_event_hw_type_mapping amd_event_mapping[] = { |
24 | [0] = { 0x76, 0x00, PERF_COUNT_HW_CPU_CYCLES }, | 24 | [0] = { 0x76, 0x00, PERF_COUNT_HW_CPU_CYCLES }, |
25 | [1] = { 0xc0, 0x00, PERF_COUNT_HW_INSTRUCTIONS }, | 25 | [1] = { 0xc0, 0x00, PERF_COUNT_HW_INSTRUCTIONS }, |
26 | [2] = { 0x80, 0x00, PERF_COUNT_HW_CACHE_REFERENCES }, | 26 | [2] = { 0x7d, 0x07, PERF_COUNT_HW_CACHE_REFERENCES }, |
27 | [3] = { 0x81, 0x00, PERF_COUNT_HW_CACHE_MISSES }, | 27 | [3] = { 0x7e, 0x07, PERF_COUNT_HW_CACHE_MISSES }, |
28 | [4] = { 0xc2, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, | 28 | [4] = { 0xc2, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, |
29 | [5] = { 0xc3, 0x00, PERF_COUNT_HW_BRANCH_MISSES }, | 29 | [5] = { 0xc3, 0x00, PERF_COUNT_HW_BRANCH_MISSES }, |
30 | [6] = { 0xd0, 0x00, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, | 30 | [6] = { 0xd0, 0x00, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, |