From 42d32eea259738c83ecf20e605f76afb1a041732 Mon Sep 17 00:00:00 2001 From: fuhao Date: Tue, 18 Feb 2025 18:11:50 +0800 Subject: [PATCH 1/7] 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 75bff325a425..6833934a3b05 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); -- Gitee From 871d501842bc74c7b3d2ff8dd60cae6ab0f36116 Mon Sep 17 00:00:00 2001 From: fuhao Date: Tue, 18 Feb 2025 18:14:30 +0800 Subject: [PATCH 2/7] 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/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 89543149d890..319ff8781e53 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; +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; @@ -3070,6 +3093,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 aaf945935ff7..b87a74235b43 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; -- Gitee From 957ff3ad29f4494e2d5eacb6edc68d1b1d1c1dc6 Mon Sep 17 00:00:00 2001 From: fuhao Date: Wed, 19 Feb 2025 10:35:27 +0800 Subject: [PATCH 3/7] 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 ed3cbc583059..cc5c9b0b72c3 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -467,8 +467,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 6137a84bfb6b2f8ebce94575778514a7d29662b3 Mon Sep 17 00:00:00 2001 From: fuhao Date: Wed, 19 Feb 2025 10:46:37 +0800 Subject: [PATCH 4/7] 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 --- 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 d0ab59e80fb0..243687a05e10 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. */ -- Gitee From 9bed2191ada603771c71c23da6f1700781d5379b Mon Sep 17 00:00:00 2001 From: fuhao Date: Wed, 19 Feb 2025 11:45:52 +0800 Subject: [PATCH 5/7] 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 --- 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 243687a05e10..0c2bc12ee3f6 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]. -- Gitee From 6773a5c8cd22bb9285f89f6e1ba2c715a9e7da78 Mon Sep 17 00:00:00 2001 From: fuhao Date: Wed, 19 Feb 2025 14:03:06 +0800 Subject: [PATCH 6/7] 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 0c2bc12ee3f6..8ae47ed70da2 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; -- Gitee From 8e3b503d6435082e4e7b32ed63b432dadfd2631d Mon Sep 17 00:00:00 2001 From: fuhao Date: Wed, 19 Feb 2025 14:04:28 +0800 Subject: [PATCH 7/7] 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 --- 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 8ae47ed70da2..5890c6565904 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; -- Gitee