Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9220f45
perf/x86/intel/uncore: Switch to new Intel CPU model defines
aegl Apr 24, 2024
b8e3762
perf/x86/intel/uncore: Factor out common MMIO init and ops functions
Jul 31, 2024
3929a8c
perf/x86/intel/uncore: Add Lunar Lake support
Jul 31, 2024
a321323
perf/x86/intel/uncore: Add Panther Lake support
Jul 7, 2025
e59d44f
perf/x86/intel/uncore: Move uncore discovery init struct to header
ZideChen0 Dec 31, 2025
3f61246
perf/x86/intel/uncore: Support per-platform discovery base devices
ZideChen0 Dec 31, 2025
03d9313
perf/x86/intel/uncore: Remove has_generic_discovery_table()
ZideChen0 Dec 31, 2025
bd08c51
perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids
ZideChen0 Dec 31, 2025
8de79e2
perf/x86/intel/uncore: Add CBB PMON support for Diamond Rapids
ZideChen0 Dec 31, 2025
fd9b6b5
perf/x86/intel/uncore: Add domain global init callback
ZideChen0 Dec 31, 2025
0ed0c46
perf/x86/intel/uncore: Add freerunning event descriptor helper macro
ZideChen0 Dec 31, 2025
39b8a5d
perf/x86/intel/uncore: Support IIO free-running counters on DMR
ZideChen0 Dec 31, 2025
ec1d0fc
perf/x86/intel/uncore: Support uncore constraint ranges
ZideChen0 Dec 31, 2025
20ca382
perf/x86/intel/uncore: Update DMR uncore constraints preliminarily
ZideChen0 Dec 31, 2025
f6e5411
perf pmu: Relax uncore wildcard matching to allow numeric suffix
ZideChen0 Dec 31, 2025
eaf65c6
perf/x86/intel/uncore: Fix iounmap() leak on global_init failure
ZideChen0 Mar 13, 2026
52f5218
perf/x86/intel/uncore: Skip discovery table for offline dies
ZideChen0 Mar 13, 2026
21c5f7f
perf/x86/intel/uncore: Fix die ID init and look up bugs
ZideChen0 Mar 13, 2026
c2e3a6f
perf/x86/intel/uncore: Remove extra double quote mark
ZideChen0 Mar 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
239 changes: 142 additions & 97 deletions arch/x86/events/intel/uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ int uncore_die_to_segment(int die)
return bus ? pci_domain_nr(bus) : -EINVAL;
}

/* Note: This API can only be used when NUMA information is available. */
int uncore_device_to_die(struct pci_dev *dev)
{
int node = pcibus_to_node(dev->bus);
Expand Down Expand Up @@ -443,7 +444,7 @@ uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *eve

if (type->constraints) {
for_each_event_constraint(c, type->constraints) {
if ((event->hw.config & c->cmask) == c->code)
if (constraint_match(c, event->hw.config))
return c;
}
}
Expand Down Expand Up @@ -1706,203 +1707,248 @@ static int __init uncore_mmio_init(void)
return ret;
}

struct intel_uncore_init_fun {
void (*cpu_init)(void);
int (*pci_init)(void);
void (*mmio_init)(void);
/* Discovery table is required */
bool use_discovery;
/* The units in the discovery table should be ignored. */
int *uncore_units_ignore;
};
static int uncore_mmio_global_init(u64 ctl)
{
void __iomem *io_addr;

io_addr = ioremap(ctl, sizeof(ctl));
if (!io_addr)
return -ENOMEM;

/* Clear freeze bit (0) to enable all counters. */
writel(0, io_addr);

static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
iounmap(io_addr);
return 0;
}

static const struct uncore_plat_init nhm_uncore_init __initconst = {
.cpu_init = nhm_uncore_cpu_init,
};

static const struct intel_uncore_init_fun snb_uncore_init __initconst = {
static const struct uncore_plat_init snb_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = snb_uncore_pci_init,
};

static const struct intel_uncore_init_fun ivb_uncore_init __initconst = {
static const struct uncore_plat_init ivb_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = ivb_uncore_pci_init,
};

static const struct intel_uncore_init_fun hsw_uncore_init __initconst = {
static const struct uncore_plat_init hsw_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = hsw_uncore_pci_init,
};

static const struct intel_uncore_init_fun bdw_uncore_init __initconst = {
static const struct uncore_plat_init bdw_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = bdw_uncore_pci_init,
};

