Commit 6d0ef316 authored by Pu Wen's avatar Pu Wen Committed by Borislav Petkov

x86/events: Add Hygon Dhyana support to PMU infrastructure

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: default avatarPu Wen <puwen@hygon.cn>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarBorislav 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
parent 0b13bec7
...@@ -669,6 +669,10 @@ static int __init amd_core_pmu_init(void) ...@@ -669,6 +669,10 @@ static int __init amd_core_pmu_init(void)
* We fallback to using default amd_get_event_constraints. * We fallback to using default amd_get_event_constraints.
*/ */
break; break;
case 0x18:
pr_cont("Fam18h ");
/* Using default amd_get_event_constraints. */
break;
default: default:
pr_err("core perfctr but no constraints; unknown hardware!\n"); pr_err("core perfctr but no constraints; unknown hardware!\n");
return -ENODEV; return -ENODEV;
......
...@@ -507,17 +507,19 @@ static int __init amd_uncore_init(void) ...@@ -507,17 +507,19 @@ static int __init amd_uncore_init(void)
{ {
int ret = -ENODEV; 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; return -ENODEV;
if (!boot_cpu_has(X86_FEATURE_TOPOEXT)) if (!boot_cpu_has(X86_FEATURE_TOPOEXT))
return -ENODEV; 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 * For F17h or F18h, the Northbridge counters are
* Fabric counters. Also, L3 counters are supported too. The PMUs * repurposed as Data Fabric counters. Also, L3
* are exported based on family as either L2 or L3 and NB or DF. * 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_nb = NUM_COUNTERS_NB;
num_counters_llc = NUM_COUNTERS_L3; num_counters_llc = NUM_COUNTERS_L3;
...@@ -547,7 +549,9 @@ static int __init amd_uncore_init(void) ...@@ -547,7 +549,9 @@ static int __init amd_uncore_init(void)
if (ret) if (ret)
goto fail_nb; 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; ret = 0;
} }
...@@ -561,7 +565,9 @@ static int __init amd_uncore_init(void) ...@@ -561,7 +565,9 @@ static int __init amd_uncore_init(void)
if (ret) if (ret)
goto fail_llc; 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; ret = 0;
} }
......
...@@ -1776,6 +1776,10 @@ static int __init init_hw_perf_events(void) ...@@ -1776,6 +1776,10 @@ static int __init init_hw_perf_events(void)
case X86_VENDOR_AMD: case X86_VENDOR_AMD:
err = amd_pmu_init(); err = amd_pmu_init();
break; break;
case X86_VENDOR_HYGON:
err = amd_pmu_init();
x86_pmu.name = "HYGON";
break;
default: default:
err = -ENOTSUPP; err = -ENOTSUPP;
} }
......
...@@ -46,6 +46,7 @@ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) ...@@ -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 */ /* returns the bit offset of the performance counter register */
switch (boot_cpu_data.x86_vendor) { switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_HYGON:
case X86_VENDOR_AMD: case X86_VENDOR_AMD:
if (msr >= MSR_F15H_PERF_CTR) if (msr >= MSR_F15H_PERF_CTR)
return (msr - MSR_F15H_PERF_CTR) >> 1; return (msr - MSR_F15H_PERF_CTR) >> 1;
...@@ -74,6 +75,7 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) ...@@ -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 */ /* returns the bit offset of the event selection register */
switch (boot_cpu_data.x86_vendor) { switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_HYGON:
case X86_VENDOR_AMD: case X86_VENDOR_AMD:
if (msr >= MSR_F15H_PERF_CTL) if (msr >= MSR_F15H_PERF_CTL)
return (msr - MSR_F15H_PERF_CTL) >> 1; return (msr - MSR_F15H_PERF_CTL) >> 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment