2018-08-29 12:44:41

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 00/16] Add support for Hygon Dhyana Family 18h processor

As a new x86 CPU Vendor, Chengdu Haiguang IC Design Co., Ltd (Hygon)
is a Joint Venture between AMD and Haiguang Information Technology Co.,
Ltd., and aims at providing high performance x86 processor for China
server market.

The first generation Hygon's processor(Dhyana) originates from AMD
technology and shares most of the architecture with AMD's family 17h,
but with different CPU Vendor ID("HygonGenuine")/PCIE Device Vendor ID
(0x1D94)/Family series number (Family 18h).

To enable the support of Linux kernel to Hygon's CPU, we added a new
vendor type (X86_VENDOR_HYGON, with value of 9) in arch/x86/include/
asm/processor.h, and shared most of kernel support codes with AMD
family 17h.

This patch series have been applied and tested successfully in Hygon's
Dhyana SoC silicon. Also tested on AMD's EPYC (Family 17h) processor
works fine and makes no harm to existing codes.


v4->v5:
- Rebased on 4.19-rc1 and tested against it.
- Add Reviewed-by from Boris Ostrovsky for Xen.
- Rework EDAC patch without vendor checking for minimal modification.

v3->v4:
- Rebased on 4.18.3 and tested against it.
- Merge patchs 05/17 perfctr and 10/17 events in v3 to patch 05/16
PMU for better patch function group.
- Add hygon_get_topology_early() in patch 01/16.
- Rework vendor checking and refine coding style.
- Add Acked-by from Bjorn Helgaas for pci.
- Add Acked-by from Rafael J. Wysocki for cpufreq and acpi.

v2->v3:
- Rebased on 4.18-rc8 and tested against it.
- Rework vendor checking codes to improve consistency.

v1->v2:
- Rebased on 4.18-rc6 and tested against it.
- Split the patchset to small series of patches.
- Rework patch descriptions.
- Create a separated arch/x86/kernel/cpu/hygon.c for Dhyana CPU
initialization to reduce long-term maintenance effort.


Pu Wen (16):
x86/cpu: create Dhyana init file and register new cpu_dev to system
x86/cache: get cache size/leaves and setup cache cpumap for Dhyana
x86/mtrr: get MTRR number and support TOP_MEM2
x86/smpboot: smp init nodelay and no flush caches before sleep
x86/pmu: enable Hygon support to PMU infrastructure
x86/nops: init ideal_nops for Hygon
x86/pci: add Hygon PCI vendor and northbridge support
x86/apic: add modern APIC support for Hygon
x86/bugs: add lfence mitigation to spectre v2 and no meltdown for
Hygon
x86/mce: enable Hygon support to MCE infrastructure
x86/kvm: enable Hygon support to KVM infrastructure
x86/xen: enable Hygon support to Xen
driver/acpi: enable Hygon support to ACPI driver
driver/cpufreq: enable Hygon support to cpufreq driver
driver/edac: enable Hygon support to AMD64 EDAC driver
tools/cpupower: enable Hygon support to cpupower tool

MAINTAINERS | 6 +
arch/x86/Kconfig | 2 +-
arch/x86/Kconfig.cpu | 13 +
arch/x86/events/amd/core.c | 6 +
arch/x86/events/amd/uncore.c | 15 +-
arch/x86/events/core.c | 4 +
arch/x86/include/asm/cacheinfo.h | 1 +
arch/x86/include/asm/kvm_emulate.h | 4 +
arch/x86/include/asm/mce.h | 5 +
arch/x86/include/asm/nospec-branch.h | 4 +-
arch/x86/include/asm/processor.h | 3 +-
arch/x86/include/asm/virtext.h | 5 +-
arch/x86/kernel/alternative.c | 4 +
arch/x86/kernel/amd_nb.c | 51 ++-
arch/x86/kernel/apic/apic.c | 19 +-
arch/x86/kernel/apic/probe_32.c | 1 +
arch/x86/kernel/cpu/Makefile | 1 +
arch/x86/kernel/cpu/bugs.c | 28 +-
arch/x86/kernel/cpu/cacheinfo.c | 31 +-
arch/x86/kernel/cpu/common.c | 1 +
arch/x86/kernel/cpu/cpu.h | 1 +
arch/x86/kernel/cpu/hygon.c | 411 +++++++++++++++++++++
arch/x86/kernel/cpu/mcheck/mce-severity.c | 3 +-
arch/x86/kernel/cpu/mcheck/mce.c | 21 +-
arch/x86/kernel/cpu/mtrr/cleanup.c | 3 +-
arch/x86/kernel/cpu/mtrr/generic.c | 5 +-
arch/x86/kernel/cpu/mtrr/mtrr.c | 2 +-
arch/x86/kernel/cpu/perfctr-watchdog.c | 2 +
arch/x86/kernel/smpboot.c | 4 +-
arch/x86/kvm/emulate.c | 11 +-
arch/x86/pci/amd_bus.c | 6 +-
arch/x86/xen/pmu.c | 12 +-
drivers/acpi/acpi_pad.c | 1 +
drivers/acpi/processor_idle.c | 1 +
drivers/cpufreq/acpi-cpufreq.c | 5 +
drivers/cpufreq/amd_freq_sensitivity.c | 9 +-
drivers/edac/amd64_edac.c | 20 +-
drivers/edac/amd64_edac.h | 4 +
drivers/edac/mce_amd.c | 4 +-
include/linux/pci_ids.h | 2 +
tools/power/cpupower/utils/cpufreq-info.c | 6 +-
tools/power/cpupower/utils/helpers/amd.c | 6 +-
tools/power/cpupower/utils/helpers/cpuid.c | 8 +-
tools/power/cpupower/utils/helpers/helpers.h | 2 +-
tools/power/cpupower/utils/helpers/misc.c | 3 +-
.../cpupower/utils/idle_monitor/mperf_monitor.c | 3 +-
46 files changed, 690 insertions(+), 69 deletions(-)
create mode 100644 arch/x86/kernel/cpu/hygon.c

--
2.7.4



2018-08-29 12:44:41

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 01/16] x86/cpu: create Dhyana init file and register new cpu_dev to system

Add x86 architecture support for new processor Hygon Dhyana Family 18h.
Rework to create a separated file(arch/x86/kernel/cpu/hygon.c) from the
AMD init one(arch/x86/kernel/cpu/amd.c) to initialize Dhyana CPU. In
this way we can remove old AMD architecture support codes from Hygon
code path and generate a clear initialization flow for Hygon processors.
It also reduce long-term maintenance effort.
Also add Maintainer information for hygon.c in accordance.

To identify Hygon processors, add a new vendor type X86_VENDOR_HYGON(9)
for system recognition.

To enable Hygon processor config, add a separated Kconfig entry
(CPU_SUP_HYGON) for Dhyana CPU in kernel config setup.

Signed-off-by: Pu Wen <[email protected]>
---
MAINTAINERS | 6 +
arch/x86/Kconfig.cpu | 13 ++
arch/x86/include/asm/processor.h | 3 +-
arch/x86/kernel/cpu/Makefile | 1 +
arch/x86/kernel/cpu/hygon.c | 408 +++++++++++++++++++++++++++++++++++++++
5 files changed, 430 insertions(+), 1 deletion(-)
create mode 100644 arch/x86/kernel/cpu/hygon.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a5b256b..9c1d920 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6759,6 +6759,12 @@ S: Maintained
F: mm/memory-failure.c
F: mm/hwpoison-inject.c

+HYGON PROCESSOR SUPPORT
+M: Pu Wen <[email protected]>
+L: [email protected]
+S: Supported
+F: arch/x86/kernel/cpu/hygon.c
+
Hyper-V CORE AND DRIVERS
M: "K. Y. Srinivasan" <[email protected]>
M: Haiyang Zhang <[email protected]>
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 638411f..2e92267 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -426,6 +426,19 @@ config CPU_SUP_AMD

If unsure, say N.

