Set DE_CFG[9] -- a chickenbit which stops Zenbleed. The chickenbit may
authorderaadt <deraadt@openbsd.org>
Mon, 24 Jul 2023 14:53:58 +0000 (14:53 +0000)
committerderaadt <deraadt@openbsd.org>
Mon, 24 Jul 2023 14:53:58 +0000 (14:53 +0000)
have other side-effects (not disclosed by AMD), and firmwares fixes may
be better (and have other side-effects, same story).  Newer processors
will probably be validated more carefully by AMD.
Issue found by Tavis Ormandy.
This is errata 7.2/033_amdcpu.patch.sig and 7.3/011_amdcpu.patch.sig
Zenbleed also blocked on select cpus by using errata
7.3/012_amdfirmware.patch.sig + 7.3/013_amdcpufirmware.patch /
7.2/034_amdfirmware.patch.sig + 7.2/035_amdcpufirmware.patch.sig
which load AMD cpu firmwares (firmware.openbsd.org is updated often to
contain the best firmwares)
ok jsg

sys/arch/amd64/amd64/cpu.c
sys/arch/amd64/include/specialreg.h
sys/arch/i386/i386/machdep.c
sys/arch/i386/include/specialreg.h

index 9cee5a0..4d76672 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.c,v 1.171 2023/07/21 04:04:51 guenther Exp $      */
+/*     $OpenBSD: cpu.c,v 1.172 2023/07/24 14:53:58 deraadt Exp $       */
 /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
 
 /*-
@@ -1168,7 +1168,7 @@ void
 cpu_fix_msrs(struct cpu_info *ci)
 {
        int family = ci->ci_family;
-       uint64_t msr;
+       uint64_t msr, nmsr;
 
        if (!strcmp(cpu_vendor, "GenuineIntel")) {
                if ((family > 6 || (family == 6 && ci->ci_model >= 0xd)) &&
@@ -1211,11 +1211,16 @@ cpu_fix_msrs(struct cpu_info *ci)
                 * where LFENCE is always serializing.
                 */
                if (family >= 0x10 && family != 0x11) {
-                       msr = rdmsr(MSR_DE_CFG);
-                       if ((msr & DE_CFG_SERIALIZE_LFENCE) == 0) {
-                               msr |= DE_CFG_SERIALIZE_LFENCE;
-                               wrmsr(MSR_DE_CFG, msr);
-                       }
+                       nmsr = msr = rdmsr(MSR_DE_CFG);
+                       nmsr |= DE_CFG_SERIALIZE_LFENCE;
+                       if (msr != nmsr)
+                               wrmsr(MSR_DE_CFG, nmsr);
+               }
+               if (family == 0x17 && ci->ci_model >= 0x31) {
+                       nmsr = msr = rdmsr(MSR_DE_CFG);
+                       nmsr |= DE_CFG_SERIALIZE_9;
+                       if (msr != nmsr)
+                               wrmsr(MSR_DE_CFG, nmsr);
                }
        }
 
index f639379..db5d02a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: specialreg.h,v 1.104 2023/07/21 04:04:51 guenther Exp $       */
+/*     $OpenBSD: specialreg.h,v 1.105 2023/07/24 14:54:00 deraadt Exp $        */
 /*     $NetBSD: specialreg.h,v 1.1 2003/04/26 18:39:48 fvdl Exp $      */
 /*     $NetBSD: x86/specialreg.h,v 1.2 2003/04/25 21:54:30 fvdl Exp $  */
 
 #define MSR_DE_CFG     0xc0011029      /* Decode Configuration */
 #define        DE_CFG_721      0x00000001      /* errata 721 */
 #define DE_CFG_SERIALIZE_LFENCE        (1 << 1)        /* Enable serializing lfence */
+#define DE_CFG_SERIALIZE_9 (1 << 9)    /* Zenbleed chickenbit */
 
 #define IPM_C1E_CMP_HLT        0x10000000
 #define IPM_SMI_CMP_HLT        0x08000000
index 14949a6..6ef885c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: machdep.c,v 1.663 2023/01/30 10:49:05 jsg Exp $       */
+/*     $OpenBSD: machdep.c,v 1.664 2023/07/24 14:54:00 deraadt Exp $   */
 /*     $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $    */
 
 /*-
@@ -1639,6 +1639,7 @@ identifycpu(struct cpu_info *ci)
        char *cpu_device = ci->ci_dev->dv_xname;
        int skipspace;
        extern uint32_t cpu_meltdown;
+       uint64_t msr, nmsr;
 
        if (cpuid_level == -1) {
                name = "486DX";
@@ -1987,13 +1988,16 @@ identifycpu(struct cpu_info *ci)
         */
        if (!strcmp(cpu_vendor, "AuthenticAMD")) {
                if (ci->ci_family >= 0x10 && ci->ci_family != 0x11) {
-                       uint64_t msr;
-
-                       msr = rdmsr(MSR_DE_CFG);
-                       if ((msr & DE_CFG_SERIALIZE_LFENCE) == 0) {
-                               msr |= DE_CFG_SERIALIZE_LFENCE;
-                               wrmsr(MSR_DE_CFG, msr);
-                       }
+                       nmsr = msr = rdmsr(MSR_DE_CFG);
+                       nmsr |= DE_CFG_SERIALIZE_LFENCE;
+                       if (msr != nmsr)
+                               wrmsr(MSR_DE_CFG, nmsr);
+               }
+               if (family == 0x17 && ci->ci_model >= 0x31) {
+                       nmsr = msr = rdmsr(MSR_DE_CFG);
+                       nmsr |= DE_CFG_SERIALIZE_9;
+                       if (msr != nmsr)
+                               wrmsr(MSR_DE_CFG, nmsr);
                }
        }
 
index cbf5fab..3e90b17 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: specialreg.h,v 1.82 2023/07/21 04:04:52 guenther Exp $        */
+/*     $OpenBSD: specialreg.h,v 1.83 2023/07/24 14:54:00 deraadt Exp $ */
 /*     $NetBSD: specialreg.h,v 1.7 1994/10/27 04:16:26 cgd Exp $       */
 
 /*-
 #define MSR_DE_CFG     0xc0011029              /* Decode Configuration */
 #define        DE_CFG_721      0x00000001      /* errata 721 */
 #define        DE_CFG_SERIALIZE_LFENCE (1 << 1)        /* Enable serializing lfence */
+#define DE_CFG_SERIALIZE_9 (1 << 9)            /* Zenbleed chickenbit */
 
 #define IPM_C1E_CMP_HLT        0x10000000
 #define IPM_SMI_CMP_HLT        0x08000000