From 674433ecc6d49845afb80428bda853f13905443c Mon Sep 17 00:00:00 2001 From: fuhao Date: Mon, 23 Sep 2024 14:27:06 +0800 Subject: [PATCH 01/23] x86/amd_nb: Add support for Hygon family 18h model 7h Add Hygon family 18h model 7h processor support for amd_nb. Signed-off-by: fuhao --- arch/x86/kernel/amd_nb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 4fe5d30397ec..de2beb71a098 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -279,6 +279,7 @@ static int get_df_register(struct pci_dev *misc, u8 func, int offset, u32 *value device = PCI_DEVICE_ID_HYGON_18H_M04H_DF_F1; break; case 0x6: + case 0x7: device = PCI_DEVICE_ID_HYGON_18H_M05H_DF_F1; break; default: @@ -287,6 +288,7 @@ static int get_df_register(struct pci_dev *misc, u8 func, int offset, u32 *value } else if (func == 5) { switch (boot_cpu_data.x86_model) { case 0x6: + case 0x7: device = PCI_DEVICE_ID_HYGON_18H_M06H_DF_F5; break; default: @@ -319,7 +321,8 @@ int get_df_id(struct pci_dev *misc, u8 *id) u32 value; int ret; - if (boot_cpu_data.x86_model == 0x6) { + if (boot_cpu_data.x86_model >= 0x6 && + boot_cpu_data.x86_model <= 0x7) { /* F5x180[19:16]: DF ID */ ret = get_df_register(misc, 5, 0x180, &value); *id = (value >> 16) & 0xf; -- Gitee From 404517ca000d53e874830869c9191bb010fb6e7d Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 17:03:55 +0800 Subject: [PATCH 02/23] EDAC/amd64: Add support for Hygon family 18h model 7h Add Hygon family 18h model 7h processor support for amd64_edac. Signed-off-by: fuhao --- drivers/edac/amd64_edac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 0b6b6625d306..3c73f5408ce0 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -3584,6 +3584,9 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt) pvt->ops = &family_types[F19_M10H_CPUS].ops; fam_type->ctl_name = "F19h_MA0h"; break; + } else if (pvt->model == 0x7) { + pvt->ctl_name = "F18h_M07h"; + break; } fam_type = &family_types[F19_CPUS]; pvt->ops = &family_types[F19_CPUS].ops; -- Gitee From 2d32e431cdbe6834413c0148684d125863909a2e Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 17:11:52 +0800 Subject: [PATCH 03/23] perf/x86/uncore: Add L3 PMU support for Hygon family 18h model 7h From model 6h, Hygon processors can use the same L3 PMU slicemask and threadmask. Signed-off-by: fuhao --- arch/x86/events/amd/uncore.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c index 0db618ccf9a4..fda81a66ab2c 100644 --- a/arch/x86/events/amd/uncore.c +++ b/arch/x86/events/amd/uncore.c @@ -193,7 +193,7 @@ static u64 l3_thread_slice_mask(u64 config) if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON && boot_cpu_data.x86 == 0x18) { - if (boot_cpu_data.x86_model == 0x6) + if (boot_cpu_data.x86_model >= 0x6 && boot_cpu_data.x86_model <= 0xf) return ((config & HYGON_L3_SLICE_MASK) ? : HYGON_L3_SLICE_MASK) | ((config & HYGON_L3_THREAD_MASK) ? : HYGON_L3_THREAD_MASK); else @@ -274,8 +274,9 @@ static int amd_uncore_event_init(struct perf_event *event) static umode_t hygon_f18h_m6h_uncore_is_visible(struct kobject *kobj, struct attribute *attr, int i) { - return boot_cpu_data.x86 == 0x18 && boot_cpu_data.x86_model == 0x6 ? - attr->mode : 0; + return boot_cpu_data.x86 == 0x18 && + boot_cpu_data.x86_model >= 0x6 && boot_cpu_data.x86_model <= 0xf ? + attr->mode : 0; } static ssize_t amd_uncore_attr_show_cpumask(struct device *dev, @@ -686,7 +687,7 @@ static int __init amd_uncore_init(void) *l3_attr++ = &format_attr_event8.attr; *l3_attr++ = &format_attr_umask.attr; *l3_attr++ = &format_attr_slicemask.attr; - if (boot_cpu_data.x86_model == 0x6) { + if (boot_cpu_data.x86_model >= 0x6 && boot_cpu_data.x86_model <= 0xf) { *l3_attr++ = &format_attr_threadmask32.attr; amd_llc_pmu.attr_update = hygon_uncore_l3_attr_update; } else { -- Gitee From 20092e164865298b5a0ca12b210cfb6307f77c18 Mon Sep 17 00:00:00 2001 From: fuhao Date: Mon, 23 Sep 2024 14:46:52 +0800 Subject: [PATCH 04/23] x86/cpu: Get LLC ID for Hygon family 18h model 10h Get LLC ID from ApicId[3]. Signed-off-by: fuhao --- arch/x86/kernel/cpu/cacheinfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c index f467b9d18c52..c2d9f007fd37 100644 --- a/arch/x86/kernel/cpu/cacheinfo.c +++ b/arch/x86/kernel/cpu/cacheinfo.c @@ -693,7 +693,8 @@ void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu) if (!cpuid_edx(0x80000006)) return; - if (c->x86_model < 0x5) { + if (c->x86_model < 0x5 || + (c->x86_model >= 0x10 && c->x86_model <= 0x1f)) { /* * LLC is at the core complex level. * Core complex ID is ApicId[3] for these processors. -- Gitee From 5e2fd5194b3b715e66475bfd826d088898a0e491 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 17:17:43 +0800 Subject: [PATCH 05/23] x86/amd_nb: Add support for Hygon family 18h model 10h Add root and DF F1/F3/F4 device IDs for Hygon family 18h model 10h processors. Signed-off-by: fuhao --- arch/x86/kernel/amd_nb.c | 5 +++++ include/linux/pci_ids.h | 1 + 2 files changed, 6 insertions(+) diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index de2beb71a098..b873c81266e5 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -29,9 +29,11 @@ #define PCI_DEVICE_ID_AMD_19H_M10H_DF_F4 0x14b1 #define PCI_DEVICE_ID_HYGON_18H_M05H_ROOT 0x14a0 +#define PCI_DEVICE_ID_HYGON_18H_M10H_ROOT 0x14c0 #define PCI_DEVICE_ID_HYGON_18H_M04H_DF_F1 0x1491 #define PCI_DEVICE_ID_HYGON_18H_M05H_DF_F1 0x14b1 #define PCI_DEVICE_ID_HYGON_18H_M05H_DF_F4 0x14b4 +#define PCI_DEVICE_ID_HYGON_18H_M10H_DF_F4 0x14d4 #define PCI_DEVICE_ID_HYGON_18H_M06H_DF_F5 0x14b5 /* Protect the PCI config register pairs used for SMN and DF indirect access. */ @@ -93,6 +95,7 @@ static const struct pci_device_id hygon_root_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_M30H_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_M05H_ROOT) }, + { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_M10H_ROOT) }, {} }; @@ -100,6 +103,7 @@ static const struct pci_device_id hygon_nb_misc_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_M05H_DF_F3) }, + { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_M10H_DF_F3) }, {} }; @@ -107,6 +111,7 @@ static const struct pci_device_id hygon_nb_link_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_M30H_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_M05H_DF_F4) }, + { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_HYGON_18H_M10H_DF_F4) }, {} }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b3dce4e63208..8b8b65e4034e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2601,6 +2601,7 @@ #define PCI_VENDOR_ID_HYGON 0x1d94 #define PCI_DEVICE_ID_HYGON_18H_M05H_HDA 0x14a9 #define PCI_DEVICE_ID_HYGON_18H_M05H_DF_F3 0x14b3 +#define PCI_DEVICE_ID_HYGON_18H_M10H_DF_F3 0x14d3 #define PCI_VENDOR_ID_HXT 0x1dbf -- Gitee From d8065fe638b95b15ed21f35a1e797b4c358f101f Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 17:21:28 +0800 Subject: [PATCH 06/23] EDAC/amd64: Add support for Hygon family 18h model 10h Add Hygon family 18h model 10h processor support for amd64_edac. Signed-off-by: fuhao --- drivers/edac/amd64_edac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 3c73f5408ce0..6aa5aba7b82a 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -3587,6 +3587,9 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt) } else if (pvt->model == 0x7) { pvt->ctl_name = "F18h_M07h"; break; + } else if (pvt->model == 0x10) { + pvt->ctl_name = "F18h_M10h"; + break; } fam_type = &family_types[F19_CPUS]; pvt->ops = &family_types[F19_CPUS].ops; -- Gitee From 50bebd7e6e6151e0c3585381eea03350a42b2314 Mon Sep 17 00:00:00 2001 From: fuhao Date: Mon, 23 Sep 2024 15:03:21 +0800 Subject: [PATCH 07/23] hwmon/k10temp: Add support for Hygon family 18h model 10h Add 18H_M10H DF F3 device ID to get the temperature for Hygon family 18h model 10h processor. Signed-off-by: fuhao --- drivers/hwmon/k10temp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 7121f44ae1fb..e08bb92d3451 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -555,6 +555,7 @@ static const struct pci_device_id k10temp_id_table[] = { { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) }, { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) }, { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_HYGON_18H_M05H_DF_F3) }, + { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_HYGON_18H_M10H_DF_F3) }, {} }; MODULE_DEVICE_TABLE(pci, k10temp_id_table); -- Gitee From 6d26ec036a468e629e0f2718dd1e3ec81dfe1fe1 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 17:35:27 +0800 Subject: [PATCH 08/23] ALSA: hda: Add support for Hygon family 18h model 10h HD-Audio Add the new PCI ID 0x1d94 0x14c9 for Hygon family 18h model 10h HDA controller. Signed-off-by: fuhao --- include/linux/pci_ids.h | 1 + sound/pci/hda/hda_intel.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 8b8b65e4034e..2a87de3c0b3e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2600,6 +2600,7 @@ #define PCI_VENDOR_ID_HYGON 0x1d94 #define PCI_DEVICE_ID_HYGON_18H_M05H_HDA 0x14a9 +#define PCI_DEVICE_ID_HYGON_18H_M10H_HDA 0x14c9 #define PCI_DEVICE_ID_HYGON_18H_M05H_DF_F3 0x14b3 #define PCI_DEVICE_ID_HYGON_18H_M10H_DF_F3 0x14d3 diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 620ce3e2f442..d45269905045 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2821,10 +2821,10 @@ static const struct pci_device_id azx_ids[] = { .driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_NO_64BIT }, /* Hygon HDAudio */ - { PCI_DEVICE(0x1d94, 0x14a9), - .driver_data = AZX_DRIVER_HYGON | AZX_DCAPS_POSFIX_LPIB | - AZX_DCAPS_NO_MSI }, - + { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_HYGON_18H_M05H_HDA), + .driver_data = AZX_DRIVER_HYGON | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI }, + { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_HYGON_18H_M10H_HDA), + .driver_data = AZX_DRIVER_HYGON }, { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); -- Gitee From 67b405d843251335c5b9b73abca116f87d9e63e2 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:24:06 +0800 Subject: [PATCH 09/23] pinctrl: Add device HID for Hygon GPIO controller Add HID HYGO0030 to support Hygon GPIO controller. Signed-off-by: fuhao --- drivers/pinctrl/pinctrl-amd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 887dc5770440..3e1bfe460ea1 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -996,6 +996,7 @@ static const struct acpi_device_id amd_gpio_acpi_match[] = { { "AMD0030", 0 }, { "AMDI0030", 0}, { "AMDI0031", 0}, + { "HYGO0030", 0}, { }, }; MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match); -- Gitee From 46f8e9776125b2fb4f784f4821338dc2e26fe179 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:27:24 +0800 Subject: [PATCH 10/23] KVM: x86/svm: Add set_guest_pat_wb parameter for non-passthrough application scenarios Add kernel parameter set_guest_pat_wb to set guest PAT to WB in some non-passthrough application scenarios to enhance performance. Signed-off-by: fuhao --- arch/x86/kvm/svm.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c479ea21a5b4..4e2502855b26 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -89,6 +89,8 @@ MODULE_DEVICE_TABLE(x86cpu, svm_cpu_id); #define TSC_RATIO_MIN 0x0000000000000001ULL #define TSC_RATIO_MAX 0x000000ffffffffffULL +#define GUEST_PAT_WB_ATTR 0x0606060606060606 + #define AVIC_HPA_MASK ~((0xFFFULL << 52) | 0xFFF) /* @@ -382,6 +384,17 @@ module_param(sev, int, 0444); static bool __read_mostly dump_invalid_vmcb = 0; module_param(dump_invalid_vmcb, bool, 0644); +/* + * Allow set guest PAT to WB in some non-passthrough + * application scenarios to enhance performance. + * + * Add kernel parameter set_guest_pat_wb(default 0): + * 1 - set guest PAT to WB + * 0 - keep guest PAT to the kernel default value + */ +static int set_guest_pat_wb; +module_param(set_guest_pat_wb, int, 0444); + static u8 rsm_ins_bytes[] = "\x0f\xaa"; static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); @@ -1536,6 +1549,16 @@ static void avic_init_vmcb(struct vcpu_svm *svm) vmcb->control.int_ctl |= AVIC_ENABLE_MASK; } +static void svm_set_guest_pat(struct vcpu_svm *svm, u64 *g_pat) +{ + struct kvm_vcpu *vcpu = &svm->vcpu; + + if (!kvm_arch_has_assigned_device(vcpu->kvm)) + *g_pat = GUEST_PAT_WB_ATTR; + else + *g_pat = vcpu->arch.pat; +} + static void init_vmcb(struct vcpu_svm *svm) { struct vmcb_control_area *control = &svm->vmcb->control; @@ -1648,6 +1671,8 @@ static void init_vmcb(struct vcpu_svm *svm) clr_cr_intercept(svm, INTERCEPT_CR3_READ); clr_cr_intercept(svm, INTERCEPT_CR3_WRITE); save->g_pat = svm->vcpu.arch.pat; + if (set_guest_pat_wb) + svm_set_guest_pat(svm, &save->g_pat); save->cr3 = 0; save->cr4 = 0; } @@ -4335,6 +4360,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) return 1; vcpu->arch.pat = data; svm->vmcb->save.g_pat = data; + if (npt_enabled && set_guest_pat_wb) { + svm_set_guest_pat(svm, &svm->vmcb->save.g_pat); + vcpu->arch.pat = svm->vmcb->save.g_pat; + } mark_dirty(svm->vmcb, VMCB_NPT); break; case MSR_IA32_SPEC_CTRL: -- Gitee From 9167737021ac9d029c78944206904af663f6c275 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:28:52 +0800 Subject: [PATCH 11/23] x86/amd_nb: Fix northbridge init warning in guest for Hygon family 18h model 4h When booting in guest on Hygon family 18h model 4h platform, there is warning as follows: "Hygon Fam18h Model4h northbridge init failed(-19)!" Avoid the northbridge init failure warning in guest since there is no northbridge. Signed-off-by: fuhao --- arch/x86/kernel/amd_nb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index b873c81266e5..deae0e11dae7 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -465,8 +465,9 @@ static int northbridge_init_f18h_m4h(const struct pci_device_id *root_ids, amd_northbridges.nb = NULL; ret: - pr_err("Hygon Fam%xh Model%xh northbridge init failed(%d)!\n", - boot_cpu_data.x86, boot_cpu_data.x86_model, err); + if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) + pr_err("Hygon Fam%xh Model%xh northbridge init failed(%d)!\n", + boot_cpu_data.x86, boot_cpu_data.x86_model, err); return err; } -- Gitee From 91a75d4d91d93f0218009f949a22b768cfeb179f Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:30:42 +0800 Subject: [PATCH 12/23] EDAC/amd64: Fix the calculation of cs_id for Hygon family 18h model 4h Get the correct cs_id in die interleave scenario for Hygon family 18h model 4h. Signed-off-by: fuhao --- arch/x86/kernel/cpu/mce/amd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c index 63cc38577508..7e270c730f9d 100644 --- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -848,12 +848,14 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) if (hygon_f18h_m4h()) { die_id_shift = (tmp >> 12) & 0xF; die_id_mask = tmp & 0x7FF; + cs_id |= (((cs_fabric_id & die_id_mask) >> die_id_shift) - 4) << + die_id_bit; } else { die_id_shift = (tmp >> 24) & 0xF; die_id_mask = (tmp >> 8) & 0xFF; + cs_id |= ((cs_fabric_id & die_id_mask) >> die_id_shift) << + die_id_bit; } - - cs_id |= ((cs_fabric_id & die_id_mask) >> die_id_shift) << die_id_bit; } /* If interleaved over more than 1 socket. */ -- Gitee From 2250d2239c03ccf3d79812dee3717b27fe8876ca Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:31:43 +0800 Subject: [PATCH 13/23] EDAC/amd64: Use u16 for some umc variables for Hygon family 18h model 4h The width of die/socket id mask and cs fabric id is extended to 11 bits since Hygon family 18h model 4h, so use u16 for those variables which are also suitable for all other older generation Hygon processors. Signed-off-by: fuhao --- arch/x86/kernel/cpu/mce/amd.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c index 7e270c730f9d..5d5494c03946 100644 --- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -705,7 +705,12 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) u32 tmp; - u8 die_id_shift, die_id_mask, socket_id_shift, socket_id_mask; + u8 die_id_shift, socket_id_shift; +#ifdef CONFIG_CPU_SUP_HYGON + u16 die_id_mask, socket_id_mask; +#else + u8 die_id_mask, socket_id_mask; +#endif u8 intlv_num_dies, intlv_num_chan, intlv_num_sockets; u8 intlv_addr_sel, intlv_addr_bit; u8 num_intlv_bits, hashed_bit; @@ -811,7 +816,12 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) if (num_intlv_bits > 0) { u64 temp_addr_x, temp_addr_i, temp_addr_y; - u8 die_id_bit, sock_id_bit, cs_fabric_id; + u8 die_id_bit, sock_id_bit; +#ifdef CONFIG_CPU_SUP_HYGON + u16 cs_fabric_id; +#else + u8 cs_fabric_id; +#endif /* * Read FabricBlockInstanceInformation3_CS[BlockFabricID]. -- Gitee From ab752debdbc9c9e66964567535e473ace59ac099 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:36:41 +0800 Subject: [PATCH 14/23] EDAC/amd64: Fix the calculation of instance_id for Hygon family 18h model 6h On Hygon family 18h model 6h platform, each DDR has two subchannels, and each subchannel has a mca bank with a cs corresponded. In the process of address translation, it needs to know the instance id of cs to access df register correctly. The instance id of cs can be calculated from IPID[23:20] and IPID[13]: IPID[23:20] represents which umc controller it belongs to, and IPID[13] represents which subchannel it is. Signed-off-by: fuhao --- drivers/edac/amd64_edac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 6aa5aba7b82a..13290699eecd 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2782,8 +2782,8 @@ static void decode_umc_error(int node_id, struct mce *m) err.csrow = m->synd & 0x7; - if (hygon_f18h_m4h() && boot_cpu_data.x86_model == 0x6) - umc = err.channel << 1; + if (hygon_f18h_m4h() && boot_cpu_data.x86_model >= 0x6) + umc = (err.channel << 1) + ((m->ipid & BIT(13)) >> 13); else umc = err.channel; -- Gitee From 921b3f344079efba92ee28016785b81b59d6aa01 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:38:45 +0800 Subject: [PATCH 15/23] EDAC/amd64: Get intlv_num_dies from F0x60 for Hygon family 18h model 6h The intlv_num_dies should be get from F0x60[1:0] for Hygon family 18h model 6h. Signed-off-by: fuhao --- arch/x86/kernel/cpu/mce/amd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c index 5d5494c03946..032306ca39cd 100644 --- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -772,6 +772,12 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) intlv_addr_bit = intlv_addr_sel + 8; + if (hygon_f18h_m4h() && boot_cpu_data.x86_model >= 0x6) { + if (amd_df_indirect_read(nid, 0, 0x60, umc, &tmp)) + goto out_err; + intlv_num_dies = tmp & 0x3; + } + /* Re-use intlv_num_chan by setting it equal to log2(#channels) */ switch (intlv_num_chan) { case 0: intlv_num_chan = 0; break; -- Gitee From 85a68d9c69e3d068ce8d61f480655cd478851223 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:39:40 +0800 Subject: [PATCH 16/23] EDAC/mce_amd: Add LS and IF mce types for Hygon family 18h model 7h The error types are changed in LS and IF machine check control registers of Hygon family 18h model 7h processors, so add support to get the correct error types in smca error decoding process. Signed-off-by: fuhao --- drivers/edac/mce_amd.c | 57 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c index 298e2a7dd3d1..ac401b1dfacd 100644 --- a/drivers/edac/mce_amd.c +++ b/drivers/edac/mce_amd.c @@ -202,6 +202,33 @@ static const char * const smca_ls2_mce_desc[] = { "A parity error was detected in an STLF, SCB EMEM entry or SRB store data by any access", }; +/* Hygon Model7h Scalable MCA LS error strings */ +static const char * const smca_ls_mce_hygon_desc[] = { + "Load queue parity error", + "Store queue parity error", + "Miss address buffer payload parity error", + "Level 1 TLB parity error", + "DC Tag error type 5", + "DC Tag error type 6", + "DC Tag error type 1", + "Internal error type 1", + "Internal error type 2", + "System Read Data Error 0", + "System Read Data Error 1", + "System Read Data Error 2", + "System Read Data Error 3", + "DC Tag error type 2", + "DC Data error type 1 and poison consumption", + "DC Data error type 2", + "DC Data error type 3", + "DC Tag error type 4", + "Level 2 TLB parity error", + "PDC parity error", + "DC Tag error type 3", + "DC Tag error type 5", + "L2 Fill Data error", +}; + static const char * const smca_if_mce_desc[] = { "Op Cache Microtag Probe Port Parity Error", "IC Microtag or Full Tag Multi-hit Error", @@ -219,6 +246,26 @@ static const char * const smca_if_mce_desc[] = { "System Read Data Error", }; +/* Hygon Model7h Scalable MCA IF error strings */ +static const char * const smca_if_mce_hygon_desc[] = { + "Op Cache Microtag Probe Port Parity Error", + "IC Microtag or Full Tag Multi-hit Error", + "IC Full Tag Parity Error", + "IC Data Array Parity Error", + "Decoupling Queue PhysAddr Parity Error", + "L0 ITLB Parity Error", + "L1 ITLB Parity Error", + "L2 ITLB Parity Error", + "BPQ 0 Snoop Parity Error", + "BPQ 1 Snoop Parity Error", + "BPQ 2 Snoop Parity Error", + "BPQ 3 Snoop Parity Error", + "L1 BTB Multi-Match Error", + "L2 BTB Multi-Match Error", + "L2 Cache Response Poison Error", + "System Read Data Error", +}; + static const char * const smca_l2_mce_desc[] = { "L2M Tag Multiple-Way-Hit error", "L2M Tag or State Array ECC Error", @@ -1445,6 +1492,16 @@ static int __init mce_amd_init(void) out: pr_info("MCE: In-kernel MCE decoding enabled.\n"); + if (c->x86_vendor == X86_VENDOR_HYGON && + c->x86_model >= 0x7 && c->x86_model <= 0xf) { + smca_mce_descs[SMCA_LS].descs = smca_ls_mce_hygon_desc; + smca_mce_descs[SMCA_LS].num_descs = ARRAY_SIZE(smca_ls_mce_hygon_desc); + smca_mce_descs[SMCA_IF].descs = smca_if_mce_hygon_desc; + smca_mce_descs[SMCA_IF].num_descs = ARRAY_SIZE(smca_if_mce_hygon_desc); + pr_info("MCE: Hygon Fam%xh Model%xh smca mce descs setup.\n", + c->x86, c->x86_model); + } + mce_register_decode_chain(&amd_mce_dec_nb); return 0; -- Gitee From 7bc81ed516441aef92e274f3bf565aa3df9a58fe Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:42:10 +0800 Subject: [PATCH 17/23] iommu/hygon: Add support for Hygon family 18h model 10h IOAPIC The SB IOAPIC for Hygon family 18h model 10h processors is also on the device 0xb. Signed-off-by: fuhao --- drivers/iommu/amd_iommu_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 77835053015b..7092df1002d8 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -2477,7 +2477,7 @@ static bool __init check_ioapic_information(void) (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON && boot_cpu_data.x86 == 0x18 && boot_cpu_data.x86_model >= 0x4 && - boot_cpu_data.x86_model <= 0xf && + boot_cpu_data.x86_model <= 0x10 && devid == IOAPIC_SB_DEVID_FAM18H_M4H)) { has_sb_ioapic = true; ret = true; -- Gitee From 1a01732f427ff53ea19382733ece06021edfec17 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:43:13 +0800 Subject: [PATCH 18/23] x86/amd_nb: Add helper function to identify Hygon family 18h model 10h Add hygon_f18h_m10h() to identify Hygon family 18h model 10h processors. Signed-off-by: fuhao --- arch/x86/include/asm/amd_nb.h | 2 ++ arch/x86/kernel/amd_nb.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index b6e5db1069e9..e48a7e2ba40c 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -85,6 +85,7 @@ bool amd_nb_has_feature(unsigned int feature); struct amd_northbridge *node_to_amd_nb(int node); bool hygon_f18h_m4h(void); +bool hygon_f18h_m10h(void); u16 hygon_nb_num(void); int get_df_id(struct pci_dev *misc, u8 *id); @@ -126,6 +127,7 @@ static inline bool amd_gart_present(void) #define amd_gart_present(x) false #define hygon_f18h_m4h false +#define hygon_f18h_m10h false #define hygon_nb_num(x) 0 #define get_df_id(x, y) NULL diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index deae0e11dae7..93864362937f 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -260,6 +260,20 @@ bool hygon_f18h_m4h(void) } EXPORT_SYMBOL_GPL(hygon_f18h_m4h); +bool hygon_f18h_m10h(void) +{ + if (boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) + return false; + + if (boot_cpu_data.x86 == 0x18 && + boot_cpu_data.x86_model >= 0x10 && + boot_cpu_data.x86_model <= 0x1f) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(hygon_f18h_m10h); + u16 hygon_nb_num(void) { return nb_num; -- Gitee From fbb6efc5c70bc2df282529568299da131396e9e7 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:44:48 +0800 Subject: [PATCH 19/23] EDAC/amd64: Adjust address translation for Hygon family 18h model 10h Add umc address translation support for Hygon family 18h model 10h. Signed-off-by: fuhao --- arch/x86/kernel/cpu/mce/amd.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c index 032306ca39cd..c681f9266777 100644 --- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -719,7 +719,7 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) bool hash_enabled = false; /* Read DramOffset, check if base 1 is used. */ - if (hygon_f18h_m4h() && + if ((hygon_f18h_m4h() || hygon_f18h_m10h()) && amd_df_indirect_read(nid, 0, 0x214, umc, &tmp)) goto out_err; else if (amd_df_indirect_read(nid, 0, 0x1B4, umc, &tmp)) @@ -747,7 +747,7 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) } intlv_num_sockets = 0; - if (hygon_f18h_m4h()) + if (hygon_f18h_m4h() || hygon_f18h_m10h()) intlv_num_sockets = (tmp >> 2) & 0x3; lgcy_mmio_hole_en = tmp & BIT(1); intlv_num_chan = (tmp >> 4) & 0xF; @@ -765,14 +765,15 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) if (amd_df_indirect_read(nid, 0, 0x114 + (8 * base), umc, &tmp)) goto out_err; - if (!hygon_f18h_m4h()) + if (!hygon_f18h_m4h() && !hygon_f18h_m10h()) intlv_num_sockets = (tmp >> 8) & 0x1; intlv_num_dies = (tmp >> 10) & 0x3; dram_limit_addr = ((tmp & GENMASK_ULL(31, 12)) << 16) | GENMASK_ULL(27, 0); intlv_addr_bit = intlv_addr_sel + 8; - if (hygon_f18h_m4h() && boot_cpu_data.x86_model >= 0x6) { + if ((hygon_f18h_m4h() && boot_cpu_data.x86_model >= 0x6) || + hygon_f18h_m10h()) { if (amd_df_indirect_read(nid, 0, 0x60, umc, &tmp)) goto out_err; intlv_num_dies = tmp & 0x3; @@ -838,7 +839,7 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) if (amd_df_indirect_read(nid, 0, 0x50, umc, &tmp)) goto out_err; - if (hygon_f18h_m4h()) + if (hygon_f18h_m4h() || hygon_f18h_m10h()) cs_fabric_id = (tmp >> 8) & 0x7FF; else cs_fabric_id = (tmp >> 8) & 0xFF; -- Gitee From ecb93bd383db5fa1c088fd975a6230612fd2b040 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:45:53 +0800 Subject: [PATCH 20/23] EDAC/amd64: Check if umc channel is enabled for Hygon family 18h model 10h For Hygon family 18h model 10h processor, channels without memory are gated. As a result, all bits in relevant registers are set to 1, which cause the edac driver initializing incorrectly. So add support to check if the umc channel is effectively enabled. Signed-off-by: fuhao --- drivers/edac/amd64_edac.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 13290699eecd..bcb8a325d358 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -871,12 +871,29 @@ static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl) } } +static bool hygon_umc_channel_enabled(u16 nid, int channel) +{ + u32 enable; + + if (hygon_f18h_m10h()) { + amd_df_indirect_read(nid, 1, 0x32c, 0xc, &enable); + if ((enable & BIT(channel))) + return true; + return false; + } + + return true; +} + static void __dump_misc_regs_df(struct amd64_pvt *pvt) { struct amd64_umc *umc; u32 i, tmp, umc_base; for_each_umc(i) { + if (!hygon_umc_channel_enabled(pvt->mc_node_id, i)) + continue; + if (hygon_f18h_m4h()) umc_base = get_umc_base_f18h_m4h(pvt->mc_node_id, i); else @@ -1004,6 +1021,9 @@ static void read_umc_base_mask(struct amd64_pvt *pvt) int cs, umc; for_each_umc(umc) { + if (!hygon_umc_channel_enabled(pvt->mc_node_id, umc)) + continue; + if (hygon_f18h_m4h()) umc_base = get_umc_base_f18h_m4h(pvt->mc_node_id, umc); else @@ -2931,6 +2951,9 @@ static void __read_mc_regs_df(struct amd64_pvt *pvt) /* Read registers from each UMC */ for_each_umc(i) { + if (!hygon_umc_channel_enabled(pvt->mc_node_id, i)) + continue; + if (hygon_f18h_m4h()) umc_base = get_umc_base_f18h_m4h(pvt->mc_node_id, i); else @@ -3381,6 +3404,9 @@ static bool ecc_enabled(struct amd64_pvt *pvt) for_each_umc(i) { umc = &pvt->umc[i]; + if (!hygon_umc_channel_enabled(nid, i)) + continue; + /* Only check enabled UMCs. */ if (!(umc->sdp_ctrl & UMC_SDP_INIT)) continue; -- Gitee From 89c3fd73e28a289af550e9b2eec63f6aa24ea65d Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:47:23 +0800 Subject: [PATCH 21/23] EDAC/amd64: Get correct memory type for Hygon family 18h model 10h Get the correct DDR memory types for Hygon family 18h model 10h. Signed-off-by: fuhao --- drivers/edac/amd64_edac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index bcb8a325d358..16b64bed9ee1 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1137,7 +1137,9 @@ static void determine_memory_type_df(struct amd64_pvt *pvt) * Check if the system supports the "DDR Type" field in UMC Config * and has DDR5 DIMMs in use. */ - if ((fam_type->flags.zn_regs_v2 || hygon_f18h_m4h()) && + if ((fam_type->flags.zn_regs_v2 || + hygon_f18h_m4h() || + hygon_f18h_m10h()) && ((umc->umc_cfg & GENMASK(2, 0)) == 0x1)) { if (umc->dimm_cfg & BIT(5)) umc->dram_type = MEM_LRDDR5; -- Gitee From 90b046e608a1b1c2e98a893412e0cdb012f2b1b2 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:48:36 +0800 Subject: [PATCH 22/23] EDAC/amd64: Get instance_id for Hygon family 18h model 10h The instance_id for Hygon family 18h model 10h is also get from IPID[23:20] and IPID[13]. Signed-off-by: fuhao --- drivers/edac/amd64_edac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 16b64bed9ee1..2d05c668ee6f 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2804,7 +2804,8 @@ static void decode_umc_error(int node_id, struct mce *m) err.csrow = m->synd & 0x7; - if (hygon_f18h_m4h() && boot_cpu_data.x86_model >= 0x6) + if ((hygon_f18h_m4h() && boot_cpu_data.x86_model >= 0x6) || + hygon_f18h_m10h()) umc = (err.channel << 1) + ((m->ipid & BIT(13)) >> 13); else umc = err.channel; -- Gitee From 77db5dd11e4a6ca5e7d2a0449812eb5b0144a04c Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:55:22 +0800 Subject: [PATCH 23/23] x86/cpu/hygon: Refactor the CPU topology deriving method for Hygon Refactor the CPU topology deriving method to be compatible for all the processors since Hygon family 18h model 4h. Signed-off-by: fuhao --- arch/x86/kernel/cpu/hygon.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c index 9f914bf80180..3da9c951ac31 100644 --- a/arch/x86/kernel/cpu/hygon.c +++ b/arch/x86/kernel/cpu/hygon.c @@ -84,16 +84,11 @@ static void hygon_get_topology(struct cpuinfo_x86 *c) if (smp_num_siblings > 1) c->x86_max_cores /= smp_num_siblings; - switch (c->x86_model) { - case 0x0 ... 0x3: - if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) - break; + if (c->x86 == 0x18 && c->x86_model < 0x4 && + !boot_cpu_has(X86_FEATURE_HYPERVISOR)) { /* Socket ID is ApicId[6] for these processors. */ c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT; - break; - case 0x4: - case 0x5: - case 0x6: + } else { /* * In case leaf 0xB is available, use it to derive * topology information. @@ -103,9 +98,6 @@ static void hygon_get_topology(struct cpuinfo_x86 *c) c->x86_coreid_bits = get_count_order(c->x86_max_cores); __max_die_per_package = nodes_per_socket; - break; - default: - break; } cacheinfo_hygon_init_llc_id(c, cpu); -- Gitee