mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 16:49:22 +00:00
perf/x86/intel/lbr: Fix unchecked MSR access error on HSW
commitb0380e1350
upstream. The fuzzer triggers the below trace. [ 7763.384369] unchecked MSR access error: WRMSR to 0x689 (tried to write 0x1fffffff8101349e) at rIP: 0xffffffff810704a4 (native_write_msr+0x4/0x20) [ 7763.397420] Call Trace: [ 7763.399881] <TASK> [ 7763.401994] intel_pmu_lbr_restore+0x9a/0x1f0 [ 7763.406363] intel_pmu_lbr_sched_task+0x91/0x1c0 [ 7763.410992] __perf_event_task_sched_in+0x1cd/0x240 On a machine with the LBR format LBR_FORMAT_EIP_FLAGS2, when the TSX is disabled, a TSX quirk is required to access LBR from registers. The lbr_from_signext_quirk_needed() is introduced to determine whether the TSX quirk should be applied. However, the lbr_from_signext_quirk_needed() is invoked before the intel_pmu_lbr_init(), which parses the LBR format information. Without the correct LBR format information, the TSX quirk never be applied. Move the lbr_from_signext_quirk_needed() into the intel_pmu_lbr_init(). Checking x86_pmu.lbr_has_tsx in the lbr_from_signext_quirk_needed() is not required anymore. Both LBR_FORMAT_EIP_FLAGS2 and LBR_FORMAT_INFO have LBR_TSX flag, but only the LBR_FORMAT_EIP_FLAGS2 requirs the quirk. Update the comments accordingly. Fixes:1ac7fd8159
("perf/x86/intel/lbr: Support LBR format V7") Reported-by: Vince Weaver <vincent.weaver@maine.edu> Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20220714182630.342107-1-kan.liang@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8f4f5a2e5f
commit
625bcd0685
1 changed files with 10 additions and 9 deletions
|
@ -278,9 +278,9 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For formats with LBR_TSX flags (e.g. LBR_FORMAT_EIP_FLAGS2), bits 61:62 in
|
* For format LBR_FORMAT_EIP_FLAGS2, bits 61:62 in MSR_LAST_BRANCH_FROM_x
|
||||||
* MSR_LAST_BRANCH_FROM_x are the TSX flags when TSX is supported, but when
|
* are the TSX flags when TSX is supported, but when TSX is not supported
|
||||||
* TSX is not supported they have no consistent behavior:
|
* they have no consistent behavior:
|
||||||
*
|
*
|
||||||
* - For wrmsr(), bits 61:62 are considered part of the sign extension.
|
* - For wrmsr(), bits 61:62 are considered part of the sign extension.
|
||||||
* - For HW updates (branch captures) bits 61:62 are always OFF and are not
|
* - For HW updates (branch captures) bits 61:62 are always OFF and are not
|
||||||
|
@ -288,7 +288,7 @@ enum {
|
||||||
*
|
*
|
||||||
* Therefore, if:
|
* Therefore, if:
|
||||||
*
|
*
|
||||||
* 1) LBR has TSX format
|
* 1) LBR format LBR_FORMAT_EIP_FLAGS2
|
||||||
* 2) CPU has no TSX support enabled
|
* 2) CPU has no TSX support enabled
|
||||||
*
|
*
|
||||||
* ... then any value passed to wrmsr() must be sign extended to 63 bits and any
|
* ... then any value passed to wrmsr() must be sign extended to 63 bits and any
|
||||||
|
@ -300,7 +300,7 @@ static inline bool lbr_from_signext_quirk_needed(void)
|
||||||
bool tsx_support = boot_cpu_has(X86_FEATURE_HLE) ||
|
bool tsx_support = boot_cpu_has(X86_FEATURE_HLE) ||
|
||||||
boot_cpu_has(X86_FEATURE_RTM);
|
boot_cpu_has(X86_FEATURE_RTM);
|
||||||
|
|
||||||
return !tsx_support && x86_pmu.lbr_has_tsx;
|
return !tsx_support;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEFINE_STATIC_KEY_FALSE(lbr_from_quirk_key);
|
static DEFINE_STATIC_KEY_FALSE(lbr_from_quirk_key);
|
||||||
|
@ -1611,9 +1611,6 @@ void intel_pmu_lbr_init_hsw(void)
|
||||||
x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
|
x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
|
||||||
|
|
||||||
x86_get_pmu(smp_processor_id())->task_ctx_cache = create_lbr_kmem_cache(size, 0);
|
x86_get_pmu(smp_processor_id())->task_ctx_cache = create_lbr_kmem_cache(size, 0);
|
||||||
|
|
||||||
if (lbr_from_signext_quirk_needed())
|
|
||||||
static_branch_enable(&lbr_from_quirk_key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skylake */
|
/* skylake */
|
||||||
|
@ -1704,7 +1701,11 @@ void intel_pmu_lbr_init(void)
|
||||||
switch (x86_pmu.intel_cap.lbr_format) {
|
switch (x86_pmu.intel_cap.lbr_format) {
|
||||||
case LBR_FORMAT_EIP_FLAGS2:
|
case LBR_FORMAT_EIP_FLAGS2:
|
||||||
x86_pmu.lbr_has_tsx = 1;
|
x86_pmu.lbr_has_tsx = 1;
|
||||||
fallthrough;
|
x86_pmu.lbr_from_flags = 1;
|
||||||
|
if (lbr_from_signext_quirk_needed())
|
||||||
|
static_branch_enable(&lbr_from_quirk_key);
|
||||||
|
break;
|
||||||
|
|
||||||
case LBR_FORMAT_EIP_FLAGS:
|
case LBR_FORMAT_EIP_FLAGS:
|
||||||
x86_pmu.lbr_from_flags = 1;
|
x86_pmu.lbr_from_flags = 1;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue