// SPDX-License-Identifier: GPL-2.0-only#include <linux/export.h>#include <linux/bitops.h>#include <linux/dmi.h>#include <linux/elf.h>#include <linux/mm.h>#include <linux/kvm_types.h>#include <linux/io.h>#include <linux/sched.h>#include <linux/sched/clock.h>#include <linux/random.h>#include <linux/topology.h>#include <linux/platform_data/x86/amd-fch.h>#include <asm/processor.h>#include <asm/apic.h>#include <asm/cacheinfo.h>#include <asm/cpu.h>#include <asm/cpu_device_id.h>#include <asm/cpuid/api.h>#include <asm/spec-ctrl.h>#include <asm/smp.h>#include <asm/numa.h>#include <asm/pci-direct.h>#include <asm/delay.h>#include <asm/debugreg.h>#include <asm/resctrl.h>#include <asm/msr.h>#include <asm/sev.h> #ifdef CONFIG_X86_64# include <asm/mmconfig.h>#endif #include "cpu.h" u16 invlpgb_count_max __ro_after_init = 1; static inline int rdmsrq_amd_safe(unsigned msr, u64 *p){ u32 gprs[8] = { 0 }; int err; WARN_ONCE((boot_cpu_data.x86 != 0xf), "%s should only be used on K8!\n", __func__); gprs[1] = msr; gprs[7] = 0x9c5a203a; err = rdmsr_safe_regs(gprs); *p = gprs[0] | ((u64)gprs[2] << 32); return err;} static inline int wrmsrq_amd_safe(unsigned msr, u64 val){ u32 gprs[8] = { 0 }; WARN_ONCE((boot_cpu_data.x86 != 0xf), "%s should only be used on K8!\n", __func__); gprs[0] = (u32)val; gprs[1] = msr; gprs[2] = val >> 32; gprs[7] = 0x9c5a203a; return wrmsr_safe_regs(gprs);} /* * B step AMD K6 before B 9730xxxx have hardware bugs that can cause * misexecution of code under Linux. Owners of such processors should * contact AMD for precise details and a CPU swap. * * See http://www.multimania.com/poulot/k6bug.html * and section 2.6.2 of "AMD-K6 Processor Revision Guide - Model 6" * (Publication # 21266 Issue Date: August 1998) * * The following test is erm.. interesting. AMD neglected to up * the chip setting when fixing the bug but they also tweaked some * performance at the same time.. */ #ifdef CONFIG_X86_32extern __visible void vide(void);__asm__(".text\n" ".globl vide\n" ".type vide, @function\n" ".align 4\n" "vide: ret\n");#endif static void init_amd_k5(struct cpuinfo_x86 *c){#ifdef CONFIG_X86_32/* * General Systems BIOSen alias the cpu frequency registers * of the Elan at 0x000df000. Unfortunately, one of the Linux * drivers subsequently pokes it, and changes the CPU speed. * Workaround : Remove the unneeded alias. */#define CBAR (0xfffc) /* Configuration Base Address (32-bit) */#define CBAR_ENB (0x80000000)#define CBAR_KEY (0X000000CB) if (c->x86_model == 9 || c->x86_model == 10) { if (inl(CBAR) & CBAR_ENB) outl(0 | CBAR_KEY, CBAR); }#endif} static void init_amd_k6(struct cpuinfo_x86 *c){#ifdef CONFIG_X86_32 struct msr val; int mbytes = get_num_physpages() >> (20-PAGE_SHIFT); if (c->x86_model < 6) { /* Based on AMD doc 20734R - June 2000 */ if (c->x86_model == 0) { clear_cpu_cap(c, X86_FEATURE_APIC); set_cpu_cap(c, X86_FEATURE_PGE); } return; } if (c->x86_model == 6 && c->x86_stepping == 1) { const int K6_BUG_LOOP = 1000000; int n; void (*f_vide)(void); u64 d, d2; pr_info("AMD K6 stepping B detected - "); /* * It looks like AMD fixed the 2.6.2 bug and improved indirect * calls at the same time. */ n = K6_BUG_LOOP; f_vide = vide; OPTIMIZER_HIDE_VAR(f_vide); d = rdtsc(); while (n--) f_vide(); d2 = rdtsc(); d = d2-d; if (d > 20*K6_BUG_LOOP) pr_cont("system stability may be impaired when more than 32 MB are used.\n"); else pr_cont("probably OK (after B9730xxxx).\n"); } /* K6 with old style WHCR */ if (c->x86_model < 8 || (c->x86_model == 8 && c->x86_stepping < 8)) { /* We can only write allocate on the low 508Mb */ if (mbytes > 508) mbytes = 508; rdmsrq(MSR_K6_WHCR, val.q); if ((val.l & 0x0000FFFF) == 0) { unsigned long flags; val.l = (1 << 0) | ((mbytes / 4) << 1); local_irq_save(flags); wbinvd(); wrmsrq(MSR_K6_WHCR, val.q); local_irq_restore(flags); pr_info("Enabling old style K6 write allocation for %d Mb\n", mbytes); } return; } if ((c->x86_model == 8 && c->x86_stepping > 7) || c->x86_model == 9 || c->x86_model == 13) { /* The more serious chips .. */ if (mbytes > 4092) mbytes = 4092; rdmsrq(MSR_K6_WHCR, val.q); if ((val.l & 0xFFFF0000) == 0) { unsigned long flags; val.l = ((mbytes >> 2) << 22) | (1 << 16); local_irq_save(flags); wbinvd(); wrmsrq(MSR_K6_WHCR, val.q); local_irq_restore(flags); pr_info("Enabling new style K6 write allocation for %d Mb\n", mbytes); } return; } if (c->x86_model == 10) { /* AMD Geode LX is model 10 */ /* placeholder for any needed mods */ return; }#endif} static void init_amd_k7(struct cpuinfo_x86 *c){#ifdef CONFIG_X86_32 struct msr val; /* * Bit 15 of Athlon specific MSR 15, needs to be 0 * to enable SSE on Palomino/Morgan/Barton CPU's. * If the BIOS didn't enable it already, enable it here. */ if (c->x86_model >= 6 && c->x86_model <= 10) { if (!cpu_has(c, X86_FEATURE_XMM)) { pr_info("Enabling disabled K7/SSE Support.\n"); msr_clear_bit(MSR_K7_HWCR, 15); set_cpu_cap(c, X86_FEATURE_XMM); } } /* * It's been determined by AMD that Athlons since model 8 stepping 1 * are more robust with CLK_CTL set to 200xxxxx instead of 600xxxxx * As per AMD technical note 27212 0.2 */ if ((c->x86_model == 8 && c->x86_stepping >= 1) || (c->x86_model > 8)) { rdmsrq(MSR_K7_CLK_CTL, val.q); if ((val.l & 0xfff00000) != 0x20000000) { pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", val.l, ((val.l & 0x000fffff) | 0x20000000)); val.l = (val.l & 0x000fffff) | 0x20000000; wrmsrq(MSR_K7_CLK_CTL, val.q); } } /* calling is from identify_secondary_cpu() ? */ if (!c->cpu_index) return; /* * Certain Athlons might work (for various values of 'work') in SMP * but they are not certified as MP capable. */ /* Athlon 660/661 is valid. */ if ((c->x86_model == 6) && ((c->x86_stepping == 0) || (c->x86_stepping == 1))) return; /* Duron 670 is valid */ if ((c->x86_model == 7) && (c->x86_stepping == 0)) return; /* * Athlon 662, Duron 671, and Athlon >model 7 have capability * bit. It's worth noting that the A5 stepping (662) of some * Athlon XP's have the MP bit set. * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for * more. */ if (((c->x86_model == 6) && (c->x86_stepping >= 2)) || ((c->x86_model == 7) && (c->x86_stepping >= 1)) || (c->x86_model > 7)) if (cpu_has(c, X86_FEATURE_MP)) return; /* If we get here, not a certified SMP capable AMD system. */ /* * Don't taint if we are running SMP kernel on a single non-MP * approved Athlon */ WARN_ONCE(1, "WARNING: This combination of AMD" " processors is not suitable for SMP.\n"); add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE);#endif} #ifdef CONFIG_NUMA/* * To workaround broken NUMA config. Read the comment in * srat_detect_node(). */static int nearby_node(int apicid){ int i, node; for (i = apicid - 1; i >= 0; i--) { node = __apicid_to_node[i]; if (node != NUMA_NO_NODE && node_online(node)) return node; } for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) { node = __apicid_to_node[i]; if (node != NUMA_NO_NODE && node_online(node)) return node; } return first_node(node_online_map); /* Shouldn't happen */}#endif static void srat_detect_node(struct cpuinfo_x86 *c){#ifdef CONFIG_NUMA int cpu = smp_processor_id(); int node; unsigned apicid = c->topo.apicid; node = numa_cpu_node(cpu); if (node == NUMA_NO_NODE) node = per_cpu_llc_id(cpu); /* * On multi-fabric platform (e.g. Numascale NumaChip) a * platform-specific handler needs to be called to fixup some * IDs of the CPU. */ if (x86_cpuinit.fixup_cpu_id) x86_cpuinit.fixup_cpu_id(c, node); if (!node_online(node)) { /* * Two possibilities here: * * - The CPU is missing memory and no node was created. In * that case try picking one from a nearby CPU. * * - The APIC IDs differ from the HyperTransport node IDs * which the K8 northbridge parsing fills in. Assume * they are all increased by a constant offset, but in * the same order as the HT nodeids. If that doesn't * result in a usable node fall back to the path for the * previous case. * * This workaround operates directly on the mapping between * APIC ID and NUMA node, assuming certain relationship * between APIC ID, HT node ID and NUMA topology. As going * through CPU mapping may alter the outcome, directly * access __apicid_to_node[]. */ int ht_nodeid = c->topo.initial_apicid; if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE) node = __apicid_to_node[ht_nodeid]; /* Pick a nearby node */ if (!node_online(node)) node = nearby_node(apicid); } numa_set_node(cpu, node);#endif} static void bsp_determine_snp(struct cpuinfo_x86 *c){#ifdef CONFIG_ARCH_HAS_CC_PLATFORM cc_vendor = CC_VENDOR_AMD; if (cpu_has(c, X86_FEATURE_SEV_SNP)) { /* * RMP table entry format is not architectural and is defined by the * per-processor PPR. Restrict SNP support on the known CPU models * for which the RMP table entry format is currently defined or for * processors which support the architecturally defined RMPREAD * instruction. */ if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && (cpu_feature_enabled(X86_FEATURE_ZEN3) || cpu_feature_enabled(X86_FEATURE_ZEN4) || cpu_feature_enabled(X86_FEATURE_RMPREAD)) && snp_probe_rmptable_info()) { cc_platform_set(CC_ATTR_HOST_SEV_SNP); } else { setup_clear_cpu_cap(X86_FEATURE_SEV_SNP); cc_platform_clear(CC_ATTR_HOST_SEV_SNP); } }#endif} #define ZEN_MODEL_STEP_UCODE(fam, model, step, ucode) \ X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, fam, model), \ step, step, ucode) static const struct x86_cpu_id amd_tsa_microcode[] = { ZEN_MODEL_STEP_UCODE(0x19, 0x01, 0x1, 0x0a0011d7), ZEN_MODEL_STEP_UCODE(0x19, 0x01, 0x2, 0x0a00123b), ZEN_MODEL_STEP_UCODE(0x19, 0x08, 0x2, 0x0a00820d), ZEN_MODEL_STEP_UCODE(0x19, 0x11, 0x1, 0x0a10114c), ZEN_MODEL_STEP_UCODE(0x19, 0x11, 0x2, 0x0a10124c), ZEN_MODEL_STEP_UCODE(0x19, 0x18, 0x1, 0x0a108109), ZEN_MODEL_STEP_UCODE(0x19, 0x21, 0x0, 0x0a20102e), ZEN_MODEL_STEP_UCODE(0x19, 0x21, 0x2, 0x0a201211), ZEN_MODEL_STEP_UCODE(0x19, 0x44, 0x1, 0x0a404108), ZEN_MODEL_STEP_UCODE(0x19, 0x50, 0x0, 0x0a500012), ZEN_MODEL_STEP_UCODE(0x19, 0x61, 0x2, 0x0a60120a), ZEN_MODEL_STEP_UCODE(0x19, 0x74, 0x1, 0x0a704108), ZEN_MODEL_STEP_UCODE(0x19, 0x75, 0x2, 0x0a705208), ZEN_MODEL_STEP_UCODE(0x19, 0x78, 0x0, 0x0a708008), ZEN_MODEL_STEP_UCODE(0x19, 0x7c, 0x0, 0x0a70c008), ZEN_MODEL_STEP_UCODE(0x19, 0xa0, 0x2, 0x0aa00216), {},}; static void tsa_init(struct cpuinfo_x86 *c){ if (cpu_has(c, X86_FEATURE_HYPERVISOR)) return; if (cpu_has(c, X86_FEATURE_ZEN3) || cpu_has(c, X86_FEATURE_ZEN4)) { if (x86_match_min_microcode_rev(amd_tsa_microcode)) setup_force_cpu_cap(X86_FEATURE_VERW_CLEAR); else pr_debug("%s: current revision: 0x%x\n", __func__, c->microcode); } else { setup_force_cpu_cap(X86_FEATURE_TSA_SQ_NO); setup_force_cpu_cap(X86_FEATURE_TSA_L1_NO); }} static void bsp_init_amd(struct cpuinfo_x86 *c){ if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { if (c->x86 > 0x10 || (c->x86 == 0x10 && c->x86_model >= 0x2)) { u64 val; rdmsrq(MSR_K7_HWCR, val); if (!(val & BIT(24))) pr_warn(FW_BUG "TSC doesn't count with P0 frequency!\n"); } } if (c->x86 == 0x15) { unsigned long upperbit; u32 cpuid, assoc; cpuid = cpuid_edx(0x80000005); assoc = cpuid >> 16 & 0xff; upperbit = ((cpuid >> 24) << 10) / assoc; va_align.mask = (upperbit - 1) & PAGE_MASK; va_align.flags = ALIGN_VA_32 | ALIGN_VA_64; /* A random value per boot for bit slice [12:upper_bit) */ va_align.bits = get_random_u32() & va_align.mask; } if (cpu_has(c, X86_FEATURE_MWAITX)) use_mwaitx_delay(); if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) && !boot_cpu_has(X86_FEATURE_VIRT_SSBD) && c->x86 >= 0x15 && c->x86 <= 0x17) { unsigned int bit; switch (c->x86) { case 0x15: bit = 54; break; case 0x16: bit = 33; break; case 0x17: bit = 10; break; default: return; } /* * Try to cache the base value so further operations can * avoid RMW. If that faults, do not enable SSBD. */ if (!rdmsrq_safe(MSR_AMD64_LS_CFG, &x86_amd_ls_cfg_base)) { setup_force_cpu_cap(X86_FEATURE_LS_CFG_SSBD); setup_force_cpu_cap(X86_FEATURE_SSBD); x86_amd_ls_cfg_ssbd_mask = 1ULL << bit; } } resctrl_cpu_detect(c); /* Figure out Zen generations: */ switch (c->x86) { case 0x17: switch (c->x86_model) { case 0x00 ... 0x2f: case 0x50 ... 0x5f: setup_force_cpu_cap(X86_FEATURE_ZEN1); break; case 0x30 ... 0x4f: case 0x60 ... 0x7f: case 0x90 ... 0x91: case 0xa0 ... 0xaf: setup_force_cpu_cap(X86_FEATURE_ZEN2); break; default: goto warn; } break; case 0x19: switch (c->x86_model) {Lines 1–500 of 1442. Load more
// SPDX-License-Identifier: GPL-2.0-only #include <linux/export.h> #include <linux/bitops.h> #include <linux/dmi.h> #include <linux/elf.h> #include <linux/mm.h> #include <linux/kvm_types.h> #include <linux/io.h> #include <linux/sched.h> #include <linux/sched/clock.h> #include <linux/random.h> #include <linux/topology.h> #include <linux/platform_data/x86/amd-fch.h> #include <asm/processor.h> #include <asm/apic.h> #include <asm/cacheinfo.h> #include <asm/cpu.h> #include <asm/cpu_device_id.h> #include <asm/cpuid/api.h> #include <asm/spec-ctrl.h> #include <asm/smp.h> #include <asm/numa.h> #include <asm/pci-direct.h> #include <asm/delay.h> #include <asm/debugreg.h> #include <asm/resctrl.h> #include <asm/msr.h> #include <asm/sev.h> #ifdef CONFIG_X86_64 # include <asm/mmconfig.h> #endif #include "cpu.h" u16 invlpgb_count_max __ro_after_init = 1; static inline int rdmsrq_amd_safe(unsigned msr, u64 *p) { u32 gprs[8] = { 0 }; int err; WARN_ONCE((boot_cpu_data.x86 != 0xf), "%s should only be used on K8!\n", __func__); gprs[1] = msr; gprs[7] = 0x9c5a203a; err = rdmsr_safe_regs(gprs); *p = gprs[0] | ((u64)gprs[2] << 32); return err; } static inline int wrmsrq_amd_safe(unsigned msr, u64 val) { u32 gprs[8] = { 0 }; WARN_ONCE((boot_cpu_data.x86 != 0xf), "%s should only be used on K8!\n", __func__); gprs[0] = (u32)val; gprs[1] = msr; gprs[2] = val >> 32; gprs[7] = 0x9c5a203a; return wrmsr_safe_regs(gprs); } /* * B step AMD K6 before B 9730xxxx have hardware bugs that can cause * misexecution of code under Linux. Owners of such processors should * contact AMD for precise details and a CPU swap. * * See http://www.multimania.com/poulot/k6bug.html * and section 2.6.2 of "AMD-K6 Processor Revision Guide - Model 6" * (Publication # 21266 Issue Date: August 1998) * * The following test is erm.. interesting. AMD neglected to up * the chip setting when fixing the bug but they also tweaked some * performance at the same time.. */ #ifdef CONFIG_X86_32 extern __visible void vide(void); __asm__(".text\n" ".globl vide\n" ".type vide, @function\n" ".align 4\n" "vide: ret\n"); #endif static void init_amd_k5(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_32 /* * General Systems BIOSen alias the cpu frequency registers * of the Elan at 0x000df000. Unfortunately, one of the Linux * drivers subsequently pokes it, and changes the CPU speed. * Workaround : Remove the unneeded alias. */ #define CBAR (0xfffc) /* Configuration Base Address (32-bit) */ #define CBAR_ENB (0x80000000) #define CBAR_KEY (0X000000CB) if (c->x86_model == 9 || c->x86_model == 10) { if (inl(CBAR) & CBAR_ENB) outl(0 | CBAR_KEY, CBAR); } #endif } static void init_amd_k6(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_32 struct msr val; int mbytes = get_num_physpages() >> (20-PAGE_SHIFT); if (c->x86_model < 6) { /* Based on AMD doc 20734R - June 2000 */ if (c->x86_model == 0) { clear_cpu_cap(c, X86_FEATURE_APIC); set_cpu_cap(c, X86_FEATURE_PGE); } return; } if (c->x86_model == 6 && c->x86_stepping == 1) { const int K6_BUG_LOOP = 1000000; int n; void (*f_vide)(void); u64 d, d2; pr_info("AMD K6 stepping B detected - "); /* * It looks like AMD fixed the 2.6.2 bug and improved indirect * calls at the same time. */ n = K6_BUG_LOOP; f_vide = vide; OPTIMIZER_HIDE_VAR(f_vide); d = rdtsc(); while (n--) f_vide(); d2 = rdtsc(); d = d2-d; if (d > 20*K6_BUG_LOOP) pr_cont("system stability may be impaired when more than 32 MB are used.\n"); else pr_cont("probably OK (after B9730xxxx).\n"); } /* K6 with old style WHCR */ if (c->x86_model < 8 || (c->x86_model == 8 && c->x86_stepping < 8)) { /* We can only write allocate on the low 508Mb */ if (mbytes > 508) mbytes = 508; rdmsrq(MSR_K6_WHCR, val.q); if ((val.l & 0x0000FFFF) == 0) { unsigned long flags; val.l = (1 << 0) | ((mbytes / 4) << 1); local_irq_save(flags); wbinvd(); wrmsrq(MSR_K6_WHCR, val.q); local_irq_restore(flags); pr_info("Enabling old style K6 write allocation for %d Mb\n", mbytes); } return; } if ((c->x86_model == 8 && c->x86_stepping > 7) || c->x86_model == 9 || c->x86_model == 13) { /* The more serious chips .. */ if (mbytes > 4092) mbytes = 4092; rdmsrq(MSR_K6_WHCR, val.q); if ((val.l & 0xFFFF0000) == 0) { unsigned long flags; val.l = ((mbytes >> 2) << 22) | (1 << 16); local_irq_save(flags); wbinvd(); wrmsrq(MSR_K6_WHCR, val.q); local_irq_restore(flags); pr_info("Enabling new style K6 write allocation for %d Mb\n", mbytes); } return; } if (c->x86_model == 10) { /* AMD Geode LX is model 10 */ /* placeholder for any needed mods */ return; } #endif } static void init_amd_k7(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_32 struct msr val; /* * Bit 15 of Athlon specific MSR 15, needs to be 0 * to enable SSE on Palomino/Morgan/Barton CPU's. * If the BIOS didn't enable it already, enable it here. */ if (c->x86_model >= 6 && c->x86_model <= 10) { if (!cpu_has(c, X86_FEATURE_XMM)) { pr_info("Enabling disabled K7/SSE Support.\n"); msr_clear_bit(MSR_K7_HWCR, 15); set_cpu_cap(c, X86_FEATURE_XMM); } } /* * It's been determined by AMD that Athlons since model 8 stepping 1 * are more robust with CLK_CTL set to 200xxxxx instead of 600xxxxx * As per AMD technical note 27212 0.2 */ if ((c->x86_model == 8 && c->x86_stepping >= 1) || (c->x86_model > 8)) { rdmsrq(MSR_K7_CLK_CTL, val.q); if ((val.l & 0xfff00000) != 0x20000000) { pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", val.l, ((val.l & 0x000fffff) | 0x20000000)); val.l = (val.l & 0x000fffff) | 0x20000000; wrmsrq(MSR_K7_CLK_CTL, val.q); } } /* calling is from identify_secondary_cpu() ? */ if (!c->cpu_index) return; /* * Certain Athlons might work (for various values of 'work') in SMP * but they are not certified as MP capable. */ /* Athlon 660/661 is valid. */ if ((c->x86_model == 6) && ((c->x86_stepping == 0) || (c->x86_stepping == 1))) return; /* Duron 670 is valid */ if ((c->x86_model == 7) && (c->x86_stepping == 0)) return; /* * Athlon 662, Duron 671, and Athlon >model 7 have capability * bit. It's worth noting that the A5 stepping (662) of some * Athlon XP's have the MP bit set. * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for * more. */ if (((c->x86_model == 6) && (c->x86_stepping >= 2)) || ((c->x86_model == 7) && (c->x86_stepping >= 1)) || (c->x86_model > 7)) if (cpu_has(c, X86_FEATURE_MP)) return; /* If we get here, not a certified SMP capable AMD system. */ /* * Don't taint if we are running SMP kernel on a single non-MP * approved Athlon */ WARN_ONCE(1, "WARNING: This combination of AMD" " processors is not suitable for SMP.\n"); add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE); #endif } #ifdef CONFIG_NUMA /* * To workaround broken NUMA config. Read the comment in * srat_detect_node(). */ static int nearby_node(int apicid) { int i, node; for (i = apicid - 1; i >= 0; i--) { node = __apicid_to_node[i]; if (node != NUMA_NO_NODE && node_online(node)) return node; } for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) { node = __apicid_to_node[i]; if (node != NUMA_NO_NODE && node_online(node)) return node; } return first_node(node_online_map); /* Shouldn't happen */ } #endif static void srat_detect_node(struct cpuinfo_x86 *c) { #ifdef CONFIG_NUMA int cpu = smp_processor_id(); int node; unsigned apicid = c->topo.apicid; node = numa_cpu_node(cpu); if (node == NUMA_NO_NODE) node = per_cpu_llc_id(cpu); /* * On multi-fabric platform (e.g. Numascale NumaChip) a * platform-specific handler needs to be called to fixup some * IDs of the CPU. */ if (x86_cpuinit.fixup_cpu_id) x86_cpuinit.fixup_cpu_id(c, node); if (!node_online(node)) { /* * Two possibilities here: * * - The CPU is missing memory and no node was created. In * that case try picking one from a nearby CPU. * * - The APIC IDs differ from the HyperTransport node IDs * which the K8 northbridge parsing fills in. Assume * they are all increased by a constant offset, but in * the same order as the HT nodeids. If that doesn't * result in a usable node fall back to the path for the * previous case. * * This workaround operates directly on the mapping between * APIC ID and NUMA node, assuming certain relationship * between APIC ID, HT node ID and NUMA topology. As going * through CPU mapping may alter the outcome, directly * access __apicid_to_node[]. */ int ht_nodeid = c->topo.initial_apicid; if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE) node = __apicid_to_node[ht_nodeid]; /* Pick a nearby node */ if (!node_online(node)) node = nearby_node(apicid); } numa_set_node(cpu, node); #endif } static void bsp_determine_snp(struct cpuinfo_x86 *c) { #ifdef CONFIG_ARCH_HAS_CC_PLATFORM cc_vendor = CC_VENDOR_AMD; if (cpu_has(c, X86_FEATURE_SEV_SNP)) { /* * RMP table entry format is not architectural and is defined by the * per-processor PPR. Restrict SNP support on the known CPU models * for which the RMP table entry format is currently defined or for * processors which support the architecturally defined RMPREAD * instruction. */ if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && (cpu_feature_enabled(X86_FEATURE_ZEN3) || cpu_feature_enabled(X86_FEATURE_ZEN4) || cpu_feature_enabled(X86_FEATURE_RMPREAD)) && snp_probe_rmptable_info()) { cc_platform_set(CC_ATTR_HOST_SEV_SNP); } else { setup_clear_cpu_cap(X86_FEATURE_SEV_SNP); cc_platform_clear(CC_ATTR_HOST_SEV_SNP); } } #endif } #define ZEN_MODEL_STEP_UCODE(fam, model, step, ucode) \ X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, fam, model), \ step, step, ucode) static const struct x86_cpu_id amd_tsa_microcode[] = { ZEN_MODEL_STEP_UCODE(0x19, 0x01, 0x1, 0x0a0011d7), ZEN_MODEL_STEP_UCODE(0x19, 0x01, 0x2, 0x0a00123b), ZEN_MODEL_STEP_UCODE(0x19, 0x08, 0x2, 0x0a00820d), ZEN_MODEL_STEP_UCODE(0x19, 0x11, 0x1, 0x0a10114c), ZEN_MODEL_STEP_UCODE(0x19, 0x11, 0x2, 0x0a10124c), ZEN_MODEL_STEP_UCODE(0x19, 0x18, 0x1, 0x0a108109), ZEN_MODEL_STEP_UCODE(0x19, 0x21, 0x0, 0x0a20102e), ZEN_MODEL_STEP_UCODE(0x19, 0x21, 0x2, 0x0a201211), ZEN_MODEL_STEP_UCODE(0x19, 0x44, 0x1, 0x0a404108), ZEN_MODEL_STEP_UCODE(0x19, 0x50, 0x0, 0x0a500012), ZEN_MODEL_STEP_UCODE(0x19, 0x61, 0x2, 0x0a60120a), ZEN_MODEL_STEP_UCODE(0x19, 0x74, 0x1, 0x0a704108), ZEN_MODEL_STEP_UCODE(0x19, 0x75, 0x2, 0x0a705208), ZEN_MODEL_STEP_UCODE(0x19, 0x78, 0x0, 0x0a708008), ZEN_MODEL_STEP_UCODE(0x19, 0x7c, 0x0, 0x0a70c008), ZEN_MODEL_STEP_UCODE(0x19, 0xa0, 0x2, 0x0aa00216), {}, }; static void tsa_init(struct cpuinfo_x86 *c) { if (cpu_has(c, X86_FEATURE_HYPERVISOR)) return; if (cpu_has(c, X86_FEATURE_ZEN3) || cpu_has(c, X86_FEATURE_ZEN4)) { if (x86_match_min_microcode_rev(amd_tsa_microcode)) setup_force_cpu_cap(X86_FEATURE_VERW_CLEAR); else pr_debug("%s: current revision: 0x%x\n", __func__, c->microcode); } else { setup_force_cpu_cap(X86_FEATURE_TSA_SQ_NO); setup_force_cpu_cap(X86_FEATURE_TSA_L1_NO); } } static void bsp_init_amd(struct cpuinfo_x86 *c) { if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { if (c->x86 > 0x10 || (c->x86 == 0x10 && c->x86_model >= 0x2)) { u64 val; rdmsrq(MSR_K7_HWCR, val); if (!(val & BIT(24))) pr_warn(FW_BUG "TSC doesn't count with P0 frequency!\n"); } } if (c->x86 == 0x15) { unsigned long upperbit; u32 cpuid, assoc; cpuid = cpuid_edx(0x80000005); assoc = cpuid >> 16 & 0xff; upperbit = ((cpuid >> 24) << 10) / assoc; va_align.mask = (upperbit - 1) & PAGE_MASK; va_align.flags = ALIGN_VA_32 | ALIGN_VA_64; /* A random value per boot for bit slice [12:upper_bit) */ va_align.bits = get_random_u32() & va_align.mask; } if (cpu_has(c, X86_FEATURE_MWAITX)) use_mwaitx_delay(); if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) && !boot_cpu_has(X86_FEATURE_VIRT_SSBD) && c->x86 >= 0x15 && c->x86 <= 0x17) { unsigned int bit; switch (c->x86) { case 0x15: bit = 54; break; case 0x16: bit = 33; break; case 0x17: bit = 10; break; default: return; } /* * Try to cache the base value so further operations can * avoid RMW. If that faults, do not enable SSBD. */ if (!rdmsrq_safe(MSR_AMD64_LS_CFG, &x86_amd_ls_cfg_base)) { setup_force_cpu_cap(X86_FEATURE_LS_CFG_SSBD); setup_force_cpu_cap(X86_FEATURE_SSBD); x86_amd_ls_cfg_ssbd_mask = 1ULL << bit; } } resctrl_cpu_detect(c); /* Figure out Zen generations: */ switch (c->x86) { case 0x17: switch (c->x86_model) { case 0x00 ... 0x2f: case 0x50 ... 0x5f: setup_force_cpu_cap(X86_FEATURE_ZEN1); break; case 0x30 ... 0x4f: case 0x60 ... 0x7f: case 0x90 ... 0x91: case 0xa0 ... 0xaf: setup_force_cpu_cap(X86_FEATURE_ZEN2); break; default: goto warn; } break; case 0x19: switch (c->x86_model) {