From 6c62b4bf5fdb536a3763d01547d4db1793cb9ea7 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:24:06 +0800 Subject: [PATCH 01/16] 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 32ed302d9f540ddd6fd4ddeb453831075206eb46 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:27:24 +0800 Subject: [PATCH 02/16] 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 f67f9c19f98a78ce98e64ed01635980307dae928 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:28:52 +0800 Subject: [PATCH 03/16] 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 a459ae8b9f7c..c7932a328a53 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -464,8 +464,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 2f1bb181cad69d52091e175b2c065212b3949e47 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:30:42 +0800 Subject: [PATCH 04/16] 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 12aaa4b19175c8be4db83a7c411973cca3834c41 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:31:43 +0800 Subject: [PATCH 05/16] 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 415a03a8943457c056571e177181811332f978c9 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:36:41 +0800 Subject: [PATCH 06/16] 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 552962971712..474c2a74dc45 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2792,8 +2792,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 da443fa704cee28a789e5de47b14369caafdf39c Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:38:45 +0800 Subject: [PATCH 07/16] 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 9e3ddc6fb4922414985340c8d6f6bfda1858e65e Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:39:40 +0800 Subject: [PATCH 08/16] 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 1cb870bd6f96e5f21dd8a932b20582e3f031b430 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:41:10 +0800 Subject: [PATCH 09/16] x86/amd_nb: Get DF_ID from F5 device for Hygon family 18h model 7h The DF_ID is get from DF F5 device for Hygon family 18h model 7h processors. Signed-off-by: fuhao --- arch/x86/kernel/amd_nb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index c7932a328a53..deae0e11dae7 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -326,7 +326,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 dd9a59ca1d8a1ced6a0d703e5fea09bc1274f8e7 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:42:10 +0800 Subject: [PATCH 10/16] 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 9bbb301609a4b55d62fbc22fe63a9d91d61bf0c4 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:43:13 +0800 Subject: [PATCH 11/16] 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 92e5fb03d7f2a4bf7be79560b5e64281d9c68e61 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:44:48 +0800 Subject: [PATCH 12/16] 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 b9fe3842b6945b3e73426e177edfd9369a3c22a9 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:45:53 +0800 Subject: [PATCH 13/16] 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 474c2a74dc45..e9598d2bf2b6 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 @@ -2941,6 +2961,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 @@ -3391,6 +3414,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 e058e5f3430e2362e62c1b63df8dae0cf9103f8d Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:47:23 +0800 Subject: [PATCH 14/16] 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 e9598d2bf2b6..f4a3d2690a01 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 ab2387570cc13c79159cfc0cc40458f322e845d3 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:48:36 +0800 Subject: [PATCH 15/16] 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 f4a3d2690a01..94e5e5384a04 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2814,7 +2814,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 ab799310c85881537fc363c641bd8140ef547c42 Mon Sep 17 00:00:00 2001 From: fuhao Date: Fri, 28 Feb 2025 14:55:22 +0800 Subject: [PATCH 16/16] 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