+config CPU_SUP_HYGON
+ default y
+ bool "Support Hygon processors" if PROCESSOR_SELECT
+ 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 c242972..9f18cdb 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -153,7 +153,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 347137e..1f5d229 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 0000000..ae90d1f
--- /dev/null
+++ b/arch/x86/kernel/cpu/hygon.c
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Hygon Processor Support for Linux
+ *
+ * Copyright (c) Chengdu Haiguang IC Design Co., Ltd.
+ *
+ * Author: 2018 Pu Wen <[email protected]>
+ *
+ * This file is licensed under the terms of the GNU General
+ * License v2.0 or later. See file COPYING for details.
+ */
+#include <linux/io.h>
+
+#include <asm/cpu.h>
+#include <asm/smp.h>
+#include <asm/cacheinfo.h>
+#include <asm/spec-ctrl.h>
+#include <asm/delay.h>
+#ifdef CONFIG_X86_64
+# include <asm/set_memory.h>
+#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
+
+static void hygon_get_topology_early(struct cpuinfo_x86 *c)
+{
+ if (cpu_has(c, X86_FEATURE_TOPOEXT))
+ smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1;
+}
+
+/*
+ * Fixup core topology information for
+ * (1) Hygon multi-node processors
+ * Assumption: Number of cores in each internal node is the same.
+ * (2) Hygon processors supporting compute units
+ */
+static void hygon_get_topology(struct cpuinfo_x86 *c)
+{
+ u8 node_id;
+ int cpu = smp_processor_id();
+
+ /* get information required for multi-node processors */
+ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
+ int err;
+ u32 eax, ebx, ecx, edx;
+
+ cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
+
+ node_id = ecx & 0xff;
+
+ c->cpu_core_id = ebx & 0xff;
+
+ if (smp_num_siblings > 1)
+ c->x86_max_cores /= smp_num_siblings;
+
+ /*
+ * In case leaf B is available, use it to derive
+ * topology information.
+ */
+ err = detect_extended_topology(c);
+ if (!err)
+ c->x86_coreid_bits = get_count_order(c->x86_max_cores);
+
+ } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
+ u64 value;
+
+ rdmsrl(MSR_FAM10H_NODE_ID, value);
+ node_id = value & 7;
+
+ per_cpu(cpu_llc_id, cpu) = node_id;
+ } else
+ return;
+
+ if (nodes_per_socket > 1)
+ set_cpu_cap(c, X86_FEATURE_AMD_DCM);
+}
+
+/*
+ * On Hygon setup the lower bits of the APIC id distinguish the cores.
+ * Assumes number of cores is a power of two.
+ */
+static void hygon_detect_cmp(struct cpuinfo_x86 *c)
+{
+ unsigned int bits;
+ int cpu = smp_processor_id();
+
+ bits = c->x86_coreid_bits;
+ /* Low order bits define the core id (index of core in socket) */
+ c->cpu_core_id = c->initial_apicid & ((1 << bits)-1);
+ /* Convert the initial APIC ID into the socket ID */
+ c->phys_proc_id = c->initial_apicid >> bits;
+ /* use socket ID also for last level cache */
+ per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
+}
+
+static void srat_detect_node(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_NUMA
+ int cpu = smp_processor_id();
+ int node;
+ unsigned int apicid = c->apicid;
+
+ node = numa_cpu_node(cpu);
+ if (node == NUMA_NO_NODE)
+ node = per_cpu(cpu_llc_id, cpu);
+
+ /*
+ * On multi-fabric platform (e.g. Numascale NumaChip) a
+ * platform-specific handler needs to be called to fixup some
+ * IDs of the CPU.
+ */
+ if (x86_cpuinit.fixup_cpu_id)
+ x86_cpuinit.fixup_cpu_id(c, node);
+
+ if (!node_online(node)) {
+ /*
+ * Two possibilities here:
+ *
+ * - The CPU is missing memory and no node was created. In
+ * that case try picking one from a nearby CPU.
+ *
+ * - The APIC IDs differ from the HyperTransport node IDs.
+ * Assume they are all increased by a constant offset, but
+ * in the same order as the HT nodeids. If that doesn't
+ * result in a usable node fall back to the path for the
+ * previous case.
+ *
+ * This workaround operates directly on the mapping between
+ * APIC ID and NUMA node, assuming certain relationship
+ * between APIC ID, HT node ID and NUMA topology. As going
+ * through CPU mapping may alter the outcome, directly
+ * access __apicid_to_node[].
+ */
+ int ht_nodeid = c->initial_apicid;
+
+ if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
+ node = __apicid_to_node[ht_nodeid];
+ /* Pick a nearby node */
+ if (!node_online(node))
+ node = nearby_node(apicid);
+ }
+ numa_set_node(cpu, node);
+#endif
+}
+
+static void early_init_hygon_mc(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_SMP
+ unsigned int bits, ecx;
+
+ /* Multi core CPU? */
+ if (c->extended_cpuid_level < 0x80000008)
+ return;
+
+ ecx = cpuid_ecx(0x80000008);
+
+ c->x86_max_cores = (ecx & 0xff) + 1;
+
+ /* CPU telling us the core id bits shift? */
+ bits = (ecx >> 12) & 0xF;
+
+ /* Otherwise recompute */
+ if (bits == 0) {
+ while ((1 << bits) < c->x86_max_cores)
+ bits++;
+ }
+
+ c->x86_coreid_bits = bits;
+#endif
+}
+
+static void bsp_init_hygon(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_X86_64
+ unsigned long long tseg;
+
+ /*
+ * Split up direct mapping around the TSEG SMM area.
+ * Don't do it for gbpages because there seems very little
+ * benefit in doing so.
+ */
+ if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) {
+ unsigned long pfn = tseg >> PAGE_SHIFT;
+
+ pr_debug("tseg: %010llx\n", tseg);
+ if (pfn_range_is_mapped(pfn, pfn + 1))
+ set_memory_4k((unsigned long)__va(tseg), 1);
+ }
+#endif
+
+ if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
+ u64 val;
+
+ rdmsrl(MSR_K7_HWCR, val);
+ if (!(val & BIT(24)))
+ pr_warn(FW_BUG "TSC doesn't count with P0 frequency!\n");
+ }
+
+ if (cpu_has(c, X86_FEATURE_MWAITX))
+ use_mwaitx_delay();
+
+ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
+ u32 ecx;
+
+ ecx = cpuid_ecx(0x8000001e);
+ nodes_per_socket = ((ecx >> 8) & 7) + 1;
+ } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) {
+ u64 value;
+
+ rdmsrl(MSR_FAM10H_NODE_ID, value);
+ nodes_per_socket = ((value >> 3) & 7) + 1;
+ }
+
+ if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) &&
+ !boot_cpu_has(X86_FEATURE_VIRT_SSBD)) {
+ /*
+ * Try to cache the base value so further operations can
+ * avoid RMW. If that faults, do not enable SSBD.
+ */
+ if (!rdmsrl_safe(MSR_AMD64_LS_CFG, &x86_amd_ls_cfg_base)) {
+ setup_force_cpu_cap(X86_FEATURE_LS_CFG_SSBD);
+ setup_force_cpu_cap(X86_FEATURE_SSBD);
+ x86_amd_ls_cfg_ssbd_mask = 1ULL << 10;
+ }
+ }
+}
+
+static void early_init_hygon(struct cpuinfo_x86 *c)
+{
+ u32 dummy;
+
+ early_init_hygon_mc(c);
+
+ set_cpu_cap(c, X86_FEATURE_K8);
+
+ rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
+
+ /*
+ * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
+ * with P/T states and does not stop in deep C-states
+ */
+ if (c->x86_power & (1 << 8)) {
+ set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
+ set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
+ }
+
+ /* Bit 12 of 8000_0007 edx is accumulated power mechanism. */
+ if (c->x86_power & BIT(12))
+ set_cpu_cap(c, X86_FEATURE_ACC_POWER);
+
+#ifdef CONFIG_X86_64
+ set_cpu_cap(c, X86_FEATURE_SYSCALL32);
+#endif
+
+#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
+ /*
+ * ApicID can always be treated as an 8-bit value for Hygon APIC So, we
+ * can safely set X86_FEATURE_EXTD_APICID unconditionally.
+ */
+ if (boot_cpu_has(X86_FEATURE_APIC))
+ set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
+#endif
+
+ /*
+ * This is only needed to tell the kernel whether to use VMCALL
+ * and VMMCALL. VMMCALL is never executed except under virt, so
+ * we can set it unconditionally.
+ */
+ set_cpu_cap(c, X86_FEATURE_VMMCALL);
+
+ hygon_get_topology_early(c);
+}
+
+static void init_hygon(struct cpuinfo_x86 *c)
+{
+ early_init_hygon(c);
+
+ /*
+ * Bit 31 in normal CPUID used for nonstandard 3DNow ID;
+ * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
+ */
+ clear_cpu_cap(c, 0*32+31);
+
+ set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+
+ /* get apicid instead of initial apic id from cpuid */
+ c->apicid = hard_smp_processor_id();
+
+ set_cpu_cap(c, X86_FEATURE_ZEN);
+ set_cpu_cap(c, X86_FEATURE_CPB);
+
+ cpu_detect_cache_sizes(c);
+
+ hygon_detect_cmp(c);
+ hygon_get_topology(c);
+ srat_detect_node(c);
+
+ if (cpu_has(c, X86_FEATURE_XMM2)) {
+ unsigned long long val;
+ int ret;
+
+ /*
+ * A serializing LFENCE has less overhead than MFENCE, so
+ * use it for execution serialization. On families which
+ * don't have that MSR, LFENCE is already serializing.
+ * msr_set_bit() uses the safe accessors, too, even if the MSR
+ * is not present.
+ */
+ msr_set_bit(MSR_F10H_DECFG,
+ MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
+
+ /*
+ * Verify that the MSR write was successful (could be running
+ * under a hypervisor) and only then assume that LFENCE is
+ * serializing.
+ */
+ ret = rdmsrl_safe(MSR_F10H_DECFG, &val);
+ if (!ret && (val & MSR_F10H_DECFG_LFENCE_SERIALIZE)) {
+ /* A serializing LFENCE stops RDTSC speculation */
+ set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
+ } else {
+ /* MFENCE stops RDTSC speculation */
+ set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
+ }
+ }
+
+ /*
+ * Hygon processors have APIC timer running in deep C states.
+ */
+ set_cpu_cap(c, X86_FEATURE_ARAT);
+
+ /* Hygon CPUs don't reset SS attributes on SYSRET, Xen does. */
+ if (!cpu_has(c, X86_FEATURE_XENPV))
+ set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
+}
+
+static void cpu_detect_tlb_hygon(struct cpuinfo_x86 *c)
+{
+ u32 ebx, eax, ecx, edx;
+ u16 mask = 0xfff;
+
+ if (c->extended_cpuid_level < 0x80000006)
+ return;
+
+ cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
+
+ tlb_lld_4k[ENTRIES] = (ebx >> 16) & mask;
+ tlb_lli_4k[ENTRIES] = ebx & mask;
+
+ /* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
+ if (!((eax >> 16) & mask))
+ tlb_lld_2m[ENTRIES] = (cpuid_eax(0x80000005) >> 16) & 0xff;
+ else
+ tlb_lld_2m[ENTRIES] = (eax >> 16) & mask;
+
+ /* a 4M entry uses two 2M entries */
+ tlb_lld_4m[ENTRIES] = tlb_lld_2m[ENTRIES] >> 1;
+
+ /* Handle ITLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
+ if (!(eax & mask)) {
+ cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
+ tlb_lli_2m[ENTRIES] = eax & 0xff;
+ } else
+ tlb_lli_2m[ENTRIES] = eax & mask;
+
+ tlb_lli_4m[ENTRIES] = tlb_lli_2m[ENTRIES] >> 1;
+}
+
+static const struct cpu_dev hygon_cpu_dev = {
+ .c_vendor = "Hygon",
+ .c_ident = { "HygonGenuine" },
+ .c_early_init = early_init_hygon,
+ .c_detect_tlb = cpu_detect_tlb_hygon,
+ .c_bsp_init = bsp_init_hygon,
+ .c_init = init_hygon,
+ .c_x86_vendor = X86_VENDOR_HYGON,
+};
+
+cpu_dev_register(hygon_cpu_dev);
--
2.7.4


2018-08-29 12:45:07

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 02/16] x86/cache: get cache size/leaves and setup cache cpumap for Dhyana

Hygon Dhyana processor has the topology extensions bit in CPUID.
With this bit kernel can get the cache info. So add support
in cpuid4_cache_lookup_regs() to get the correct cache size.

Dhyana also find num_cache_leaves via CPUID leaf 0x8000001d, so
add Hygon support 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 <[email protected]>
---
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 e958e28..86b63c7 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 0c5fcbd..dc1b934 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(0x8000001d, 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 = 0x8000001d;
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(0x80000006))
+ 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 7b229af..da5446a 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 ae90d1f..52670d3 100644
--- a/arch/x86/kernel/cpu/hygon.c
+++ b/arch/x86/kernel/cpu/hygon.c
@@ -90,6 +90,7 @@ static void hygon_get_topology(struct cpuinfo_x86 *c)
if (!err)
c->x86_coreid_bits = get_count_order(c->x86_max_cores);

+ cacheinfo_amd_init_llc_id(c, cpu, node_id);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
u64 value;

@@ -324,6 +325,8 @@ static void init_hygon(struct cpuinfo_x86 *c)
hygon_get_topology(c);
srat_detect_node(c);

+ init_hygon_cacheinfo(c);
+
if (cpu_has(c, X86_FEATURE_XMM2)) {
unsigned long long val;
int ret;
--
2.7.4


2018-08-29 12:45:23

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 03/16] x86/mtrr: get MTRR number and support TOP_MEM2

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

The MtrrFixDramModEn bit on Hygon platform should also be set to 1
during BIOS initialization of the fixed MTRRs, then cleared to 0 for
operation.

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

Signed-off-by: Pu Wen <[email protected]>
---
arch/x86/kernel/cpu/mtrr/cleanup.c | 3 ++-
arch/x86/kernel/cpu/mtrr/generic.c | 5 +++--
arch/x86/kernel/cpu/mtrr/mtrr.c | 2 +-
3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
index 765afd5..3668c5d 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/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index e12ee86..77c3eaa 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -49,8 +49,9 @@ static inline void k8_check_syscfg_dram_mod_en(void)
{
u32 lo, hi;

- if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
- (boot_cpu_data.x86 >= 0x0f)))
+ if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+ boot_cpu_data.x86 >= 0x0f) ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON))
return;

rdmsr(MSR_K8_SYSCFG, lo, hi);
diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c
index 9a19c80..507039c 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;
--
2.7.4


2018-08-29 12:45:54

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 04/16] x86/smpboot: smp init nodelay and no flush caches before sleep

Dhyana use no delay in smp_quirk_init_udelay(), and return in
mwait_play_dead() as AMD does.

Signed-off-by: Pu Wen <[email protected]>
---
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 f02ecaf..5369d7f 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;
--
2.7.4


2018-08-29 12:46:16

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 07/16] x86/pci: add Hygon PCI vendor and northbridge support

As Hygon register its PCI Vendor ID as a new one "0x1d94", so add a new
definition PCI_VENDOR_ID_HYGON in include/linux/pci_ids.h.

Also Hygon PCI Device ID(0x1450/0x1463/0x1464) for Host bridge is added
to amd_nb.c. And it need to define new arrays for Hygon:
hygon_root_ids[], hygon_nb_misc_ids[], hygon_nb_link_ids[].

To enable Hygon north bridge support, add new variable root_ids, and
assign its value based on whether CPU vendor is AMD or Hygon. Modify
the CONFIG_AMD_NB to depends on either AMD or Hygon.

Add Hygon support in amd_postcore_init(), early_root_info_init().

Acked-by: Bjorn Helgaas <[email protected]> # pci_ids.h
Signed-off-by: Pu Wen <[email protected]>
---
arch/x86/Kconfig | 2 +-
arch/x86/kernel/amd_nb.c | 51 ++++++++++++++++++++++++++++++++++++++++++------
arch/x86/pci/amd_bus.c | 6 ++++--
include/linux/pci_ids.h | 2 ++
4 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c5ff296..733f1ec 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2818,7 +2818,7 @@ endif # X86_32

config AMD_NB
def_bool y
- depends on CPU_SUP_AMD && PCI
+ depends on (CPU_SUP_AMD || CPU_SUP_HYGON) && PCI

source "drivers/pcmcia/Kconfig"

diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index b481b95..d9867b2 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -20,6 +20,10 @@
#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb
#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4 0x15ec

+#define PCI_DEVICE_ID_HYGON_18H_ROOT 0x1450
+#define PCI_DEVICE_ID_HYGON_18H_DF_F3 0x1463
+#define PCI_DEVICE_ID_HYGON_18H_DF_F4 0x1464
+
/* Protect the PCI config register pairs used for SMN and DF indirect access. */
static DEFINE_MUTEX(smn_mutex);

@@ -61,6 +65,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_HYGON_18H_ROOT) },
+ {}
+};
+
+const struct pci_device_id hygon_nb_misc_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_DF_F3) },
+ {}
+};
+
+static const struct pci_device_id hygon_nb_link_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_DF_F4) },
+ {}
+};
+
const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[] __initconst = {
{ 0x00, 0x18, 0x20 },
{ 0xff, 0x00, 0x20 },
@@ -197,12 +216,25 @@ int amd_cache_northbridges(void)
u16 i = 0;
struct amd_northbridge *nb;
struct pci_dev *root, *misc, *link;
+ const struct pci_device_id *root_ids = NULL;
+ const struct pci_device_id *misc_ids = NULL;
+ const struct pci_device_id *link_ids = NULL;
+
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
+ root_ids = amd_root_ids;
+ misc_ids = amd_nb_misc_ids;
+ link_ids = amd_nb_link_ids;
+ } else 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;
+ }

