x86/events: Add Hygon Dhyana support to PMU infrastructure
authorPu Wen <puwen@hygon.cn>
Sun, 23 Sep 2018 09:34:47 +0000 (17:34 +0800)
committerBorislav Petkov <bp@suse.de>
Thu, 27 Sep 2018 16:28:57 +0000 (18:28 +0200)
The PMU architecture for the Hygon Dhyana CPU is similar to the AMD
Family 17h one. To support it, call amd_pmu_init() to share the AMD PMU
initialization flow, and change the PMU name to "HYGON".

The Hygon Dhyana CPU supports both legacy and extension PMC MSRs (perf
counter registers and event selection registers), so add Hygon Dhyana
support in the similar way as AMD does.

Signed-off-by: Pu Wen <puwen@hygon.cn>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Borislav Petkov <bp@suse.de>
Cc: tglx@linutronix.de
Cc: mingo@redhat.com
Cc: hpa@zytor.com
Cc: x86@kernel.org
Cc: thomas.lendacky@amd.com
Link: https://lkml.kernel.org/r/9d93ed54a975f33ef7247e0967960f4ce5d3d990.1537533369.git.puwen@hygon.cn
arch/x86/events/amd/core.c
arch/x86/events/amd/uncore.c
arch/x86/events/core.c
arch/x86/kernel/cpu/perfctr-watchdog.c

index c84584bb940280b56f3b7d6d5365803ec4364505..7d2d7c801dba6abb226b630104d1f038242562cf 100644 (file)
@@ -669,6 +669,10 @@ static int __init amd_core_pmu_init(void)
                 * We fallback to using default amd_get_event_constraints.
                 */
                break;
+       case 0x18:
+               pr_cont("Fam18h ");
+               /* Using default amd_get_event_constraints. */
+               break;
        default:
                pr_err("core perfctr but no constraints; unknown hardware!\n");
                return -ENODEV;
index 981ba5e8241ba2ece923ef22f162ac3820c684c4..c7d745bc41362252c654679f6fcb5a53d5bb4707 100644 (file)
@@ -507,17 +507,19 @@ static int __init amd_uncore_init(void)
 {
        int ret = -ENODEV;
 
-       if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+       if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
+           boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
                return -ENODEV;
 
        if (!boot_cpu_has(X86_FEATURE_TOPOEXT))
                return -ENODEV;
 
-       if (boot_cpu_data.x86 == 0x17) {
+       if (boot_cpu_data.x86 == 0x17 || boot_cpu_data.x86 == 0x18) {
                /*
-                * For F17h, the Northbridge counters are repurposed as Data
-                * Fabric counters. Also, L3 counters are supported too. The PMUs
-                * are exported based on  family as either L2 or L3 and NB or DF.
+                * For F17h or F18h, the Northbridge counters are
+                * repurposed as Data Fabric counters. Also, L3
+                * counters are supported too. The PMUs are exported
+                * based on family as either L2 or L3 and NB or DF.
                 */
                num_counters_nb           = NUM_COUNTERS_NB;
                num_counters_llc          = NUM_COUNTERS_L3;
@@ -547,7 +549,9 @@ static int __init amd_uncore_init(void)
                if (ret)
                        goto fail_nb;
 
-               pr_info("AMD NB counters detected\n");
+               pr_info("%s NB counters detected\n",
+                       boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ?
+                               "HYGON" : "AMD");
                ret = 0;
        }
 
@@ -561,7 +565,9 @@ static int __init amd_uncore_init(void)
                if (ret)
                        goto fail_llc;
 
-               pr_info("AMD LLC counters detected\n");
+               pr_info("%s LLC counters detected\n",
+                       boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ?
+                               "HYGON" : "AMD");
                ret = 0;
        }
 
index dfb2f7c0d0192bcd16569d03badd498f355accf7..9c562f5fbde0a7586192c46a2d6a7046b019b78c 100644 (file)
@@ -1776,6 +1776,10 @@ static int __init init_hw_perf_events(void)
        case X86_VENDOR_AMD:
                err = amd_pmu_init();
                break;
+       case X86_VENDOR_HYGON:
+               err = amd_pmu_init();
+               x86_pmu.name = "HYGON";
+               break;
        default:
                err = -ENOTSUPP;
        }
index d389083330c50f8efb57a436a6af6773365ae00e..9556930cd8c1a4248db2937d63e82cfaec18a1f2 100644 (file)
@@ -46,6 +46,7 @@ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr)
 {
        /* returns the bit offset of the performance counter register */
        switch (boot_cpu_data.x86_vendor) {
+       case X86_VENDOR_HYGON:
        case X86_VENDOR_AMD:
                if (msr >= MSR_F15H_PERF_CTR)
                        return (msr - MSR_F15H_PERF_CTR) >> 1;
@@ -74,6 +75,7 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr)
 {
        /* returns the bit offset of the event selection register */
        switch (boot_cpu_data.x86_vendor) {
+       case X86_VENDOR_HYGON:
        case X86_VENDOR_AMD:
                if (msr >= MSR_F15H_PERF_CTL)
                        return (msr - MSR_F15H_PERF_CTL) >> 1;