/* * 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..
*/
staticvoid 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
}
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) { constint 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;
rdmsr(MSR_K6_WHCR, l, h); if ((l&0x0000FFFF) == 0) { unsignedlong flags;
l = (1<<0)|((mbytes/4)<<1);
local_irq_save(flags);
wbinvd();
wrmsr(MSR_K6_WHCR, l, h);
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;
rdmsr(MSR_K6_WHCR, l, h); if ((l&0xFFFF0000) == 0) { unsignedlong flags;
l = ((mbytes>>2)<<22)|(1<<16);
local_irq_save(flags);
wbinvd();
wrmsr(MSR_K6_WHCR, l, h);
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
}
/* * 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)) {
rdmsr(MSR_K7_CLK_CTL, l, h); if ((l & 0xfff00000) != 0x20000000) {
pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
l, ((l & 0x000fffff)|0x20000000));
wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h);
}
}
/* 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().
*/ staticint 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
staticvoid 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
}
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
}
switch (c->x86) { case0x15: bit = 54; break; case0x16: bit = 33; break; case0x17: 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;
}
}
/* * BIOS support is required for SME and SEV. * For SME: If BIOS has enabled SME then adjust x86_phys_bits by * the SME physical address space reduction value. * If BIOS has not enabled SME then don't advertise the * SME feature (set in scattered.c). * If the kernel has not enabled SME via any means then * don't advertise the SME feature. * For SEV: If BIOS has not enabled SEV then don't advertise SEV and * any additional functionality based on it. * * In all cases, since support for SME and SEV requires long mode, * don't advertise the feature under CONFIG_X86_32.
*/ if (cpu_has(c, X86_FEATURE_SME) || cpu_has(c, X86_FEATURE_SEV)) { /* Check if memory encryption is enabled */
rdmsrq(MSR_AMD64_SYSCFG, msr); if (!(msr & MSR_AMD64_SYSCFG_MEM_ENCRYPT)) goto clear_all;
/* * Always adjust physical address bits. Even though this * will be a value above 32-bits this is still done for * CONFIG_X86_32 so that accurate values are reported.
*/
c->x86_phys_bits -= (cpuid_ebx(0x8000001f) >> 6) & 0x3f;
if (IS_ENABLED(CONFIG_X86_32)) goto clear_all;
if (!sme_me_mask)
setup_clear_cpu_cap(X86_FEATURE_SME);
rdmsrq(MSR_K7_HWCR, msr); if (!(msr & MSR_K7_HWCR_SMMLOCK)) goto clear_sev;
/* * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate * with P/T states and does not stop in deep C-states
*/ if (c->x86_power & (1 << 8)) {
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
}
/* Bit 12 of 8000_0007 edx is accumulated power mechanism. */ if (c->x86_power & BIT(12))
set_cpu_cap(c, X86_FEATURE_ACC_POWER);
/* Bit 14 indicates the Runtime Average Power Limit interface. */ if (c->x86_power & BIT(14))
set_cpu_cap(c, X86_FEATURE_RAPL);
#ifdef CONFIG_X86_64
set_cpu_cap(c, X86_FEATURE_SYSCALL32); #else /* Set MTRR capability flag if appropriate */ if (c->x86 == 5) if (c->x86_model == 13 || c->x86_model == 9 ||
(c->x86_model == 8 && c->x86_stepping >= 8))
set_cpu_cap(c, X86_FEATURE_K6_MTRR); #endif #ifdefined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI) /* * ApicID can always be treated as an 8-bit value for AMD APIC versions * >= 0x10, but even old K8s came out of reset with version 0x10. So, we * can safely set X86_FEATURE_EXTD_APICID unconditionally for families * after 16h.
*/ if (boot_cpu_has(X86_FEATURE_APIC)) { if (c->x86 > 0x16)
set_cpu_cap(c, X86_FEATURE_EXTD_APICID); elseif (c->x86 >= 0xf) { /* check CPU config space for extended APIC ID */ unsignedint val;
val = read_pci_config(0, 24, 0, 0x68); if ((val >> 17 & 0x3) == 0x3)
set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
}
} #endif
/* * This is only needed to tell the kernel whether to use VMCALL * and VMMCALL. VMMCALL is never executed except under virt, so * we can set it unconditionally.
*/
set_cpu_cap(c, X86_FEATURE_VMMCALL);
/* On C+ stepping K8 rep microcode works well for copy/memset */
level = cpuid_eax(1); if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
set_cpu_cap(c, X86_FEATURE_REP_GOOD);
/* * Some BIOSes incorrectly force this feature, but only K8 revision D * (model = 0x14) and later actually support it. * (AMD Erratum #110, docId: 25759).
*/ if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM) && !cpu_has(c, X86_FEATURE_HYPERVISOR)) {
clear_cpu_cap(c, X86_FEATURE_LAHF_LM); if (!rdmsrq_amd_safe(0xc001100d, &value)) {
value &= ~BIT_64(32);
wrmsrq_amd_safe(0xc001100d, value);
}
}
if (!c->x86_model_id[0])
strscpy(c->x86_model_id, "Hammer");
#ifdef CONFIG_SMP /* * Disable TLB flush filter by setting HWCR.FFDIS on K8 * bit 6 of msr C001_0015 * * Errata 63 for SH-B3 steppings * Errata 122 for all steppings (F+ have it disabled by default)
*/
msr_set_bit(MSR_K7_HWCR, 6); #endif
set_cpu_bug(c, X86_BUG_SWAPGS_FENCE);
/* * Check models and steppings affected by erratum 400. This is * used to select the proper idle routine and to enable the * check whether the machine is affected in arch_post_acpi_subsys_init() * which sets the X86_BUG_AMD_APIC_C1E bug depending on the MSR check.
*/ if (c->x86_model > 0x41 ||
(c->x86_model == 0x41 && c->x86_stepping >= 0x2))
setup_force_cpu_bug(X86_BUG_AMD_E400);
}
staticvoid init_amd_gh(struct cpuinfo_x86 *c)
{ #ifdef CONFIG_MMCONF_FAM10H /* do this for boot cpu */ if (c == &boot_cpu_data)
check_enable_amd_mmconf_dmi();
fam10h_check_enable_mmcfg(); #endif
/* * Disable GART TLB Walk Errors on Fam10h. We do this here because this * is always needed when GART is enabled, even in a kernel which has no * MCE support built in. BIOS should disable GartTlbWlk Errors already. * If it doesn't, we do it here as suggested by the BKDG. * * Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=33012
*/
msr_set_bit(MSR_AMD64_MCx_MASK(4), 10);
/* * On family 10h BIOS may not have properly enabled WC+ support, causing * it to be converted to CD memtype. This may result in performance * degradation for certain nested-paging guests. Prevent this conversion * by clearing bit 24 in MSR_AMD64_BU_CFG2. * * NOTE: we want to use the _safe accessors so as not to #GP kvm * guests on older kvm hosts.
*/
msr_clear_bit(MSR_AMD64_BU_CFG2, 24);
set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH);
/* * Check models and steppings affected by erratum 400. This is * used to select the proper idle routine and to enable the * check whether the machine is affected in arch_post_acpi_subsys_init() * which sets the X86_BUG_AMD_APIC_C1E bug depending on the MSR check.
*/ if (c->x86_model > 0x2 ||
(c->x86_model == 0x2 && c->x86_stepping >= 0x1))
setup_force_cpu_bug(X86_BUG_AMD_E400);
}
staticvoid init_amd_ln(struct cpuinfo_x86 *c)
{ /* * Apply erratum 665 fix unconditionally so machines without a BIOS * fix work.
*/
msr_set_bit(MSR_AMD64_DE_CFG, 31);
}
staticbool rdrand_force;
staticint __init rdrand_cmdline(char *str)
{ if (!str) return -EINVAL;
if (!strcmp(str, "force"))
rdrand_force = true; else return -EINVAL;
return0;
}
early_param("rdrand", rdrand_cmdline);
staticvoid clear_rdrand_cpuid_bit(struct cpuinfo_x86 *c)
{ /* * Saving of the MSR used to hide the RDRAND support during * suspend/resume is done by arch/x86/power/cpu.c, which is * dependent on CONFIG_PM_SLEEP.
*/ if (!IS_ENABLED(CONFIG_PM_SLEEP)) return;
/* * The self-test can clear X86_FEATURE_RDRAND, so check for * RDRAND support using the CPUID function directly.
*/ if (!(cpuid_ecx(1) & BIT(30)) || rdrand_force) return;
msr_clear_bit(MSR_AMD64_CPUID_FN_1, 62);
/* * Verify that the CPUID change has occurred in case the kernel is * running virtualized and the hypervisor doesn't support the MSR.
*/ if (cpuid_ecx(1) & BIT(30)) {
pr_info_once("BIOS may not properly restore RDRAND after suspend, but hypervisor does not support hiding RDRAND via CPUID.\n"); return;
}
clear_cpu_cap(c, X86_FEATURE_RDRAND);
pr_info_once("BIOS may not properly restore RDRAND after suspend, hiding RDRAND via CPUID. Use rdrand=force to reenable.\n");
}
staticvoid init_amd_jg(struct cpuinfo_x86 *c)
{ /* * Some BIOS implementations do not restore proper RDRAND support * across suspend and resume. Check on whether to hide the RDRAND * instruction support via CPUID.
*/
clear_rdrand_cpuid_bit(c);
}
/* * The way access filter has a performance penalty on some workloads. * Disable it on the affected CPUs.
*/ if ((c->x86_model >= 0x02) && (c->x86_model < 0x20)) { if (!rdmsrq_safe(MSR_F15H_IC_CFG, &value) && !(value & 0x1E)) {
value |= 0x1E;
wrmsrq_safe(MSR_F15H_IC_CFG, value);
}
}
/* * Some BIOS implementations do not restore proper RDRAND support * across suspend and resume. Check on whether to hide the RDRAND * instruction support via CPUID.
*/
clear_rdrand_cpuid_bit(c);
}
staticvoid fix_erratum_1386(struct cpuinfo_x86 *c)
{ /* * Work around Erratum 1386. The XSAVES instruction malfunctions in * certain circumstances on Zen1/2 uarch, and not all parts have had * updated microcode at the time of writing (March 2023). * * Affected parts all have no supervisor XSAVE states, meaning that * the XSAVEC instruction (which works fine) is equivalent. * * Clear the feature flag only on microcode revisions which * don't have the fix.
*/ if (x86_match_min_microcode_rev(erratum_1386_microcode)) return;
/* * On Zen2 we offer this chicken (bit) on the altar of Speculation. * * This suppresses speculation from the middle of a basic block, i.e. it * suppresses non-branch predictions.
*/ if (!cpu_has(c, X86_FEATURE_HYPERVISOR)) { if (!rdmsrq_safe(MSR_ZEN2_SPECTRAL_CHICKEN, &value)) {
value |= MSR_ZEN2_SPECTRAL_CHICKEN_BIT;
wrmsrq_safe(MSR_ZEN2_SPECTRAL_CHICKEN, value);
}
} #endif
}
/* Fix up CPUID bits, but only if not virtualised. */ if (!cpu_has(c, X86_FEATURE_HYPERVISOR)) {
/* Erratum 1076: CPB feature bit not being set in CPUID. */ if (!cpu_has(c, X86_FEATURE_CPB))
set_cpu_cap(c, X86_FEATURE_CPB);
}
pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n");
setup_force_cpu_bug(X86_BUG_DIV0);
/* * Turn off the Instructions Retired free counter on machines that are * susceptible to erratum #1054 "Instructions Retired Performance * Counter May Be Inaccurate".
*/ if (c->x86_model < 0x30) {
msr_clear_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT);
clear_cpu_cap(c, X86_FEATURE_IRPERF);
}
}
if (boot_cpu_data.microcode < good_rev) returnfalse;
returntrue;
}
staticvoid zen2_zenbleed_check(struct cpuinfo_x86 *c)
{ if (cpu_has(c, X86_FEATURE_HYPERVISOR)) return;
if (!cpu_has(c, X86_FEATURE_AVX)) return;
if (!cpu_has_zenbleed_microcode()) {
pr_notice_once("Zenbleed: please update your microcode for the most optimal fix\n");
msr_set_bit(MSR_AMD64_DE_CFG, MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT);
} else {
msr_clear_bit(MSR_AMD64_DE_CFG, MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT);
}
}
/* Disable RDSEED on AMD Cyan Skillfish because of an error. */ if (c->x86_model == 0x47 && c->x86_stepping == 0x0) {
clear_cpu_cap(c, X86_FEATURE_RDSEED);
msr_clear_bit(MSR_AMD64_CPUID_FN_7, 18);
pr_emerg("RDSEED is not reliable on this platform; disabling.\n");
}
/* Correct misconfigured CPUID on some clients. */
clear_cpu_cap(c, X86_FEATURE_INVLPGB);
}
staticvoid init_amd_zen3(struct cpuinfo_x86 *c)
{ if (!cpu_has(c, X86_FEATURE_HYPERVISOR)) { /* * Zen3 (Fam19 model < 0x10) parts are not susceptible to * Branch Type Confusion, but predate the allocation of the * BTC_NO bit.
*/ if (!cpu_has(c, X86_FEATURE_BTC_NO))
set_cpu_cap(c, X86_FEATURE_BTC_NO);
}
}
staticvoid init_amd_zen4(struct cpuinfo_x86 *c)
{ if (!cpu_has(c, X86_FEATURE_HYPERVISOR))
msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT);
/* * These Zen4 SoCs advertise support for virtualized VMLOAD/VMSAVE * in some BIOS versions but they can lead to random host reboots.
*/ switch (c->x86_model) { case0x18 ... 0x1f: case0x60 ... 0x7f:
clear_cpu_cap(c, X86_FEATURE_V_VMSAVE_VMLOAD); break;
}
}
/* * Enable workaround for FXSAVE leak on CPUs * without a XSaveErPtr feature
*/ if ((c->x86 >= 6) && (!cpu_has(c, X86_FEATURE_XSAVEERPTR)))
set_cpu_bug(c, X86_BUG_FXSAVE_LEAK);
cpu_detect_cache_sizes(c);
srat_detect_node(c);
init_amd_cacheinfo(c);
if (cpu_has(c, X86_FEATURE_SVM)) {
rdmsrq(MSR_VM_CR, vm_cr); if (vm_cr & SVM_VM_CR_SVM_DIS_MASK) {
pr_notice_once("SVM disabled (by BIOS) in MSR_VM_CR\n");
clear_cpu_cap(c, X86_FEATURE_SVM);
}
}
if (!cpu_has(c, X86_FEATURE_LFENCE_RDTSC) && cpu_has(c, X86_FEATURE_XMM2)) { /* * Use LFENCE for execution serialization. On families which * don't have that MSR, LFENCE is already serializing. * msr_set_bit() uses the safe accessors, too, even if the MSR * is not present.
*/
msr_set_bit(MSR_AMD64_DE_CFG,
MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT);
/* * Family 0x12 and above processors have APIC timer * running in deep C states.
*/ if (c->x86 > 0x11)
set_cpu_cap(c, X86_FEATURE_ARAT);
/* 3DNow or LM implies PREFETCHW */ if (!cpu_has(c, X86_FEATURE_3DNOWPREFETCH)) if (cpu_has(c, X86_FEATURE_3DNOW) || cpu_has(c, X86_FEATURE_LM))
set_cpu_cap(c, X86_FEATURE_3DNOWPREFETCH);
/* AMD CPUs don't reset SS attributes on SYSRET, Xen does. */ if (!cpu_feature_enabled(X86_FEATURE_XENPV))
set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
/* Enable the Instructions Retired free counter */ if (cpu_has(c, X86_FEATURE_IRPERF))
msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT);
check_null_seg_clears_base(c);
/* * Make sure EFER[AIBRSE - Automatic IBRS Enable] is set. The APs are brought up * using the trampoline code and as part of it, MSR_EFER gets prepared there in * order to be replicated onto them. Regardless, set it here again, if not set, * to protect against any future refactoring/code reorganization which might * miss setting this important bit.
*/ if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) &&
cpu_has(c, X86_FEATURE_AUTOIBRS))
WARN_ON_ONCE(msr_set_bit(MSR_EFER, _EFER_AUTOIBRS) < 0);
/* AMD CPUs don't need fencing after x2APIC/TSC_DEADLINE MSR writes. */
clear_cpu_cap(c, X86_FEATURE_APIC_MSRS_FENCE);
/* * K8 doesn't have 2M/4M entries in the L2 TLB so read out the L1 TLB * characteristics from the CPUID function 0x80000005 instead.
*/ if (c->x86 == 0xf) {
cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
mask = 0xff;
}
/* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */ if (!((eax >> 16) & mask))
tlb_lld_2m = (cpuid_eax(0x80000005) >> 16) & 0xff; else
tlb_lld_2m = (eax >> 16) & mask;
/* a 4M entry uses two 2M entries */
tlb_lld_4m = tlb_lld_2m >> 1;
/* Handle ITLB 2M and 4M sizes, fall back to L1 if L2 is disabled */ if (!(eax & mask)) { /* Erratum 658 */ if (c->x86 == 0x15 && c->x86_model <= 0x1f) {
tlb_lli_2m = 1024;
} else {
cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
tlb_lli_2m = eax & 0xff;
}
} else
tlb_lli_2m = eax & mask;
tlb_lli_4m = tlb_lli_2m >> 1;
/* Max number of pages INVLPGB can invalidate in one shot */ if (cpu_has(c, X86_FEATURE_INVLPGB))
invlpgb_count_max = (cpuid_edx(0x80000008) & 0xffff) + 1;
}
void amd_check_microcode(void)
{ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) return;
if (cpu_feature_enabled(X86_FEATURE_ZEN2))
on_each_cpu(zenbleed_check_cpu, NULL, 1);
}
staticconstchar * const s5_reset_reason_txt[] = {
[0] = "thermal pin BP_THERMTRIP_L was tripped",
[1] = "power button was pressed for 4 seconds",
[2] = "shutdown pin was tripped",
[4] = "remote ASF power off command was received",
[9] = "internal CPU thermal limit was tripped",
[16] = "system reset pin BP_SYS_RST_L was tripped",
[17] = "software issued PCI reset",
[18] = "software wrote 0x4 to reset control register 0xCF9",
[19] = "software wrote 0x6 to reset control register 0xCF9",
[20] = "software wrote 0xE to reset control register 0xCF9",
[21] = "ACPI power state transition occurred",
[22] = "keyboard reset pin KB_RST_L was tripped",
[23] = "internal CPU shutdown event occurred",
[24] = "system failed to boot before failed boot timer expired",
[25] = "hardware watchdog timer expired",
[26] = "remote ASF reset command was received",
[27] = "an uncorrected error caused a data fabric sync flood event",
[29] = "FCH and MP1 failed warm reset handshake",
[30] = "a parity error occurred",
[31] = "a software sync flood event occurred",
};
static __init int print_s5_reset_status_mmio(void)
{ void __iomem *addr;
u32 value; int i;
if (!cpu_feature_enabled(X86_FEATURE_ZEN)) return0;
addr = ioremap(FCH_PM_BASE + FCH_PM_S5_RESET_STATUS, sizeof(value)); if (!addr) return0;
value = ioread32(addr);
/* Value with "all bits set" is an error response and should be ignored. */ if (value == U32_MAX) {
iounmap(addr); return0;
}
/* * Clear all reason bits so they won't be retained if the next reset * does not update the register. Besides, some bits are never cleared by * hardware so it's software's responsibility to clear them. * * Writing the value back effectively clears all reason bits as they are * write-1-to-clear.
*/
iowrite32(value, addr);
iounmap(addr);
for (i = 0; i < ARRAY_SIZE(s5_reset_reason_txt); i++) { if (!(value & BIT(i))) continue;
if (s5_reset_reason_txt[i]) {
pr_info("x86/amd: Previous system reset reason [0x%08x]: %s\n",
value, s5_reset_reason_txt[i]);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.