if (amd_northbridges.num)
return 0;

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 +250,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())
@@ -263,9 +295,15 @@ bool __init early_is_amd_nb(u32 device)
{
const struct pci_device_id *id;
u32 vendor = device & 0xffff;
+ const struct pci_device_id *misc_ids = NULL;
+
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+ misc_ids = amd_nb_misc_ids;
+ else 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;
@@ -277,7 +315,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 649bdde..bfa50e6 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -93,7 +93,8 @@ static int __init early_root_info_init(void)
vendor = id & 0xffff;
device = (id>>16) & 0xffff;

- if (vendor != PCI_VENDOR_ID_AMD)
+ if (vendor != PCI_VENDOR_ID_AMD &&
+ vendor != PCI_VENDOR_ID_HYGON)
continue;

if (hb_probes[i].device == device) {
@@ -390,7 +391,8 @@ static int __init pci_io_ecs_init(void)

static int __init amd_postcore_init(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)
return 0;

early_root_info_init();
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 99d366c..d2d281f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2561,6 +2561,8 @@

#define PCI_VENDOR_ID_AMAZON 0x1d0f

+#define PCI_VENDOR_ID_HYGON 0x1d94
+
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29

--
2.7.4


2018-08-29 12:46:24

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 05/16] x86/pmu: enable Hygon support to PMU infrastructure

Hygon PMU arch is similar to AMD Family 17h. To support Hygon PMU, the
initialization flow for it just call amd_pmu_init() and change PMU name
to "HYGON". To share AMD's flow, add code check for Hygon family ID 18h
to run the code path of AMD family 17h in core/uncore functions.

Also it returns the bit offset of the performance counter register and
event selection register for Hygon CPU in the similar way as AMD does.

Signed-off-by: Pu Wen <[email protected]>
---
arch/x86/events/amd/core.c | 6 ++++++
arch/x86/events/amd/uncore.c | 15 ++++++++++-----
arch/x86/events/core.c | 4 ++++
arch/x86/kernel/cpu/perfctr-watchdog.c | 2 ++
4 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
index c84584b..6c13c9d 100644
--- a/arch/x86/events/amd/core.c
+++ b/arch/x86/events/amd/core.c
@@ -669,6 +669,12 @@ static int __init amd_core_pmu_init(void)
* We fallback to using default amd_get_event_constraints.
*/
break;
+ case 0x18:
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
+ 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 981ba5e..9f2eb43 100644
--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -507,17 +507,22 @@ 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_vendor == X86_VENDOR_AMD &&
+ boot_cpu_data.x86 == 0x17) ||
+ (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON &&
+ 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 AMD F17h or Hygon F18h, the Northbridge counters are
+ * repurposed as DataFabric 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;
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 5f4829f..93e026b 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 d389083..9556930 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_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;
--
2.7.4


2018-08-29 12:46:26

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 08/16] x86/apic: add modern APIC support for Hygon

Hygon processors use modern APIC, so just return in modern_apic() and
sync_Arb_IDs(). And should break in switch case in detect_init_API().

When running on 32 bit mode, should set bigsmp if there are more than
8 cores.

Signed-off-by: Pu Wen <[email protected]>
---
arch/x86/kernel/apic/apic.c | 19 ++++++++++++++-----
arch/x86/kernel/apic/probe_32.c | 1 +
2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 84132ed..a62968e 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -220,10 +220,15 @@ static inline int lapic_is_integrated(void)
*/
static int modern_apic(void)
{
- /* AMD systems use old APIC versions, so check the CPU */
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
- boot_cpu_data.x86 >= 0xf)
+ /*
+ * Old AMD systems use old APIC versions, newer AMD systems
+ * and Hygon systems use modern APIC, so check the CPU
+ */
+ if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+ boot_cpu_data.x86 >= 0xf) ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
return 1;
+
return lapic_get_version() >= 0x14;
}

@@ -1211,9 +1216,11 @@ void __init sync_Arb_IDs(void)
{
/*
* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 And not
- * needed on AMD.
+ * needed on AMD or Hygon.
*/
- if (modern_apic() || boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+ if (modern_apic() ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
return;

/*
@@ -1912,6 +1919,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 02e8acb..47ff297 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;
}
--
2.7.4


2018-08-29 12:46:40

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 06/16] x86/nops: init ideal_nops for Hygon

The ideal_nops for Dhyana processors should be p6_nops.

Signed-off-by: Pu Wen <[email protected]>
---
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 014f214..3f51d1c 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;
--
2.7.4


2018-08-29 12:46:41

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 09/16] x86/bugs: add lfence mitigation to spectre v2 and no meltdown for Hygon

To share codes between AMD and Hygon to mitigate Spectre V2 Retpoline
vulnerability, rename macros SPECTRE_V2_RETPOLINE_MINIMAL_AMD to
SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE, and SPECTRE_V2_CMD_RETPOLINE_AMD
to SPECTRE_V2_CMD_RETPOLINE_LFENCE.

As Hygon processors are not affected by meltdown vulnerability as AMD's,
so add exception in array cpu_no_meltdown[] for Hygon.

Signed-off-by: Pu Wen <[email protected]>
---
arch/x86/include/asm/nospec-branch.h | 4 ++--
arch/x86/kernel/cpu/bugs.c | 28 +++++++++++++++-------------
arch/x86/kernel/cpu/common.c | 1 +
3 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
index fd2a8c1..6763f9b 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -211,9 +211,9 @@
enum spectre_v2_mitigation {
SPECTRE_V2_NONE,
SPECTRE_V2_RETPOLINE_MINIMAL,
- SPECTRE_V2_RETPOLINE_MINIMAL_AMD,
+ SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE,
SPECTRE_V2_RETPOLINE_GENERIC,
- SPECTRE_V2_RETPOLINE_AMD,
+ SPECTRE_V2_RETPOLINE_LFENCE,
SPECTRE_V2_IBRS_ENHANCED,
};

diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 4c2313d..15be045 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -132,15 +132,15 @@ enum spectre_v2_mitigation_cmd {
SPECTRE_V2_CMD_FORCE,
SPECTRE_V2_CMD_RETPOLINE,
SPECTRE_V2_CMD_RETPOLINE_GENERIC,
- SPECTRE_V2_CMD_RETPOLINE_AMD,
+ SPECTRE_V2_CMD_RETPOLINE_LFENCE,
};

static const char *spectre_v2_strings[] = {
[SPECTRE_V2_NONE] = "Vulnerable",
[SPECTRE_V2_RETPOLINE_MINIMAL] = "Vulnerable: Minimal generic ASM retpoline",
- [SPECTRE_V2_RETPOLINE_MINIMAL_AMD] = "Vulnerable: Minimal AMD ASM retpoline",
+ [SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE] = "Vulnerable: Minimal LFENCE ASM retpoline",
[SPECTRE_V2_RETPOLINE_GENERIC] = "Mitigation: Full generic retpoline",
- [SPECTRE_V2_RETPOLINE_AMD] = "Mitigation: Full AMD retpoline",
+ [SPECTRE_V2_RETPOLINE_LFENCE] = "Mitigation: Full LFENCE retpoline",
[SPECTRE_V2_IBRS_ENHANCED] = "Mitigation: Enhanced IBRS",
};

@@ -272,7 +272,7 @@ static const struct {
{ "off", SPECTRE_V2_CMD_NONE, false },
{ "on", SPECTRE_V2_CMD_FORCE, true },
{ "retpoline", SPECTRE_V2_CMD_RETPOLINE, false },
- { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_AMD, false },
+ { "retpoline,lfence", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false },
{ "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false },
{ "auto", SPECTRE_V2_CMD_AUTO, false },
};
@@ -304,16 +304,17 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
}

if ((cmd == SPECTRE_V2_CMD_RETPOLINE ||
- cmd == SPECTRE_V2_CMD_RETPOLINE_AMD ||
+ cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE ||
cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) &&
!IS_ENABLED(CONFIG_RETPOLINE)) {
pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option);
return SPECTRE_V2_CMD_AUTO;
}

- if (cmd == SPECTRE_V2_CMD_RETPOLINE_AMD &&
+ if (cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE &&
+ 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");
+ pr_err("retpoline,lfence selected but CPU is not AMD or Hygon. Switching to AUTO select\n");
return SPECTRE_V2_CMD_AUTO;
}

@@ -354,9 +355,9 @@ static void __init spectre_v2_select_mitigation(void)
if (IS_ENABLED(CONFIG_RETPOLINE))
goto retpoline_auto;
break;
- case SPECTRE_V2_CMD_RETPOLINE_AMD:
+ case SPECTRE_V2_CMD_RETPOLINE_LFENCE:
if (IS_ENABLED(CONFIG_RETPOLINE))
- goto retpoline_amd;
+ goto retpoline_lfence;
break;
case SPECTRE_V2_CMD_RETPOLINE_GENERIC:
if (IS_ENABLED(CONFIG_RETPOLINE))
@@ -371,14 +372,15 @@ static void __init spectre_v2_select_mitigation(void)
return;

retpoline_auto:
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
- retpoline_amd:
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
+ retpoline_lfence:
if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n");
goto retpoline_generic;
}
- mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_AMD :
- SPECTRE_V2_RETPOLINE_MINIMAL_AMD;
+ mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_LFENCE :
+ SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE;
setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD);
setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
} else {
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 84dee5a..ffcc501 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -962,6 +962,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 },
{}
};

--
2.7.4


2018-08-29 12:47:06

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 10/16] x86/mce: enable Hygon support to MCE infrastructure

Hygon machine check arch is similar to AMD family 17h. To enable the MCE
infrastructure support, add CPU vendor check for Hygon to share the code
path of AMD.

Add hygon mce init function mce_hygon_feature_init() to minimize further
maintenance effort.

Signed-off-by: Pu Wen <[email protected]>
---
arch/x86/include/asm/mce.h | 5 +++++
arch/x86/kernel/cpu/mcheck/mce-severity.c | 3 ++-
arch/x86/kernel/cpu/mcheck/mce.c | 21 +++++++++++++++------
3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 3a17107..12357aa 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -214,6 +214,11 @@ 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 f34d89c..44396d5 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 953b3ce..12408a1 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -270,7 +270,8 @@ 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 +509,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
@@ -536,7 +537,9 @@ EXPORT_SYMBOL_GPL(mce_is_memory_error);

static bool mce_is_correctable(struct mce *m)
{
- if (m->cpuvendor == X86_VENDOR_AMD && m->status & MCI_STATUS_DEFERRED)
+ if ((m->cpuvendor == X86_VENDOR_AMD ||
+ m->cpuvendor == X86_VENDOR_HYGON) &&
+ (m->status & MCI_STATUS_DEFERRED))
return false;

if (m->status & MCI_STATUS_UC)
@@ -1705,7 +1708,8 @@ 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 +1750,9 @@ 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 +1978,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), etc.
*/
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ||
boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
return;

--
2.7.4


2018-08-29 12:47:24

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 11/16] x86/kvm: enable Hygon support to KVM infrastructure

Hygon Dhyana CPU has the SVM feature as AMD family 17h does.
Add Hygon support in the KVM infrastructure.

Signed-off-by: Pu Wen <[email protected]>
---
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 0f82cd9..93c4bf5 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 0116b2e..e05e0d3 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 106482d..34edf19 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;
}

--
2.7.4


2018-08-29 12:47:34

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 12/16] x86/xen: enable Hygon support to Xen

