aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Carrillo-Cisneros <davidcc@google.com>2016-06-21 14:31:11 -0400
committerIngo Molnar <mingo@kernel.org>2016-06-27 05:34:19 -0400
commit19fc9ddd61e059cc45464bdf6e8fa304bb94080f (patch)
tree51d48bf3b59a20c07f3b06df7e3ff9e6c752e16c
parentf09509b9398b23ca53360ca57106555698ec2e93 (diff)
perf/x86/intel: Fix MSR_LAST_BRANCH_FROM_x bug when no TSX
Intel's SDM states that bits 61:62 in MSR_LAST_BRANCH_FROM_x are the TSX flags for formats with LBR_TSX flags (i.e. LBR_FORMAT_EIP_EFLAGS2). However, when the CPU has TSX support deactivated, bits 61:62 actually behave as follows: - For wrmsr(), bits 61:62 are considered part of the sign extension. - When capturing branches, the LBR hw will always clear bits 61:62. regardless of the sign extension. Therefore, if: 1) LBR has TSX format. 2) CPU has no TSX support enabled. ... then any value passed to wrmsr() must be sign extended to 63 bits and any value from rdmsr() must be converted to have a sign extension of 61 bits, ignoring the values at TSX flags. This bug was masked by the work-around to the Intel's CPU bug: BJ94. "LBR May Contain Incorrect Information When Using FREEZE_LBRS_ON_PMI" in Document Number: 324643-037US. The aforementioned work-around uses hw flags to filter out all kernel branches, limiting LBR callstack to user level execution only. Since user addresses are not sign extended, they do not trigger the wrmsr() bug in MSR_LAST_BRANCH_FROM_x when saved/restored at context switch. To verify the hw bug: $ perf record -b -e cycles sleep 1 $ rdmsr -p 0 0x680 0x1fffffffb0b9b0cc $ wrmsr -p 0 0x680 0x1fffffffb0b9b0cc write(): Input/output error The quirk for LBR_FROM_ MSRs is required before calls to wrmsrl() and after rdmsrl(). This patch introduces it for wrmsrl()'s done for testing LBR support. Future patch in series adds the quirk for context switch, that would be required if LBR callstack is to be enabled for ring 0. Signed-off-by: David Carrillo-Cisneros <davidcc@google.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Stephane Eranian <eranian@google.com> Reviewed-by: Andi Kleen <ak@linux.intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Kan Liang <kan.liang@intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vince Weaver <vincent.weaver@maine.edu> Link: http://lkml.kernel.org/r/1466533874-52003-3-git-send-email-davidcc@google.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/events/intel/core.c18
-rw-r--r--arch/x86/events/intel/lbr.c52
-rw-r--r--arch/x86/events/perf_event.h2
3 files changed, 72 insertions, 0 deletions
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 61a027b694a3..3eccc42e2d88 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -3361,6 +3361,13 @@ static void intel_snb_check_microcode(void)
3361 } 3361 }
3362} 3362}
3363 3363
3364static bool is_lbr_from(unsigned long msr)
3365{
3366 unsigned long lbr_from_nr = x86_pmu.lbr_from + x86_pmu.lbr_nr;
3367
3368 return x86_pmu.lbr_from <= msr && msr < lbr_from_nr;
3369}
3370
3364/* 3371/*
3365 * Under certain circumstances, access certain MSR may cause #GP. 3372 * Under certain circumstances, access certain MSR may cause #GP.
3366 * The function tests if the input MSR can be safely accessed. 3373 * The function tests if the input MSR can be safely accessed.
@@ -3381,13 +3388,24 @@ static bool check_msr(unsigned long msr, u64 mask)
3381 * Only change the bits which can be updated by wrmsrl. 3388 * Only change the bits which can be updated by wrmsrl.
3382 */ 3389 */
3383 val_tmp = val_old ^ mask; 3390 val_tmp = val_old ^ mask;
3391
3392 if (is_lbr_from(msr))
3393 val_tmp = lbr_from_signext_quirk_wr(val_tmp);
3394
3384 if (wrmsrl_safe(msr, val_tmp) || 3395 if (wrmsrl_safe(msr, val_tmp) ||
3385 rdmsrl_safe(msr, &val_new)) 3396 rdmsrl_safe(msr, &val_new))
3386 return false; 3397 return false;
3387 3398
3399 /*
3400 * Quirk only affects validation in wrmsr(), so wrmsrl()'s value
3401 * should equal rdmsrl()'s even with the quirk.
3402 */
3388 if (val_new != val_tmp) 3403 if (val_new != val_tmp)
3389 return false; 3404 return false;
3390 3405
3406 if (is_lbr_from(msr))
3407 val_old = lbr_from_signext_quirk_wr(val_old);
3408
3391 /* Here it's sure that the MSR can be safely accessed. 3409 /* Here it's sure that the MSR can be safely accessed.
3392 * Restore the old value and return. 3410 * Restore the old value and return.
3393 */ 3411 */
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 2dca66cec617..88093e0915a9 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -81,6 +81,8 @@ static enum {
81#define LBR_FROM_FLAG_IN_TX (1ULL << 62) 81#define LBR_FROM_FLAG_IN_TX (1ULL << 62)
82#define LBR_FROM_FLAG_ABORT (1ULL << 61) 82#define LBR_FROM_FLAG_ABORT (1ULL << 61)
83 83
84#define LBR_FROM_SIGNEXT_2MSB (BIT_ULL(60) | BIT_ULL(59))
85
84/* 86/*
85 * x86control flow change classification 87 * x86control flow change classification
86 * x86control flow changes include branches, interrupts, traps, faults 88 * x86control flow changes include branches, interrupts, traps, faults
@@ -235,6 +237,53 @@ enum {
235 LBR_VALID, 237 LBR_VALID,
236}; 238};
237 239
240/*
241 * For formats with LBR_TSX flags (e.g. LBR_FORMAT_EIP_FLAGS2), bits 61:62 in
242 * MSR_LAST_BRANCH_FROM_x are the TSX flags when TSX is supported, but when
243 * TSX is not supported they have no consistent behavior:
244 *
245 * - For wrmsr(), bits 61:62 are considered part of the sign extension.
246 * - For HW updates (branch captures) bits 61:62 are always OFF and are not
247 * part of the sign extension.
248 *
249 * Therefore, if:
250 *
251 * 1) LBR has TSX format
252 * 2) CPU has no TSX support enabled
253 *
254 * ... then any value passed to wrmsr() must be sign extended to 63 bits and any
255 * value from rdmsr() must be converted to have a 61 bits sign extension,
256 * ignoring the TSX flags.
257 */
258static inline bool lbr_from_signext_quirk_needed(void)
259{
260 int lbr_format = x86_pmu.intel_cap.lbr_format;
261 bool tsx_support = boot_cpu_has(X86_FEATURE_HLE) ||
262 boot_cpu_has(X86_FEATURE_RTM);
263
264 return !tsx_support && (lbr_desc[lbr_format] & LBR_TSX);
265}
266
267DEFINE_STATIC_KEY_FALSE(lbr_from_quirk_key);
268
269/* If quirk is enabled, ensure sign extension is 63 bits: */
270inline u64 lbr_from_signext_quirk_wr(u64 val)
271{
272 if (static_branch_unlikely(&lbr_from_quirk_key)) {
273 /*
274 * Sign extend into bits 61:62 while preserving bit 63.
275 *
276 * Quirk is enabled when TSX is disabled. Therefore TSX bits
277 * in val are always OFF and must be changed to be sign
278 * extension bits. Since bits 59:60 are guaranteed to be
279 * part of the sign extension bits, we can just copy them
280 * to 61:62.
281 */
282 val |= (LBR_FROM_SIGNEXT_2MSB & val) << 2;
283 }
284 return val;
285}
286
238static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx) 287static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
239{ 288{
240 int i; 289 int i;
@@ -1007,6 +1056,9 @@ void intel_pmu_lbr_init_hsw(void)
1007 1056
1008 x86_pmu.lbr_sel_mask = LBR_SEL_MASK; 1057 x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
1009 x86_pmu.lbr_sel_map = hsw_lbr_sel_map; 1058 x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
1059
1060 if (lbr_from_signext_quirk_needed())
1061 static_branch_enable(&lbr_from_quirk_key);
1010} 1062}
1011 1063
1012/* skylake */ 1064/* skylake */
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index e2d7285a2dac..8c4a47706296 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -902,6 +902,8 @@ void intel_ds_init(void);
902 902
903void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in); 903void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in);
904 904
905u64 lbr_from_signext_quirk_wr(u64 val);
906
905void intel_pmu_lbr_reset(void); 907void intel_pmu_lbr_reset(void);
906 908
907void intel_pmu_lbr_enable(struct perf_event *event); 909void intel_pmu_lbr_enable(struct perf_event *event);