Skip to content

Commit b2d6504

Browse files
Like XuPeter Zijlstra
authored andcommitted
perf/x86/lbr: Add interface to get LBR information
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 <[email protected]> Signed-off-by: Wei Wang <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 027440b commit b2d6504

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

arch/x86/events/intel/lbr.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,3 +1343,23 @@ void intel_pmu_lbr_init_knl(void)
13431343
if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_LIP)
13441344
x86_pmu.intel_cap.lbr_format = LBR_FORMAT_EIP_FLAGS;
13451345
}
1346+
1347+
/**
1348+
* x86_perf_get_lbr - get the LBR records information
1349+
*
1350+
* @lbr: the caller's memory to store the LBR records information
1351+
*
1352+
* Returns: 0 indicates the LBR info has been successfully obtained
1353+
*/
1354+
int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
1355+
{
1356+
int lbr_fmt = x86_pmu.intel_cap.lbr_format;
1357+
1358+
lbr->nr = x86_pmu.lbr_nr;
1359+
lbr->from = x86_pmu.lbr_from;
1360+
lbr->to = x86_pmu.lbr_to;
1361+
lbr->info = (lbr_fmt == LBR_FORMAT_INFO) ? MSR_LBR_INFO_0 : 0;
1362+
1363+
return 0;
1364+
}
1365+
EXPORT_SYMBOL_GPL(x86_perf_get_lbr);

arch/x86/include/asm/perf_event.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,13 @@ struct perf_guest_switch_msr {
333333
u64 host, guest;
334334
};
335335

336+
struct x86_pmu_lbr {
337+
unsigned int nr;
338+
unsigned int from;
339+
unsigned int to;
340+
unsigned int info;
341+
};
342+
336343
extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap);
337344
extern void perf_check_microcode(void);
338345
extern int x86_perf_rdpmc_index(struct perf_event *event);
@@ -348,12 +355,17 @@ static inline void perf_check_microcode(void) { }
348355

349356
#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
350357
extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
358+
extern int x86_perf_get_lbr(struct x86_pmu_lbr *lbr);
351359
#else
352360
static inline struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
353361
{
354362
*nr = 0;
355363
return NULL;
356364
}
365+
static inline int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
366+
{
367+
return -1;
368+
}
357369
#endif
358370

359371
#ifdef CONFIG_CPU_SUP_INTEL

0 commit comments

Comments
 (0)