To make Xen works functionly on Hygon platforms, reuse AMD's Xen support
code path for Hygon.

There are six core performance events counters per thread, so there are
six MSRs for these counters(0-5). Also there are four legacy PMC MSRs,
they are alias of the counters(0-3).

In this version of kernel Hygon use the lagacy and safe versions of MSR
access. It works fine when VPMU enabled in Xen on Hygon platforms by
testing with perf.

Reviewed-by: Boris Ostrovsky <[email protected]>
Signed-off-by: Pu Wen <[email protected]>
---
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 7d00d4a..9403854 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);
--
2.7.4


2018-08-29 12:47:37

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 13/16] driver/acpi: enable Hygon support to ACPI driver

For Dhyana processors have NONSTOP TSC feature, so enable the support
to ACPI driver.

Acked-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Pu Wen <[email protected]>
---
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 552c1f7..a47676a 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 abb559c..b2131c4 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:
--
2.7.4


2018-08-29 12:47:44

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 14/16] driver/cpufreq: enable Hygon support to cpufreq driver

Enable ACPI cpufreq driver support for Hygon by adding family ID check
along with AMD.

As Hygon platforms have SMBus device(PCI device ID 0x790b), enable Hygon
support to function amd_freq_sensitivity_init().

Acked-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Pu Wen <[email protected]>
---
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 b61f4ec..d62fd37 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -61,6 +61,7 @@ enum {

#define INTEL_MSR_RANGE (0xffff)
#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 be926d9..4ac7c3c 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) {
--
2.7.4


2018-08-29 12:48:15

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 16/16] tools/cpupower: enable Hygon support to cpupower tool

Tool cpupower is useful to get CPU frequency information and monitor
power stats on Hygon platforms. So enable platform support to cpupower
for Hygon Dhyana Family 0x18 processors by checking vendor ID & family
and vendor string by using the code path of AMD family 0x17.

