[tip:x86/cpu] x86/CPU/hygon: Fix phys_proc_id calculation logic for multi-die processors

2019-03-23 Thread tip-bot for Pu Wen
Commit-ID:  e0ceeae708cebf22c990c3d703a4ca187dc837f5
Gitweb: https://git.kernel.org/tip/e0ceeae708cebf22c990c3d703a4ca187dc837f5
Author: Pu Wen 
AuthorDate: Sat, 23 Mar 2019 23:42:20 +0800
Committer:  Borislav Petkov 
CommitDate: Sat, 23 Mar 2019 17:41:09 +0100

x86/CPU/hygon: Fix phys_proc_id calculation logic for multi-die processors

The Hygon family 18h multi-die processor platform supports 1, 2 or
4-Dies per socket. The topology looks like this:

  System View (with 1-Die 2-Socket):
 ||
   --   -
   SOCKET0 | D0 |   | D1 |  SOCKET1
   --   -

  System View (with 2-Die 2-socket):
 
 | -|--
 | || |
      
   SOCKET0 | D1 -- D0 |   | D3 -- D2 | SOCKET1
      

  System View (with 4-Die 2-Socket) :
 
 | -|--
 | || |
      
   | D1 -- D0 |   | D7 -- D6 |
   | |  \/ |  |   | |  \/ |  |
   SOCKET0 | |  /\ |  |   | |  /\ |  | SOCKET1
   | D2 -- D3 |   | D4 -- D5 |
      
 | || |
 --|| |
   

Currently

  phys_proc_id = initial_apicid >> bits

calculates the physical processor ID from the initial_apicid by shifting
*bits*.

However, this does not work for 1-Die and 2-Die 2-socket systems.

According to document [1] section 2.1.11.1, the bits is the value of
CPUID_Fn8008_ECX[12:15]. The possible values are 4, 5 or 6 which
mean:

  4 - 1 die
  5 - 2 dies
  6 - 3/4 dies.

Hygon programs the initial ApicId the same way as AMD. The ApicId is
read from CPUID_Fn0001_EBX (see section 2.1.11.1 of referrence [1])
and the definition is as below (see section 2.1.10.2.1.3 of [1]):

  -
  Bit | 6 |   5  4  |3   |2   1   0   |
  |---|-|||
  IDs | Socket ID | Node ID | CCX ID | Core/Thread ID |
  -

So for 3/4-Die configurations, the bits variable is 6, which is the same
as the ApicID definition field.

For 1-Die and 2-Die configurations, bits is 4 or 5, which will cause the
right shifted result to not be exactly the value of socket ID.

However, the socket ID should be obtained from ApicId[6]. To fix the
problem and match the ApicID field definition, set the shift bits to 6
for all Hygon family 18h multi-die CPUs.

Because AMD doesn't have 2-Socket systems with 1-Die/2-Die processors
(see reference [2]), this doesn't need to be changed on the AMD side but
only for Hygon.

References:
[1] 
https://www.amd.com/system/files/TechDocs/54945_PPR_Family_17h_Models_00h-0Fh.pdf
[2] https://www.amd.com/en/products/specifications/processors

 [bp: heavily massage commit message. ]

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Cc: H. Peter Anvin 
Cc: Ingo Molnar 
Cc: Thomas Gleixner 
Cc: Thomas Lendacky 
Cc: Yazen Ghannam 
Cc: x86-ml 
Link: https://lkml.kernel.org/r/1553355740-1-1-git-send-email-pu...@hygon.cn
---
 arch/x86/kernel/cpu/hygon.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
index cf25405444ab..415621ddb8a2 100644
--- a/arch/x86/kernel/cpu/hygon.c
+++ b/arch/x86/kernel/cpu/hygon.c
@@ -19,6 +19,8 @@
 
 #include "cpu.h"
 
+#define APICID_SOCKET_ID_BIT 6
+
 /*
  * nodes_per_socket: Stores the number of nodes per socket.
  * Refer to CPUID Fn8000_001E_ECX Node Identifiers[10:8]
@@ -87,6 +89,9 @@ static void hygon_get_topology(struct cpuinfo_x86 *c)
if (!err)
c->x86_coreid_bits = get_count_order(c->x86_max_cores);
 
+   /* Socket ID is ApicId[6] for these processors. */
+   c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT;
+
cacheinfo_hygon_init_llc_id(c, cpu, node_id);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
u64 value;


[tip:perf/core] perf tools: Add Hygon Dhyana support

2018-11-21 Thread tip-bot for Pu Wen
Commit-ID:  4787eff3fa88f62fede6ed7afa06477ae6bf984d
Gitweb: https://git.kernel.org/tip/4787eff3fa88f62fede6ed7afa06477ae6bf984d
Author: Pu Wen 
AuthorDate: Mon, 12 Nov 2018 15:40:51 +0800
Committer:  Arnaldo Carvalho de Melo 
CommitDate: Wed, 21 Nov 2018 22:39:56 -0300

perf tools: Add Hygon Dhyana support

The tool perf is useful for the performance analysis on the Hygon Dhyana
platform. But right now there is no Hygon support for it to analyze the
KVM guest os data. So add Hygon Dhyana support to it by checking vendor
string to share the code path of AMD.

Signed-off-by: Pu Wen 
Acked-by: Borislav Petkov 
Cc: Alexander Shishkin 
Cc: Jiri Olsa 
Cc: Namhyung Kim 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Link: http://lkml.kernel.org/r/1542008451-31735-1-git-send-email-pu...@hygon.cn
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/arch/x86/util/kvm-stat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/arch/x86/util/kvm-stat.c 
b/tools/perf/arch/x86/util/kvm-stat.c
index b32409a0e546..081353d7b095 100644
--- a/tools/perf/arch/x86/util/kvm-stat.c
+++ b/tools/perf/arch/x86/util/kvm-stat.c
@@ -156,7 +156,7 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char 
*cpuid)
if (strstr(cpuid, "Intel")) {
kvm->exit_reasons = vmx_exit_reasons;
kvm->exit_reasons_isa = "VMX";
-   } else if (strstr(cpuid, "AMD")) {
+   } else if (strstr(cpuid, "AMD") || strstr(cpuid, "Hygon")) {
kvm->exit_reasons = svm_exit_reasons;
kvm->exit_reasons_isa = "SVM";
} else


[tip:x86/cpu] tools/cpupower: Add Hygon Dhyana support

2018-10-04 Thread tip-bot for Pu Wen
Commit-ID:  995d5f64b62f20f05b8e0972f07ec4d6c2c9
Gitweb: https://git.kernel.org/tip/995d5f64b62f20f05b8e0972f07ec4d6c2c9
Author: Pu Wen 
AuthorDate: Thu, 4 Oct 2018 09:21:43 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 4 Oct 2018 09:57:25 +0200

tools/cpupower: Add Hygon Dhyana support

The tool cpupower is useful to get CPU frequency information and monitor
power stats on the Hygon Dhyana platform. So add Hygon Dhyana support to
it by checking vendor and family to share the code path of AMD family
17h.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Acked-by: Shuah Khan (Samsung OSG) 
CC: Prarit Bhargava 
CC: Shuah Khan 
CC: Thomas Gleixner 
CC: Thomas Renninger 
CC: linux...@vger.kernel.org
Link: 
http://lkml.kernel.org/r/5ce86123a7b9dad925ac583d88d2f921040e859b.1538583282.git.pu...@hygon.cn
---
 tools/power/cpupower/utils/cpufreq-info.c   | 6 --
 tools/power/cpupower/utils/helpers/amd.c| 4 ++--
 tools/power/cpupower/utils/helpers/cpuid.c  | 8 +---
 tools/power/cpupower/utils/helpers/helpers.h| 2 +-
 tools/power/cpupower/utils/helpers/misc.c   | 2 +-
 tools/power/cpupower/utils/idle_monitor/mperf_monitor.c | 3 ++-
 6 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/tools/power/cpupower/utils/cpufreq-info.c 
b/tools/power/cpupower/utils/cpufreq-info.c
index df43cd45d810..56e54eabc65c 100644
--- a/tools/power/cpupower/utils/cpufreq-info.c
+++ b/tools/power/cpupower/utils/cpufreq-info.c
@@ -170,6 +170,7 @@ static int get_boost_mode(unsigned int cpu)
unsigned long pstates[MAX_HW_PSTATES] = {0,};
 
if (cpupower_cpu_info.vendor != X86_VENDOR_AMD &&
+   cpupower_cpu_info.vendor != X86_VENDOR_HYGON &&
cpupower_cpu_info.vendor != X86_VENDOR_INTEL)
return 0;
 
@@ -190,8 +191,9 @@ static int get_boost_mode(unsigned int cpu)
printf(_("Supported: %s\n"), support ? _("yes") : _("no"));
printf(_("Active: %s\n"), active ? _("yes") : _("no"));
 
-   if (cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
-   cpupower_cpu_info.family >= 0x10) {
+   if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
+cpupower_cpu_info.family >= 0x10) ||
+cpupower_cpu_info.vendor == X86_VENDOR_HYGON) {
ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states,
 pstates, &pstate_no);
if (ret)
diff --git a/tools/power/cpupower/utils/helpers/amd.c 
b/tools/power/cpupower/utils/helpers/amd.c
index bb41cdd0df6b..65beaeefeef0 100644
--- a/tools/power/cpupower/utils/helpers/amd.c
+++ b/tools/power/cpupower/utils/helpers/amd.c
@@ -45,7 +45,7 @@ static int get_did(int family, union msr_pstate pstate)
 
if (family == 0x12)
t = pstate.val & 0xf;
-   else if (family == 0x17)
+   else if (family == 0x17 || family == 0x18)
t = pstate.fam17h_bits.did;
else
t = pstate.bits.did;
@@ -59,7 +59,7 @@ static int get_cof(int family, union msr_pstate pstate)
int fid, did, cof;
 
