diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 2da034b27e6530a0943b6a883037ca5b208f7d34..58b37844c430bf7d2a73c2136d197a70a3ab4410 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -222,7 +222,10 @@ static bool verify_sha256_digest(u32 patch_id, u32 cur_rev, const u8 *data, unsi struct sha256_state s; int i; - if (x86_family(bsp_cpuid_1_eax) < 0x17) + + if ((x86_cpuid_vendor() == X86_VENDOR_AMD && + x86_family(bsp_cpuid_1_eax) < 0x17) || + x86_cpuid_vendor() == X86_VENDOR_HYGON) return true; if (!need_sha_check(cur_rev)) @@ -285,7 +288,8 @@ static u16 find_equiv_id(struct equiv_cpu_table *et, u32 sig) unsigned int i; /* Zen and newer do not need an equivalence table. */ - if (x86_family(bsp_cpuid_1_eax) >= 0x17) + if (x86_cpuid_vendor() == X86_VENDOR_AMD && + x86_family(bsp_cpuid_1_eax) >= 0x17) return 0; if (!et || !et->num_entries) @@ -335,7 +339,8 @@ static bool verify_equivalence_table(const u8 *buf, size_t buf_size) return false; /* Zen and newer do not need an equivalence table. */ - if (x86_family(bsp_cpuid_1_eax) >= 0x17) + if (x86_cpuid_vendor() == X86_VENDOR_AMD && + x86_family(bsp_cpuid_1_eax) >= 0x17) return true; cont_type = hdr[1]; @@ -491,7 +496,8 @@ static int verify_patch(const u8 *buf, size_t buf_size, u32 *patch_size) static bool mc_patch_matches(struct microcode_amd *mc, u16 eq_id) { /* Zen and newer do not need an equivalence table. */ - if (x86_family(bsp_cpuid_1_eax) >= 0x17) + if (x86_cpuid_vendor() == X86_VENDOR_AMD && + x86_family(bsp_cpuid_1_eax) >= 0x17) return ucode_rev_to_cpuid(mc->hdr.patch_id).full == bsp_cpuid_1_eax; else return eq_id == mc->hdr.processor_rev_id; @@ -612,7 +618,9 @@ static bool __apply_microcode_amd(struct microcode_amd *mc, u32 *cur_rev, native_wrmsrl(MSR_AMD64_PATCH_LOADER, p_addr); - if (x86_family(bsp_cpuid_1_eax) == 0x17) { + if ((x86_cpuid_vendor() == X86_VENDOR_AMD && + x86_family(bsp_cpuid_1_eax) == 0x17) || + x86_cpuid_vendor() == X86_VENDOR_HYGON) { unsigned long p_addr_end = p_addr + psize - 1; invlpg(p_addr); @@ -667,10 +675,9 @@ static bool __init find_blobs_in_containers(struct cpio_data *ret) const char *path; if (x86_cpuid_vendor() == X86_VENDOR_HYGON) - path = (const char *)__pa_nodebug( - "kernel/x86/microcode/HygonGenuine.bin"); + path = "kernel/x86/microcode/HygonGenuine.bin"; else - path = (const char *)__pa_nodebug(ucode_path); + path = ucode_path; if (!get_builtin_microcode(&cp)) cp = find_microcode_in_initrd(path); @@ -741,7 +748,8 @@ static inline bool patch_cpus_equivalent(struct ucode_patch *p, bool ignore_stepping) { /* Zen and newer hardcode the f/m/s in the patch ID */ - if (x86_family(bsp_cpuid_1_eax) >= 0x17) { + if (x86_cpuid_vendor() == X86_VENDOR_AMD && + x86_family(bsp_cpuid_1_eax) >= 0x17) { union cpuid_1_eax p_cid = ucode_rev_to_cpuid(p->patch_id); union cpuid_1_eax n_cid = ucode_rev_to_cpuid(n->patch_id); @@ -767,7 +775,8 @@ static struct ucode_patch *cache_find_patch(struct ucode_cpu_info *uci, u16 equi n.equiv_cpu = equiv_cpu; n.patch_id = uci->cpu_sig.rev; - WARN_ON_ONCE(!n.patch_id); + if (x86_cpuid_vendor() != X86_VENDOR_HYGON) + WARN_ON_ONCE(!n.patch_id); list_for_each_entry(p, µcode_cache, plist) if (patch_cpus_equivalent(p, &n, false)) @@ -779,7 +788,8 @@ static struct ucode_patch *cache_find_patch(struct ucode_cpu_info *uci, u16 equi static inline int patch_newer(struct ucode_patch *p, struct ucode_patch *n) { /* Zen and newer hardcode the f/m/s in the patch ID */ - if (x86_family(bsp_cpuid_1_eax) >= 0x17) { + if (x86_cpuid_vendor() == X86_VENDOR_AMD && + x86_family(bsp_cpuid_1_eax) >= 0x17) { union zen_patch_rev zp, zn; zp.ucode_rev = p->patch_id; @@ -839,7 +849,9 @@ static struct ucode_patch *find_patch(unsigned int cpu) uci->cpu_sig.rev = get_patch_level(); - if (x86_family(bsp_cpuid_1_eax) < 0x17) { + if ((x86_cpuid_vendor() == X86_VENDOR_AMD && + x86_family(bsp_cpuid_1_eax) < 0x17) || + x86_cpuid_vendor() == X86_VENDOR_HYGON) { equiv_id = find_equiv_id(&equiv_table, uci->cpu_sig.sig); if (!equiv_id) return NULL; @@ -954,7 +966,8 @@ static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size) equiv_tbl_len = hdr[2]; /* Zen and newer do not need an equivalence table. */ - if (x86_family(bsp_cpuid_1_eax) >= 0x17) + if (x86_cpuid_vendor() == X86_VENDOR_AMD && + x86_family(bsp_cpuid_1_eax) >= 0x17) goto out; equiv_table.entry = vmalloc(equiv_tbl_len); @@ -973,7 +986,8 @@ static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size) static void free_equiv_cpu_table(void) { - if (x86_family(bsp_cpuid_1_eax) >= 0x17) + if (x86_cpuid_vendor() == X86_VENDOR_AMD && + x86_family(bsp_cpuid_1_eax) >= 0x17) return; vfree(equiv_table.entry); @@ -1119,7 +1133,9 @@ static int __init save_microcode_in_initrd(void) enum ucode_state ret; struct cpio_data cp; - if (dis_ucode_ldr || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) + if (dis_ucode_ldr || + (c->x86_vendor != X86_VENDOR_AMD && c->x86_vendor != X86_VENDOR_HYGON) || + (c->x86_vendor == X86_VENDOR_AMD && c->x86 < 0x10)) return 0; if (!find_blobs_in_containers(&cp))