Signed-off-by: Pu Wen <[email protected]>
---
tools/power/cpupower/utils/cpufreq-info.c | 6 ++++--
tools/power/cpupower/utils/helpers/amd.c | 6 ++++--
tools/power/cpupower/utils/helpers/cpuid.c | 8 +++++---
tools/power/cpupower/utils/helpers/helpers.h | 2 +-
tools/power/cpupower/utils/helpers/misc.c | 3 ++-
tools/power/cpupower/utils/idle_monitor/mperf_monitor.c | 3 ++-
6 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
index df43cd4..56e54ea 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 bb41cdd..dbce56c 100644
--- a/tools/power/cpupower/utils/helpers/amd.c
+++ b/tools/power/cpupower/utils/helpers/amd.c
@@ -45,7 +45,8 @@ 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 && cpupower_cpu_info.vendor == X86_VENDOR_HYGON))
t = pstate.fam17h_bits.did;
else
t = pstate.bits.did;
@@ -59,7 +60,8 @@ 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 && cpupower_cpu_info.vendor == X86_VENDOR_HYGON)) {
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 732b0b4..5cc39d4 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 @@ int get_cpu_info(struct cpupower_cpu_info *cpu_info)
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 @@ int get_cpu_info(struct cpupower_cpu_info *cpu_info)
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 >= 0x80000007 &&
(cpuid_edx(0x80000007) & (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 41da392..9021396 100644
--- a/tools/power/cpupower/utils/helpers/helpers.h
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -61,7 +61,7 @@ extern int be_verbose;

/* cpuid and cpuinfo helpers **************************/
enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
- X86_VENDOR_AMD, X86_VENDOR_MAX};
+ X86_VENDOR_AMD, X86_VENDOR_HYGON, X86_VENDOR_MAX};

#define CPUPOWER_CAP_INV_TSC 0x00000001
#define CPUPOWER_CAP_APERF 0x00000002
diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c
index 80fdf55..0be93ee 100644
--- a/tools/power/cpupower/utils/helpers/misc.c
+++ b/tools/power/cpupower/utils/helpers/misc.c
@@ -26,7 +26,8 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
* has Hardware determined variable increments instead.
*/

- if (cpu_info.family == 0x17) {
+ if (cpu_info.family == 0x17 ||
+ (cpu_info.family == 0x18 && cpu_info.vendor == X86_VENDOR_HYGON)) {
if (!read_msr(cpu, MSR_AMD_HWCR, &val)) {
if (!(val & CPUPOWER_AMD_CPBDIS))
*active = 1;
diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
index d7c2a6d..f2a7e9c 100644
--- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
+++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
@@ -241,7 +241,8 @@ static int init_maxfreq_mode(void)
if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_INV_TSC))
goto use_sysfs;

- if (cpupower_cpu_info.vendor == X86_VENDOR_AMD) {
+ if (cpupower_cpu_info.vendor == X86_VENDOR_AMD ||
+ cpupower_cpu_info.vendor == X86_VENDOR_HYGON) {
/* MSR_AMD_HWCR tells us whether TSC runs at P0/mperf
* freq.
* A test whether hwcr is accessable/available would be:
--
2.7.4


2018-08-29 12:49:02

by Wen Pu

[permalink] [raw]
Subject: [PATCH v5 15/16] driver/edac: enable Hygon support to AMD64 EDAC driver

To make AMD64 EDAC and MCE drivers working on Hygon platforms, add
support for Hygon by using the code path of AMD family 0x17.

As Hygon will negotiate with AMD to make sure that only Hygon will
use family 0x18, under this consideration try to minimize code
modifications and share most codes with AMD.

Also Hygon PCI Device ID DF_F0/DF_F6(0x1460/0x1466) of Host bridges
is needed for edac driver.

Signed-off-by: Pu Wen <[email protected]>
---
drivers/edac/amd64_edac.c | 20 +++++++++++++++++++-
drivers/edac/amd64_edac.h | 4 ++++
drivers/edac/mce_amd.c | 4 +++-
3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 18aeabb..d8b4b0e 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -211,7 +211,7 @@ static int __set_scrub_rate(struct amd64_pvt *pvt, u32 new_bw, u32 min_rate)

scrubval = scrubrates[i].scrubval;

- if (pvt->fam == 0x17) {
+ if (pvt->fam == 0x17 || pvt->fam == 0x18) {
__f17h_set_scrubval(pvt, scrubval);
} else if (pvt->fam == 0x15 && pvt->model == 0x60) {
f15h_select_dct(pvt, 0);
@@ -264,6 +264,7 @@ static int get_scrub_rate(struct mem_ctl_info *mci)
break;

case 0x17:
+ case 0x18:
amd64_read_pci_cfg(pvt->F6, F17H_SCR_BASE_ADDR, &scrubval);
if (scrubval & BIT(0)) {
amd64_read_pci_cfg(pvt->F6, F17H_SCR_LIMIT_ADDR, &scrubval);
@@ -1044,6 +1045,7 @@ static void determine_memory_type(struct amd64_pvt *pvt)
goto ddr3;

case 0x17:
+ case 0x18:
if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(5))
pvt->dram_type = MEM_LRDDR4;
else if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(4))
@@ -2200,6 +2202,16 @@ static struct amd64_family_type family_types[] = {
.dbam_to_cs = f17_base_addr_to_cs_size,
}
},
+ [HYGON_F18_CPUS] = {
+ /* Hygon F18h uses the same AMD F17h support */
+ .ctl_name = "Hygon_F18h",
+ .f0_id = PCI_DEVICE_ID_HYGON_18H_DF_F0,
+ .f6_id = PCI_DEVICE_ID_HYGON_18H_DF_F6,
+ .ops = {
+ .early_channel_count = f17_early_channel_count,
+ .dbam_to_cs = f17_base_addr_to_cs_size,
+ }
+ },
};

/*
@@ -3192,6 +3204,11 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt)
pvt->ops = &family_types[F17_CPUS].ops;
break;

+ case 0x18:
+ fam_type = &family_types[HYGON_F18_CPUS];
+ pvt->ops = &family_types[HYGON_F18_CPUS].ops;
+ break;
+
default:
amd64_err("Unsupported family!\n");
return NULL;
@@ -3428,6 +3445,7 @@ static const struct x86_cpu_id amd64_cpuids[] = {
{ X86_VENDOR_AMD, 0x15, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
{ X86_VENDOR_AMD, 0x16, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
{ X86_VENDOR_AMD, 0x17, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
+ { X86_VENDOR_HYGON, 0x18, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
{ }
};
MODULE_DEVICE_TABLE(x86cpu, amd64_cpuids);
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 1d4b74e..6e5f609 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -116,6 +116,9 @@
#define PCI_DEVICE_ID_AMD_17H_DF_F0 0x1460
#define PCI_DEVICE_ID_AMD_17H_DF_F6 0x1466

+#define PCI_DEVICE_ID_HYGON_18H_DF_F0 0x1460
+#define PCI_DEVICE_ID_HYGON_18H_DF_F6 0x1466
+
/*
* Function 1 - Address Map
*/
@@ -281,6 +284,7 @@ enum amd_families {
F16_CPUS,
F16_M30H_CPUS,
F17_CPUS,
+ HYGON_F18_CPUS,
NUM_FAMILIES,
};

diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 2ab4d61..c605089 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -1059,7 +1059,8 @@ static int __init mce_amd_init(void)
{
struct cpuinfo_x86 *c = &boot_cpu_data;

- if (c->x86_vendor != X86_VENDOR_AMD)
+ if (c->x86_vendor != X86_VENDOR_AMD &&
+ c->x86_vendor != X86_VENDOR_HYGON)
return -ENODEV;

fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
@@ -1113,6 +1114,7 @@ static int __init mce_amd_init(void)
break;

case 0x17:
+ case 0x18:
xec_mask = 0x3f;
if (!boot_cpu_has(X86_FEATURE_SMCA)) {
printk(KERN_WARNING "Decoding supported only on Scalable MCA processors.\n");
--
2.7.4


2018-08-29 19:37:40

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH v5 01/16] x86/cpu: create Dhyana init file and register new cpu_dev to system

Pu Wen <[email protected]> writes:

> Add x86 architecture support for new processor Hygon Dhyana Family 18h.
> Rework to create a separated file(arch/x86/kernel/cpu/hygon.c) from the
> AMD init one(arch/x86/kernel/cpu/amd.c) to initialize Dhyana CPU.

Standard approach would be to move the shared code into a different
file and call it from both amd.c and hygon.c instead of duplicating.

-Andi

2018-08-30 12:37:17

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 01/16] x86/cpu: create Dhyana init file and register new cpu_dev to system

On Wed, Aug 29, 2018 at 08:42:49PM +0800, Pu Wen wrote:
> Add x86 architecture support for new processor Hygon Dhyana Family 18h.
> Rework to create a separated file(arch/x86/kernel/cpu/hygon.c) from the
> AMD init one(arch/x86/kernel/cpu/amd.c) to initialize Dhyana CPU. In
> this way we can remove old AMD architecture support codes from Hygon
> code path and generate a clear initialization flow for Hygon processors.
> It also reduce long-term maintenance effort.
> Also add Maintainer information for hygon.c in accordance.
>
> To identify Hygon processors, add a new vendor type X86_VENDOR_HYGON(9)
> for system recognition.
>
> To enable Hygon processor config, add a separated Kconfig entry
> (CPU_SUP_HYGON) for Dhyana CPU in kernel config setup.
>
> Signed-off-by: Pu Wen <[email protected]>
> ---
> MAINTAINERS | 6 +
> arch/x86/Kconfig.cpu | 13 ++
> arch/x86/include/asm/processor.h | 3 +-
> arch/x86/kernel/cpu/Makefile | 1 +
> arch/x86/kernel/cpu/hygon.c | 408 +++++++++++++++++++++++++++++++++++++++
> 5 files changed, 430 insertions(+), 1 deletion(-)
> create mode 100644 arch/x86/kernel/cpu/hygon.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a5b256b..9c1d920 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6759,6 +6759,12 @@ S: Maintained
> F: mm/memory-failure.c
> F: mm/hwpoison-inject.c
>
> +HYGON PROCESSOR SUPPORT
> +M: Pu Wen <[email protected]>
> +L: [email protected]

This is probably the wrong ML. You either have your own or use lkml, I'd
say.

> +S: Supported
> +F: arch/x86/kernel/cpu/hygon.c
> +
> Hyper-V CORE AND DRIVERS
> M: "K. Y. Srinivasan" <[email protected]>
> M: Haiyang Zhang <[email protected]>
> diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
> index 638411f..2e92267 100644
> --- a/arch/x86/Kconfig.cpu
> +++ b/arch/x86/Kconfig.cpu
> @@ -426,6 +426,19 @@ config CPU_SUP_AMD
>
> If unsure, say N.
>
> +config CPU_SUP_HYGON
> + default y
> + bool "Support Hygon processors" if PROCESSOR_SELECT
> + 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 c242972..9f18cdb 100644
> --- a/arch/x86/include/asm/processor.h
> +++ b/arch/x86/include/asm/processor.h
> @@ -153,7 +153,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 347137e..1f5d229 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 0000000..ae90d1f
> --- /dev/null
> +++ b/arch/x86/kernel/cpu/hygon.c
> @@ -0,0 +1,408 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Hygon Processor Support for Linux
> + *
> + * Copyright (c) Chengdu Haiguang IC Design Co., Ltd.
> + *
> + * Author: 2018 Pu Wen <[email protected]>

Year goes with the copyright.

Otherwise looks ok.

--
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.
--

2018-08-30 17:42:27

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 01/16] x86/cpu: create Dhyana init file and register new cpu_dev to system

On 2018-08-30 03:35, Andi Kleen wrote:
>Pu Wen <[email protected]> writes:
>> Add x86 architecture support for new processor Hygon Dhyana Family 18h.
>> Rework to create a separated file(arch/x86/kernel/cpu/hygon.c) from the
>> AMD init one(arch/x86/kernel/cpu/amd.c) to initialize Dhyana CPU.
>
>Standard approach would be to move the shared code into a different
>file and call it from both amd.c and hygon.c instead of duplicating.

Hi Andi, Thanks for your feedback.

As Hygon Dhyana arch originate from AMD, we share most arch codes with
AMD. In our first patch v1, we direct reuse AMD's init codes in amd.c,
which can work out a minimal patch. But the code mixture between AMD
and Hygon occur, which might cause problem in long term.

To reduce long term maintaining effort, we reworked the patch and do the
arch code duplication and removed unnecessary old arch support code/family
condition check, which reduce code size to 37%, and give a clear view for
hygon arch initialize flow. For long term, it also remove code modification
interference between AMD and Hygon, make hygon code easy to modify for it's
further products. That's the patch since v2.

We did try the standard approach as you suggested between v1 and v2
internally, and found out it's hard to find a clear version. Because amd.c
has many family checking to support it's multiple family products, which
make the common function strip difficult. Also based on the consideration
of common functions also might interference with each other, we finally
choose the patch v2 style.

It's hard to find a best way between code duplication and code reuse.
Any suggestion please let us know.

Regards,
Pu Wen


2018-08-30 18:04:25

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 01/16] x86/cpu: create Dhyana init file and register new cpu_dev to system

On 2018-08-30 20:35, Borislav Petkov wrote:
>> +HYGON PROCESSOR SUPPORT
>> +M: Pu Wen <[email protected]>
>> +L: [email protected]
>
>This is probably the wrong ML. You either have your own or use lkml,
>I'd say.

That's all right, I'll use [email protected] instead.

>> +++ b/arch/x86/kernel/cpu/hygon.c
>> @@ -0,0 +1,408 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Hygon Processor Support for Linux
>> + *
>> + * Copyright (c) Chengdu Haiguang IC Design Co., Ltd.
>> + *
>> + * Author: 2018 Pu Wen <[email protected]>
>
>Year goes with the copyright.

OK, will change it as below: (in next version of patches)
+ * Copyright (c) 2018 Chengdu Haiguang IC Design Co., Ltd.
+ * Author: Pu Wen <[email protected]>

Thanks,
Pu Wen

>Otherwise looks ok.


2018-09-03 09:57:51

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 02/16] x86/cache: get cache size/leaves and setup cache cpumap for Dhyana

Patch subject needs to be of the format:

<file path(s)>: Sentence starting with a capital letter and describing
concisely the patch

Fix all your subjects pls.

On Wed, Aug 29, 2018 at 08:43:10PM +0800, Pu Wen wrote:
> Hygon Dhyana processor has the topology extensions bit in CPUID.
> With this bit kernel can get the cache info. So add support

"With this bit, the kernel... "

> in cpuid4_cache_lookup_regs() to get the correct cache size.
>
> Dhyana also find num_cache_leaves via CPUID leaf 0x8000001d, so

"... also discovers num_cache_leaves ..."

> add Hygon support 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 <[email protected]>
> ---
> 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(-)

With that:

Reviewed-by: Borislav Petkov <[email protected]>

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-03 13:00:50

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 02/16] x86/cache: get cache size/leaves and setup cache cpumap for Dhyana

On 2018/9/3 17:57, Borislav Petkov wrote:
> Patch subject needs to be of the format:
>
> <file path(s)>: Sentence starting with a capital letter and describing
> concisely the patch
>
> Fix all your subjects pls.

OK, will fix them in next version of patches.

>> With this bit kernel can get the cache info. So add support
>
> "With this bit, the kernel..."
>
>> Dhyana also find num_cache_leaves via CPUID leaf 0x8000001d, so
>
> "... also discovers num_cache_leaves ..."
>

Thanks for the correction.

Regards,
Pu Wen

>
> With that:
>
> Reviewed-by: Borislav Petkov <[email protected]>
>


2018-09-03 19:05:06

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 03/16] x86/mtrr: get MTRR number and support TOP_MEM2

On Wed, Aug 29, 2018 at 08:43:23PM +0800, Pu Wen wrote:
> Hygon CPU have a special magic MSR way to force WB for memory >4GB,

It was "Hygon Dhyana" before now "Hygon" only. Can we agree on the
naming nomenclature and stick with it.

Also, it is "The ... CPU has a special..."

> and also support TOP_MEM2. Therefore, it is necessary to add Hygon
> support in amd_special_default_mtrr().
>
> The MtrrFixDramModEn bit on Hygon platform should also be set to 1
> during BIOS initialization of the fixed MTRRs, then cleared to 0 for
> operation.
>
> The number of variable MTRRs for Hygon is 2 as AMD's.
>
> Signed-off-by: Pu Wen <[email protected]>
> ---
> arch/x86/kernel/cpu/mtrr/cleanup.c | 3 ++-
> arch/x86/kernel/cpu/mtrr/generic.c | 5 +++--
> arch/x86/kernel/cpu/mtrr/mtrr.c | 2 +-
> 3 files changed, 6 insertions(+), 4 deletions(-)

...

> diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
> index e12ee86..77c3eaa 100644
> --- a/arch/x86/kernel/cpu/mtrr/generic.c
> +++ b/arch/x86/kernel/cpu/mtrr/generic.c
> @@ -49,8 +49,9 @@ static inline void k8_check_syscfg_dram_mod_en(void)
> {
> u32 lo, hi;
>
> - if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
> - (boot_cpu_data.x86 >= 0x0f)))
> + if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
> + boot_cpu_data.x86 >= 0x0f) ||
> + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON))

Why are you even touching this statement? The function returns early on
!X86_VENDOR_AMD.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-04 03:04:18

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 03/16] x86/mtrr: get MTRR number and support TOP_MEM2

On 2018/9/4 3:04, Borislav Petkov wrote:
> It was "Hygon Dhyana" before now "Hygon" only. Can we agree on the
> naming nomenclature and stick with it.

OK, agree on it.

...

>> - if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
>> - (boot_cpu_data.x86 >= 0x0f)))
>> + if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
>> + boot_cpu_data.x86 >= 0x0f) ||
>> + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON))
>
> Why are you even touching this statement? The function returns early on
> !X86_VENDOR_AMD.

The statement is briefly equal to !(X86_VENDOR_AMD || X86_VENDOR_HYGON).
So the function will not return early on !X86_VENDOR_AMD. :-)

Also the statement can be changed to:
+ if (!(boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+ boot_cpu_data.x86 >= 0x0f) &&
+ !(boot_cpu_data.x86_vendor == X86_VENDOR_HYGON))
or:
+ if ((boot_cpu_data.x86_vendor != X86_VENDOR_AMD ||
+ boot_cpu_data.x86 < 0x0f) &&
+ (boot_cpu_data.x86_vendor != X86_VENDOR_HYGON))

Which statement is better?

Thanks,
Pu Wen


2018-09-04 08:05:02

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 03/16] x86/mtrr: get MTRR number and support TOP_MEM2

On Tue, Sep 04, 2018 at 11:02:41AM +0800, Pu Wen wrote:
> > > - if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
> > > - (boot_cpu_data.x86 >= 0x0f)))
> > > + if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
> > > + boot_cpu_data.x86 >= 0x0f) ||
> > > + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON))
> >
> > Why are you even touching this statement? The function returns early on
> > !X86_VENDOR_AMD.
>
> The statement is briefly equal to !(X86_VENDOR_AMD || X86_VENDOR_HYGON).
> So the function will not return early on !X86_VENDOR_AMD. :-)

I meant the *original* version - not yours!

My question is why are you even touching a K8-old BIOS workaround?! Your
commit message says:

The MtrrFixDramModEn bit on Hygon platform should also be set to 1
during BIOS initialization of the fixed MTRRs, then cleared to 0 for
operation.

Is your BIOS already broken?

Searching the net for

pr_err(FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
" not cleared by BIOS, clearing this bit\n",

shows only old mails so I'm going to assume this got fixed, finally! And
you probably have received a *fixed* BIOS even, allegedly.

So what's up?

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-04 09:17:23

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 04/16] x86/smpboot: smp init nodelay and no flush caches before sleep

On Wed, Aug 29, 2018 at 08:43:41PM +0800, Pu Wen wrote:
> Dhyana use no delay in smp_quirk_init_udelay(), and return in
> mwait_play_dead() as AMD does.
>
> Signed-off-by: Pu Wen <[email protected]>
> ---
> 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 f02ecaf..5369d7f 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;
> --

Reviewed-by: Borislav Petkov <[email protected]>

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-04 10:50:32

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 05/16] x86/pmu: enable Hygon support to PMU infrastructure

On Wed, Aug 29, 2018 at 08:43:54PM +0800, Pu Wen wrote:
> Hygon PMU arch is similar to AMD Family 17h. To support Hygon PMU, the
> initialization flow for it just call amd_pmu_init() and change PMU name

That sentence reads funny.

> to "HYGON". To share AMD's flow, add code check for Hygon family ID 18h

s/family ID/family/

> to run the code path of AMD family 17h in core/uncore functions.
>
> Also it returns the bit offset of the performance counter register and
> event selection register for Hygon CPU in the similar way as AMD does.

In general, you seem to be explaining *what* your patches do and not
*why*. This is the wrong. Always explain the *why* - the *what* is
visible from the diff.

You probably need to brush up on
Documentation/process/submitting-patches.rst, section 2.

> Signed-off-by: Pu Wen <[email protected]>
> ---
> arch/x86/events/amd/core.c | 6 ++++++
> arch/x86/events/amd/uncore.c | 15 ++++++++++-----
> arch/x86/events/core.c | 4 ++++
> arch/x86/kernel/cpu/perfctr-watchdog.c | 2 ++
> 4 files changed, 22 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
> index c84584b..6c13c9d 100644
> --- a/arch/x86/events/amd/core.c
> +++ b/arch/x86/events/amd/core.c
> @@ -669,6 +669,12 @@ static int __init amd_core_pmu_init(void)
> * We fallback to using default amd_get_event_constraints.
> */
> break;
> + case 0x18:
> + if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
> + pr_cont("Fam18h ");

Didn't we agree that you'll verify whether family 0x18 is going to be
Hygon only?

What happened to that checking?

> + /* 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 981ba5e..9f2eb43 100644
> --- a/arch/x86/events/amd/uncore.c
> +++ b/arch/x86/events/amd/uncore.c
> @@ -507,17 +507,22 @@ 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_vendor == X86_VENDOR_AMD &&
> + boot_cpu_data.x86 == 0x17) ||
> + (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON &&
> + boot_cpu_data.x86 == 0x18)) {

Same here.

What's up?

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-04 12:45:40

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 03/16] x86/mtrr: get MTRR number and support TOP_MEM2

On 2018/9/4 16:02, Borislav Petkov wrote:
> shows only old mails so I'm going to assume this got fixed, finally! And
> you probably have received a *fixed* BIOS even, allegedly.
>
> So what's up?

I tested the function on Hygon Dhyana platforms with the latest BIOS,
found that this problem is indeed fixed. So the workaround is not
needed for Hygon Dhyana platforms any more, and the vendor checking
for Hygon will be removed in next version of patch.

Thanks,
Pu Wen


2018-09-04 13:34:48

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 05/16] x86/pmu: enable Hygon support to PMU infrastructure

On 2018/9/4 18:48, Borislav Petkov wrote:
> On Wed, Aug 29, 2018 at 08:43:54PM +0800, Pu Wen wrote:
>> Hygon PMU arch is similar to AMD Family 17h. To support Hygon PMU, the
>> initialization flow for it just call amd_pmu_init() and change PMU name
>
> That sentence reads funny.

Will rewrite this sentence to make it more understandable. :)

> In general, you seem to be explaining *what* your patches do and not
> *why*. This is the wrong. Always explain the *why* - the *what* is
> visible from the diff.
>
> You probably need to brush up on
> Documentation/process/submitting-patches.rst, section 2.

All right, will relearn the document and rework the patch descriptions.

>> + case 0x18:
>> + if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
>> + pr_cont("Fam18h ");
>
> Didn't we agree that you'll verify whether family 0x18 is going to be
> Hygon only?
>
> What happened to that checking?
...
> Same here.
>
> What's up?

Will remove all the remaining unneeded Hygon vendor checking through
the whole patch set to minimize the code modification.

Thanks,
Pu Wen


2018-09-04 14:04:43

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 06/16] x86/nops: init ideal_nops for Hygon

On Wed, Aug 29, 2018 at 08:44:07PM +0800, Pu Wen wrote:
> The ideal_nops for Dhyana processors should be p6_nops.
>
> Signed-off-by: Pu Wen <[email protected]>
> ---
> 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 014f214..3f51d1c 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;
> --

Reviewed-by: Borislav Petkov <[email protected]>

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-04 14:55:11

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 07/16] x86/pci: add Hygon PCI vendor and northbridge support

On Wed, Aug 29, 2018 at 08:44:18PM +0800, Pu Wen wrote:
> As Hygon register its PCI Vendor ID as a new one "0x1d94", so add a new
> definition PCI_VENDOR_ID_HYGON in include/linux/pci_ids.h.
>
> Also Hygon PCI Device ID(0x1450/0x1463/0x1464) for Host bridge is added
> to amd_nb.c. And it need to define new arrays for Hygon:
> hygon_root_ids[], hygon_nb_misc_ids[], hygon_nb_link_ids[].
>
> To enable Hygon north bridge support, add new variable root_ids, and
> assign its value based on whether CPU vendor is AMD or Hygon. Modify
> the CONFIG_AMD_NB to depends on either AMD or Hygon.
>
> Add Hygon support in amd_postcore_init(), early_root_info_init().

This whole commit message needs to not say *what* the patch does.

> Acked-by: Bjorn Helgaas <[email protected]> # pci_ids.h
> Signed-off-by: Pu Wen <[email protected]>
> ---
> arch/x86/Kconfig | 2 +-
> arch/x86/kernel/amd_nb.c | 51 ++++++++++++++++++++++++++++++++++++++++++------
> arch/x86/pci/amd_bus.c | 6 ++++--
> include/linux/pci_ids.h | 2 ++
> 4 files changed, 52 insertions(+), 9 deletions(-)
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index c5ff296..733f1ec 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2818,7 +2818,7 @@ endif # X86_32
>
> config AMD_NB
> def_bool y
> - depends on CPU_SUP_AMD && PCI
> + depends on (CPU_SUP_AMD || CPU_SUP_HYGON) && PCI
>
> source "drivers/pcmcia/Kconfig"
>
> diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
> index b481b95..d9867b2 100644
> --- a/arch/x86/kernel/amd_nb.c
> +++ b/arch/x86/kernel/amd_nb.c
> @@ -20,6 +20,10 @@
> #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb
> #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4 0x15ec
>
> +#define PCI_DEVICE_ID_HYGON_18H_ROOT 0x1450
> +#define PCI_DEVICE_ID_HYGON_18H_DF_F3 0x1463
> +#define PCI_DEVICE_ID_HYGON_18H_DF_F4 0x1464

Why are you adding those if you can use the AMD f17h ones? They're the same.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-04 15:47:00

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 07/16] x86/pci: add Hygon PCI vendor and northbridge support

On 2018/9/4 22:52, Borislav Petkov wrote:
>> Add Hygon support in amd_postcore_init(), early_root_info_init().
>
> This whole commit message needs to not say *what* the patch does.

Will rework the whole commit messages.

>> +#define PCI_DEVICE_ID_HYGON_18H_ROOT 0x1450
>> +#define PCI_DEVICE_ID_HYGON_18H_DF_F3 0x1463
>> +#define PCI_DEVICE_ID_HYGON_18H_DF_F4 0x1464
>
> Why are you adding those if you can use the AMD f17h ones? They're
the same.

I add these definitions to indicate that there are Hygon PCI device IDs.
You are right, I can just use the AMD f17h ones here.

--
Regards,
Pu Wen


2018-09-04 16:06:03

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 07/16] x86/pci: add Hygon PCI vendor and northbridge support

On Tue, Sep 04, 2018 at 11:45:02PM +0800, Pu Wen wrote:
> I add these definitions to indicate that there are Hygon PCI device IDs.
> You are right, I can just use the AMD f17h ones here.

Right, if this is a small piece where they're all together in a single
compilation unit - like in this case - I don't see an issue with using
the AMD ones. Later, when you start splitting functionality, you can do
proper defines.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-04 18:35:00

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 08/16] x86/apic: add modern APIC support for Hygon

On Wed, Aug 29, 2018 at 08:44:30PM +0800, Pu Wen wrote:
> Hygon processors use modern APIC, so just return in modern_apic() and
> sync_Arb_IDs(). And should break in switch case in detect_init_API().
>
> When running on 32 bit mode, should set bigsmp if there are more than
> 8 cores.
>
> Signed-off-by: Pu Wen <[email protected]>
> ---
> arch/x86/kernel/apic/apic.c | 19 ++++++++++++++-----
> arch/x86/kernel/apic/probe_32.c | 1 +
> 2 files changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
> index 84132ed..a62968e 100644
> --- a/arch/x86/kernel/apic/apic.c
> +++ b/arch/x86/kernel/apic/apic.c
> @@ -220,10 +220,15 @@ static inline int lapic_is_integrated(void)
> */
> static int modern_apic(void)
> {
> - /* AMD systems use old APIC versions, so check the CPU */
> - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
> - boot_cpu_data.x86 >= 0xf)
> + /*
> + * Old AMD systems use old APIC versions, newer AMD systems
> + * and Hygon systems use modern APIC, so check the CPU
> + */
> + if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
> + boot_cpu_data.x86 >= 0xf) ||
> + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
> return 1;

