Skip to content

Commit 6805591

Browse files
Andi KleenIngo Molnar
authored andcommitted
perf/x86/intel/uncore: Fix boot crash on SBOX PMU on Haswell-EP
There were several reports that on some systems writing the SBOX0 PMU initialization MSR would #GP at boot. This did not happen on all systems -- my two test systems booted fine. Writing the three initialization bits bit-by-bit seems to avoid the problem. So add a special callback to do just that. This replaces an earlier patch that disabled the SBOX. Reported-by: Alexei Starovoitov <[email protected]> Reported-and-Tested-by: Patrick Lu <[email protected]> Signed-off-by: Andi Kleen <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Link: http://lkml.kernel.org/r/[email protected] [ Fixed a whitespace error and added attribution tags that were left out inexplicably. ] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 41a134a commit 6805591

File tree

1 file changed

+30
-3
lines changed

1 file changed

+30
-3
lines changed

arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,14 +486,17 @@ static struct attribute_group snbep_uncore_qpi_format_group = {
486486
.attrs = snbep_uncore_qpi_formats_attr,
487487
};
488488

489-
#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \
490-
.init_box = snbep_uncore_msr_init_box, \
489+
#define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \
491490
.disable_box = snbep_uncore_msr_disable_box, \
492491
.enable_box = snbep_uncore_msr_enable_box, \
493492
.disable_event = snbep_uncore_msr_disable_event, \
494493
.enable_event = snbep_uncore_msr_enable_event, \
495494
.read_counter = uncore_msr_read_counter
496495

496+
#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \
497+
__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), \
498+
.init_box = snbep_uncore_msr_init_box \
499+
497500
static struct intel_uncore_ops snbep_uncore_msr_ops = {
498501
SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
499502
};
@@ -1919,6 +1922,30 @@ static struct intel_uncore_type hswep_uncore_cbox = {
19191922
.format_group = &hswep_uncore_cbox_format_group,
19201923
};
19211924

1925+
/*
1926+
* Write SBOX Initialization register bit by bit to avoid spurious #GPs
1927+
*/
1928+
static void hswep_uncore_sbox_msr_init_box(struct intel_uncore_box *box)
1929+
{
1930+
unsigned msr = uncore_msr_box_ctl(box);
1931+
1932+
if (msr) {
1933+
u64 init = SNBEP_PMON_BOX_CTL_INT;
1934+
u64 flags = 0;
1935+
int i;
1936+
1937+
for_each_set_bit(i, (unsigned long *)&init, 64) {
1938+
flags |= (1ULL << i);
1939+
wrmsrl(msr, flags);
1940+
}
1941+
}
1942+
}
1943+
1944+
static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = {
1945+
__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1946+
.init_box = hswep_uncore_sbox_msr_init_box
1947+
};
1948+
19221949
static struct attribute *hswep_uncore_sbox_formats_attr[] = {
19231950
&format_attr_event.attr,
19241951
&format_attr_umask.attr,
@@ -1944,7 +1971,7 @@ static struct intel_uncore_type hswep_uncore_sbox = {
19441971
.event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
19451972
.box_ctl = HSWEP_S0_MSR_PMON_BOX_CTL,
19461973
.msr_offset = HSWEP_SBOX_MSR_OFFSET,
1947-
.ops = &snbep_uncore_msr_ops,
1974+
.ops = &hswep_uncore_sbox_msr_ops,
19481975
.format_group = &hswep_uncore_sbox_format_group,
19491976
};
19501977

0 commit comments

Comments
 (0)