[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen staging-4.10] x86/spec-ctrl: Introduce an option to control L1TF mitigation for PV guests



commit 614fd2558f4183755e8fe6259f108698ee2bb131
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Mon Jul 23 13:46:10 2018 +0000
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Tue Aug 14 17:16:28 2018 +0100

    x86/spec-ctrl: Introduce an option to control L1TF mitigation for PV guests
    
    Shadowing a PV guest is only available when shadow paging is compiled in.
    When shadow paging isn't available, guests can be crashed instead as
    mitigation from Xen's point of view.
    
    Ideally, dom0 would also be potentially-shadowed-by-default, but dom0 has
    never been shadowed before, and there are some stability issues under
    investigation.
    
    This is part of XSA-273 / CVE-2018-3620.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    (cherry picked from commit 66a4e986819a86ba66ca2fe9d925e62a4fd30114)
---
 docs/misc/xen-command-line.markdown | 24 ++++++++++
 xen/arch/x86/Kconfig                |  1 +
 xen/arch/x86/spec_ctrl.c            | 89 +++++++++++++++++++++++++++++++++++--
 xen/include/asm-x86/spec_ctrl.h     |  4 ++
 4 files changed, 115 insertions(+), 3 deletions(-)

diff --git a/docs/misc/xen-command-line.markdown 
b/docs/misc/xen-command-line.markdown
index 4dae02475d..2a1b8e159d 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -1528,6 +1528,30 @@ do; there may be other custom operating systems which 
do.  If you're
 certain you don't plan on having PV guests which use this feature,
 turning it off can reduce the attack surface.
 
+### pv-l1tf (x86)
+> `= List of [ <bool>, dom0=<bool>, domu=<bool> ]`
+
+> Default: `false` on believed-unaffected hardware, or in pv-shim mode.
+>          `domu`  on believed-affected hardware.
+
+Mitigations for L1TF / XSA-273 / CVE-2018-3620 for PV guests.
+
+For backwards compatibility, we may not alter an architecturally-legitimate
+pagetable entry a PV guest chooses to write.  We can however force such a
+guest into shadow mode so that Xen controls the PTEs which are reachable by
+the CPU pagewalk.
+
+Shadowing is performed at the point where a PV guest first tries to write an
+L1TF-vulnerable PTE.  Therefore, a PV guest kernel which has been updated with
+its own L1TF mitigations will not trigger shadow mode if it is well behaved.
+
+If CONFIG\_SHADOW\_PAGING is not compiled in, this mitigation instead crashes
+the guest when an L1TF-vulnerable PTE is written, which still allows updated,
+well-behaved PV guests to run, despite Shadow being compiled out.
+
+In the pv-shim case, Shadow is expected to be compiled out, and a malicious
+guest kernel can only leak data from the shim Xen, rather than the host Xen.
+
 ### pv-shim (x86)
 > `= <boolean>`
 
diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
index f621e799ed..33535ca9aa 100644
--- a/xen/arch/x86/Kconfig
+++ b/xen/arch/x86/Kconfig
@@ -71,6 +71,7 @@ config SHADOW_PAGING
             * Running HVM guests on hardware lacking hardware paging support
               (First-generation Intel VT-x or AMD SVM).
             * Live migration of PV guests.
+            * L1TF sidechannel mitigation for PV guests.
 
           Under a small number of specific workloads, shadow paging may be
           deliberately used as a performance optimisation.
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index eaac103bc3..aa1b3ac91b 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -23,6 +23,7 @@
 #include <asm/microcode.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
+#include <asm/pv/shim.h>
 #include <asm/spec_ctrl.h>
 #include <asm/spec_ctrl_asm.h>
 
@@ -187,6 +188,55 @@ static int __init parse_spec_ctrl(const char *s)
 }
 custom_param("spec-ctrl", parse_spec_ctrl);
 