Those compound conditionals are not nice to read. Just add yours
underneath:

if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
boot_cpu_data.x86 >= 0xf)
return 1;

if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
return 1;

Do that where applicable and where it makes sense, syntax-wise to have a
separate vendor == HYGON check in the other patches too.

Thx.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-05 08:10:03

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 08/16] x86/apic: add modern APIC support for Hygon

On 2018/9/5 2:33, Borislav Petkov wrote:
> On Wed, Aug 29, 2018 at 08:44:30PM +0800, Pu Wen wrote:
...
>> + if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
>> + boot_cpu_data.x86 >= 0xf) ||
>> + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
>> return 1;
>
> Those compound conditionals are not nice to read. Just add yours
> underneath:
>
> if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
> boot_cpu_data.x86 >= 0xf)
> return 1;
>
> if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
> return 1;
>
> Do that where applicable and where it makes sense, syntax-wise to have a
> separate vendor == HYGON check in the other patches too.

That's OK, will check other patches and split the compound conditionals
where it's possible.

--
Thanks,
Pu Wen


2018-09-05 09:15:00

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 09/16] x86/bugs: add lfence mitigation to spectre v2 and no meltdown for Hygon

On Wed, Aug 29, 2018 at 08:44:41PM +0800, Pu Wen wrote:
> To share codes between AMD and Hygon to mitigate Spectre V2 Retpoline
> vulnerability, rename macros SPECTRE_V2_RETPOLINE_MINIMAL_AMD to
> SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE, and SPECTRE_V2_CMD_RETPOLINE_AMD
> to SPECTRE_V2_CMD_RETPOLINE_LFENCE.
>
> As Hygon processors are not affected by meltdown vulnerability as AMD's,
> so add exception in array cpu_no_meltdown[] for Hygon.
>
> Signed-off-by: Pu Wen <[email protected]>
> ---
> arch/x86/include/asm/nospec-branch.h | 4 ++--
> arch/x86/kernel/cpu/bugs.c | 28 +++++++++++++++-------------
> arch/x86/kernel/cpu/common.c | 1 +
> 3 files changed, 18 insertions(+), 15 deletions(-)
>
> diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
> index fd2a8c1..6763f9b 100644
> --- a/arch/x86/include/asm/nospec-branch.h
> +++ b/arch/x86/include/asm/nospec-branch.h
> @@ -211,9 +211,9 @@
> enum spectre_v2_mitigation {
> SPECTRE_V2_NONE,
> SPECTRE_V2_RETPOLINE_MINIMAL,
> - SPECTRE_V2_RETPOLINE_MINIMAL_AMD,
> + SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE,
> SPECTRE_V2_RETPOLINE_GENERIC,
> - SPECTRE_V2_RETPOLINE_AMD,
> + SPECTRE_V2_RETPOLINE_LFENCE,
> SPECTRE_V2_IBRS_ENHANCED,
> };
>
> diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
> index 4c2313d..15be045 100644
> --- a/arch/x86/kernel/cpu/bugs.c
> +++ b/arch/x86/kernel/cpu/bugs.c
> @@ -132,15 +132,15 @@ enum spectre_v2_mitigation_cmd {
> SPECTRE_V2_CMD_FORCE,
> SPECTRE_V2_CMD_RETPOLINE,
> SPECTRE_V2_CMD_RETPOLINE_GENERIC,
> - SPECTRE_V2_CMD_RETPOLINE_AMD,
> + SPECTRE_V2_CMD_RETPOLINE_LFENCE,
> };
>
> static const char *spectre_v2_strings[] = {
> [SPECTRE_V2_NONE] = "Vulnerable",
> [SPECTRE_V2_RETPOLINE_MINIMAL] = "Vulnerable: Minimal generic ASM retpoline",
> - [SPECTRE_V2_RETPOLINE_MINIMAL_AMD] = "Vulnerable: Minimal AMD ASM retpoline",
> + [SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE] = "Vulnerable: Minimal LFENCE ASM retpoline",
> [SPECTRE_V2_RETPOLINE_GENERIC] = "Mitigation: Full generic retpoline",
> - [SPECTRE_V2_RETPOLINE_AMD] = "Mitigation: Full AMD retpoline",
> + [SPECTRE_V2_RETPOLINE_LFENCE] = "Mitigation: Full LFENCE retpoline",
> [SPECTRE_V2_IBRS_ENHANCED] = "Mitigation: Enhanced IBRS",
> };

This is user-visible and with all the back'n'forth and backporting
and the whole security fiasco, I don't want to have another source of
confusion. You'll have to live with it saying "AMD" in dmesg.

> @@ -272,7 +272,7 @@ static const struct {
> { "off", SPECTRE_V2_CMD_NONE, false },
> { "on", SPECTRE_V2_CMD_FORCE, true },
> { "retpoline", SPECTRE_V2_CMD_RETPOLINE, false },
> - { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_AMD, false },
> + { "retpoline,lfence", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false },
> { "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false },
> { "auto", SPECTRE_V2_CMD_AUTO, false },
> };

This even more so. Those are command line strings which we're still
communicating to people, even. So no, it needs to remain "retpoline,amd"
on Hygon.

And then to not confuse people staring at the code either, we can drop
this change too:

- SPECTRE_V2_CMD_RETPOLINE_AMD,
+ SPECTRE_V2_CMD_RETPOLINE_LFENCE,

Which leaves this patch only with the addition of the vendor tests. The
other stuff you can drop.

Thx.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-05 09:24:45

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 10/16] x86/mce: enable Hygon support to MCE infrastructure

On Wed, Aug 29, 2018 at 08:44:54PM +0800, Pu Wen wrote:
> Hygon machine check arch is similar to AMD family 17h. To enable the MCE
> infrastructure support, add CPU vendor check for Hygon to share the code
> path of AMD.
>
> Add hygon mce init function mce_hygon_feature_init() to minimize further
> maintenance effort.
>
> Signed-off-by: Pu Wen <[email protected]>
> ---
> arch/x86/include/asm/mce.h | 5 +++++
> arch/x86/kernel/cpu/mcheck/mce-severity.c | 3 ++-
> arch/x86/kernel/cpu/mcheck/mce.c | 21 +++++++++++++++------
> 3 files changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
> index 3a17107..12357aa 100644
> --- a/arch/x86/include/asm/mce.h
> +++ b/arch/x86/include/asm/mce.h
> @@ -214,6 +214,11 @@ 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);
> +}
> +

What happens if CONFIG_X86_MCE_AMD=n ?

In general, since you're using AMD code, you need to make CPU_SUP_HYGON
depend on a bunch of AMD config items like CONFIG_X86_MCE_AMD,
CONFIG_CPU_SUP_AMD, CONFIG_AMD_NB,... Audit your code and see what other
config items need to be selected.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-05 10:32:14

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 11/16] x86/kvm: enable Hygon support to KVM infrastructure

On Wed, Aug 29, 2018 at 08:45:05PM +0800, Pu Wen wrote:
> Hygon Dhyana CPU has the SVM feature as AMD family 17h does.
> Add Hygon support in the KVM infrastructure.
>
> Signed-off-by: Pu Wen <[email protected]>
> ---
> 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(-)

Reviewed-by: Borislav Petkov <[email protected]>

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-05 10:42:19

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 09/16] x86/bugs: add lfence mitigation to spectre v2 and no meltdown for Hygon

On 2018/9/5 17:13, Borislav Petkov wrote:
>> static const char *spectre_v2_strings[] = {
>> [SPECTRE_V2_NONE] = "Vulnerable",
>> [SPECTRE_V2_RETPOLINE_MINIMAL] = "Vulnerable: Minimal generic ASM retpoline",
>> - [SPECTRE_V2_RETPOLINE_MINIMAL_AMD] = "Vulnerable: Minimal AMD ASM retpoline",
>> + [SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE] = "Vulnerable: Minimal LFENCE ASM retpoline",
>> [SPECTRE_V2_RETPOLINE_GENERIC] = "Mitigation: Full generic retpoline",
>> - [SPECTRE_V2_RETPOLINE_AMD] = "Mitigation: Full AMD retpoline",
>> + [SPECTRE_V2_RETPOLINE_LFENCE] = "Mitigation: Full LFENCE retpoline",
>> [SPECTRE_V2_IBRS_ENHANCED] = "Mitigation: Enhanced IBRS",
>> };
>
> This is user-visible and with all the back'n'forth and backporting
> and the whole security fiasco, I don't want to have another source of
> confusion. You'll have to live with it saying "AMD" in dmesg
....
>> @@ -272,7 +272,7 @@ static const struct {
>> { "off", SPECTRE_V2_CMD_NONE, false },
>> { "on", SPECTRE_V2_CMD_FORCE, true },
>> { "retpoline", SPECTRE_V2_CMD_RETPOLINE, false },
>> - { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_AMD, false },
>> + { "retpoline,lfence", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false },
>> { "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false },
>> { "auto", SPECTRE_V2_CMD_AUTO, false },
>> };
>
> This even more so. Those are command line strings which we're still
> communicating to people, even. So no, it needs to remain "retpoline,amd"
> on Hygon.
>
> And then to not confuse people staring at the code either, we can drop
> this change too:
>
> - SPECTRE_V2_CMD_RETPOLINE_AMD,
> + SPECTRE_V2_CMD_RETPOLINE_LFENCE,
>
> Which leaves this patch only with the addition of the vendor tests. The
> other stuff you can drop.

That's reasonable. To avoid the confusion, will only leave the vendor
testing for Hygon and drop the other changes, which also minimize the
code modification.

--
Regards,
Pu Wen


2018-09-05 10:46:17

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 15/16] driver/edac: enable Hygon support to AMD64 EDAC driver

Subject should be:

EDAC, amd64: Add Hygon Dhyana support

