Skip to content

Commit 97c08c6

Browse files
committed
perf/x86/intel/uncore: Support MSR portal for discovery tables
JIRA: https://issues.redhat.com/browse/RHEL-47456 JIRA: https://issues.redhat.com/browse/RHEL-47442 upstream ======== commit cf002da Author: Kan Liang <kan.liang@linux.intel.com> Date: Mon Jul 7 13:17:47 2025 -0700 description =========== Starting from the Panther Lake, the discovery table mechanism is also supported in client platforms. The difference is that the portal of the global discovery table is retrieved from an MSR. The layout of discovery tables are the same as the server platforms. Factor out __parse_discovery_table() to parse discover tables. The uncore PMON is Die scope. Need to parse the discovery tables for each die. Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Link: https://lore.kernel.org/r/20250707201750.616527-2-kan.liang@linux.intel.com Conflicts: ========== In RHEL-9, we haven't adopted the s/rdmsrl/rdmsrq/ rename: c435e60 ("x86/msr: Rename 'rdmsrl()' to 'rdmsrq()'"), thus we need to fall back to rdmsrl_safe_on_cpu(). Signed-off-by: Michael Petlan <mpetlan@redhat.com>
1 parent f197184 commit 97c08c6

File tree

2 files changed

+70
-20
lines changed

2 files changed

+70
-20
lines changed

arch/x86/events/intel/uncore_discovery.c

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -273,32 +273,15 @@ uncore_ignore_unit(struct uncore_unit_discovery *unit, int *ignore)
273273
return false;
274274
}
275275

276-
static int parse_discovery_table(struct pci_dev *dev, int die,
277-
u32 bar_offset, bool *parsed,
278-
int *ignore)
276+
static int __parse_discovery_table(resource_size_t addr, int die,
277+
bool *parsed, int *ignore)
279278
{
280279
struct uncore_global_discovery global;
281280
struct uncore_unit_discovery unit;
282281
void __iomem *io_addr;
283-
resource_size_t addr;
284282
unsigned long size;
285-
u32 val;
286283
int i;
287284

288-
pci_read_config_dword(dev, bar_offset, &val);
289-
290-
if (val & ~PCI_BASE_ADDRESS_MEM_MASK & ~PCI_BASE_ADDRESS_MEM_TYPE_64)
291-
return -EINVAL;
292-
293-
addr = (resource_size_t)(val & PCI_BASE_ADDRESS_MEM_MASK);
294-
#ifdef CONFIG_PHYS_ADDR_T_64BIT
295-
if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
296-
u32 val2;
297-
298-
pci_read_config_dword(dev, bar_offset + 4, &val2);
299-
addr |= ((resource_size_t)val2) << 32;
300-
}
301-
#endif
302285
size = UNCORE_DISCOVERY_GLOBAL_MAP_SIZE;
303286
io_addr = ioremap(addr, size);
304287
if (!io_addr)
@@ -341,7 +324,32 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
341324
return 0;
342325
}
343326

344-
bool intel_uncore_has_discovery_tables(int *ignore)
327+
static int parse_discovery_table(struct pci_dev *dev, int die,
328+
u32 bar_offset, bool *parsed,
329+
int *ignore)
330+
{
331+
resource_size_t addr;
332+
u32 val;
333+
334+
pci_read_config_dword(dev, bar_offset, &val);
335+
336+
if (val & ~PCI_BASE_ADDRESS_MEM_MASK & ~PCI_BASE_ADDRESS_MEM_TYPE_64)
337+
return -EINVAL;
338+
339+
addr = (resource_size_t)(val & PCI_BASE_ADDRESS_MEM_MASK);
340+
#ifdef CONFIG_PHYS_ADDR_T_64BIT
341+
if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
342+
u32 val2;
343+
344+
pci_read_config_dword(dev, bar_offset + 4, &val2);
345+
addr |= ((resource_size_t)val2) << 32;
346+
}
347+
#endif
348+
349+
return __parse_discovery_table(addr, die, parsed, ignore);
350+
}
351+
352+
static bool intel_uncore_has_discovery_tables_pci(int *ignore)
345353
{
346354
u32 device, val, entry_id, bar_offset;
347355
int die, dvsec = 0, ret = true;
@@ -390,6 +398,45 @@ bool intel_uncore_has_discovery_tables(int *ignore)
390398
return ret;
391399
}
392400

401+
static bool intel_uncore_has_discovery_tables_msr(int *ignore)
402+
{
403+
unsigned long *die_mask;
404+
bool parsed = false;
405+
int cpu, die;
406+
u64 base;
407+
408+
die_mask = kcalloc(BITS_TO_LONGS(uncore_max_dies()),
409+
sizeof(unsigned long), GFP_KERNEL);
410+
if (!die_mask)
411+
return false;
412+
413+
cpus_read_lock();
414+
for_each_online_cpu(cpu) {
415+
die = topology_logical_die_id(cpu);
416+
if (__test_and_set_bit(die, die_mask))
417+
continue;
418+
419+
if (rdmsrl_safe_on_cpu(cpu, UNCORE_DISCOVERY_MSR, &base))
420+
continue;
421+
422+
if (!base)
423+
continue;
424+
425+
__parse_discovery_table(base, die, &parsed, ignore);
426+
}
427+
428+
cpus_read_unlock();
429+
430+
kfree(die_mask);
431+
return parsed;
432+
}
433+
434+
bool intel_uncore_has_discovery_tables(int *ignore)
435+
{
436+
return intel_uncore_has_discovery_tables_msr(ignore) ||
437+
intel_uncore_has_discovery_tables_pci(ignore);
438+
}
439+
393440
void intel_uncore_clear_discovery_tables(void)
394441
{
395442
struct intel_uncore_discovery_type *type, *next;

arch/x86/events/intel/uncore_discovery.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
/* SPDX-License-Identifier: GPL-2.0-only */
22

3+
/* Store the full address of the global discovery table */
4+
#define UNCORE_DISCOVERY_MSR 0x201e
5+
36
/* Generic device ID of a discovery table device */
47
#define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
58
/* Capability ID for a discovery table device */

0 commit comments

Comments
 (0)