+int8_t __read_mostly opt_pv_l1tf = -1;
+
+static __init int parse_pv_l1tf(const char *s)
+{
+    const char *ss;
+    int val, rc = 0;
+
+    /* Inhibit the defaults as an explicit choice has been given. */
+    if ( opt_pv_l1tf == -1 )
+        opt_pv_l1tf = 0;
+
+    /* Interpret 'pv-l1tf' alone in its positive boolean form. */
+    if ( *s == '\0' )
+        opt_xpti = OPT_PV_L1TF_DOM0 | OPT_PV_L1TF_DOMU;
+
+    do {
+        ss = strchr(s, ',');
+        if ( !ss )
+            ss = strchr(s, '\0');
+
+        switch ( parse_bool(s, ss) )
+        {
+        case 0:
+            opt_pv_l1tf = 0;
+            break;
+
+        case 1:
+            opt_pv_l1tf = OPT_PV_L1TF_DOM0 | OPT_PV_L1TF_DOMU;
+            break;
+
+        default:
+            if ( (val = parse_boolean("dom0", s, ss)) >= 0 )
+                opt_pv_l1tf = ((opt_pv_l1tf & ~OPT_PV_L1TF_DOM0) |
+                               (val ? OPT_PV_L1TF_DOM0 : 0));
+            else if ( (val = parse_boolean("domu", s, ss)) >= 0 )
+                opt_pv_l1tf = ((opt_pv_l1tf & ~OPT_PV_L1TF_DOMU) |
+                               (val ? OPT_PV_L1TF_DOMU : 0));
+            else
+                rc = -EINVAL;
+            break;
+        }
+
+        s = ss + 1;
+    } while ( *ss );
+
+    return rc;
+}
+custom_param("pv-l1tf", parse_pv_l1tf);
+
 static void __init print_details(enum ind_thunk thunk, uint64_t caps)
 {
     unsigned int _7d0 = 0, e8b = 0, tmp;
@@ -210,9 +260,16 @@ static void __init print_details(enum ind_thunk thunk, 
uint64_t caps)
            (caps & ARCH_CAPS_RSBA)                  ? " RSBA"      : "",
            (caps & ARCH_CAPS_SSB_NO)                ? " SSB_NO"    : "");
 
-    /* Compiled-in support which pertains to BTI mitigations. */
-    if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
-        printk("  Compiled-in support: INDIRECT_THUNK\n");
+    /* Compiled-in support which pertains to mitigations. */
+    if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) || IS_ENABLED(CONFIG_SHADOW_PAGING) 
)
+        printk("  Compiled-in support:"
+#ifdef CONFIG_INDIRECT_THUNK
+               " INDIRECT_THUNK"
+#endif
+#ifdef CONFIG_SHADOW_PAGING
+               " SHADOW_PAGING"
+#endif
+               "\n");
 
     /* Settings for Xen's protection, irrespective of guests. */
     printk("  Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s, Other:%s\n",
@@ -226,6 +283,13 @@ static void __init print_details(enum ind_thunk thunk, 
uint64_t caps)
            (default_xen_spec_ctrl & SPEC_CTRL_SSBD)  ? " SSBD+" : " SSBD-",
            opt_ibpb                                  ? " IBPB"  : "");
 
+    /* L1TF diagnostics, printed if vulnerable or PV shadowing is in use. */
+    if ( cpu_has_bug_l1tf || opt_pv_l1tf )
+        printk("  L1TF: believed%s vulnerable, maxphysaddr L1D %u, CPUID %u"
+               ", Safe address %"PRIx64"\n",
+               cpu_has_bug_l1tf ? "" : " not",
+               l1d_maxphysaddr, paddr_bits, l1tf_safe_maddr);
+
     /*
      * Alternatives blocks for protecting against and/or virtualising
      * mitigation support for guests.
@@ -247,6 +311,10 @@ static void __init print_details(enum ind_thunk thunk, 
uint64_t caps)
     printk("  XPTI (64-bit PV only): Dom0 %s, DomU %s\n",
            opt_xpti & OPT_XPTI_DOM0 ? "enabled" : "disabled",
            opt_xpti & OPT_XPTI_DOMU ? "enabled" : "disabled");
+
+    printk("  PV L1TF shadowing: Dom0 %s, DomU %s\n",
+           opt_pv_l1tf & OPT_PV_L1TF_DOM0  ? "enabled"  : "disabled",
+           opt_pv_l1tf & OPT_PV_L1TF_DOMU  ? "enabled"  : "disabled");
 }
 
 /* Calculate whether Retpoline is known-safe on this CPU. */
@@ -770,6 +838,21 @@ void __init init_speculation_mitigations(void)
 
     l1tf_calculations(caps);
 
+    /*
+     * By default, enable PV domU L1TF mitigations on all L1TF-vulnerable
+     * hardware, except when running in shim mode.
+     *
+     * In shim mode, SHADOW is expected to be compiled out, and a malicious
+     * guest kernel can only attack the shim Xen, not the host Xen.
+     */
+    if ( opt_pv_l1tf == -1 )
+    {
+        if ( pv_shim || !cpu_has_bug_l1tf )
+            opt_pv_l1tf = 0;
+        else
+            opt_pv_l1tf = OPT_PV_L1TF_DOMU;
+    }
+
     print_details(thunk, caps);
 
     /*
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
index d7e8ed0f5f..cdf5737dc2 100644
--- a/xen/include/asm-x86/spec_ctrl.h
+++ b/xen/include/asm-x86/spec_ctrl.h
@@ -38,6 +38,10 @@ extern int8_t opt_xpti;
 #define OPT_XPTI_DOM0  0x01
 #define OPT_XPTI_DOMU  0x02
 
+extern int8_t opt_pv_l1tf;
+#define OPT_PV_L1TF_DOM0  0x01
+#define OPT_PV_L1TF_DOMU  0x02
+
 /*
  * The L1D address mask, which might be wider than reported in CPUID, and the
  * system physical address above which there are believed to be no cacheable
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.