On Wed, Aug 29, 2018 at 08:45:45PM +0800, Pu Wen wrote:
> To make AMD64 EDAC and MCE drivers working on Hygon platforms, add
> support for Hygon by using the code path of AMD family 0x17.
>
> As Hygon will negotiate with AMD to make sure that only Hygon will
> use family 0x18, under this consideration try to minimize code
> modifications and share most codes with AMD.
>
> Also Hygon PCI Device ID DF_F0/DF_F6(0x1460/0x1466) of Host bridges
> is needed for edac driver.
>
> Signed-off-by: Pu Wen <[email protected]>
> ---
> drivers/edac/amd64_edac.c | 20 +++++++++++++++++++-
> drivers/edac/amd64_edac.h | 4 ++++
> drivers/edac/mce_amd.c | 4 +++-
> 3 files changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
> index 18aeabb..d8b4b0e 100644
> --- a/drivers/edac/amd64_edac.c
> +++ b/drivers/edac/amd64_edac.c
> @@ -211,7 +211,7 @@ static int __set_scrub_rate(struct amd64_pvt *pvt, u32 new_bw, u32 min_rate)
>
> scrubval = scrubrates[i].scrubval;
>
> - if (pvt->fam == 0x17) {
> + if (pvt->fam == 0x17 || pvt->fam == 0x18) {
> __f17h_set_scrubval(pvt, scrubval);
> } else if (pvt->fam == 0x15 && pvt->model == 0x60) {
> f15h_select_dct(pvt, 0);
> @@ -264,6 +264,7 @@ static int get_scrub_rate(struct mem_ctl_info *mci)
> break;
>
> case 0x17:
> + case 0x18:
> amd64_read_pci_cfg(pvt->F6, F17H_SCR_BASE_ADDR, &scrubval);
> if (scrubval & BIT(0)) {
> amd64_read_pci_cfg(pvt->F6, F17H_SCR_LIMIT_ADDR, &scrubval);
> @@ -1044,6 +1045,7 @@ static void determine_memory_type(struct amd64_pvt *pvt)
> goto ddr3;
>
> case 0x17:
> + case 0x18:
> if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(5))
> pvt->dram_type = MEM_LRDDR4;
> else if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(4))
> @@ -2200,6 +2202,16 @@ static struct amd64_family_type family_types[] = {
> .dbam_to_cs = f17_base_addr_to_cs_size,
> }
> },
> + [HYGON_F18_CPUS] = {
> + /* Hygon F18h uses the same AMD F17h support */
> + .ctl_name = "Hygon_F18h",
> + .f0_id = PCI_DEVICE_ID_HYGON_18H_DF_F0,
> + .f6_id = PCI_DEVICE_ID_HYGON_18H_DF_F6,
> + .ops = {
> + .early_channel_count = f17_early_channel_count,
> + .dbam_to_cs = f17_base_addr_to_cs_size,
> + }
> + },
> };
>
> /*
> @@ -3192,6 +3204,11 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt)
> pvt->ops = &family_types[F17_CPUS].ops;
> break;
>
> + case 0x18:
> + fam_type = &family_types[HYGON_F18_CPUS];
> + pvt->ops = &family_types[HYGON_F18_CPUS].ops;
> + break;
> +

You can use the F17_CPUS array element here and overwrite the ->ctl_name
string only. No need to define [HYGON_F18_CPUS] above... yet.

> default:
> amd64_err("Unsupported family!\n");
> return NULL;
> @@ -3428,6 +3445,7 @@ static const struct x86_cpu_id amd64_cpuids[] = {
> { X86_VENDOR_AMD, 0x15, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
> { X86_VENDOR_AMD, 0x16, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
> { X86_VENDOR_AMD, 0x17, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
> + { X86_VENDOR_HYGON, 0x18, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
> { }
> };
> MODULE_DEVICE_TABLE(x86cpu, amd64_cpuids);
> diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
> index 1d4b74e..6e5f609 100644
> --- a/drivers/edac/amd64_edac.h
> +++ b/drivers/edac/amd64_edac.h
> @@ -116,6 +116,9 @@
> #define PCI_DEVICE_ID_AMD_17H_DF_F0 0x1460
> #define PCI_DEVICE_ID_AMD_17H_DF_F6 0x1466
>
> +#define PCI_DEVICE_ID_HYGON_18H_DF_F0 0x1460
> +#define PCI_DEVICE_ID_HYGON_18H_DF_F6 0x1466

As in the previous patch - use the AMD defines.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-05 13:01:15

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 10/16] x86/mce: enable Hygon support to MCE infrastructure

On 2018/9/5 17:22, Borislav Petkov wrote:
>> @@ -214,6 +214,11 @@ static inline void mce_amd_feature_init(struct cpuinfo_x86 *c) { }
>> #endif
>>
>> +static inline void mce_hygon_feature_init(struct cpuinfo_x86 *c)
>> +{
>> + return mce_amd_feature_init(c);
>> +}
>> +
>
> What happens if CONFIG_X86_MCE_AMD=n ?

If CONFIG_X86_MCE_AMD=n, mce_hygon_feature_init will call the other
one mce_amd_feature_init which is a null function and located in the
else branch of "#ifdef CONFIG_X86_MCE_AMD". The compilation is OK and
the kernel will run without MCE support.

> In general, since you're using AMD code, you need to make CPU_SUP_HYGON
> depend on a bunch of AMD config items like CONFIG_X86_MCE_AMD,
> CONFIG_CPU_SUP_AMD, CONFIG_AMD_NB,... Audit your code and see what other
> config items need to be selected.

All right, will check all the config items which are necessary for
CONFIG_CPU_SUP_HYGON.

--
Regards,
Pu Wen


2018-09-05 13:05:16

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 15/16] driver/edac: enable Hygon support to AMD64 EDAC driver

On 2018/9/5 18:44, Borislav Petkov wrote:
> Subject should be:
>
> EDAC, amd64: Add Hygon Dhyana support

Thanks for the correction.

>> + case 0x18:
>> + fam_type = &family_types[HYGON_F18_CPUS];
>> + pvt->ops = &family_types[HYGON_F18_CPUS].ops;
>> + break;
>> +
>
> You can use the F17_CPUS array element here and overwrite the ->ctl_name
> string only. No need to define [HYGON_F18_CPUS] above... yet.

All right, the way reusing F17_CPUS will also minimize the code
modification.

>> +#define PCI_DEVICE_ID_HYGON_18H_DF_F0 0x1460
>> +#define PCI_DEVICE_ID_HYGON_18H_DF_F6 0x1466
>
> As in the previous patch - use the AMD defines.

Will remove them in next version of patches.

--
Regards,
Pu Wen


2018-09-05 13:17:30

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 10/16] x86/mce: enable Hygon support to MCE infrastructure

On Wed, Sep 05, 2018 at 08:59:24PM +0800, Pu Wen wrote:
> If CONFIG_X86_MCE_AMD=n, mce_hygon_feature_init will call the other
> one mce_amd_feature_init which is a null function and located in the
> else branch of "#ifdef CONFIG_X86_MCE_AMD". The compilation is OK and
> the kernel will run without MCE support.

So my question was rather ironic but I guess irony can't travel through
mail. So let me paraphrase: is that a use case you wanna support?
Because I'd advise very strongly against !MCE kernels.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-06 03:55:07

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 10/16] x86/mce: enable Hygon support to MCE infrastructure

On 2018/9/5 21:15, Borislav Petkov wrote:
> On Wed, Sep 05, 2018 at 08:59:24PM +0800, Pu Wen wrote:
>> If CONFIG_X86_MCE_AMD=n, mce_hygon_feature_init will call the other
>> one mce_amd_feature_init which is a null function and located in the
>> else branch of "#ifdef CONFIG_X86_MCE_AMD". The compilation is OK and
>> the kernel will run without MCE support.
>
> So my question was rather ironic but I guess irony can't travel through
> mail. So let me paraphrase: is that a use case you wanna support?
> Because I'd advise very strongly against !MCE kernels.

In most of the normal use cases MCE is necessary. Rarely in some cases
such as for test purpose MCE may be unselected.

--
Regards,
Pu Wen


2018-09-06 08:41:27

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 10/16] x86/mce: enable Hygon support to MCE infrastructure

On Thu, Sep 06, 2018 at 11:52:42AM +0800, Pu Wen wrote:
> In most of the normal use cases MCE is necessary. Rarely in some cases
> such as for test purpose MCE may be unselected.

Test with MCE disabled? Please elaborate.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-06 11:47:05

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 10/16] x86/mce: enable Hygon support to MCE infrastructure

On 2018/9/6 16:39, Borislav Petkov wrote:
> On Thu, Sep 06, 2018 at 11:52:42AM +0800, Pu Wen wrote:
>> In most of the normal use cases MCE is necessary. Rarely in some cases
>> such as for test purpose MCE may be unselected.
>
> Test with MCE disabled? Please elaborate.

The first is the compilation test. Test the kernel with both MCE selected
and unselected to see if is the compiling process successful or not.
The other test is functionality test. For example, during the MCE BIOS
development, to see if the MCE functions OK, it may need to select and
unselect MCE in kernel for double checking.

Actually in normal use scenario and in real product the MCE should be
always selected. To ensure this, I think there are two ways as below:
- Select X86_MCE_AMD in CPU_SUP_HYGON config entry, it also cater to the
first test scenario, but meanwhile lacks flexibility.
- The linux distros(Ubuntu, CentOS, etc) ensure that X86_MCE_AMD is
selected to the default config file, and indeed they do.
Which way is better?

--
Regards,
Pu Wen


2018-09-06 18:26:35

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v5 10/16] x86/mce: enable Hygon support to MCE infrastructure

On Thu, Sep 06, 2018 at 07:40:52PM +0800, Pu Wen wrote:
> The first is the compilation test. Test the kernel with both MCE selected
> and unselected to see if is the compiling process successful or not.

This is a kernel compile test - it has nothing to do with actual machine
testing.

> The other test is functionality test. For example, during the MCE BIOS
> development, to see if the MCE functions OK, it may need to select and
> unselect MCE in kernel for double checking.

Say what now?! What testing do you do if you boot a kernel which doesn't
even use the functionality you're testing?!

> Actually in normal use scenario and in real product the MCE should be
> always selected.

It better be!

> To ensure this, I think there are two ways as below:
> - Select X86_MCE_AMD in CPU_SUP_HYGON config entry, it also cater to the
> first test scenario, but meanwhile lacks flexibility.
> - The linux distros(Ubuntu, CentOS, etc) ensure that X86_MCE_AMD is
> selected to the default config file, and indeed they do.
> Which way is better?

The first way but change that dependency to CPU_SUP_AMD because there
are people building their own kernels and don't run distro configs. And
you need CPU_SUP_AMD because you're using their code.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-09-06 20:37:01

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH v5 10/16] x86/mce: enable Hygon support to MCE infrastructure

On 2018/9/6 20:29, Borislav Petkov wrote:
> Say what now?! What testing do you do if you boot a kernel which doesn't
> even use the functionality you're testing?!

I'm sorry, this case is not good to demonstrate the useage. And I think
there are no other people will do the test without MCE in kernel. So
with MCE enabled in kernel is the main case to support.

> The first way but change that dependency to CPU_SUP_AMD because there
> are people building their own kernels and don't run distro configs. And
> you need CPU_SUP_AMD because you're using their code.

That's good, will select CPU_SUP_AMD for CPU_SUP_HYGON to solve the
dependency issues in kernel.

--
Regards,
Pu Wen