Skip to content

Commit 9d48015

Browse files
Kan LiangPeter Zijlstra
authored andcommitted
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: 5306c31 ("perf/x86/uncore/hsw-ep: Handle systems with only two SBOXes") Reported-by: Steve Wahl <[email protected]> Signed-off-by: Kan Liang <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Tested-by: Steve Wahl <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent bf05bf1 commit 9d48015

File tree

1 file changed

+26
-35
lines changed

1 file changed

+26
-35
lines changed

arch/x86/events/intel/uncore_snbep.c

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,6 @@ enum {
11591159
SNBEP_PCI_QPI_PORT0_FILTER,
11601160
SNBEP_PCI_QPI_PORT1_FILTER,
11611161
BDX_PCI_QPI_PORT2_FILTER,
1162-
HSWEP_PCI_PCU_3,
11631162
};
11641163

11651164
static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
@@ -2857,22 +2856,33 @@ static struct intel_uncore_type *hswep_msr_uncores[] = {
28572856
NULL,
28582857
};
28592858

2860-
void hswep_uncore_cpu_init(void)
2859+
#define HSWEP_PCU_DID 0x2fc0
2860+
#define HSWEP_PCU_CAPID4_OFFET 0x94
2861+
#define hswep_get_chop(_cap) (((_cap) >> 6) & 0x3)
2862+
2863+
static bool hswep_has_limit_sbox(unsigned int device)
28612864
{
2862-
int pkg = boot_cpu_data.logical_proc_id;
2865+
struct pci_dev *dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
2866+
u32 capid4;
2867+
2868+
if (!dev)
2869+
return false;
2870+
2871+
pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4);
2872+
if (!hswep_get_chop(capid4))
2873+
return true;
28632874

2875+
return false;
2876+
}
2877+
2878+
void hswep_uncore_cpu_init(void)
2879+
{
28642880
if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
28652881
hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
28662882

28672883
/* Detect 6-8 core systems with only two SBOXes */
2868-
if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) {
2869-
u32 capid4;
2870-
2871-
pci_read_config_dword(uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3],
2872-
0x94, &capid4);
2873-
if (((capid4 >> 6) & 0x3) == 0)
2874-
hswep_uncore_sbox.num_boxes = 2;
2875-
}
2884+
if (hswep_has_limit_sbox(HSWEP_PCU_DID))
2885+
hswep_uncore_sbox.num_boxes = 2;
28762886

28772887
uncore_msr_uncores = hswep_msr_uncores;
28782888
}
@@ -3135,11 +3145,6 @@ static const struct pci_device_id hswep_uncore_pci_ids[] = {
31353145
.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
31363146
SNBEP_PCI_QPI_PORT1_FILTER),
31373147
},
3138-
{ /* PCU.3 (for Capability registers) */
3139-
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fc0),
3140-
.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3141-
HSWEP_PCI_PCU_3),
3142-
},
31433148
{ /* end: all zeroes */ }
31443149
};
31453150

@@ -3231,27 +3236,18 @@ static struct event_constraint bdx_uncore_pcu_constraints[] = {
32313236
EVENT_CONSTRAINT_END
32323237
};
32333238

3239+
#define BDX_PCU_DID 0x6fc0
3240+
32343241
void bdx_uncore_cpu_init(void)
32353242
{
3236-
int pkg = topology_phys_to_logical_pkg(boot_cpu_data.phys_proc_id);
3237-
32383243
if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
32393244
bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
32403245
uncore_msr_uncores = bdx_msr_uncores;
32413246

3242-
/* BDX-DE doesn't have SBOX */
3243-
if (boot_cpu_data.x86_model == 86) {
3244-
uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
32453247
/* Detect systems with no SBOXes */
3246-
} else if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) {
3247-
struct pci_dev *pdev;
3248-
u32 capid4;
3249-
3250-
pdev = uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3];
3251-
pci_read_config_dword(pdev, 0x94, &capid4);
3252-
if (((capid4 >> 6) & 0x3) == 0)
3253-
bdx_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
3254-
}
3248+
if ((boot_cpu_data.x86_model == 86) || hswep_has_limit_sbox(BDX_PCU_DID))
3249+
uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
3250+
32553251
hswep_uncore_pcu.constraints = bdx_uncore_pcu_constraints;
32563252
}
32573253

@@ -3472,11 +3468,6 @@ static const struct pci_device_id bdx_uncore_pci_ids[] = {
34723468
.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
34733469
BDX_PCI_QPI_PORT2_FILTER),
34743470
},
3475-
{ /* PCU.3 (for Capability registers) */
3476-
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fc0),
3477-
.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3478-
HSWEP_PCI_PCU_3),
3479-
},
34803471
{ /* end: all zeroes */ }
34813472
};
34823473

0 commit comments

Comments
 (0)