[Devel] [PATCH RHEL8 COMMIT] perf/x86/intel: Move LBR-related data into a separate structure

Konstantin Khorenko khorenko at virtuozzo.com
Fri Apr 30 13:21:22 MSK 2021


The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.23
------>
commit f3456a43b158bb4062d6a78646c59d7defbde34d
Author: Jan Dakinevich <jan.dakinevich at virtuozzo.com>
Date:   Fri Apr 30 13:21:22 2021 +0300

    perf/x86/intel: Move LBR-related data into a separate structure
    
    Move LBR information from `struct x86_pmu' to separate structure
    `struct x86_pmu_lbr'.
    
    LBR initialization is nailed to perf subsystem and to global
    'boot_x86_pmu' structure. To reuse this code and keep these changes
    readable the work splited into to parts.
    
    https://jira.sw.ru/browse/PSBM-75679
    Signed-off-by: Jan Dakinevich <jan.dakinevich at virtuozzo.com>
    
    Commit 81325a25ac55 in the kernels from VZ7.
    
    In commit 7b6f4449 "Simplify perf/x86/intel: make reusable LBR initialization
    code", Vasily Averin also added a few #defines (like #define lbr_nr lbr.nr)
    to keep more code unchanged and to simplify future maintenance and kernel
    rebases. I added such defines here, in the first patch, to make it less
    invasive. It is not possible, however, to add such defines for lbr.from and
    lbr.to fields: there would be conflicts with the existing arrays lbr_from[]
    and lbr_to[].
    
    Besides, the kernel 4.18.0-x has support for more CPU modes ("Icelake",
    "Tigerlake", etc). The calls to intel_pmu_lbr_init_*() for these models are
    now handled too.
    
    The original patch also removed the check for a specific Atom-related
    erratum - I kept it unchanged here, because it logially belongs to the
    second patch ("perf/x86/intel: make LBR initialization reusable").
    
    Apart from that, it was mostly context changes.
    
    Done in the scope of https://jira.sw.ru/browse/PSBM-127794.
    
    Signed-off-by: Evgenii Shatokhin <eshatokhin at virtuozzo.com>
    
    =====================
    Patchset description:
    
    KVM: x86/vPMU: ignore access to LBR-related MSRs (PSBM-75679)
    
    This is the part of patchset from PSBM-75679 which is not present in
    mainline or RHEL kernels.
    
    I have adapted it to VZ8, added handling of new CPU models and simplified
    the code a bit more.
    
    Apart from that the patches have been renamed. The first two were named
    "perf/x86/intel: make reusable LBR initialization code, part 1/2" and
    "perf/x86/intel: make reusable LBR initialization code, part 2/2" in
    VZ7. This confused the tools like 'git format-patch' which stripped the
    last parts of the names, making them identical.
    
    "ms/" prefix was also removed: the patches did not make it into the
    mainline kernel.
    
    They are probably not needed there: It looks like, the recent mainline kernels
    (5.12-rcN+) added support for passthrough of LBR registers to the guest systems.
    It should probably fix the issue described in PSBM-75679 but I haven't tried
    that.
    Details: https://lore.kernel.org/kvm/20210201051039.255478-1-like.xu@linux.intel.com
    
    That mainline patchset has more prerequisites and some follow-up fixes.
    It is likely, it has not been tested very thoroughly in production yet, esp.
    with Windows guests. The kernels 4.18.0-240.* from RHEL8 do not have it yet,
    by the way.
    I'd stick with the VZ-specific patches for now, they are less invasive.
    
    https://jira.sw.ru/browse/PSBM-75679
    Done in the scope of https://jira.sw.ru/browse/PSBM-127794
    
    Signed-off-by: Evgenii Shatokhin <eshatokhin at virtuozzo.com>
