From 02e57d5beb0c1ed7a6c21c0567b2a8417a1c53d2 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Fri, 10 Jan 2025 08:14:39 -0500 Subject: [PATCH 01/18] pinctrl: Add device HID for Hygon GPIO controller Add HID HYGO0030 to support Hygon GPIO controller. Signed-off-by: Liao Xuan --- 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 75bff325a4251..6833934a3b053 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -1207,6 +1207,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); From 8dc88019f7763b40179162157a6b8f59422e32a8 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 02:37:29 -0500 Subject: [PATCH 02/18] 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: Yanjing Zhou Signed-off-by: Liao Xuan --- arch/x86/kvm/svm/svm.c | 27 +++++++++++++++++++++++++++ arch/x86/kvm/svm/svm.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 45230e8b7a421..9fdf7edf9c64d 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -243,6 +243,17 @@ module_param(intercept_smi, bool, 0444); bool vnmi = true; module_param(vnmi, bool, 0444); +/* + * 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 = false; +module_param(set_guest_pat_wb, int, 0444); + static bool svm_gp_erratum_intercept = true; static u8 rsm_ins_bytes[] = "\x0f\xaa"; @@ -1256,6 +1267,16 @@ static inline void init_vmcb_after_set_cpuid(struct kvm_vcpu *vcpu) } } +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 kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); @@ -1357,6 +1378,8 @@ static void init_vmcb(struct kvm_vcpu *vcpu) svm_clr_intercept(svm, INTERCEPT_CR3_READ); svm_clr_intercept(svm, INTERCEPT_CR3_WRITE); save->g_pat = vcpu->arch.pat; + if (set_guest_pat_wb) + svm_set_guest_pat(svm, &save->g_pat); save->cr3 = 0; } svm->current_vmcb->asid_generation = 0; @@ -3068,6 +3091,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) svm->vmcb01.ptr->save.g_pat = data; if (is_guest_mode(vcpu)) nested_vmcb02_compute_g_pat(svm); + if (npt_enabled && set_guest_pat_wb) { + svm_set_guest_pat(svm, &svm->vmcb01.ptr->save.g_pat); + vcpu->arch.pat = svm->vmcb01.ptr->save.g_pat; + } vmcb_mark_dirty(svm->vmcb, VMCB_NPT); break; case MSR_IA32_SPEC_CTRL: diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index aaf945935ff7c..b87a74235b43e 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -30,6 +30,8 @@ #define IOPM_SIZE PAGE_SIZE * 3 #define MSRPM_SIZE PAGE_SIZE * 2 +#define GUEST_PAT_WB_ATTR 0x0606060606060606 + #define MAX_DIRECT_ACCESS_MSRS 48 #define MSRPM_OFFSETS 32 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; From 42b9ec6545add6630af1b4d3ba5e9355f4e182e0 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 03:01:46 -0500 Subject: [PATCH 03/18] 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. Fixes: dc29574a837c ("x86/amd_nb: Add northbridge support for Hygon family 18h model 4h") Signed-off-by: Liao Xuan --- 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 3d6d25b64bb39..5f1ea0e0e3a48 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -466,8 +466,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; } From 3e9c72d6dbde5293e50fa3dccc953f891a4532b3 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 04:34:16 -0500 Subject: [PATCH 04/18] 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. Fixes: f7aa40486ad9 ("EDAC/amd64: Adjust address translation for Hygon family 18h model 4h") Signed-off-by: Liao Xuan --- drivers/edac/amd64_edac.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index d0ab59e80fb09..243687a05e100 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1282,12 +1282,14 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr if (hygon_f18h_m4h()) { die_id_shift = (ctx.tmp >> 12) & 0xF; die_id_mask = ctx.tmp & 0x7FF; + cs_id |= (((cs_fabric_id & die_id_mask) >> die_id_shift) - 4) << + die_id_bit; } else { die_id_shift = (ctx.tmp >> 24) & 0xF; die_id_mask = (ctx.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. */ From 054d5a3fd9164a62fa55d82ed71c46a290f86d51 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 05:13:11 -0500 Subject: [PATCH 05/18] 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: Liao Xuan --- drivers/edac/amd64_edac.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 243687a05e100..0c2bc12ee3f67 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1130,7 +1130,12 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr { u64 dram_base_addr, dram_limit_addr, dram_hole_base; - 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; @@ -1245,7 +1250,12 @@ static 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]. From e7aa0495190322f5a4813e76fb29c554774cae51 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 05:39:48 -0500 Subject: [PATCH 06/18] 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. Fixes: 47ed942f1901 ("EDAC/amd64: Adjust UMC channel for Hygon family 18h model 6h") Signed-off-by: Liao Xuan --- 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 0c2bc12ee3f67..8ae47ed70da27 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -3160,8 +3160,8 @@ static void decode_umc_error(int node_id, struct mce *m) pvt->ops->get_err_info(m, &err); - 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; From 3290b2d979639a2b4365e57336001a62207945e8 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 07:20:18 -0500 Subject: [PATCH 07/18] 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. Fixes: a6712ab72cdf ("EDAC/amd64: Add support for Hygon family 18h model 6h") Signed-off-by: Liao Xuan --- drivers/edac/amd64_edac.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 8ae47ed70da27..5890c65659040 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1207,6 +1207,12 @@ static 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 (df_indirect_read_instance(nid, 0, 0x60, umc, &ctx.tmp)) + goto out_err; + intlv_num_dies = ctx.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; From 7ad8c8284625449afd47dda4d4a8cd2d6ac2f985 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 08:12:34 -0500 Subject: [PATCH 08/18] 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: Liao Xuan --- drivers/edac/mce_amd.c | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c index 06e29d2b51d1e..cf0298e448498 100644 --- a/drivers/edac/mce_amd.c +++ b/drivers/edac/mce_amd.c @@ -168,6 +168,33 @@ static const char * const smca_ls_mce_desc[] = { "L2 Fill Data error", }; +/* 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_ls2_mce_desc[] = { "An ECC error was detected on a data cache read by a probe or victimization", "An ECC error or L2 poison was detected on a data cache read by a load", @@ -217,6 +244,31 @@ static const char * const smca_if_mce_desc[] = { "CT MCE", }; +/* 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", + "Hardware Assertion Error", + "L1-TLB Multi-Hit", + "L2-TLB Multi-Hit", + "BSR Parity Error", + "CT MCE", +}; + static const char * const smca_l2_mce_desc[] = { "L2M Tag Multiple-Way-Hit error", "L2M Tag or State Array ECC Error", @@ -1433,6 +1485,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; From 6195d544f9bd927126b89676ba7678ebfd650bf2 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 08:28:58 -0500 Subject: [PATCH 09/18] 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: Liao Xuan --- 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 5f1ea0e0e3a48..cc5c9b0b72c38 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -328,7 +328,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; From ce140527b659d8bf744b55dd7a09d5d90a3268b3 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 08:43:54 -0500 Subject: [PATCH 10/18] 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: Liao Xuan --- drivers/iommu/amd/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index f6c1f7e04d471..4beddd8cc4201 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -3045,7 +3045,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; From a8f1ab78d467a1bdd889193406e56dacb257f000 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 08:58:07 -0500 Subject: [PATCH 11/18] 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: Liao Xuan --- 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 497ad86ef2256..a2948b68ba83b 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -83,6 +83,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); @@ -127,6 +128,7 @@ static inline struct amd_northbridge *node_to_amd_nb(int node) #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 cc5c9b0b72c38..f2830067e1741 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -262,6 +262,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; From 94e8c1ca5be83f5b558d62009279ef81e601c1c7 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 09:19:39 -0500 Subject: [PATCH 12/18] 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: Liao Xuan --- drivers/edac/amd64_edac.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 5890c65659040..0e739514437b9 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1154,7 +1154,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr ctx.inst_id = umc; /* Read DramOffset, check if base 1 is used. */ - if (hygon_f18h_m4h() && + if ((hygon_f18h_m4h() || hygon_f18h_m10h()) && df_indirect_read_instance(nid, 0, 0x214, umc, &ctx.tmp)) goto out_err; else if (df_indirect_read_instance(nid, 0, 0x1B4, umc, &ctx.tmp)) @@ -1182,7 +1182,7 @@ static 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 = (ctx.tmp >> 2) & 0x3; lgcy_mmio_hole_en = ctx.tmp & BIT(1); intlv_num_chan = (ctx.tmp >> 4) & 0xF; @@ -1200,14 +1200,15 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr if (df_indirect_read_instance(nid, 0, 0x114 + (8 * base), umc, &ctx.tmp)) goto out_err; - if (!hygon_f18h_m4h()) + if (!hygon_f18h_m4h() && !hygon_f18h_m10h()) intlv_num_sockets = (ctx.tmp >> 8) & 0x1; intlv_num_dies = (ctx.tmp >> 10) & 0x3; dram_limit_addr = ((ctx.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 (df_indirect_read_instance(nid, 0, 0x60, umc, &ctx.tmp)) goto out_err; intlv_num_dies = ctx.tmp & 0x3; @@ -1272,7 +1273,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr if (df_indirect_read_instance(nid, 0, 0x50, umc, &ctx.tmp)) goto out_err; - if (hygon_f18h_m4h()) + if (hygon_f18h_m4h() || hygon_f18h_m10h()) cs_fabric_id = (ctx.tmp >> 8) & 0x7FF; else cs_fabric_id = (ctx.tmp >> 8) & 0xFF; From c376a438c22828af87b03f4e35d2602bc184b409 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 09:08:27 -0500 Subject: [PATCH 13/18] 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: Liao Xuan --- drivers/edac/amd64_edac.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 0e739514437b9..42d7c1bc65824 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1656,12 +1656,29 @@ static void umc_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) } } +static bool hygon_umc_channel_enabled(struct amd64_pvt *pvt, int channel) +{ + u32 enable; + + if (hygon_f18h_m10h()) { + __df_indirect_read(pvt->mc_node_id, 1, 0x32c, 0xc, &enable); + if ((enable & BIT(channel))) + return true; + return false; + } + + return true; +} + static void umc_dump_misc_regs(struct amd64_pvt *pvt) { struct amd64_umc *umc; u32 i, tmp, umc_base; for_each_umc(i) { + if (!hygon_umc_channel_enabled(pvt, i)) + continue; + if (hygon_f18h_m4h()) umc_base = get_umc_base_f18h_m4h(pvt->mc_node_id, i); else @@ -1778,6 +1795,9 @@ static void umc_read_base_mask(struct amd64_pvt *pvt) int cs, umc; for_each_umc(umc) { + if (!hygon_umc_channel_enabled(pvt, umc)) + continue; + if (hygon_f18h_m4h()) umc_base = get_umc_base_f18h_m4h(pvt->mc_node_id, umc); else @@ -3246,6 +3266,9 @@ static void umc_read_mc_regs(struct amd64_pvt *pvt) /* Read registers from each UMC */ for_each_umc(i) { + if (!hygon_umc_channel_enabled(pvt, i)) + continue; + if (hygon_f18h_m4h()) umc_base = get_umc_base_f18h_m4h(pvt->mc_node_id, i); else From 6a39d22a81f80839a62f8e3c913f08f22075784b Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 09:27:51 -0500 Subject: [PATCH 14/18] 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: Liao Xuan --- 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 42d7c1bc65824..f5877cf961dec 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1906,7 +1906,9 @@ static void umc_determine_memory_type(struct amd64_pvt *pvt) * Check if the system supports the "DDR Type" field in UMC Config * and has DDR5 DIMMs in use. */ - if ((pvt->flags.zn_regs_v2 || hygon_f18h_m4h()) && + if ((pvt->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; From 8804da9e822ceafd9a7fe450d97b31bba632089c Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 09:37:33 -0500 Subject: [PATCH 15/18] 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: Liao Xuan --- 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 f5877cf961dec..2286146e0ac7e 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -3189,7 +3189,8 @@ static void decode_umc_error(int node_id, struct mce *m) pvt->ops->get_err_info(m, &err); - 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; From defd20ad78f5ab16ccc5f58505b634b2f31f4292 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 09:43:24 -0500 Subject: [PATCH 16/18] x86/amd_nb: Add support for Hygon family 18h model 8h Add Hygon family 18h model 8h processor support for amd_nb. Signed-off-by: Liao Xuan --- arch/x86/kernel/amd_nb.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index f2830067e1741..95fc11b374b7f 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -299,8 +299,7 @@ static int get_df_register(struct pci_dev *misc, u8 func, int offset, u32 *value else device = PCI_DEVICE_ID_HYGON_18H_M04H_DF_F1; break; - case 0x6: - case 0x7: + case 0x6 ... 0x8: device = PCI_DEVICE_ID_HYGON_18H_M05H_DF_F1; break; default: @@ -308,8 +307,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: + case 0x6 ... 0x8: device = PCI_DEVICE_ID_HYGON_18H_M06H_DF_F5; break; default: @@ -343,7 +341,7 @@ int get_df_id(struct pci_dev *misc, u8 *id) int ret; if (boot_cpu_data.x86_model >= 0x6 && - boot_cpu_data.x86_model <= 0x7) { + boot_cpu_data.x86_model <= 0xf) { /* F5x180[19:16]: DF ID */ ret = get_df_register(misc, 5, 0x180, &value); *id = (value >> 16) & 0xf; From e06110ebe202808af241dc0dc08d5d8f6e251e29 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Tue, 14 Jan 2025 09:47:28 -0500 Subject: [PATCH 17/18] EDAC/amd64: Add support for Hygon family 18h model 8h Add Hygon family 18h model 8h processor support for amd64_edac. Signed-off-by: Liao Xuan --- 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 2286146e0ac7e..d23488f258645 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -4209,6 +4209,9 @@ static int per_family_init(struct amd64_pvt *pvt) } else if (pvt->model == 0x7) { pvt->ctl_name = "F18h_M07h"; break; + } else if (pvt->model == 0x8) { + pvt->ctl_name = "F18h_M08h"; + break; } else if (pvt->model == 0x10) { pvt->ctl_name = "F18h_M10h"; break; From fc26d7179fb47ec5d2ef4cb3d503122ec24d36c0 Mon Sep 17 00:00:00 2001 From: Liao Xuan Date: Mon, 20 Jan 2025 23:10:52 -0500 Subject: [PATCH 18/18] perf/x86/amd/core: Fix performance monitor for Hygon family 18h processor The commit 69fe5f177ad3 ("perf/x86/amd/core: Update and fix stalled-cycles-* events for Zen 2 and later") changed amd_f17h_perfmon_event_map to amd_zen1_perfmon_event_map which is limited to processors only with X86_FEATURE_ZEN1. This makes some event counters such as cache-misses and cache-references can not be tracked on Hygon family 18h processors. When using perf tool to monitor performance, the result will be listed as follows: 0 cache-miesses # 0.000 % of all cache refs 0 cache-references So add perfmon_event_map support for Hygon family 18h processors to fix the incorrect display. Fixes: 69fe5f177ad3 ("perf/x86/amd/core: Update and fix stalled-cycles-* events for Zen 2 and later") Signed-off-by: Liao Xuan --- arch/x86/events/amd/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 6266921e23a00..cabd516eb081b 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -296,6 +296,9 @@ static u64 amd_pmu_event_map(int hw_event) if (cpu_feature_enabled(X86_FEATURE_ZEN1)) return amd_zen1_perfmon_event_map[hw_event]; + if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) + return amd_zen1_perfmon_event_map[hw_event]; + return amd_perfmon_event_map[hw_event]; }