Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'perf-core-2025-07-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 performance events updates from Ingo Molnar:
"Intel uncore driver enhancements (Kan Liang):

- Support MSR portal for discovery tables

- Support customized MMIO map size

- Add Panther Lake support

- Add IMC freerunning support for Panther Lake"

* tag 'perf-core-2025-07-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/intel/uncore: Add iMC freerunning for Panther Lake
perf/x86/intel/uncore: Add Panther Lake support
perf/x86/intel/uncore: Support customized MMIO map size
perf/x86/intel/uncore: Support MSR portal for discovery tables

+166 -22
+7
arch/x86/events/intel/uncore.c
··· 1807 1807 .mmio_init = lnl_uncore_mmio_init, 1808 1808 }; 1809 1809 1810 + static const struct intel_uncore_init_fun ptl_uncore_init __initconst = { 1811 + .cpu_init = ptl_uncore_cpu_init, 1812 + .mmio_init = ptl_uncore_mmio_init, 1813 + .use_discovery = true, 1814 + }; 1815 + 1810 1816 static const struct intel_uncore_init_fun icx_uncore_init __initconst = { 1811 1817 .cpu_init = icx_uncore_cpu_init, 1812 1818 .pci_init = icx_uncore_pci_init, ··· 1894 1888 X86_MATCH_VFM(INTEL_ARROWLAKE_U, &mtl_uncore_init), 1895 1889 X86_MATCH_VFM(INTEL_ARROWLAKE_H, &mtl_uncore_init), 1896 1890 X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_uncore_init), 1891 + X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &ptl_uncore_init), 1897 1892 X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &spr_uncore_init), 1898 1893 X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &spr_uncore_init), 1899 1894 X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &gnr_uncore_init),
+2
arch/x86/events/intel/uncore.h
··· 612 612 void adl_uncore_cpu_init(void); 613 613 void lnl_uncore_cpu_init(void); 614 614 void mtl_uncore_cpu_init(void); 615 + void ptl_uncore_cpu_init(void); 615 616 void tgl_uncore_mmio_init(void); 616 617 void tgl_l_uncore_mmio_init(void); 617 618 void adl_uncore_mmio_init(void); 618 619 void lnl_uncore_mmio_init(void); 620 + void ptl_uncore_mmio_init(void); 619 621 int snb_pci2phy_map_init(int devid); 620 622 621 623 /* uncore_snbep.c */
+68 -21
arch/x86/events/intel/uncore_discovery.c
··· 274 274 return false; 275 275 } 276 276 277 - static int parse_discovery_table(struct pci_dev *dev, int die, 278 - u32 bar_offset, bool *parsed, 279 - int *ignore) 277 + static int __parse_discovery_table(resource_size_t addr, int die, 278 + bool *parsed, int *ignore) 280 279 { 281 280 struct uncore_global_discovery global; 282 281 struct uncore_unit_discovery unit; 283 282 void __iomem *io_addr; 284 - resource_size_t addr; 285 283 unsigned long size; 286 - u32 val; 287 284 int i; 288 285 289 - pci_read_config_dword(dev, bar_offset, &val); 290 - 291 - if (val & ~PCI_BASE_ADDRESS_MEM_MASK & ~PCI_BASE_ADDRESS_MEM_TYPE_64) 292 - return -EINVAL; 293 - 294 - addr = (resource_size_t)(val & PCI_BASE_ADDRESS_MEM_MASK); 295 - #ifdef CONFIG_PHYS_ADDR_T_64BIT 296 - if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) { 297 - u32 val2; 298 - 299 - pci_read_config_dword(dev, bar_offset + 4, &val2); 300 - addr |= ((resource_size_t)val2) << 32; 301 - } 302 - #endif 303 286 size = UNCORE_DISCOVERY_GLOBAL_MAP_SIZE; 304 287 io_addr = ioremap(addr, size); 305 288 if (!io_addr) ··· 325 342 return 0; 326 343 } 327 344 328 - bool intel_uncore_has_discovery_tables(int *ignore) 345 + static int parse_discovery_table(struct pci_dev *dev, int die, 346 + u32 bar_offset, bool *parsed, 347 + int *ignore) 348 + { 349 + resource_size_t addr; 350 + u32 val; 351 + 352 + pci_read_config_dword(dev, bar_offset, &val); 353 + 354 + if (val & ~PCI_BASE_ADDRESS_MEM_MASK & ~PCI_BASE_ADDRESS_MEM_TYPE_64) 355 + return -EINVAL; 356 + 357 + addr = (resource_size_t)(val & PCI_BASE_ADDRESS_MEM_MASK); 358 + #ifdef CONFIG_PHYS_ADDR_T_64BIT 359 + if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) { 360 + u32 val2; 361 + 362 + pci_read_config_dword(dev, bar_offset + 4, &val2); 363 + addr |= ((resource_size_t)val2) << 32; 364 + } 365 + #endif 366 + 367 + return __parse_discovery_table(addr, die, parsed, ignore); 368 + } 369 + 370 + static bool intel_uncore_has_discovery_tables_pci(int *ignore) 329 371 { 330 372 u32 device, val, entry_id, bar_offset; 331 373 int die, dvsec = 0, ret = true; ··· 397 389 pci_dev_put(dev); 398 390 399 391 return ret; 392 + } 393 + 394 + static bool intel_uncore_has_discovery_tables_msr(int *ignore) 395 + { 396 + unsigned long *die_mask; 397 + bool parsed = false; 398 + int cpu, die; 399 + u64 base; 400 + 401 + die_mask = kcalloc(BITS_TO_LONGS(uncore_max_dies()), 402 + sizeof(unsigned long), GFP_KERNEL); 403 + if (!die_mask) 404 + return false; 405 + 406 + cpus_read_lock(); 407 + for_each_online_cpu(cpu) { 408 + die = topology_logical_die_id(cpu); 409 + if (__test_and_set_bit(die, die_mask)) 410 + continue; 411 + 412 + if (rdmsrq_safe_on_cpu(cpu, UNCORE_DISCOVERY_MSR, &base)) 413 + continue; 414 + 415 + if (!base) 416 + continue; 417 + 418 + __parse_discovery_table(base, die, &parsed, ignore); 419 + } 420 + 421 + cpus_read_unlock(); 422 + 423 + kfree(die_mask); 424 + return parsed; 425 + } 426 + 427 + bool intel_uncore_has_discovery_tables(int *ignore) 428 + { 429 + return intel_uncore_has_discovery_tables_msr(ignore) || 430 + intel_uncore_has_discovery_tables_pci(ignore); 400 431 } 401 432 402 433 void intel_uncore_clear_discovery_tables(void) ··· 651 604 } 652 605 653 606 addr = unit->addr; 654 - box->io_addr = ioremap(addr, UNCORE_GENERIC_MMIO_SIZE); 607 + box->io_addr = ioremap(addr, type->mmio_map_size); 655 608 if (!box->io_addr) { 656 609 pr_warn("Uncore type %d box %d: ioremap error for 0x%llx.\n", 657 610 type->type_id, unit->id, (unsigned long long)addr);
+7
arch/x86/events/intel/uncore_discovery.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 3 + /* Store the full address of the global discovery table */ 4 + #define UNCORE_DISCOVERY_MSR 0x201e 5 + 3 6 /* Generic device ID of a discovery table device */ 4 7 #define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7 5 8 /* Capability ID for a discovery table device */ ··· 171 168 struct intel_uncore_box *box); 172 169 void uncore_find_add_unit(struct intel_uncore_discovery_unit *node, 173 170 struct rb_root *root, u16 *num_units); 171 + struct intel_uncore_type ** 172 + uncore_get_uncores(enum uncore_access_type type_id, int num_extra, 173 + struct intel_uncore_type **extra, int max_num_types, 174 + struct intel_uncore_type **uncores);
+79
arch/x86/events/intel/uncore_snb.c
··· 1855 1855 } 1856 1856 1857 1857 /* end of Lunar Lake MMIO uncore support */ 1858 + 1859 + /* Panther Lake uncore support */ 1860 + 1861 + #define UNCORE_PTL_MAX_NUM_UNCORE_TYPES 42 1862 + #define UNCORE_PTL_TYPE_IMC 6 1863 + #define UNCORE_PTL_TYPE_SNCU 34 1864 + #define UNCORE_PTL_TYPE_HBO 41 1865 + 1866 + #define PTL_UNCORE_GLOBAL_CTL_OFFSET 0x380 1867 + 1868 + static struct intel_uncore_type ptl_uncore_imc = { 1869 + .name = "imc", 1870 + .mmio_map_size = 0xf00, 1871 + }; 1872 + 1873 + static void ptl_uncore_sncu_init_box(struct intel_uncore_box *box) 1874 + { 1875 + intel_generic_uncore_mmio_init_box(box); 1876 + 1877 + /* Clear the global freeze bit */ 1878 + if (box->io_addr) 1879 + writel(0, box->io_addr + PTL_UNCORE_GLOBAL_CTL_OFFSET); 1880 + } 1881 + 1882 + static struct intel_uncore_ops ptl_uncore_sncu_ops = { 1883 + .init_box = ptl_uncore_sncu_init_box, 1884 + .exit_box = uncore_mmio_exit_box, 1885 + .disable_box = intel_generic_uncore_mmio_disable_box, 1886 + .enable_box = intel_generic_uncore_mmio_enable_box, 1887 + .disable_event = intel_generic_uncore_mmio_disable_event, 1888 + .enable_event = intel_generic_uncore_mmio_enable_event, 1889 + .read_counter = uncore_mmio_read_counter, 1890 + }; 1891 + 1892 + static struct intel_uncore_type ptl_uncore_sncu = { 1893 + .name = "sncu", 1894 + .ops = &ptl_uncore_sncu_ops, 1895 + .mmio_map_size = 0xf00, 1896 + }; 1897 + 1898 + static struct intel_uncore_type ptl_uncore_hbo = { 1899 + .name = "hbo", 1900 + .mmio_map_size = 0xf00, 1901 + }; 1902 + 1903 + static struct intel_uncore_type *ptl_uncores[UNCORE_PTL_MAX_NUM_UNCORE_TYPES] = { 1904 + [UNCORE_PTL_TYPE_IMC] = &ptl_uncore_imc, 1905 + [UNCORE_PTL_TYPE_SNCU] = &ptl_uncore_sncu, 1906 + [UNCORE_PTL_TYPE_HBO] = &ptl_uncore_hbo, 1907 + }; 1908 + 1909 + #define UNCORE_PTL_MMIO_EXTRA_UNCORES 1 1910 + 1911 + static struct intel_uncore_type *ptl_mmio_extra_uncores[UNCORE_PTL_MMIO_EXTRA_UNCORES] = { 1912 + &adl_uncore_imc_free_running, 1913 + }; 1914 + 1915 + void ptl_uncore_mmio_init(void) 1916 + { 1917 + uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 1918 + UNCORE_PTL_MMIO_EXTRA_UNCORES, 1919 + ptl_mmio_extra_uncores, 1920 + UNCORE_PTL_MAX_NUM_UNCORE_TYPES, 1921 + ptl_uncores); 1922 + } 1923 + 1924 + static struct intel_uncore_type *ptl_msr_uncores[] = { 1925 + &mtl_uncore_cbox, 1926 + NULL 1927 + }; 1928 + 1929 + void ptl_uncore_cpu_init(void) 1930 + { 1931 + mtl_uncore_cbox.num_boxes = 6; 1932 + mtl_uncore_cbox.ops = &lnl_uncore_msr_ops; 1933 + uncore_msr_uncores = ptl_msr_uncores; 1934 + } 1935 + 1936 + /* end of Panther Lake uncore support */
+3 -1
arch/x86/events/intel/uncore_snbep.c
··· 6409 6409 to_type->get_topology = from_type->get_topology; 6410 6410 if (from_type->cleanup_mapping) 6411 6411 to_type->cleanup_mapping = from_type->cleanup_mapping; 6412 + if (from_type->mmio_map_size) 6413 + to_type->mmio_map_size = from_type->mmio_map_size; 6412 6414 } 6413 6415 6414 - static struct intel_uncore_type ** 6416 + struct intel_uncore_type ** 6415 6417 uncore_get_uncores(enum uncore_access_type type_id, int num_extra, 6416 6418 struct intel_uncore_type **extra, int max_num_types, 6417 6419 struct intel_uncore_type **uncores)