static const struct intel_uncore_init_fun snbep_uncore_init __initconst = {
static const struct uncore_plat_init snbep_uncore_init __initconst = {
.cpu_init = snbep_uncore_cpu_init,
.pci_init = snbep_uncore_pci_init,
};

static const struct intel_uncore_init_fun nhmex_uncore_init __initconst = {
static const struct uncore_plat_init nhmex_uncore_init __initconst = {
.cpu_init = nhmex_uncore_cpu_init,
};

static const struct intel_uncore_init_fun ivbep_uncore_init __initconst = {
static const struct uncore_plat_init ivbep_uncore_init __initconst = {
.cpu_init = ivbep_uncore_cpu_init,
.pci_init = ivbep_uncore_pci_init,
};

static const struct intel_uncore_init_fun hswep_uncore_init __initconst = {
static const struct uncore_plat_init hswep_uncore_init __initconst = {
.cpu_init = hswep_uncore_cpu_init,
.pci_init = hswep_uncore_pci_init,
};

static const struct intel_uncore_init_fun bdx_uncore_init __initconst = {
static const struct uncore_plat_init bdx_uncore_init __initconst = {
.cpu_init = bdx_uncore_cpu_init,
.pci_init = bdx_uncore_pci_init,
};

static const struct intel_uncore_init_fun knl_uncore_init __initconst = {
static const struct uncore_plat_init knl_uncore_init __initconst = {
.cpu_init = knl_uncore_cpu_init,
.pci_init = knl_uncore_pci_init,
};

static const struct intel_uncore_init_fun skl_uncore_init __initconst = {
static const struct uncore_plat_init skl_uncore_init __initconst = {
.cpu_init = skl_uncore_cpu_init,
.pci_init = skl_uncore_pci_init,
};

static const struct intel_uncore_init_fun skx_uncore_init __initconst = {
static const struct uncore_plat_init skx_uncore_init __initconst = {
.cpu_init = skx_uncore_cpu_init,
.pci_init = skx_uncore_pci_init,
};

static const struct intel_uncore_init_fun icl_uncore_init __initconst = {
static const struct uncore_plat_init icl_uncore_init __initconst = {
.cpu_init = icl_uncore_cpu_init,
.pci_init = skl_uncore_pci_init,
};

static const struct intel_uncore_init_fun tgl_uncore_init __initconst = {
static const struct uncore_plat_init tgl_uncore_init __initconst = {
.cpu_init = tgl_uncore_cpu_init,
.mmio_init = tgl_uncore_mmio_init,
};

static const struct intel_uncore_init_fun tgl_l_uncore_init __initconst = {
static const struct uncore_plat_init tgl_l_uncore_init __initconst = {
.cpu_init = tgl_uncore_cpu_init,
.mmio_init = tgl_l_uncore_mmio_init,
};

static const struct intel_uncore_init_fun rkl_uncore_init __initconst = {
static const struct uncore_plat_init rkl_uncore_init __initconst = {
.cpu_init = tgl_uncore_cpu_init,
.pci_init = skl_uncore_pci_init,
};

static const struct intel_uncore_init_fun adl_uncore_init __initconst = {
static const struct uncore_plat_init adl_uncore_init __initconst = {
.cpu_init = adl_uncore_cpu_init,
.mmio_init = adl_uncore_mmio_init,
};

static const struct intel_uncore_init_fun mtl_uncore_init __initconst = {
static const struct uncore_plat_init mtl_uncore_init __initconst = {
.cpu_init = mtl_uncore_cpu_init,
.mmio_init = adl_uncore_mmio_init,
};

static const struct intel_uncore_init_fun icx_uncore_init __initconst = {
static const struct uncore_plat_init lnl_uncore_init __initconst = {
.cpu_init = lnl_uncore_cpu_init,
.mmio_init = lnl_uncore_mmio_init,
};

static const struct uncore_plat_init ptl_uncore_init __initconst = {
.cpu_init = ptl_uncore_cpu_init,
.mmio_init = ptl_uncore_mmio_init,
.domain[0].discovery_base = UNCORE_DISCOVERY_MSR,
};

static const struct uncore_plat_init icx_uncore_init __initconst = {
.cpu_init = icx_uncore_cpu_init,
.pci_init = icx_uncore_pci_init,
.mmio_init = icx_uncore_mmio_init,
};

static const struct intel_uncore_init_fun snr_uncore_init __initconst = {
static const struct uncore_plat_init snr_uncore_init __initconst = {
.cpu_init = snr_uncore_cpu_init,
.pci_init = snr_uncore_pci_init,
.mmio_init = snr_uncore_mmio_init,
};

static const struct intel_uncore_init_fun spr_uncore_init __initconst = {
static const struct uncore_plat_init spr_uncore_init __initconst = {
.cpu_init = spr_uncore_cpu_init,
.pci_init = spr_uncore_pci_init,
.mmio_init = spr_uncore_mmio_init,
.use_discovery = true,
.uncore_units_ignore = spr_uncore_units_ignore,
.domain[0].base_is_pci = true,
.domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
.domain[0].units_ignore = spr_uncore_units_ignore,
};

static const struct intel_uncore_init_fun gnr_uncore_init __initconst = {
static const struct uncore_plat_init gnr_uncore_init __initconst = {
.cpu_init = gnr_uncore_cpu_init,
.pci_init = gnr_uncore_pci_init,
.mmio_init = gnr_uncore_mmio_init,
.use_discovery = true,
.uncore_units_ignore = gnr_uncore_units_ignore,
.domain[0].base_is_pci = true,
.domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
.domain[0].units_ignore = gnr_uncore_units_ignore,
};

static const struct intel_uncore_init_fun generic_uncore_init __initconst = {
static const struct uncore_plat_init dmr_uncore_init __initconst = {
.pci_init = dmr_uncore_pci_init,
.mmio_init = dmr_uncore_mmio_init,
.domain[0].base_is_pci = true,
.domain[0].discovery_base = DMR_UNCORE_DISCOVERY_TABLE_DEVICE,
.domain[0].units_ignore = dmr_uncore_imh_units_ignore,
.domain[1].discovery_base = CBB_UNCORE_DISCOVERY_MSR,
.domain[1].units_ignore = dmr_uncore_cbb_units_ignore,
.domain[1].global_init = uncore_mmio_global_init,
};

static const struct uncore_plat_init generic_uncore_init __initconst = {
.cpu_init = intel_uncore_generic_uncore_cpu_init,
.pci_init = intel_uncore_generic_uncore_pci_init,
.mmio_init = intel_uncore_generic_uncore_mmio_init,
.domain[0].base_is_pci = true,
.domain[0].discovery_base = PCI_ANY_ID,
.domain[1].discovery_base = UNCORE_DISCOVERY_MSR,
};

static const struct x86_cpu_id intel_uncore_match[] __initconst = {
X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &nhm_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &nhm_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(WESTMERE, &nhm_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EP, &nhm_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE, &snb_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE, &ivb_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(HASWELL, &hsw_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(HASWELL_L, &hsw_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(HASWELL_G, &hsw_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(BROADWELL, &bdw_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_G, &bdw_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE_X, &snbep_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EX, &nhmex_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EX, &nhmex_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &ivbep_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &hswep_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &bdx_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &bdx_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &knl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &knl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &skl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &skl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &skx_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &skl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &skl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L, &skl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, &skl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, &icl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_NNPI, &icl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE, &icl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &icx_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &icx_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &tgl_l_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &tgl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &rkl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &adl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &adl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &adl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, &adl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE, &mtl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, &mtl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &spr_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &spr_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_X, &gnr_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_D, &gnr_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &snr_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT, &adl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT_X, &gnr_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT, &gnr_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_DARKMONT_X, &gnr_uncore_init),
X86_MATCH_VFM(INTEL_NEHALEM_EP, &nhm_uncore_init),
X86_MATCH_VFM(INTEL_NEHALEM, &nhm_uncore_init),
X86_MATCH_VFM(INTEL_WESTMERE, &nhm_uncore_init),
X86_MATCH_VFM(INTEL_WESTMERE_EP, &nhm_uncore_init),
X86_MATCH_VFM(INTEL_SANDYBRIDGE, &snb_uncore_init),
X86_MATCH_VFM(INTEL_IVYBRIDGE, &ivb_uncore_init),
X86_MATCH_VFM(INTEL_HASWELL, &hsw_uncore_init),
X86_MATCH_VFM(INTEL_HASWELL_L, &hsw_uncore_init),
X86_MATCH_VFM(INTEL_HASWELL_G, &hsw_uncore_init),
X86_MATCH_VFM(INTEL_BROADWELL, &bdw_uncore_init),
X86_MATCH_VFM(INTEL_BROADWELL_G, &bdw_uncore_init),
X86_MATCH_VFM(INTEL_SANDYBRIDGE_X, &snbep_uncore_init),
X86_MATCH_VFM(INTEL_NEHALEM_EX, &nhmex_uncore_init),
X86_MATCH_VFM(INTEL_WESTMERE_EX, &nhmex_uncore_init),
X86_MATCH_VFM(INTEL_IVYBRIDGE_X, &ivbep_uncore_init),
X86_MATCH_VFM(INTEL_HASWELL_X, &hswep_uncore_init),
X86_MATCH_VFM(INTEL_BROADWELL_X, &bdx_uncore_init),
X86_MATCH_VFM(INTEL_BROADWELL_D, &bdx_uncore_init),
X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &knl_uncore_init),
X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &knl_uncore_init),
X86_MATCH_VFM(INTEL_SKYLAKE, &skl_uncore_init),
X86_MATCH_VFM(INTEL_SKYLAKE_L, &skl_uncore_init),
X86_MATCH_VFM(INTEL_SKYLAKE_X, &skx_uncore_init),
X86_MATCH_VFM(INTEL_KABYLAKE_L, &skl_uncore_init),
X86_MATCH_VFM(INTEL_KABYLAKE, &skl_uncore_init),
X86_MATCH_VFM(INTEL_COMETLAKE_L, &skl_uncore_init),
X86_MATCH_VFM(INTEL_COMETLAKE, &skl_uncore_init),
X86_MATCH_VFM(INTEL_ICELAKE_L, &icl_uncore_init),
X86_MATCH_VFM(INTEL_ICELAKE_NNPI, &icl_uncore_init),
X86_MATCH_VFM(INTEL_ICELAKE, &icl_uncore_init),
X86_MATCH_VFM(INTEL_ICELAKE_D, &icx_uncore_init),
X86_MATCH_VFM(INTEL_ICELAKE_X, &icx_uncore_init),
X86_MATCH_VFM(INTEL_TIGERLAKE_L, &tgl_l_uncore_init),
X86_MATCH_VFM(INTEL_TIGERLAKE, &tgl_uncore_init),
X86_MATCH_VFM(INTEL_ROCKETLAKE, &rkl_uncore_init),
X86_MATCH_VFM(INTEL_ALDERLAKE, &adl_uncore_init),
X86_MATCH_VFM(INTEL_ALDERLAKE_L, &adl_uncore_init),
X86_MATCH_VFM(INTEL_RAPTORLAKE, &adl_uncore_init),
X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &adl_uncore_init),
X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &adl_uncore_init),
X86_MATCH_VFM(INTEL_METEORLAKE, &mtl_uncore_init),
X86_MATCH_VFM(INTEL_METEORLAKE_L, &mtl_uncore_init),
X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_uncore_init),
X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &ptl_uncore_init),
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &spr_uncore_init),
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &spr_uncore_init),
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &gnr_uncore_init),
X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, &gnr_uncore_init),
X86_MATCH_VFM(INTEL_ATOM_TREMONT_D, &snr_uncore_init),
X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &adl_uncore_init),
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, &gnr_uncore_init),
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, &gnr_uncore_init),
X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X, &gnr_uncore_init),
X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, &dmr_uncore_init),
{},
};
MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);

static bool uncore_use_discovery(struct uncore_plat_init *config)
{
for (int i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
if (config->domain[i].discovery_base)
return true;
}

return false;
}

static int __init intel_uncore_init(void)
{
const struct x86_cpu_id *id;
struct intel_uncore_init_fun *uncore_init;
struct uncore_plat_init *uncore_init;
int pret = 0, cret = 0, mret = 0, ret;

if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
Expand All @@ -1913,16 +1959,15 @@ static int __init intel_uncore_init(void)

id = x86_match_cpu(intel_uncore_match);
if (!id) {
if (!uncore_no_discover && intel_uncore_has_discovery_tables(NULL))
uncore_init = (struct intel_uncore_init_fun *)&generic_uncore_init;
else
uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
if (uncore_no_discover || !uncore_discovery(uncore_init))
return -ENODEV;
} else {
uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
if (uncore_no_discover && uncore_init->use_discovery)
uncore_init = (struct uncore_plat_init *)id->driver_data;
if (uncore_no_discover && uncore_use_discovery(uncore_init))
return -ENODEV;
if (uncore_init->use_discovery &&
!intel_uncore_has_discovery_tables(uncore_init->uncore_units_ignore))
if (uncore_use_discovery(uncore_init) &&
!uncore_discovery(uncore_init))
return -ENODEV;
}

Expand Down
Loading