did = get_did(family, pstate);
-   if (family == 0x17) {
+   if (family == 0x17 || family == 0x18) {
fid = pstate.fam17h_bits.fid;
cof = 200 * fid / did;
} else {
diff --git a/tools/power/cpupower/utils/helpers/cpuid.c 
b/tools/power/cpupower/utils/helpers/cpuid.c
index 732b0b41ba26..5cc39d4e23ed 100644
--- a/tools/power/cpupower/utils/helpers/cpuid.c
+++ b/tools/power/cpupower/utils/helpers/cpuid.c
@@ -8,7 +8,7 @@
 #include "helpers/helpers.h"
 
 static const char *cpu_vendor_table[X86_VENDOR_MAX] = {
-   "Unknown", "GenuineIntel", "AuthenticAMD",
+   "Unknown", "GenuineIntel", "AuthenticAMD", "HygonGenuine",
 };
 
 #if defined(__i386__) || defined(__x86_64__)
@@ -109,6 +109,7 @@ out:
fclose(fp);
/* Get some useful CPU capabilities from cpuid */
if (cpu_info->vendor != X86_VENDOR_AMD &&
+   cpu_info->vendor != X86_VENDOR_HYGON &&
cpu_info->vendor != X86_VENDOR_INTEL)
return ret;
 
@@ -124,8 +125,9 @@ out:
if (cpuid_level >= 6 && (cpuid_ecx(6) & 0x1))
cpu_info->caps |= CPUPOWER_CAP_APERF;
 
-   /* AMD Boost state enable/disable register */
-   if (cpu_info->vendor == X86_VENDOR_AMD) {
+   /* AMD or Hygon Boost state enable/disable register */
+   if (cpu_info->vendor == X86_VENDOR_AMD ||
+   cpu_info->vendor == X86_VENDOR_HYGON) {
if (ext_cpuid_level >= 0x8007 &&
(cpuid_edx(0x8007) & (1 << 9)))
cpu_info->caps |= CPUPOWER_CAP_AMD_CBP;
diff --git a/tools/power/cpupower/utils/helpers/helpers.h 
b/tools/power/cpupower/utils/helpers/helpers.h
index 41da392be448..902139689315 100644
--- a/tools/power/cpupower/utils/helpers/helpers.h
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -61

[tip:x86/cpu] cpufreq: Add Hygon Dhyana support

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  cc9690cfc7a36873b219d569049e10f073dd22e4
Gitweb: https://git.kernel.org/tip/cc9690cfc7a36873b219d569049e10f073dd22e4
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:37:38 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:29:00 +0200

cpufreq: Add Hygon Dhyana support

The Hygon Dhyana CPU supports ACPI P-States, and there is SMBus device
(PCI device ID 0x790b) on the Hygon platform. Add Hygon Dhyana support
to the cpufreq driver by using the code path of AMD family 17h.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Acked-by: Rafael J. Wysocki 
Cc: r...@rjwysocki.net
Cc: viresh.ku...@linaro.org
Cc: b...@alien8.de
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Cc: raf...@kernel.org
Cc: linux...@vger.kernel.org
Link: 
https://lkml.kernel.org/r/4db6f0f8537a93c172430c446a0297a6ab1c3c2d.1537533369.git.pu...@hygon.cn
---
 drivers/cpufreq/acpi-cpufreq.c | 5 +
 drivers/cpufreq/amd_freq_sensitivity.c | 9 +++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index b61f4ec43e06..d62fd374d5c7 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -61,6 +61,7 @@ enum {
 
 #define INTEL_MSR_RANGE(0x)
 #define AMD_MSR_RANGE  (0x7)
+#define HYGON_MSR_RANGE(0x7)
 
 #define MSR_K7_HWCR_CPB_DIS(1ULL << 25)
 
@@ -95,6 +96,7 @@ static bool boost_state(unsigned int cpu)
rdmsr_on_cpu(cpu, MSR_IA32_MISC_ENABLE, &lo, &hi);
msr = lo | ((u64)hi << 32);
return !(msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
+   case X86_VENDOR_HYGON:
case X86_VENDOR_AMD:
rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
msr = lo | ((u64)hi << 32);
@@ -113,6 +115,7 @@ static int boost_set_msr(bool enable)
msr_addr = MSR_IA32_MISC_ENABLE;
msr_mask = MSR_IA32_MISC_ENABLE_TURBO_DISABLE;
break;
+   case X86_VENDOR_HYGON:
case X86_VENDOR_AMD:
msr_addr = MSR_K7_HWCR;
msr_mask = MSR_K7_HWCR_CPB_DIS;
@@ -225,6 +228,8 @@ static unsigned extract_msr(struct cpufreq_policy *policy, 
u32 msr)
 
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
msr &= AMD_MSR_RANGE;
+   else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
+   msr &= HYGON_MSR_RANGE;
else
msr &= INTEL_MSR_RANGE;
 
diff --git a/drivers/cpufreq/amd_freq_sensitivity.c 
b/drivers/cpufreq/amd_freq_sensitivity.c
index be926d9a66e5..4ac7c3cf34be 100644
--- a/drivers/cpufreq/amd_freq_sensitivity.c
+++ b/drivers/cpufreq/amd_freq_sensitivity.c
@@ -111,11 +111,16 @@ static int __init amd_freq_sensitivity_init(void)
 {
u64 val;
struct pci_dev *pcidev;
+   unsigned int pci_vendor;
 
-   if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+   if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+   pci_vendor = PCI_VENDOR_ID_AMD;
+   else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
+   pci_vendor = PCI_VENDOR_ID_HYGON;
+   else
return -ENODEV;
 
-   pcidev = pci_get_device(PCI_VENDOR_ID_AMD,
+   pcidev = pci_get_device(pci_vendor,
PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, NULL);
 
if (!pcidev) {


[tip:x86/cpu] ACPI: Add Hygon Dhyana support

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  7377ed4bd56e6cc1ddbb63f03626fc5b92d3d6fe
Gitweb: https://git.kernel.org/tip/7377ed4bd56e6cc1ddbb63f03626fc5b92d3d6fe
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:37:05 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:29:00 +0200

ACPI: Add Hygon Dhyana support

The Hygon Dhyana CPU has NONSTOP TSC feature, so enable the ACPI driver
support to it.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Acked-by: Rafael J. Wysocki 
Cc: r...@rjwysocki.net
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Cc: l...@kernel.org
Cc: raf...@kernel.org
Cc: linux-a...@vger.kernel.org
Link: 
https://lkml.kernel.org/r/cce6ee26f4e2ebbab493433264d89d7cea661284.1537533369.git.pu...@hygon.cn
---
 drivers/acpi/acpi_pad.c   | 1 +
 drivers/acpi/processor_idle.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 552c1f725b6c..a47676a55b84 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -70,6 +70,7 @@ static void power_saving_mwait_init(void)
 
 #if defined(CONFIG_X86)
switch (boot_cpu_data.x86_vendor) {
+   case X86_VENDOR_HYGON:
case X86_VENDOR_AMD:
case X86_VENDOR_INTEL:
/*
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index abb559cd28d7..b2131c4ea124 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -205,6 +205,7 @@ static void lapic_timer_state_broadcast(struct 
acpi_processor *pr,
 static void tsc_check_state(int state)
 {
switch (boot_cpu_data.x86_vendor) {
+   case X86_VENDOR_HYGON:
case X86_VENDOR_AMD:
case X86_VENDOR_INTEL:
case X86_VENDOR_CENTAUR:


[tip:x86/cpu] x86/xen: Add Hygon Dhyana support to Xen

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  4044240365e85ef7ae43a6dc454669b57853124c
Gitweb: https://git.kernel.org/tip/4044240365e85ef7ae43a6dc454669b57853124c
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:36:46 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:59 +0200

x86/xen: Add Hygon Dhyana support to Xen

To make Xen work on the Hygon platform, reuse AMD's Xen support code
path for Hygon Dhyana CPU.

There are six core performance events counters per thread, so there are
six MSRs for these counters. Also there are four legacy PMC MSRs, they
are aliases of the counters.

In this version, use the legacy and safe version of MSR access. Tested
successfully with VPMU enabled in Xen on Hygon platform by testing with
perf.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Reviewed-by: Boris Ostrovsky 
Cc: jgr...@suse.com
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Cc: xen-de...@lists.xenproject.org
Link: 
https://lkml.kernel.org/r/311bf41f08f24550aa6c5da3f1e03a68d3b89dac.1537533369.git.pu...@hygon.cn
---
 arch/x86/xen/pmu.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/xen/pmu.c b/arch/x86/xen/pmu.c
index 7d00d4ad44d4..9403854cde31 100644
--- a/arch/x86/xen/pmu.c
+++ b/arch/x86/xen/pmu.c
@@ -90,6 +90,12 @@ static void xen_pmu_arch_init(void)
k7_counters_mirrored = 0;
break;
}
+   } else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
+   amd_num_counters = F10H_NUM_COUNTERS;
+   amd_counters_base = MSR_K7_PERFCTR0;
+   amd_ctrls_base = MSR_K7_EVNTSEL0;
+   amd_msr_step = 1;
+   k7_counters_mirrored = 0;
} else {
uint32_t eax, ebx, ecx, edx;
 
@@ -285,7 +291,7 @@ static bool xen_amd_pmu_emulate(unsigned int msr, u64 *val, 
bool is_read)
 
 bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err)
 {
-   if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
+   if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) {
if (is_amd_pmu_msr(msr)) {
if (!xen_amd_pmu_emulate(msr, val, 1))
*val = native_read_msr_safe(msr, err);
@@ -308,7 +314,7 @@ bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t 
high, int *err)
 {
uint64_t val = ((uint64_t)high << 32) | low;
 
-   if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
+   if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) {
if (is_amd_pmu_msr(msr)) {
if (!xen_amd_pmu_emulate(msr, &val, 0))
*err = native_write_msr_safe(msr, low, high);
@@ -379,7 +385,7 @@ static unsigned long long xen_intel_read_pmc(int counter)
 
 unsigned long long xen_read_pmc(int counter)
 {
-   if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+   if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
return xen_amd_read_pmc(counter);
else
return xen_intel_read_pmc(counter);


[tip:x86/cpu] x86/kvm: Add Hygon Dhyana support to KVM

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  b8f4abb652146ddde04ab6e2a80e8cde27ff4470
Gitweb: https://git.kernel.org/tip/b8f4abb652146ddde04ab6e2a80e8cde27ff4470
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:36:31 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:59 +0200

x86/kvm: Add Hygon Dhyana support to KVM

The Hygon Dhyana CPU has the SVM feature as AMD family 17h does.
So enable the KVM infrastructure support to it.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Reviewed-by: Borislav Petkov 
Cc: pbonz...@redhat.com
Cc: rkrc...@redhat.com
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Cc: k...@vger.kernel.org
Link: 
https://lkml.kernel.org/r/654dd12876149fba9561698eaf9fc15d030301f8.1537533369.git.pu...@hygon.cn
---
 arch/x86/include/asm/kvm_emulate.h |  4 
 arch/x86/include/asm/virtext.h |  5 +++--
 arch/x86/kvm/emulate.c | 11 ++-
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h 
b/arch/x86/include/asm/kvm_emulate.h
index 0f82cd91cd3c..93c4bf598fb0 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -364,6 +364,10 @@ struct x86_emulate_ctxt {
 #define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574
 #define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273
 
+#define X86EMUL_CPUID_VENDOR_HygonGenuine_ebx 0x6f677948
+#define X86EMUL_CPUID_VENDOR_HygonGenuine_ecx 0x656e6975
+#define X86EMUL_CPUID_VENDOR_HygonGenuine_edx 0x6e65476e
+
 #define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547
 #define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e
 #define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69
diff --git a/arch/x86/include/asm/virtext.h b/arch/x86/include/asm/virtext.h
index 0116b2ee9e64..e05e0d309244 100644
--- a/arch/x86/include/asm/virtext.h
+++ b/arch/x86/include/asm/virtext.h
@@ -83,9 +83,10 @@ static inline void cpu_emergency_vmxoff(void)
  */
 static inline int cpu_has_svm(const char **msg)
 {
-   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) {
if (msg)
-   *msg = "not amd";
+   *msg = "not amd or hygon";
return 0;
}
 
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 106482da6388..34edf198708f 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2711,7 +2711,16 @@ static bool em_syscall_is_enabled(struct 
x86_emulate_ctxt *ctxt)
edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
return true;
 
-   /* default: (not Intel, not AMD), apply Intel's stricter rules... */
+   /* Hygon ("HygonGenuine") */
+   if (ebx == X86EMUL_CPUID_VENDOR_HygonGenuine_ebx &&
+   ecx == X86EMUL_CPUID_VENDOR_HygonGenuine_ecx &&
+   edx == X86EMUL_CPUID_VENDOR_HygonGenuine_edx)
+   return true;
+
+   /*
+* default: (not Intel, not AMD, not Hygon), apply Intel's
+* stricter rules...
+*/
return false;
 }
 


[tip:x86/cpu] x86/mce: Add Hygon Dhyana support to the MCA infrastructure

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  ac78bd72355d0da64c073c12927264d4ff19b886
Gitweb: https://git.kernel.org/tip/ac78bd72355d0da64c073c12927264d4ff19b886
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:36:04 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:59 +0200

x86/mce: Add Hygon Dhyana support to the MCA infrastructure

The machine check architecture for Hygon Dhyana CPU is similar to the
AMD family 17h one. Add vendor checking for Hygon Dhyana to share the
code path of AMD family 17h.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Reviewed-by: Borislav Petkov 
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: tony.l...@intel.com
Cc: thomas.lenda...@amd.com
Cc: linux-e...@vger.kernel.org
Link: 
https://lkml.kernel.org/r/87d8a4f16bdea0bfe0c0cf2e4a8d2c2a99b1055c.1537533369.git.pu...@hygon.cn
---
 arch/x86/include/asm/mce.h|  2 ++
 arch/x86/kernel/cpu/mcheck/mce-severity.c |  3 ++-
 arch/x86/kernel/cpu/mcheck/mce.c  | 20 +++-
 3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 3a17107594c8..550f2c95dc1e 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -214,6 +214,8 @@ static inline void mce_amd_feature_init(struct cpuinfo_x86 
*c) { }
 static inline int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 
*sys_addr) { return -EINVAL; };
 #endif
 
+static inline void mce_hygon_feature_init(struct cpuinfo_x86 *c) { return 
mce_amd_feature_init(c); }
+
 int mce_available(struct cpuinfo_x86 *c);
 bool mce_is_memory_error(struct mce *m);
 
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c 
b/arch/x86/kernel/cpu/mcheck/mce-severity.c
index f34d89c01edc..44396d521987 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
@@ -336,7 +336,8 @@ int (*mce_severity)(struct mce *m, int tolerant, char 
**msg, bool is_excp) =
 
 void __init mcheck_vendor_init_severity(void)
 {
-   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)
mce_severity = mce_severity_amd;
 }
 
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 953b3ce92dcc..909f1d75165c 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -270,7 +270,7 @@ static void print_mce(struct mce *m)
 {
__print_mce(m);
 
-   if (m->cpuvendor != X86_VENDOR_AMD)
+   if (m->cpuvendor != X86_VENDOR_AMD && m->cpuvendor != X86_VENDOR_HYGON)
pr_emerg_ratelimited(HW_ERR "Run the above through 'mcelog 
--ascii'\n");
 }
 
@@ -508,9 +508,9 @@ static int mce_usable_address(struct mce *m)
 
 bool mce_is_memory_error(struct mce *m)
 {
-   if (m->cpuvendor == X86_VENDOR_AMD) {
+   if (m->cpuvendor == X86_VENDOR_AMD ||
+   m->cpuvendor == X86_VENDOR_HYGON) {
return amd_mce_is_memory_error(m);
-
} else if (m->cpuvendor == X86_VENDOR_INTEL) {
/*
 * Intel SDM Volume 3B - 15.9.2 Compound Error Codes
@@ -539,6 +539,9 @@ static bool mce_is_correctable(struct mce *m)
if (m->cpuvendor == X86_VENDOR_AMD && m->status & MCI_STATUS_DEFERRED)
return false;
 
+   if (m->cpuvendor == X86_VENDOR_HYGON && m->status & MCI_STATUS_DEFERRED)
+   return false;
+
if (m->status & MCI_STATUS_UC)
return false;
 
@@ -1705,7 +1708,7 @@ static int __mcheck_cpu_ancient_init(struct cpuinfo_x86 
*c)
  */
 static void __mcheck_cpu_init_early(struct cpuinfo_x86 *c)
 {
-   if (c->x86_vendor == X86_VENDOR_AMD) {
+   if (c->x86_vendor == X86_VENDOR_AMD || c->x86_vendor == 
X86_VENDOR_HYGON) {
mce_flags.overflow_recov = !!cpu_has(c, 
X86_FEATURE_OVERFLOW_RECOV);
mce_flags.succor = !!cpu_has(c, X86_FEATURE_SUCCOR);
mce_flags.smca   = !!cpu_has(c, X86_FEATURE_SMCA);
@@ -1746,6 +1749,11 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 
*c)
mce_amd_feature_init(c);
break;
}
+
+   case X86_VENDOR_HYGON:
+   mce_hygon_feature_init(c);
+   break;
+
case X86_VENDOR_CENTAUR:
mce_centaur_feature_init(c);
break;
@@ -1971,12 +1979,14 @@ static void mce_disable_error_reporting(void)
 static void vendor_disable_error_reporting(void)
 {
/*
-* Don't clear on Intel or AMD CPUs. Some of these MSRs are socket-wide.
+* Don't clear on Intel or AMD or Hygon CPUs. Some of these MSRs
+* are socket-wide.
 * Disabling them for just a single offlined CPU is bad, since it will
 * inhibit reporting for all shared resources on the socket like the
 * last level cache (LLC), the integrated memory controller (iMC

[tip:x86/cpu] x86/bugs: Add Hygon Dhyana to the respective mitigation machinery

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  1a576b23d63794f39a247fb31056eecccbf9a287
Gitweb: https://git.kernel.org/tip/1a576b23d63794f39a247fb31056eecccbf9a287
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:35:50 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:59 +0200

x86/bugs: Add Hygon Dhyana to the respective mitigation machinery

The Hygon Dhyana CPU has the same speculative execution as AMD family
17h, so share AMD spectre mitigation code with Hygon Dhyana.

Also Hygon Dhyana is not affected by meltdown, so add exception for it.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Link: 
https://lkml.kernel.org/r/0861d39c8a103fc0deca15bafbc85d403666d9ef.1537533369.git.pu...@hygon.cn
---
 arch/x86/kernel/cpu/bugs.c   | 4 +++-
 arch/x86/kernel/cpu/common.c | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 40bdaea97fe7..b810cc239375 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -312,6 +312,7 @@ static enum spectre_v2_mitigation_cmd __init 
spectre_v2_parse_cmdline(void)
}
 
if (cmd == SPECTRE_V2_CMD_RETPOLINE_AMD &&
+   boot_cpu_data.x86_vendor != X86_VENDOR_HYGON &&
boot_cpu_data.x86_vendor != X86_VENDOR_AMD) {
pr_err("retpoline,amd selected but CPU is not AMD. Switching to 
AUTO select\n");
return SPECTRE_V2_CMD_AUTO;
@@ -371,7 +372,8 @@ static void __init spectre_v2_select_mitigation(void)
return;
 
 retpoline_auto:
-   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) {
retpoline_amd:
if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
pr_err("Spectre mitigation: LFENCE not serializing, 
switching to generic retpoline\n");
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 658c85d16a9b..d14c879ba7ba 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -963,6 +963,7 @@ static const __initconst struct x86_cpu_id 
cpu_no_speculation[] = {
 
 static const __initconst struct x86_cpu_id cpu_no_meltdown[] = {
{ X86_VENDOR_AMD },
+   { X86_VENDOR_HYGON },
{}
 };
 


[tip:x86/cpu] x86/apic: Add Hygon Dhyana support

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  da33dfef404174b0b452f4d2a9a9e00801794f3a
Gitweb: https://git.kernel.org/tip/da33dfef404174b0b452f4d2a9a9e00801794f3a
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:35:28 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:58 +0200

x86/apic: Add Hygon Dhyana support

Add Hygon Dhyana support to the APIC subsystem. When running in 32 bit
mode, bigsmp should be enabled if there are more than 8 cores online.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Reviewed-by: Borislav Petkov 
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Link: 
https://lkml.kernel.org/r/7a557265a8c7c9e842fe60f9d8e064458801aef3.1537533369.git.pu...@hygon.cn
---
 arch/x86/kernel/apic/apic.c | 7 +++
 arch/x86/kernel/apic/probe_32.c | 1 +
 2 files changed, 8 insertions(+)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 84132eddb5a8..ab731ab09f06 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -224,6 +224,11 @@ static int modern_apic(void)
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
boot_cpu_data.x86 >= 0xf)
return 1;
+
+   /* Hygon systems use modern APIC */
+   if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
+   return 1;
+
return lapic_get_version() >= 0x14;
 }
 
@@ -1912,6 +1917,8 @@ static int __init detect_init_APIC(void)
(boot_cpu_data.x86 >= 15))
break;
goto no_apic;
+   case X86_VENDOR_HYGON:
+   break;
case X86_VENDOR_INTEL:
if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 ||
(boot_cpu_data.x86 == 5 && boot_cpu_has(X86_FEATURE_APIC)))
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 02e8acb134f8..47ff2976c292 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -185,6 +185,7 @@ void __init default_setup_apic_routing(void)
break;
}
/* If P4 and above fall through */
+   case X86_VENDOR_HYGON:
case X86_VENDOR_AMD:
def_to_bigsmp = 1;
}


[tip:x86/cpu] x86/pci, x86/amd_nb: Add Hygon Dhyana support to PCI and northbridge

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  c6babb5806b77c6ca7078c3487bb0a29704a4e38
Gitweb: https://git.kernel.org/tip/c6babb5806b77c6ca7078c3487bb0a29704a4e38
Author: Pu Wen 
AuthorDate: Tue, 25 Sep 2018 22:46:11 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:58 +0200

x86/pci, x86/amd_nb: Add Hygon Dhyana support to PCI and northbridge

Hygon's PCI vendor ID is 0x1d94, and there are PCI devices
0x1450/0x1463/0x1464 for the host bridge on the Hygon Dhyana platform.
Add Hygon Dhyana support to the PCI and northbridge subsystems by using
the code path of AMD family 17h.

 [ bp: Massage commit message, sort local vars into reverse xmas tree
   order and move the amd_northbridges.num check up. ]

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Acked-by: Bjorn Helgaas# pci_ids.h
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Cc: helg...@kernel.org
Cc: linux-...@vger.kernel.org
Link: 
https://lkml.kernel.org/r/5f8877bd413f2ea0833378dd5454df0720e1c0df.1537885177.git.pu...@hygon.cn
---
 arch/x86/kernel/amd_nb.c | 45 +
 arch/x86/pci/amd_bus.c   |  6 --
 include/linux/pci_ids.h  |  2 ++
 3 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index b51c6b183a35..a6eca647bc76 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -61,6 +61,21 @@ static const struct pci_device_id amd_nb_link_ids[] = {
{}
 };
 
+static const struct pci_device_id hygon_root_ids[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_ROOT) },
+   {}
+};
+
+const struct pci_device_id hygon_nb_misc_ids[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
+   {}
+};
+
+static const struct pci_device_id hygon_nb_link_ids[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F4) },
+   {}
+};
+
 const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[] __initconst = {
{ 0x00, 0x18, 0x20 },
{ 0xff, 0x00, 0x20 },
@@ -194,15 +209,24 @@ EXPORT_SYMBOL_GPL(amd_df_indirect_read);
 
 int amd_cache_northbridges(void)
 {
-   u16 i = 0;
-   struct amd_northbridge *nb;
+   const struct pci_device_id *misc_ids = amd_nb_misc_ids;
+   const struct pci_device_id *link_ids = amd_nb_link_ids;
+   const struct pci_device_id *root_ids = amd_root_ids;
struct pci_dev *root, *misc, *link;
+   struct amd_northbridge *nb;
+   u16 i = 0;
 
if (amd_northbridges.num)
return 0;
 
+   if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
+   root_ids = hygon_root_ids;
+   misc_ids = hygon_nb_misc_ids;
+   link_ids = hygon_nb_link_ids;
+   }
+
misc = NULL;
-   while ((misc = next_northbridge(misc, amd_nb_misc_ids)) != NULL)
+   while ((misc = next_northbridge(misc, misc_ids)) != NULL)
i++;
 
if (!i)
@@ -218,11 +242,11 @@ int amd_cache_northbridges(void)
link = misc = root = NULL;
for (i = 0; i != amd_northbridges.num; i++) {
node_to_amd_nb(i)->root = root =
-   next_northbridge(root, amd_root_ids);
+   next_northbridge(root, root_ids);
node_to_amd_nb(i)->misc = misc =
-   next_northbridge(misc, amd_nb_misc_ids);
+   next_northbridge(misc, misc_ids);
node_to_amd_nb(i)->link = link =
-   next_northbridge(link, amd_nb_link_ids);
+   next_northbridge(link, link_ids);
}
 
if (amd_gart_present())
@@ -261,6 +285,7 @@ EXPORT_SYMBOL_GPL(amd_cache_northbridges);
  */
 bool __init early_is_amd_nb(u32 device)
 {
+   const struct pci_device_id *misc_ids = amd_nb_misc_ids;
const struct pci_device_id *id;
u32 vendor = device & 0x;
 
@@ -268,8 +293,11 @@ bool __init early_is_amd_nb(u32 device)
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
return false;
 
+   if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
+   misc_ids = hygon_nb_misc_ids;
+
device >>= 16;
-   for (id = amd_nb_misc_ids; id->vendor; id++)
+   for (id = misc_ids; id->vendor; id++)
if (vendor == id->vendor && device == id->device)
return true;
return false;
@@ -281,7 +309,8 @@ struct resource *amd_get_mmconfig_range(struct resource 
*res)
u64 base, msr;
unsigned int segn_busn_bits;
 
-   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 NULL;
 
/* assume all cpus from fam10h have mmconfig */
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 649bdde63e32..bfa50e65ef6c 100644
--- a/arch/x86

[tip:x86/cpu] x86/amd_nb: Check vendor in AMD-only functions

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  b7a5cb4f220e78490735b2b984ad29b7d8e612a9
Gitweb: https://git.kernel.org/tip/b7a5cb4f220e78490735b2b984ad29b7d8e612a9
Author: Pu Wen 
AuthorDate: Tue, 25 Sep 2018 22:45:01 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:58 +0200

x86/amd_nb: Check vendor in AMD-only functions

Exit early in functions which are meant to run on AMD only but which get
run on different vendor (VMs, etc).

 [ bp: rewrite commit message. ]

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Cc: bhelg...@google.com
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Cc: helg...@kernel.org
Link: 
https://lkml.kernel.org/r/487d8078708baedaf63eb00a82251e228b58f1c2.1537885177.git.pu...@hygon.cn
---
 arch/x86/include/asm/amd_nb.h | 3 +++
 arch/x86/kernel/amd_nb.c  | 4 
 2 files changed, 7 insertions(+)

diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
index fddb6d26239f..1ae4e5791afa 100644
--- a/arch/x86/include/asm/amd_nb.h
+++ b/arch/x86/include/asm/amd_nb.h
@@ -103,6 +103,9 @@ static inline u16 amd_pci_dev_to_node_id(struct pci_dev 
*pdev)
 
 static inline bool amd_gart_present(void)
 {
+   if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+   return false;
+
/* GART present only on Fam15h, upto model 0fh */
if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 ||
(boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model < 0x10))
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index b481b95bd8f6..b51c6b183a35 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -264,6 +264,10 @@ bool __init early_is_amd_nb(u32 device)
const struct pci_device_id *id;
u32 vendor = device & 0x;
 
+   if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
+   boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+   return false;
+
device >>= 16;
for (id = amd_nb_misc_ids; id->vendor; id++)
if (vendor == id->vendor && device == id->device)


[tip:x86/cpu] x86/alternative: Init ideal_nops for Hygon Dhyana

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  c3fecca457c1aa1c1a2f81bfe68393af244a263e
Gitweb: https://git.kernel.org/tip/c3fecca457c1aa1c1a2f81bfe68393af244a263e
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:35:01 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:58 +0200

x86/alternative: Init ideal_nops for Hygon Dhyana

The ideal_nops for Hygon Dhyana CPU should be p6_nops.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Reviewed-by: Borislav Petkov 
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Link: 
https://lkml.kernel.org/r/79e76c3173716984fe5fdd4a8e2c798bf4193205.1537533369.git.pu...@hygon.cn
---
 arch/x86/kernel/alternative.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index b9d5e7c9ef43..184e9a06b0ff 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -222,6 +222,10 @@ void __init arch_init_ideal_nops(void)
}
break;
 
+   case X86_VENDOR_HYGON:
+   ideal_nops = p6_nops;
+   return;
+
case X86_VENDOR_AMD:
if (boot_cpu_data.x86 > 0xf) {
ideal_nops = p6_nops;


[tip:x86/cpu] x86/events: Add Hygon Dhyana support to PMU infrastructure

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  6d0ef316b9f8ea03fa867debda70b2f11a0b9736
Gitweb: https://git.kernel.org/tip/6d0ef316b9f8ea03fa867debda70b2f11a0b9736
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:34:47 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:57 +0200

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: Pu Wen 
Signed-off-by: Borislav Petkov 
Reviewed-by: Borislav Petkov 
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Link: 
https://lkml.kernel.org/r/9d93ed54a975f33ef7247e0967960f4ce5d3d990.1537533369.git.pu...@hygon.cn
---
 arch/x86/events/amd/core.c |  4 
 arch/x86/events/amd/uncore.c   | 20 +---
 arch/x86/events/core.c |  4 
 arch/x86/kernel/cpu/perfctr-watchdog.c |  2 ++
 4 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
index c84584bb9402..7d2d7c801dba 100644
--- a/arch/x86/events/amd/core.c
+++ b/arch/x86/events/amd/core.c
@@ -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;
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
index 981ba5e8241b..c7d745bc4136 100644
--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -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;
}
 
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index dfb2f7c0d019..9c562f5fbde0 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -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;
}
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c 
b/arch/x86/kernel/cpu/perfctr-watchdog.c
index d389083330c5..9556930cd8c1 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -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_VEND

[tip:x86/cpu] x86/smpboot: Do not use BSP INIT delay and MWAIT to idle on Dhyana

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  0b13bec787dccca96f8c431da732657ae01baf9a
Gitweb: https://git.kernel.org/tip/0b13bec787dccca96f8c431da732657ae01baf9a
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:34:32 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:57 +0200

x86/smpboot: Do not use BSP INIT delay and MWAIT to idle on Dhyana

The Hygon Dhyana CPU uses no delay in smp_quirk_init_udelay(), and does
HLT on idle just like AMD does.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Reviewed-by: Borislav Petkov 
Cc: b...@alien8.de
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Link: 
https://lkml.kernel.org/r/87000fa82e273f5967c908448414228faf61e077.1537533369.git.pu...@hygon.cn
---
 arch/x86/kernel/smpboot.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index f02ecaf97904..5369d7fac797 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -676,6 +676,7 @@ static void __init smp_quirk_init_udelay(void)
 
/* if modern processor, use no delay */
if (((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && 
(boot_cpu_data.x86 == 6)) ||
+   ((boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) && 
(boot_cpu_data.x86 >= 0x18)) ||
((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 
>= 0xF))) {
init_udelay = 0;
return;
@@ -1592,7 +1593,8 @@ static inline void mwait_play_dead(void)
void *mwait_ptr;
int i;
 
-   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;
if (!this_cpu_has(X86_FEATURE_MWAIT))
return;


[tip:x86/cpu] x86/cpu/mtrr: Support TOP_MEM2 and get MTRR number

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  39dc6f154dac134e4612827cb5283934c1862cb8
Gitweb: https://git.kernel.org/tip/39dc6f154dac134e4612827cb5283934c1862cb8
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:34:16 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:57 +0200

x86/cpu/mtrr: Support TOP_MEM2 and get MTRR number

The Hygon Dhyana CPU has a special MSR way to force WB for memory >4GB,
and support TOP_MEM2. Therefore, it is necessary to add Hygon Dhyana
support in amd_special_default_mtrr().

The number of variable MTRRs for Hygon is 2 as AMD's.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Reviewed-by: Borislav Petkov 
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Link: 
https://lkml.kernel.org/r/8246f81648d014601de3812ade40e85d9c50d9b3.1537533369.git.pu...@hygon.cn
---
 arch/x86/kernel/cpu/mtrr/cleanup.c | 3 ++-
 arch/x86/kernel/cpu/mtrr/mtrr.c| 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c 
b/arch/x86/kernel/cpu/mtrr/cleanup.c
index 765afd599039..3668c5df90c6 100644
--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
+++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -831,7 +831,8 @@ int __init amd_special_default_mtrr(void)
 {
u32 l, h;
 
-   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 0;
if (boot_cpu_data.x86 < 0xf)
return 0;
diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c
index 9a19c800fe40..507039c20128 100644
--- a/arch/x86/kernel/cpu/mtrr/mtrr.c
+++ b/arch/x86/kernel/cpu/mtrr/mtrr.c
@@ -127,7 +127,7 @@ static void __init set_num_var_ranges(void)
 
if (use_intel())
rdmsr(MSR_MTRRcap, config, dummy);
-   else if (is_cpu(AMD))
+   else if (is_cpu(AMD) || is_cpu(HYGON))
config = 2;
else if (is_cpu(CYRIX) || is_cpu(CENTAUR))
config = 8;


[tip:x86/cpu] x86/cpu: Get cache info and setup cache cpumap for Hygon Dhyana

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  d4f7423efdd1419b17524d090ff9ff4024bcf09b
Gitweb: https://git.kernel.org/tip/d4f7423efdd1419b17524d090ff9ff4024bcf09b
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:33:44 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 18:28:57 +0200

x86/cpu: Get cache info and setup cache cpumap for Hygon Dhyana

The Hygon Dhyana CPU has a topology extensions bit in CPUID. With
this bit, the kernel can get the cache information. So add support in
cpuid4_cache_lookup_regs() to get the correct cache size.

The Hygon Dhyana CPU also discovers num_cache_leaves via CPUID leaf
0x801d, so add support to it in find_num_cache_leaves().

Also add cacheinfo_hygon_init_llc_id() and init_hygon_cacheinfo()
functions to initialize Dhyana cache info. Setup cache cpumap in the
same way as AMD does.

Signed-off-by: Pu Wen 
Signed-off-by: Borislav Petkov 
Reviewed-by: Borislav Petkov 
Cc: b...@alien8.de
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Link: 
https://lkml.kernel.org/r/2a686b2ac0e2f5a1f2f5f101124d9dd44f949731.1537533369.git.pu...@hygon.cn
---
 arch/x86/include/asm/cacheinfo.h |  1 +
 arch/x86/kernel/cpu/cacheinfo.c  | 31 +--
 arch/x86/kernel/cpu/cpu.h|  1 +
 arch/x86/kernel/cpu/hygon.c  |  3 +++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/cacheinfo.h b/arch/x86/include/asm/cacheinfo.h
index e958e28f7ab5..86b63c7feab7 100644
--- a/arch/x86/include/asm/cacheinfo.h
+++ b/arch/x86/include/asm/cacheinfo.h
@@ -3,5 +3,6 @@
 #define _ASM_X86_CACHEINFO_H
 
 void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id);
+void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id);
 
 #endif /* _ASM_X86_CACHEINFO_H */
diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index 0c5fcbd998cf..dc1b9342e9c4 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -602,6 +602,10 @@ cpuid4_cache_lookup_regs(int index, struct 
_cpuid4_info_regs *this_leaf)
else
amd_cpuid4(index, &eax, &ebx, &ecx);
amd_init_l3_cache(this_leaf, index);
+   } else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
+   cpuid_count(0x801d, index, &eax.full,
+   &ebx.full, &ecx.full, &edx);
+   amd_init_l3_cache(this_leaf, index);
} else {
cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
}
@@ -625,7 +629,8 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
union _cpuid4_leaf_eax  cache_eax;
int i = -1;
 
-   if (c->x86_vendor == X86_VENDOR_AMD)
+   if (c->x86_vendor == X86_VENDOR_AMD ||
+   c->x86_vendor == X86_VENDOR_HYGON)
op = 0x801d;
else
op = 4;
@@ -678,6 +683,22 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int 
cpu, u8 node_id)
}
 }
 
