Print this page
OS-7125 Need mitigation of L1TF (CVE-2018-3646)
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

@@ -2118,10 +2118,23 @@
         cpi->cpi_nthread_bits = ddi_fls(cpi->cpi_ncpu_per_chip /
             cpi->cpi_ncore_per_chip);
 }
 
 static void
+spec_l1d_flush_noop(void)
+{
+}
+
+static void
+spec_l1d_flush_msr(void)
+{
+        wrmsr(MSR_IA32_FLUSH_CMD, IA32_FLUSH_CMD_L1D);
+}
+
+void (*spec_l1d_flush)(void) = spec_l1d_flush_noop;
+
+static void
 cpuid_scan_security(cpu_t *cpu, uchar_t *featureset)
 {
         struct cpuid_info *cpi = cpu->cpu_m.mcpu_cpi;
 
         if (cpi->cpi_vendor == X86_VENDOR_AMD &&

@@ -2202,10 +2215,47 @@
                         add_x86_feature(featureset, X86FSET_SSBD);
 
                 if (ecp->cp_edx & CPUID_INTC_EDX_7_0_FLUSH_CMD)
                         add_x86_feature(featureset, X86FSET_FLUSH_CMD);
         }
+
+        if (cpu->cpu_id != 0)
+                return;
+
+        /*
+         * We're the boot CPU, so let's figure out our L1TF status.
+         *
+         * First, if this is a RDCL_NO CPU, then we are not vulnerable: we don't
+         * need to exclude with ht_acquire(), and we don't need to flush.
+         */
+        if (is_x86_feature(featureset, X86FSET_RDCL_NO)) {
+                extern int ht_exclusion;
+                ht_exclusion = 0;
+                spec_l1d_flush = spec_l1d_flush_noop;
+                membar_producer();
+                return;
+        }
+
+        /*
+         * If HT is enabled, we will need HT exclusion, as well as the flush on
+         * VM entry.  If HT isn't enabled, we still need at least the flush for
+         * the L1TF sequential case.
+         *
+         * However, if X86FSET_L1D_VM_NO is set, we're most likely running
+         * inside a VM ourselves, and we don't need the flush.
+         *
+         * If we don't have the FLUSH_CMD available at all, we'd better just
+         * hope HT is disabled.
+         */
+        if (is_x86_feature(featureset, X86FSET_FLUSH_CMD) &&
+            !is_x86_feature(featureset, X86FSET_L1D_VM_NO)) {
+                spec_l1d_flush = spec_l1d_flush_msr;
+        } else {
+                spec_l1d_flush = spec_l1d_flush_noop;
+        }
+
+        membar_producer();
 }
 
 /*
  * Setup XFeature_Enabled_Mask register. Required by xsave feature.
  */