aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKan Liang <kan.liang@linux.intel.com>2018-03-13 14:51:34 -0400
committerIngo Molnar <mingo@kernel.org>2018-03-20 03:58:47 -0400
commit320b0651f32b830add6497fcdcfdcb6ae8c7b8a0 (patch)
tree74ac6ff5ae2fc2288cc9a1de967d78adb5ceb7ab
parent174afc3e7dd7823df8218e16e7768b834097184e (diff)
perf/x86/intel/uncore: Fix multi-domain PCI CHA enumeration bug on Skylake servers
The number of CHAs is miscalculated on multi-domain PCI Skylake server systems, resulting in an uncore driver initialization error. Gary Kroening explains: "For systems with a single PCI segment, it is sufficient to look for the bus number to change in order to determine that all of the CHa's have been counted for a single socket. However, for multi PCI segment systems, each socket is given a new segment and the bus number does NOT change. So looking only for the bus number to change ends up counting all of the CHa's on all sockets in the system. This leads to writing CPU MSRs beyond a valid range and causes an error in ivbep_uncore_msr_init_box()." To fix this bug, query the number of CHAs from the CAPID6 register: it should read bits 27:0 in the CAPID6 register located at Device 30, Function 3, Offset 0x9C. These 28 bits form a bit vector of available LLC slices and the CHAs that manage those slices. Reported-by: Kroening, Gary <gary.kroening@hpe.com> Tested-by: Kroening, Gary <gary.kroening@hpe.com> Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vince Weaver <vincent.weaver@maine.edu> Cc: abanman@hpe.com Cc: dimitri.sivanich@hpe.com Cc: hpa@zytor.com Cc: mike.travis@hpe.com Cc: russ.anderson@hpe.com Fixes: cd34cd97b7b4 ("perf/x86/intel/uncore: Add Skylake server uncore support") Link: http://lkml.kernel.org/r/1520967094-13219-1-git-send-email-kan.liang@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/events/intel/uncore_snbep.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 0876798f2ac9..c98b943e58b4 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -3563,24 +3563,27 @@ static struct intel_uncore_type *skx_msr_uncores[] = {
3563 NULL, 3563 NULL,
3564}; 3564};
3565 3565
3566/*
3567 * To determine the number of CHAs, it should read bits 27:0 in the CAPID6
3568 * register which located at Device 30, Function 3, Offset 0x9C. PCI ID 0x2083.
3569 */
3570#define SKX_CAPID6 0x9c
3571#define SKX_CHA_BIT_MASK GENMASK(27, 0)
3572
3566static int skx_count_chabox(void) 3573static int skx_count_chabox(void)
3567{ 3574{
3568 struct pci_dev *chabox_dev = NULL; 3575 struct pci_dev *dev = NULL;
3569 int bus, count = 0; 3576 u32 val = 0;
3570 3577
3571 while (1) { 3578 dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2083, dev);
3572 chabox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x208d, chabox_dev); 3579 if (!dev)
3573 if (!chabox_dev) 3580 goto out;
3574 break;
3575 if (count == 0)
3576 bus = chabox_dev->bus->number;
3577 if (bus != chabox_dev->bus->number)
3578 break;
3579 count++;
3580 }
3581 3581
3582 pci_dev_put(chabox_dev); 3582 pci_read_config_dword(dev, SKX_CAPID6, &val);
3583 return count; 3583 val &= SKX_CHA_BIT_MASK;
3584out:
3585 pci_dev_put(dev);
3586 return hweight32(val);
3584} 3587}
3585 3588
3586void skx_uncore_cpu_init(void) 3589void skx_uncore_cpu_init(void)