+void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id)
+{
+   /*
+* We may have multiple LLCs if L3 caches exist, so check if we
+* have an L3 cache by looking at the L3 cache CPUID leaf.
+*/
+   if (!cpuid_edx(0x8006))
+   return;
+
+   /*
+* LLC is at the core complex level.
+* Core complex ID is ApicId[3] for these processors.
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+}
+
 void init_amd_cacheinfo(struct cpuinfo_x86 *c)
 {
 
@@ -691,6 +712,11 @@ void init_amd_cacheinfo(struct cpuinfo_x86 *c)
}
 }
 
+void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
+{
+   num_cache_leaves = find_num_cache_leaves(c);
+}
+
 void init_intel_cacheinfo(struct cpuinfo_x86 *c)
 {
/* Cache sizes */
@@ -913,7 +939,8 @@ static void __cache_cpumap_setup(unsigned int cpu, int 
index,
int index_msb, i;
struct cpuinfo_x86 *c = &cpu_data(cpu);
 
-   if (c->x86_vendor == X86_VENDOR_AMD) {
+   if (c->x86_vendor == X86_VENDOR_AMD ||
+   c->x86_vendor == X86_VENDOR_HYGON) {
if (__cache_amd_cpumap_setup(cpu, index, base))
return;
}
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index 7b229afa0a37..da5446acc241 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -54,6 +54,7 @@ extern u32 get_scattered_cpuid_leaf(unsigned int level,
enum cpuid_regs_idx reg);
 extern void init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern void init_amd_cacheinfo(struct cpuinfo_x86 *c);
+extern void init_hygon_cacheinfo(struct cpuinfo_x86 *c);
 
 extern void detect_num_cpu_cores(struct cpuinfo_x86 *c);
 extern int detect_extended_topology_early(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
index a43d5f1f8b41..

[tip:x86/cpu] x86/cpu: Create Hygon Dhyana architecture support file

2018-09-27 Thread tip-bot for Pu Wen
Commit-ID:  c9661c1e80b609cd038db7c908e061f0535804ef
Gitweb: https://git.kernel.org/tip/c9661c1e80b609cd038db7c908e061f0535804ef
Author: Pu Wen 
AuthorDate: Sun, 23 Sep 2018 17:33:12 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 16:14:05 +0200

x86/cpu: Create Hygon Dhyana architecture support file

Add x86 architecture support for a new processor: Hygon Dhyana Family
18h. Carve out initialization code needed by Dhyana into a separate
compilation unit.

To identify Hygon Dhyana CPU, add a new vendor type X86_VENDOR_HYGON.

Since Dhyana uses AMD functionality to a large degree, select
CPU_SUP_AMD which provides that functionality.

 [ bp: drop explicit license statement as it has an SPDX tag already. ]

Signed-off-by: Pu Wen 
Reviewed-by: Borislav Petkov 
Signed-off-by: Borislav Petkov 
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: x...@kernel.org
Cc: thomas.lenda...@amd.com
Link: 
https://lkml.kernel.org/r/1a882065223bacbde5726f3beaa70cebd8dcd814.1537533369.git.pu...@hygon.cn
---
 MAINTAINERS  |   6 +
 arch/x86/Kconfig.cpu |  14 ++
 arch/x86/include/asm/processor.h |   3 +-
 arch/x86/kernel/cpu/Makefile |   1 +
 arch/x86/kernel/cpu/hygon.c  | 405 +++
 5 files changed, 428 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4ece30f15777..c028e1d45c90 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6762,6 +6762,12 @@ S:   Maintained
 F: mm/memory-failure.c
 F: mm/hwpoison-inject.c
 
+HYGON PROCESSOR SUPPORT
+M: Pu Wen 
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: arch/x86/kernel/cpu/hygon.c
+
 Hyper-V CORE AND DRIVERS
 M: "K. Y. Srinivasan" 
 M: Haiyang Zhang 
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 638411f22267..6adce15268bd 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -426,6 +426,20 @@ config CPU_SUP_AMD
 
  If unsure, say N.
 
+config CPU_SUP_HYGON
+   default y
+   bool "Support Hygon processors" if PROCESSOR_SELECT
+   select CPU_SUP_AMD
+   help
+ This enables detection, tunings and quirks for Hygon processors
+
+ You need this enabled if you want your kernel to run on an
+ Hygon CPU. Disabling this option on other types of CPUs
+ makes the kernel a tiny bit smaller. Disabling it on an Hygon
+ CPU might render the kernel unbootable.
+
+ If unsure, say N.
+
 config CPU_SUP_CENTAUR
default y
bool "Support Centaur processors" if PROCESSOR_SELECT
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index d53c54b842da..d4dfd02b740e 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -155,7 +155,8 @@ enum cpuid_regs_idx {
 #define X86_VENDOR_CENTAUR 5
 #define X86_VENDOR_TRANSMETA   7
 #define X86_VENDOR_NSC 8
-#define X86_VENDOR_NUM 9
+#define X86_VENDOR_HYGON   9
+#define X86_VENDOR_NUM 10
 
 #define X86_VENDOR_UNKNOWN 0xff
 
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 347137e80bf5..1f5d2291c31e 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
 
 obj-$(CONFIG_CPU_SUP_INTEL)+= intel.o intel_pconfig.o
 obj-$(CONFIG_CPU_SUP_AMD)  += amd.o
+obj-$(CONFIG_CPU_SUP_HYGON)+= hygon.o
 obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o
 obj-$(CONFIG_CPU_SUP_CENTAUR)  += centaur.o
 obj-$(CONFIG_CPU_SUP_TRANSMETA_32) += transmeta.o
diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
new file mode 100644
index ..a43d5f1f8b41
--- /dev/null
+++ b/arch/x86/kernel/cpu/hygon.c
@@ -0,0 +1,405 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Hygon Processor Support for Linux
+ *
+ * Copyright (C) 2018 Chengdu Haiguang IC Design Co., Ltd.
+ *
+ * Author: Pu Wen 
+ */
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#ifdef CONFIG_X86_64
+# include 
+#endif
+
+#include "cpu.h"
+
+/*
+ * nodes_per_socket: Stores the number of nodes per socket.
+ * Refer to CPUID Fn8000_001E_ECX Node Identifiers[10:8]
+ */
+static u32 nodes_per_socket = 1;
+
+#ifdef CONFIG_NUMA
+/*
+ * To workaround broken NUMA config.  Read the comment in
+ * srat_detect_node().
+ */
+static int nearby_node(int apicid)
+{
+   int i, node;
+
+   for (i = apicid - 1; i >= 0; i--) {
+   node = __apicid_to_node[i];
+   if (node != NUMA_NO_NODE && node_online(node))
+   return node;
+   }
+   for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
+   node = __apicid_to_node[i];
+   if (node != NUMA_NO_NODE && node_online(node))
+   return node;
+   }
+   return first_node(node_online_map); /* Shouldn't happen */
+}
+#endif