perf/x86/intel/uncore: Remove uncore extra PCI dev HSWEP_PCI_PCU_3

There may be a kernel panic on the Haswell server and the Broadwell
server, if the snbep_pci2phy_map_init() return error.

The uncore_extra_pci_dev[HSWEP_PCI_PCU_3] is used in the cpu_init() to
detect the existence of the SBOX, which is a MSR type of PMON unit.
The uncore_extra_pci_dev is allocated in the uncore_pci_init(). If the
snbep_pci2phy_map_init() returns error, perf doesn't initialize the
PCI type of the PMON units, so the uncore_extra_pci_dev will not be
allocated. But perf may continue initializing the MSR type of PMON
units. A null dereference kernel panic will be triggered.

The sockets in a Haswell server or a Broadwell server are identical.
Only need to detect the existence of the SBOX once.
Current perf probes all available PCU devices and stores them into the
uncore_extra_pci_dev. It's unnecessary.
Use the pci_get_device() to replace the uncore_extra_pci_dev. Only
detect the existence of the SBOX on the first available PCU device once.

Factor out hswep_has_limit_sbox(), since the Haswell server and the
Broadwell server uses the same way to detect the existence of the SBOX.

Add some macros to replace the magic number.

Fixes: 5306c31c5733 ("perf/x86/uncore/hsw-ep: Handle systems with only two SBOXes")
Reported-by: Steve Wahl <steve.wahl@hpe.com>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Steve Wahl <steve.wahl@hpe.com>
Link: https://lkml.kernel.org/r/1618521764-100923-1-git-send-email-kan.liang@linux.intel.com

authored by Kan Liang and committed by Peter Zijlstra 9d480158 bf05bf16

Changed files
+25 -34
arch
x86
events
+25 -34
arch/x86/events/intel/uncore_snbep.c
··· 1159 1159 SNBEP_PCI_QPI_PORT0_FILTER, 1160 1160 SNBEP_PCI_QPI_PORT1_FILTER, 1161 1161 BDX_PCI_QPI_PORT2_FILTER, 1162 - HSWEP_PCI_PCU_3, 1163 1162 }; 1164 1163 1165 1164 static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event) ··· 2856 2857 NULL, 2857 2858 }; 2858 2859 2860 + #define HSWEP_PCU_DID 0x2fc0 2861 + #define HSWEP_PCU_CAPID4_OFFET 0x94 2862 + #define hswep_get_chop(_cap) (((_cap) >> 6) & 0x3) 2863 + 2864 + static bool hswep_has_limit_sbox(unsigned int device) 2865 + { 2866 + struct pci_dev *dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL); 2867 + u32 capid4; 2868 + 2869 + if (!dev) 2870 + return false; 2871 + 2872 + pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4); 2873 + if (!hswep_get_chop(capid4)) 2874 + return true; 2875 + 2876 + return false; 2877 + } 2878 + 2859 2879 void hswep_uncore_cpu_init(void) 2860 2880 { 2861 - int pkg = boot_cpu_data.logical_proc_id; 2862 - 2863 2881 if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) 2864 2882 hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; 2865 2883 2866 2884 /* Detect 6-8 core systems with only two SBOXes */ 2867 - if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) { 2868 - u32 capid4; 2869 - 2870 - pci_read_config_dword(uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3], 2871 - 0x94, &capid4); 2872 - if (((capid4 >> 6) & 0x3) == 0) 2873 - hswep_uncore_sbox.num_boxes = 2; 2874 - } 2885 + if (hswep_has_limit_sbox(HSWEP_PCU_DID)) 2886 + hswep_uncore_sbox.num_boxes = 2; 2875 2887 2876 2888 uncore_msr_uncores = hswep_msr_uncores; 2877 2889 } ··· 3145 3135 .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 3146 3136 SNBEP_PCI_QPI_PORT1_FILTER), 3147 3137 }, 3148 - { /* PCU.3 (for Capability registers) */ 3149 - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fc0), 3150 - .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 3151 - HSWEP_PCI_PCU_3), 3152 - }, 3153 3138 { /* end: all zeroes */ } 3154 3139 }; 3155 3140 ··· 3236 3231 EVENT_CONSTRAINT_END 3237 3232 }; 3238 3233 3234 + #define BDX_PCU_DID 0x6fc0 3235 + 3239 3236 void bdx_uncore_cpu_init(void) 3240 3237 { 3241 - int pkg = topology_phys_to_logical_pkg(boot_cpu_data.phys_proc_id); 3242 - 3243 3238 if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) 3244 3239 bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; 3245 3240 uncore_msr_uncores = bdx_msr_uncores; 3246 3241 3247 - /* BDX-DE doesn't have SBOX */ 3248 - if (boot_cpu_data.x86_model == 86) { 3249 - uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL; 3250 3242 /* Detect systems with no SBOXes */ 3251 - } else if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) { 3252 - struct pci_dev *pdev; 3253 - u32 capid4; 3243 + if ((boot_cpu_data.x86_model == 86) || hswep_has_limit_sbox(BDX_PCU_DID)) 3244 + uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL; 3254 3245 3255 - pdev = uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]; 3256 - pci_read_config_dword(pdev, 0x94, &capid4); 3257 - if (((capid4 >> 6) & 0x3) == 0) 3258 - bdx_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL; 3259 - } 3260 3246 hswep_uncore_pcu.constraints = bdx_uncore_pcu_constraints; 3261 3247 } 3262 3248 ··· 3467 3471 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f46), 3468 3472 .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 3469 3473 BDX_PCI_QPI_PORT2_FILTER), 3470 - }, 3471 - { /* PCU.3 (for Capability registers) */ 3472 - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fc0), 3473 - .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 3474 - HSWEP_PCI_PCU_3), 3475 3474 }, 3476 3475 { /* end: all zeroes */ } 3477 3476 };