diff options
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 23 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_lbr.c | 12 |
3 files changed, 27 insertions, 10 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 7250c0281f9d..329f0356ad4a 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
@@ -870,7 +870,7 @@ void intel_pmu_lbr_enable(struct perf_event *event); | |||
870 | 870 | ||
871 | void intel_pmu_lbr_disable(struct perf_event *event); | 871 | void intel_pmu_lbr_disable(struct perf_event *event); |
872 | 872 | ||
873 | void intel_pmu_lbr_enable_all(void); | 873 | void intel_pmu_lbr_enable_all(bool pmi); |
874 | 874 | ||
875 | void intel_pmu_lbr_disable_all(void); | 875 | void intel_pmu_lbr_disable_all(void); |
876 | 876 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 59994602bb94..9da2400c2ec3 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -1244,7 +1244,10 @@ static __initconst const u64 slm_hw_cache_event_ids | |||
1244 | }, | 1244 | }, |
1245 | }; | 1245 | }; |
1246 | 1246 | ||
1247 | static void intel_pmu_disable_all(void) | 1247 | /* |
1248 | * Use from PMIs where the LBRs are already disabled. | ||
1249 | */ | ||
1250 | static void __intel_pmu_disable_all(void) | ||
1248 | { | 1251 | { |
1249 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 1252 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
1250 | 1253 | ||
@@ -1256,15 +1259,20 @@ static void intel_pmu_disable_all(void) | |||
1256 | intel_bts_disable_local(); | 1259 | intel_bts_disable_local(); |
1257 | 1260 | ||
1258 | intel_pmu_pebs_disable_all(); | 1261 | intel_pmu_pebs_disable_all(); |
1262 | } | ||
1263 | |||
1264 | static void intel_pmu_disable_all(void) | ||
1265 | { | ||
1266 | __intel_pmu_disable_all(); | ||
1259 | intel_pmu_lbr_disable_all(); | 1267 | intel_pmu_lbr_disable_all(); |
1260 | } | 1268 | } |
1261 | 1269 | ||
1262 | static void intel_pmu_enable_all(int added) | 1270 | static void __intel_pmu_enable_all(int added, bool pmi) |
1263 | { | 1271 | { |
1264 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 1272 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
1265 | 1273 | ||
1266 | intel_pmu_pebs_enable_all(); | 1274 | intel_pmu_pebs_enable_all(); |
1267 | intel_pmu_lbr_enable_all(); | 1275 | intel_pmu_lbr_enable_all(pmi); |
1268 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, | 1276 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, |
1269 | x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask); | 1277 | x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask); |
1270 | 1278 | ||
@@ -1280,6 +1288,11 @@ static void intel_pmu_enable_all(int added) | |||
1280 | intel_bts_enable_local(); | 1288 | intel_bts_enable_local(); |
1281 | } | 1289 | } |
1282 | 1290 | ||
1291 | static void intel_pmu_enable_all(int added) | ||
1292 | { | ||
1293 | __intel_pmu_enable_all(added, false); | ||
1294 | } | ||
1295 | |||
1283 | /* | 1296 | /* |
1284 | * Workaround for: | 1297 | * Workaround for: |
1285 | * Intel Errata AAK100 (model 26) | 1298 | * Intel Errata AAK100 (model 26) |
@@ -1573,7 +1586,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
1573 | */ | 1586 | */ |
1574 | if (!x86_pmu.late_ack) | 1587 | if (!x86_pmu.late_ack) |
1575 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 1588 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
1576 | intel_pmu_disable_all(); | 1589 | __intel_pmu_disable_all(); |
1577 | handled = intel_pmu_drain_bts_buffer(); | 1590 | handled = intel_pmu_drain_bts_buffer(); |
1578 | handled += intel_bts_interrupt(); | 1591 | handled += intel_bts_interrupt(); |
1579 | status = intel_pmu_get_status(); | 1592 | status = intel_pmu_get_status(); |
@@ -1658,7 +1671,7 @@ again: | |||
1658 | goto again; | 1671 | goto again; |
1659 | 1672 | ||
1660 | done: | 1673 | done: |
1661 | intel_pmu_enable_all(0); | 1674 | __intel_pmu_enable_all(0, true); |
1662 | /* | 1675 | /* |
1663 | * Only unmask the NMI after the overflow counters | 1676 | * Only unmask the NMI after the overflow counters |
1664 | * have been reset. This avoids spurious NMIs on | 1677 | * have been reset. This avoids spurious NMIs on |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index 0473874109cb..3d537252f011 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c | |||
@@ -132,12 +132,16 @@ static void intel_pmu_lbr_filter(struct cpu_hw_events *cpuc); | |||
132 | * otherwise it becomes near impossible to get a reliable stack. | 132 | * otherwise it becomes near impossible to get a reliable stack. |
133 | */ | 133 | */ |
134 | 134 | ||
135 | static void __intel_pmu_lbr_enable(void) | 135 | static void __intel_pmu_lbr_enable(bool pmi) |
136 | { | 136 | { |
137 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 137 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
138 | u64 debugctl, lbr_select = 0; | 138 | u64 debugctl, lbr_select = 0; |
139 | 139 | ||
140 | if (cpuc->lbr_sel) { | 140 | /* |
141 | * No need to reprogram LBR_SELECT in a PMI, as it | ||
142 | * did not change. | ||
143 | */ | ||
144 | if (cpuc->lbr_sel && !pmi) { | ||
141 | lbr_select = cpuc->lbr_sel->config; | 145 | lbr_select = cpuc->lbr_sel->config; |
142 | wrmsrl(MSR_LBR_SELECT, lbr_select); | 146 | wrmsrl(MSR_LBR_SELECT, lbr_select); |
143 | } | 147 | } |
@@ -351,12 +355,12 @@ void intel_pmu_lbr_disable(struct perf_event *event) | |||
351 | } | 355 | } |
352 | } | 356 | } |
353 | 357 | ||
354 | void intel_pmu_lbr_enable_all(void) | 358 | void intel_pmu_lbr_enable_all(bool pmi) |
355 | { | 359 | { |
356 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 360 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
357 | 361 | ||
358 | if (cpuc->lbr_users) | 362 | if (cpuc->lbr_users) |
359 | __intel_pmu_lbr_enable(); | 363 | __intel_pmu_lbr_enable(pmi); |
360 | } | 364 | } |
361 | 365 | ||
362 | void intel_pmu_lbr_disable_all(void) | 366 | void intel_pmu_lbr_disable_all(void) |