[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1408538179-792-14-git-send-email-alexander.shishkin@linux.intel.com>
Date: Wed, 20 Aug 2014 15:36:10 +0300
From: Alexander Shishkin <alexander.shishkin@...ux.intel.com>
To: Peter Zijlstra <a.p.zijlstra@...llo.nl>
Cc: Ingo Molnar <mingo@...hat.com>, linux-kernel@...r.kernel.org,
Robert Richter <rric@...nel.org>,
Frederic Weisbecker <fweisbec@...il.com>,
Mike Galbraith <efault@....de>,
Paul Mackerras <paulus@...ba.org>,
Stephane Eranian <eranian@...gle.com>,
Andi Kleen <ak@...ux.intel.com>, kan.liang@...el.com,
Alexander Shishkin <alexander.shishkin@...ux.intel.com>
Subject: [PATCH v4 13/22] x86: perf: Intel PT and LBR/BTS are mutually exclusive
Intel PT cannot be used at the same time as LBR or BTS and will cause a
general protection fault if they are used together. In order to avoid
fixing up GPs in the fast path, instead we use flags to indicate that
that one of these is in use so that the other avoids MSR access altogether.
Signed-off-by: Alexander Shishkin <alexander.shishkin@...ux.intel.com>
---
arch/x86/kernel/cpu/perf_event.h | 6 ++++++
arch/x86/kernel/cpu/perf_event_intel_ds.c | 8 +++++++-
arch/x86/kernel/cpu/perf_event_intel_lbr.c | 9 +++++----
3 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index fc5eb390b3..a542fa8a1d 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -148,6 +148,7 @@ struct cpu_hw_events {
* Intel DebugStore bits
*/
struct debug_store *ds;
+ unsigned int bts_enabled;
u64 pebs_enabled;
/*
@@ -161,6 +162,11 @@ struct cpu_hw_events {
u64 br_sel;
/*
+ * Intel Processor Trace
+ */
+ unsigned int pt_enabled;
+
+ /*
* Intel host/guest exclude bits
*/
u64 intel_ctrl_guest_mask;
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 9dc4199917..5ae212af23 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -455,8 +455,13 @@ struct event_constraint bts_constraint =
void intel_pmu_enable_bts(u64 config)
{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
unsigned long debugctlmsr;
+ if (cpuc->pt_enabled)
+ return;
+
+ cpuc->bts_enabled = 1;
debugctlmsr = get_debugctlmsr();
debugctlmsr |= DEBUGCTLMSR_TR;
@@ -477,9 +482,10 @@ void intel_pmu_disable_bts(void)
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
unsigned long debugctlmsr;
- if (!cpuc->ds)
+ if (!cpuc->ds || cpuc->pt_enabled)
return;
+ cpuc->bts_enabled = 0;
debugctlmsr = get_debugctlmsr();
debugctlmsr &=
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index 9dd2459a4c..516e52d0ac 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -172,7 +172,9 @@ static void intel_pmu_lbr_reset_64(void)
void intel_pmu_lbr_reset(void)
{
- if (!x86_pmu.lbr_nr)
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+ if (!x86_pmu.lbr_nr || cpuc->pt_enabled)
return;
if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
@@ -185,7 +187,7 @@ void intel_pmu_lbr_enable(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- if (!x86_pmu.lbr_nr)
+ if (!x86_pmu.lbr_nr || cpuc->pt_enabled)
return;
/*
@@ -205,11 +207,10 @@ void intel_pmu_lbr_disable(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- if (!x86_pmu.lbr_nr)
+ if (!x86_pmu.lbr_nr || !cpuc->lbr_users || cpuc->pt_enabled)
return;
cpuc->lbr_users--;
- WARN_ON_ONCE(cpuc->lbr_users < 0);
if (cpuc->enabled && !cpuc->lbr_users) {
__intel_pmu_lbr_disable();
--
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists