aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2014-11-03 20:00:28 -0500
committerIngo Molnar <mingo@kernel.org>2014-11-16 03:53:36 -0500
commit68055915c1c22489f9658bd2b7391bb11b2cf4e4 (patch)
treed1fc12606a313d76851d468b09eb1cede3a0c0d9 /arch/x86
parent41a134a5830a5e1396723ace0a63000780d6e267 (diff)
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 <alexei.starovoitov@gmail.com> Reported-and-Tested-by: Patrick Lu <patrick.lu@intel.com> Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Link: http://lkml.kernel.org/r/1415062828-19759-4-git-send-email-andi@firstfloor.org [ Fixed a whitespace error and added attribution tags that were left out inexplicably. ] Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
index 0af1c932fa0f..f9ed429d6e4f 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
@@ -486,14 +486,17 @@ static struct attribute_group snbep_uncore_qpi_format_group = {
486 .attrs = snbep_uncore_qpi_formats_attr, 486 .attrs = snbep_uncore_qpi_formats_attr,
487}; 487};
488 488
489#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \ 489#define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \
490 .init_box = snbep_uncore_msr_init_box, \
491 .disable_box = snbep_uncore_msr_disable_box, \ 490 .disable_box = snbep_uncore_msr_disable_box, \
492 .enable_box = snbep_uncore_msr_enable_box, \ 491 .enable_box = snbep_uncore_msr_enable_box, \
493 .disable_event = snbep_uncore_msr_disable_event, \ 492 .disable_event = snbep_uncore_msr_disable_event, \
494 .enable_event = snbep_uncore_msr_enable_event, \ 493 .enable_event = snbep_uncore_msr_enable_event, \
495 .read_counter = uncore_msr_read_counter 494 .read_counter = uncore_msr_read_counter
496 495
496#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \
497 __SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), \
498 .init_box = snbep_uncore_msr_init_box \
499
497static struct intel_uncore_ops snbep_uncore_msr_ops = { 500static struct intel_uncore_ops snbep_uncore_msr_ops = {
498 SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), 501 SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
499}; 502};
@@ -1919,6 +1922,30 @@ static struct intel_uncore_type hswep_uncore_cbox = {
1919 .format_group = &hswep_uncore_cbox_format_group, 1922 .format_group = &hswep_uncore_cbox_format_group,
1920}; 1923};
1921 1924
1925/*
1926 * Write SBOX Initialization register bit by bit to avoid spurious #GPs
1927 */
1928static 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
1944static 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
1922static struct attribute *hswep_uncore_sbox_formats_attr[] = { 1949static struct attribute *hswep_uncore_sbox_formats_attr[] = {
1923 &format_attr_event.attr, 1950 &format_attr_event.attr,
1924 &format_attr_umask.attr, 1951 &format_attr_umask.attr,
@@ -1944,7 +1971,7 @@ static struct intel_uncore_type hswep_uncore_sbox = {
1944 .event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK, 1971 .event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
1945 .box_ctl = HSWEP_S0_MSR_PMON_BOX_CTL, 1972 .box_ctl = HSWEP_S0_MSR_PMON_BOX_CTL,
1946 .msr_offset = HSWEP_SBOX_MSR_OFFSET, 1973 .msr_offset = HSWEP_SBOX_MSR_OFFSET,
1947 .ops = &snbep_uncore_msr_ops, 1974 .ops = &hswep_uncore_sbox_msr_ops,
1948 .format_group = &hswep_uncore_sbox_format_group, 1975 .format_group = &hswep_uncore_sbox_format_group,
1949}; 1976};
1950 1977