---
 arch/x86/events/intel/core.c      |  38 ++++++------
 arch/x86/events/intel/lbr.c       | 120 +++++++++++++++++++-------------------
 arch/x86/events/perf_event.h      |  23 +++-----
 arch/x86/include/asm/perf_event.h |  20 +++++++
 4 files changed, 108 insertions(+), 93 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index fc55b91bdf39..e67d708f9140 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4083,9 +4083,9 @@ static void intel_snb_check_microcode(void)
 
 static bool is_lbr_from(unsigned long msr)
 {
-	unsigned long lbr_from_nr = x86_pmu.lbr_from + x86_pmu.lbr_nr;
+	unsigned long lbr_from_nr = x86_pmu.lbr.from + x86_pmu.lbr_nr;
 
-	return x86_pmu.lbr_from <= msr && msr < lbr_from_nr;
+	return x86_pmu.lbr.from <= msr && msr < lbr_from_nr;
 }
 
 /*
@@ -4632,7 +4632,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
 
-		intel_pmu_lbr_init_core();
+		intel_pmu_lbr_init_core(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_core2_event_constraints;
 		x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints;
@@ -4648,7 +4648,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
 		       sizeof(hw_cache_extra_regs));
 
-		intel_pmu_lbr_init_nhm();
+		intel_pmu_lbr_init_nhm(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_nehalem_event_constraints;
 		x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
@@ -4682,7 +4682,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
 
-		intel_pmu_lbr_init_atom();
+		intel_pmu_lbr_init_atom(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_gen_event_constraints;
 		x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints;
@@ -4701,7 +4701,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
 		       sizeof(hw_cache_extra_regs));
 
-		intel_pmu_lbr_init_slm();
+		intel_pmu_lbr_init_slm(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_slm_event_constraints;
 		x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
@@ -4721,7 +4721,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_extra_regs, glm_hw_cache_extra_regs,
 		       sizeof(hw_cache_extra_regs));
 
-		intel_pmu_lbr_init_skl();
+		intel_pmu_lbr_init_skl(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_slm_event_constraints;
 		x86_pmu.pebs_constraints = intel_glm_pebs_event_constraints;
@@ -4748,7 +4748,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_extra_regs, glp_hw_cache_extra_regs,
 		       sizeof(hw_cache_extra_regs));
 
-		intel_pmu_lbr_init_skl();
+		intel_pmu_lbr_init_skl(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_slm_event_constraints;
 		x86_pmu.extra_regs = intel_glm_extra_regs;
@@ -4779,7 +4779,7 @@ __init int intel_pmu_init(void)
 		       sizeof(hw_cache_extra_regs));
 		hw_cache_event_ids[C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = -1;
 
-		intel_pmu_lbr_init_skl();
+		intel_pmu_lbr_init_skl(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_slm_event_constraints;
 		x86_pmu.extra_regs = intel_tnt_extra_regs;
@@ -4805,7 +4805,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
 		       sizeof(hw_cache_extra_regs));
 
-		intel_pmu_lbr_init_nhm();
+		intel_pmu_lbr_init_nhm(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_westmere_event_constraints;
 		x86_pmu.enable_all = intel_pmu_nhm_enable_all;
@@ -4837,7 +4837,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
 		       sizeof(hw_cache_extra_regs));
 
-		intel_pmu_lbr_init_snb();
+		intel_pmu_lbr_init_snb(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_snb_event_constraints;
 		x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
@@ -4879,7 +4879,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
 		       sizeof(hw_cache_extra_regs));
 
-		intel_pmu_lbr_init_snb();
+		intel_pmu_lbr_init_snb(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_ivb_event_constraints;
 		x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
@@ -4917,7 +4917,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
 
-		intel_pmu_lbr_init_hsw();
+		intel_pmu_lbr_init_hsw(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_hsw_event_constraints;
 		x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
@@ -4959,7 +4959,7 @@ __init int intel_pmu_init(void)
 		hw_cache_extra_regs[C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = HSW_DEMAND_WRITE|
 									      BDW_L3_MISS_LOCAL|HSW_SNOOP_DRAM;
 
-		intel_pmu_lbr_init_hsw();
+		intel_pmu_lbr_init_hsw(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_bdw_event_constraints;
 		x86_pmu.pebs_constraints = intel_bdw_pebs_event_constraints;
@@ -4988,7 +4988,7 @@ __init int intel_pmu_init(void)
 		       slm_hw_cache_event_ids, sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs,
 		       knl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
-		intel_pmu_lbr_init_knl();
+		intel_pmu_lbr_init_knl(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_slm_event_constraints;
 		x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
@@ -5015,7 +5015,7 @@ __init int intel_pmu_init(void)
 		x86_pmu.late_ack = true;
 		memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
-		intel_pmu_lbr_init_skl();
+		intel_pmu_lbr_init_skl(&x86_pmu.lbr);
 
 		/* INT_MISC.RECOVERY_CYCLES has umask 1 in Skylake */
 		event_attr_td_recovery_bubbles.event_str_noht =
