aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/cpu/perf_event.h2
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c23
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_lbr.c12
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
871void intel_pmu_lbr_disable(struct perf_event *event); 871void intel_pmu_lbr_disable(struct perf_event *event);
872 872
873void intel_pmu_lbr_enable_all(void); 873void intel_pmu_lbr_enable_all(bool pmi);
874 874
875void intel_pmu_lbr_disable_all(void); 875void 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
1247static void intel_pmu_disable_all(void) 1247/*
1248 * Use from PMIs where the LBRs are already disabled.
1249 */
1250static 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
1264static 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
1262static void intel_pmu_enable_all(int added) 1270static 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
1291static 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
1660done: 1673done:
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
135static void __intel_pmu_lbr_enable(void) 135static 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
354void intel_pmu_lbr_enable_all(void) 358void 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
362void intel_pmu_lbr_disable_all(void) 366void intel_pmu_lbr_disable_all(void)