]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf/x86/intel/uncore: Implement global init callback for GNR uncore
authorZide Chen <zide.chen@intel.com>
Tue, 2 Jun 2026 14:49:08 +0000 (07:49 -0700)
committerPeter Zijlstra <peterz@infradead.org>
Thu, 4 Jun 2026 09:38:38 +0000 (11:38 +0200)
On Sierra Forest and Clearwater Forest, the FRZ_ALL bit in the global
control register defaults to 0 at boot, but UBOX PMON units do not
work until the global control register is explicitly written with 0
to trigger hardware initialization properly.

Implement the generic uncore_msr_global_init() callback and add it to
gnr_uncore_init[], which is shared by GNR, GRR, SRF, and CWF.

Fixes: 632c4bf6d007 ("perf/x86/intel/uncore: Support Granite Rapids")
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260602144908.263680-8-zide.chen@intel.com
arch/x86/events/intel/uncore.c
arch/x86/events/intel/uncore.h
arch/x86/events/intel/uncore_discovery.c

index 4b3a1fa5b41b7de6323754307e980844f6d29e29..7857959c6e823c807befb72af84be013ebb0c73b 100644 (file)
@@ -1716,7 +1716,7 @@ err:
        return ret;
 }
 
-static int uncore_mmio_global_init(u64 ctl)
+static int uncore_mmio_global_init(int die, u64 ctl)
 {
        void __iomem *io_addr;
 
@@ -1731,6 +1731,16 @@ static int uncore_mmio_global_init(u64 ctl)
        return 0;
 }
 
+static int uncore_msr_global_init(int die, u64 msr)
+{
+       int cpu = uncore_die_to_cpu(die);
+
+       if (cpu == -1)
+               return -ENODEV;
+
+       return wrmsrq_on_cpu(cpu, msr, 0);
+}
+
 static const struct uncore_plat_init nhm_uncore_init __initconst = {
        .cpu_init = nhm_uncore_cpu_init,
 };
@@ -1871,6 +1881,7 @@ static const struct uncore_plat_init gnr_uncore_init __initconst = {
        .domain[0].base_is_pci = true,
        .domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
        .domain[0].units_ignore = gnr_uncore_units_ignore,
+       .domain[0].global_init = uncore_msr_global_init,
 };
 
 static const struct uncore_plat_init dmr_uncore_init __initconst = {
index 94c68e3417b6e88c9446e563972aa9c06a4146d8..c2e5ccb1d72c4b2a11862527bc43e123816d5e93 100644 (file)
@@ -53,7 +53,7 @@ struct uncore_discovery_domain {
        /* MSR address or PCI device used as the discovery base */
        u32     discovery_base;
        bool    base_is_pci;
-       int     (*global_init)(u64 ctl);
+       int     (*global_init)(int die, u64 ctl);
 
        /* The units in the discovery table should be ignored. */
        int     *units_ignore;
index af7e80fee81fb1e35a852dff06d119e997c1d3f0..e5077622225686035537011fe103f11c8e2784ba 100644 (file)
@@ -287,7 +287,7 @@ static int __parse_discovery_table(struct uncore_discovery_domain *domain,
        if (!io_addr)
                return -ENOMEM;
 
-       if (domain->global_init && domain->global_init(global.ctl)) {
+       if (domain->global_init && domain->global_init(die, global.ctl)) {
                ret = -ENODEV;
                goto out;
        }
@@ -399,7 +399,6 @@ static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
        if (!die_mask)
                return false;
 
-       cpus_read_lock();
        for_each_online_cpu(cpu) {
                die = topology_logical_die_id(cpu);
                if (__test_and_set_bit(die, die_mask))
@@ -414,8 +413,6 @@ static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
                __parse_discovery_table(domain, base, die, &parsed);
        }
 
-       cpus_read_unlock();
-
        kfree(die_mask);
        return parsed;
 }
@@ -429,10 +426,14 @@ bool uncore_discovery(struct uncore_plat_init *init)
        for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
                domain = &init->domain[i];
                if (domain->discovery_base) {
+                       cpus_read_lock();
+
                        if (!domain->base_is_pci)
                                ret |= uncore_discovery_msr(domain);
                        else
                                ret |= uncore_discovery_pci(domain);
+
+                       cpus_read_unlock();
                }
        }