@@ -5065,7 +5065,7 @@ __init int intel_pmu_init(void)
 		memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
 		hw_cache_event_ids[C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = -1;
-		intel_pmu_lbr_init_skl();
+		intel_pmu_lbr_init_skl(&x86_pmu.lbr);
 
 		x86_pmu.event_constraints = intel_icl_event_constraints;
 		x86_pmu.pebs_constraints = intel_icl_pebs_event_constraints;
@@ -5159,8 +5159,8 @@ __init int intel_pmu_init(void)
 	if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL))
 		x86_pmu.lbr_nr = 0;
 	for (i = 0; i < x86_pmu.lbr_nr; i++) {
-		if (!(check_msr(x86_pmu.lbr_from + i, 0xffffUL) &&
-		      check_msr(x86_pmu.lbr_to + i, 0xffffUL)))
+		if (!(check_msr(x86_pmu.lbr.from + i, 0xffffUL) &&
+		      check_msr(x86_pmu.lbr.to + i, 0xffffUL)))
 			x86_pmu.lbr_nr = 0;
 	}
 
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 65113b16804a..ea971fd767af 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -199,7 +199,7 @@ static void intel_pmu_lbr_reset_32(void)
 	int i;
 
 	for (i = 0; i < x86_pmu.lbr_nr; i++)
-		wrmsrl(x86_pmu.lbr_from + i, 0);
+		wrmsrl(x86_pmu.lbr.from + i, 0);
 }
 
 static void intel_pmu_lbr_reset_64(void)
@@ -207,8 +207,8 @@ static void intel_pmu_lbr_reset_64(void)
 	int i;
 
 	for (i = 0; i < x86_pmu.lbr_nr; i++) {
-		wrmsrl(x86_pmu.lbr_from + i, 0);
-		wrmsrl(x86_pmu.lbr_to   + i, 0);
+		wrmsrl(x86_pmu.lbr.from + i, 0);
+		wrmsrl(x86_pmu.lbr.to   + i, 0);
 		if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
 			wrmsrl(MSR_LBR_INFO_0 + i, 0);
 	}
@@ -311,19 +311,19 @@ static u64 lbr_from_signext_quirk_rd(u64 val)
 static inline void wrlbr_from(unsigned int idx, u64 val)
 {
 	val = lbr_from_signext_quirk_wr(val);
-	wrmsrl(x86_pmu.lbr_from + idx, val);
+	wrmsrl(x86_pmu.lbr.from + idx, val);
 }
 
 static inline void wrlbr_to(unsigned int idx, u64 val)
 {
-	wrmsrl(x86_pmu.lbr_to + idx, val);
+	wrmsrl(x86_pmu.lbr.to + idx, val);
 }
 
 static inline u64 rdlbr_from(unsigned int idx)
 {
 	u64 val;
 
-	rdmsrl(x86_pmu.lbr_from + idx, val);
+	rdmsrl(x86_pmu.lbr.from + idx, val);
 
 	return lbr_from_signext_quirk_rd(val);
 }
@@ -332,7 +332,7 @@ static inline u64 rdlbr_to(unsigned int idx)
 {
 	u64 val;
 
-	rdmsrl(x86_pmu.lbr_to + idx, val);
+	rdmsrl(x86_pmu.lbr.to + idx, val);
 
 	return val;
 }
