From 45ed991d964fb6b2d3978ead8c43e656e0bd7f71 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 27 Jul 2018 15:31:20 +0000 Subject: [PATCH] On amd64, enable workarounds for several Ryzen erratas as described in the AMD document 55449 'Revision Guide for AMD Family 17h Models 00h-0Fh Processors' rev 1.12. The errata numbers are mentioned near each action. It seems that newer BIOSes already include required chicken bits settings, so the magic MSR updates are only needed when BIOS cannot be updated. On the other hand, MWAIT avoidance seems to be important. Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/amd64/amd64/initcpu.c | 24 ++++++++++++++++++++++++ sys/x86/x86/cpu_machdep.c | 7 +++++++ 2 files changed, 31 insertions(+) diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c index ccc5e64d0c4..bb342f42dec 100644 --- a/sys/amd64/amd64/initcpu.c +++ b/sys/amd64/amd64/initcpu.c @@ -130,6 +130,30 @@ init_amd(void) } } + /* Ryzen erratas. */ + if (CPUID_TO_FAMILY(cpu_id) == 0x17 && CPUID_TO_MODEL(cpu_id) == 0x1 && + (cpu_feature2 & CPUID2_HV) == 0) { + /* 1021 */ + msr = rdmsr(0xc0011029); + msr |= 0x2000; + wrmsr(0xc0011029, msr); + + /* 1033 */ + msr = rdmsr(0xc0011020); + msr |= 0x10; + wrmsr(0xc0011020, msr); + + /* 1049 */ + msr = rdmsr(0xc0011028); + msr |= 0x10; + wrmsr(0xc0011028, msr); + + /* 1095 */ + msr = rdmsr(0xc0011020); + msr |= 0x200000000000000; + wrmsr(0xc0011020, msr); + } + /* * Work around a problem on Ryzen that is triggered by executing * code near the top of user memory, in our case the signal diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c index d897d518cbc..3416f949686 100644 --- a/sys/x86/x86/cpu_machdep.c +++ b/sys/x86/x86/cpu_machdep.c @@ -709,6 +709,13 @@ cpu_idle_tun(void *unused __unused) if (TUNABLE_STR_FETCH("machdep.idle", tunvar, sizeof(tunvar))) cpu_idle_selector(tunvar); + else if (cpu_vendor_id == CPU_VENDOR_AMD && + CPUID_TO_FAMILY(cpu_id) == 0x17 && CPUID_TO_MODEL(cpu_id) == 0x1) { + /* Ryzen erratas 1057, 1109. */ + cpu_idle_selector("hlt"); + idle_mwait = 0; + } + if (cpu_vendor_id == CPU_VENDOR_INTEL && cpu_id == 0x506c9) { /* * Apollo Lake errata APL31 (public errata APL30). -- 2.45.0