From: Like Xu like.xu@linux.intel.com
mainline inclusion from mainline-v5.9-rc1 commit b2d6504761a50b9493eb4b20f6e188b673f20c32 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I47H3V CVE: NA
--------------------------------
commit b2d6504761a50b9493eb4b20f6e188b673f20c32 upstream Backport summary: backport to kernel 4.19.57 for ICX perf topdown support
The LBR records msrs are model specific. The perf subsystem has already obtained the base addresses of LBR records based on the cpu model.
Therefore, an interface is added to allow callers outside the perf subsystem to obtain these LBR information. It's useful for hypervisors to emulate the LBR feature for guests with less code.
Signed-off-by: Like Xu like.xu@linux.intel.com Signed-off-by: Wei Wang wei.w.wang@intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20200613080958.132489-4-like.xu@linux.intel.com Signed-off-by: Yunying Sun yunying.sun@intel.com Signed-off-by: Jackie Liu liuyun01@kylinos.cn Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Reviewed-by: Wei Li liwei391@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/x86/events/intel/lbr.c | 20 ++++++++++++++++++++ arch/x86/include/asm/perf_event.h | 16 ++++++++++++++++ 2 files changed, 36 insertions(+)
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index b8cac31f089c..15aa2fbdd60e 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -1310,3 +1310,23 @@ void intel_pmu_lbr_init_knl(void) if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_LIP) x86_pmu.intel_cap.lbr_format = LBR_FORMAT_EIP_FLAGS; } + +/** + * x86_perf_get_lbr - get the LBR records information + * + * @lbr: the caller's memory to store the LBR records information + * + * Returns: 0 indicates the LBR info has been successfully obtained + */ +int x86_perf_get_lbr(struct x86_pmu_lbr *lbr) +{ + int lbr_fmt = x86_pmu.intel_cap.lbr_format; + + lbr->nr = x86_pmu.lbr_nr; + lbr->from = x86_pmu.lbr_from; + lbr->to = x86_pmu.lbr_to; + lbr->info = (lbr_fmt == LBR_FORMAT_INFO) ? MSR_LBR_INFO_0 : 0; + + return 0; +} +EXPORT_SYMBOL_GPL(x86_perf_get_lbr); diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index b4085e08cc5e..b0174e83ddda 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -322,6 +322,13 @@ struct perf_guest_switch_msr { u64 host, guest; };
+struct x86_pmu_lbr { + unsigned int nr; + unsigned int from; + unsigned int to; + unsigned int info; +}; + extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr); extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); extern void perf_check_microcode(void); @@ -341,6 +348,15 @@ static inline void perf_events_lapic_init(void) { } static inline void perf_check_microcode(void) { } #endif
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL) +extern int x86_perf_get_lbr(struct x86_pmu_lbr *lbr); +#else +static inline int x86_perf_get_lbr(struct x86_pmu_lbr *lbr) +{ + return -1; +} +#endif + #ifdef CONFIG_CPU_SUP_INTEL extern void intel_pt_handle_vmx(int on); #endif