@@ -572,7 +572,7 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
 			u64     lbr;
 		} msr_lastbranch;
 
-		rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);
+		rdmsrl(x86_pmu.lbr.from + lbr_idx, msr_lastbranch.lbr);
 
 		cpuc->lbr_entries[i].from	= msr_lastbranch.from;
 		cpuc->lbr_entries[i].to		= msr_lastbranch.to;
@@ -1199,12 +1199,12 @@ static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
 };
 
 /* core */
-void __init intel_pmu_lbr_init_core(void)
+void __init intel_pmu_lbr_init_core(struct x86_pmu_lbr *lbr)
 {
-	x86_pmu.lbr_nr     = 4;
-	x86_pmu.lbr_tos    = MSR_LBR_TOS;
-	x86_pmu.lbr_from   = MSR_LBR_CORE_FROM;
-	x86_pmu.lbr_to     = MSR_LBR_CORE_TO;
+	lbr->nr     = 4;
+	lbr->tos    = MSR_LBR_TOS;
+	lbr->from   = MSR_LBR_CORE_FROM;
+	lbr->to     = MSR_LBR_CORE_TO;
 
 	/*
 	 * SW branch filter usage:
@@ -1213,15 +1213,15 @@ void __init intel_pmu_lbr_init_core(void)
 }
 
 /* nehalem/westmere */
-void __init intel_pmu_lbr_init_nhm(void)
+void __init intel_pmu_lbr_init_nhm(struct x86_pmu_lbr *lbr)
 {
-	x86_pmu.lbr_nr     = 16;
-	x86_pmu.lbr_tos    = MSR_LBR_TOS;
-	x86_pmu.lbr_from   = MSR_LBR_NHM_FROM;
-	x86_pmu.lbr_to     = MSR_LBR_NHM_TO;
+	lbr->nr     = 16;
+	lbr->tos    = MSR_LBR_TOS;
+	lbr->from   = MSR_LBR_NHM_FROM;
+	lbr->to     = MSR_LBR_NHM_TO;
 
-	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
-	x86_pmu.lbr_sel_map  = nhm_lbr_sel_map;
+	lbr->sel_mask = LBR_SEL_MASK;
+	lbr->sel_map  = nhm_lbr_sel_map;
 
 	/*
 	 * SW branch filter usage:
@@ -1233,15 +1233,15 @@ void __init intel_pmu_lbr_init_nhm(void)
 }
 
 /* sandy bridge */
-void __init intel_pmu_lbr_init_snb(void)
+void __init intel_pmu_lbr_init_snb(struct x86_pmu_lbr *lbr)
 {
-	x86_pmu.lbr_nr	 = 16;
-	x86_pmu.lbr_tos	 = MSR_LBR_TOS;
-	x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
-	x86_pmu.lbr_to   = MSR_LBR_NHM_TO;
+	lbr->nr   = 16;
+	lbr->tos  = MSR_LBR_TOS;
+	lbr->from = MSR_LBR_NHM_FROM;
+	lbr->to   = MSR_LBR_NHM_TO;
 
-	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
-	x86_pmu.lbr_sel_map  = snb_lbr_sel_map;
+	lbr->sel_mask = LBR_SEL_MASK;
+	lbr->sel_map  = snb_lbr_sel_map;
 
 	/*
 	 * SW branch filter usage:
@@ -1252,30 +1252,30 @@ void __init intel_pmu_lbr_init_snb(void)
 }
 
 /* haswell */
-void intel_pmu_lbr_init_hsw(void)
+void intel_pmu_lbr_init_hsw(struct x86_pmu_lbr *lbr)
 {
-	x86_pmu.lbr_nr	 = 16;
-	x86_pmu.lbr_tos	 = MSR_LBR_TOS;
-	x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
-	x86_pmu.lbr_to   = MSR_LBR_NHM_TO;
+	lbr->nr	 = 16;
+	lbr->tos = MSR_LBR_TOS;
+	lbr->from = MSR_LBR_NHM_FROM;
+	lbr->to   = MSR_LBR_NHM_TO;
 
-	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
-	x86_pmu.lbr_sel_map  = hsw_lbr_sel_map;
+	lbr->sel_mask = LBR_SEL_MASK;
+	lbr->sel_map  = hsw_lbr_sel_map;
 
 	if (lbr_from_signext_quirk_needed())
 		static_branch_enable(&lbr_from_quirk_key);
 }
 
 /* skylake */
-__init void intel_pmu_lbr_init_skl(void)
+__init void intel_pmu_lbr_init_skl(struct x86_pmu_lbr *lbr)
 {
-	x86_pmu.lbr_nr	 = 32;
-	x86_pmu.lbr_tos	 = MSR_LBR_TOS;
-	x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
-	x86_pmu.lbr_to   = MSR_LBR_NHM_TO;
+	lbr->nr	 = 32;
+	lbr->tos = MSR_LBR_TOS;
+	lbr->from = MSR_LBR_NHM_FROM;
+	lbr->to   = MSR_LBR_NHM_TO;
 
-	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
-	x86_pmu.lbr_sel_map  = hsw_lbr_sel_map;
+	lbr->sel_mask = LBR_SEL_MASK;
+	lbr->sel_map  = hsw_lbr_sel_map;
 
 	/*
 	 * SW branch filter usage:
@@ -1286,7 +1286,7 @@ __init void intel_pmu_lbr_init_skl(void)
 }
 
 /* atom */
-void __init intel_pmu_lbr_init_atom(void)
+void __init intel_pmu_lbr_init_atom(struct x86_pmu_lbr *lbr)
 {
 	/*
 	 * only models starting at stepping 10 seems
@@ -1299,10 +1299,10 @@ void __init intel_pmu_lbr_init_atom(void)
 		return;
 	}
 
-	x86_pmu.lbr_nr	   = 8;
-	x86_pmu.lbr_tos    = MSR_LBR_TOS;
-	x86_pmu.lbr_from   = MSR_LBR_CORE_FROM;
-	x86_pmu.lbr_to     = MSR_LBR_CORE_TO;
+	lbr->nr   = 8;
+	lbr->tos  = MSR_LBR_TOS;
+	lbr->from = MSR_LBR_CORE_FROM;
+	lbr->to   = MSR_LBR_CORE_TO;
 
 	/*
 	 * SW branch filter usage:
@@ -1311,15 +1311,15 @@ void __init intel_pmu_lbr_init_atom(void)
 }
 
 /* slm */
-void __init intel_pmu_lbr_init_slm(void)
+void __init intel_pmu_lbr_init_slm(struct x86_pmu_lbr *lbr)
 {
-	x86_pmu.lbr_nr	   = 8;
-	x86_pmu.lbr_tos    = MSR_LBR_TOS;
-	x86_pmu.lbr_from   = MSR_LBR_CORE_FROM;
-	x86_pmu.lbr_to     = MSR_LBR_CORE_TO;
+	lbr->nr   = 8;
+	lbr->tos  = MSR_LBR_TOS;
+	lbr->from = MSR_LBR_CORE_FROM;
+	lbr->to   = MSR_LBR_CORE_TO;
 
-	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
-	x86_pmu.lbr_sel_map  = nhm_lbr_sel_map;
+	lbr->sel_mask = LBR_SEL_MASK;
+	lbr->sel_map  = nhm_lbr_sel_map;
 
 	/*
 	 * SW branch filter usage:
@@ -1329,15 +1329,15 @@ void __init intel_pmu_lbr_init_slm(void)
 }
 
 /* Knights Landing */
-void intel_pmu_lbr_init_knl(void)
+void intel_pmu_lbr_init_knl(struct x86_pmu_lbr *lbr)
 {
-	x86_pmu.lbr_nr	   = 8;
-	x86_pmu.lbr_tos    = MSR_LBR_TOS;
-	x86_pmu.lbr_from   = MSR_LBR_NHM_FROM;
-	x86_pmu.lbr_to     = MSR_LBR_NHM_TO;
+	lbr->nr   = 8;
+	lbr->tos  = MSR_LBR_TOS;
+	lbr->from = MSR_LBR_NHM_FROM;
+	lbr->to   = MSR_LBR_NHM_TO;
 
-	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
-	x86_pmu.lbr_sel_map  = snb_lbr_sel_map;
+	lbr->sel_mask = LBR_SEL_MASK;
+	lbr->sel_map  = snb_lbr_sel_map;
 
 	/* Knights Landing does have MISPREDICT bit */
 	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_LIP)
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index f1cd1ca1a77b..b48cf9ed405c 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -672,12 +672,7 @@ struct x86_pmu {
 	/*
 	 * Intel LBR
 	 */
-	unsigned long	lbr_tos, lbr_from, lbr_to; /* MSR base regs       */
-	int		lbr_nr;			   /* hardware stack size */
-	u64		lbr_sel_mask;		   /* LBR_SELECT valid bits */
-	const int	*lbr_sel_map;		   /* lbr_select mappings */
-	bool		lbr_double_abort;	   /* duplicated lbr aborts */
-	bool		lbr_pt_coexist;		   /* (LBR|BTS) may coexist with PT */
+	struct x86_pmu_lbr lbr;
 
 	/*
 	 * Intel PT/LBR/BTS are exclusive
@@ -1063,21 +1058,21 @@ void intel_pmu_lbr_disable_all(void);
 
 void intel_pmu_lbr_read(void);
 
-void intel_pmu_lbr_init_core(void);
+void intel_pmu_lbr_init_core(struct x86_pmu_lbr *lbr);
 
-void intel_pmu_lbr_init_nhm(void);
+void intel_pmu_lbr_init_nhm(struct x86_pmu_lbr *lbr);
 
-void intel_pmu_lbr_init_atom(void);
+void intel_pmu_lbr_init_atom(struct x86_pmu_lbr *lbr);
 
-void intel_pmu_lbr_init_slm(void);
+void intel_pmu_lbr_init_slm(struct x86_pmu_lbr *lbr);
 
-void intel_pmu_lbr_init_snb(void);
+void intel_pmu_lbr_init_snb(struct x86_pmu_lbr *lbr);
 
-void intel_pmu_lbr_init_hsw(void);
+void intel_pmu_lbr_init_hsw(struct x86_pmu_lbr *lbr);
 
-void intel_pmu_lbr_init_skl(void);
+void intel_pmu_lbr_init_skl(struct x86_pmu_lbr *lbr);
 
-void intel_pmu_lbr_init_knl(void);
+void intel_pmu_lbr_init_knl(struct x86_pmu_lbr *lbr);
 
 void intel_pmu_pebs_data_source_nhm(void);
 
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index c5b3c137ca8c..721f4f2034c5 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -152,6 +152,26 @@ struct x86_pmu_capability {
 	int		events_mask_len;
 };
 
+struct x86_pmu_lbr {
+	unsigned long	tos, from, to;	/* MSR base regs */
+	int		nr;		/* hardware stack size */
+	u64		sel_mask;	/* LBR_SELECT valid bits */
+	const int	*sel_map;	/* lbr_select mappings */
+	bool		double_abort;	/* duplicated lbr aborts */
+	bool		pt_coexist;	/* (LBR|BTS) may coexist with PT */
+};
+
+/*
+ * Convenience defines to keep more of the code unchanged - it makes it
+ * easier to rebase the kernel to newer versions.
+ */
+#define lbr_tos			lbr.tos
+#define lbr_nr			lbr.nr
+#define lbr_sel_mask		lbr.sel_mask
+#define lbr_sel_map		lbr.sel_map
+#define lbr_double_abort	lbr.double_abort
+#define lbr_pt_coexist		lbr.pt_coexist
+
 /*
  * Fixed-purpose performance events:
  */


More information about the Devel mailing list