]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
x86/spec-ctrl: introduce Address Space Isolation command line option
authorRoger Pau Monne <roger.pau@citrix.com>
Fri, 14 Jun 2024 11:07:31 +0000 (13:07 +0200)
committerRoger Pau Monne <roger.pau@citrix.com>
Tue, 10 Dec 2024 17:42:33 +0000 (18:42 +0100)
No functional change, as the option is not used.

Introduced new so newly added functionality is keyed on the option being
enabled, even if the feature is non-functional.

When ASI is enabled for PV domains, printing the usage of XPTI might be
omitted if it must be uniformly disabled given the usage of ASI.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Changes since v1:
 - Improve comments and documentation about what ASI provides.
 - Do not print the XPTI information if ASI is used for pv domUs and dom0 is
   PVH, or if ASI is used for both domU and dom0.

FWIW, I would print the state of XPTI uniformly, as otherwise I find the output
might be confusing for user expecting to assert the state of XPTI.

docs/misc/xen-command-line.pandoc
xen/arch/x86/include/asm/domain.h
xen/arch/x86/include/asm/spec_ctrl.h
xen/arch/x86/spec_ctrl.c

index 293dbc1a957ba6e668fd4d55d58e84f643822126..c7241b44db9c6f19b5e0cd06f168742b3b2e2c10 100644 (file)
@@ -2387,7 +2387,7 @@ By default SSBD will be mitigated at runtime (i.e `ssbd=runtime`).
 
 ### spec-ctrl (x86)
 > `= List of [ <bool>, xen=<bool>, {pv,hvm}=<bool>,
->              {msr-sc,rsb,verw,{ibpb,bhb}-entry}=<bool>|{pv,hvm}=<bool>,
+>              {msr-sc,rsb,verw,{ibpb,bhb}-entry,asi}=<bool>|{pv,hvm}=<bool>,
 >              bti-thunk=retpoline|lfence|jmp,bhb-seq=short|tsx|long,
 >              {ibrs,ibpb,ssbd,psfd,
 >              eager-fpu,l1d-flush,branch-harden,srb-lock,
@@ -2414,10 +2414,10 @@ in place for guests to use.
 
 Use of a positive boolean value for either of these options is invalid.
 
-The `pv=`, `hvm=`, `msr-sc=`, `rsb=`, `verw=`, `ibpb-entry=` and `bhb-entry=`
-options offer fine grained control over the primitives by Xen.  These impact
-Xen's ability to protect itself, and/or Xen's ability to virtualise support
-for guests to use.
+The `pv=`, `hvm=`, `msr-sc=`, `rsb=`, `verw=`, `ibpb-entry=`, `bhb-entry=` and
+`asi=` options offer fine grained control over the primitives used by Xen.
+These impact Xen's ability to protect itself, and/or Xen's ability to
+virtualise support for guests to use.
 
 * `pv=` and `hvm=` offer control over all suboptions for PV and HVM guests
   respectively.
@@ -2449,6 +2449,11 @@ for guests to use.
   is not available (see `bhi-dis-s`).  The choice of scrubbing sequence can be
   selected using the `bhb-seq=` option.  If it is necessary to protect dom0
   too, boot with `spec-ctrl=bhb-entry`.
+* `asi=` offers control over whether the hypervisor will engage in Address
+  Space Isolation, by not having sensitive information permanently mapped in
+  the VMM page-tables.  Not having sensitive information permanently mapped on
+  the page-tables avoids having to perform some mitigations for speculative
+  attacks when context-switching to the hypervisor.
 
 If Xen was compiled with `CONFIG_INDIRECT_THUNK` support, `bti-thunk=` can be
 used to select which of the thunks gets patched into the
index 5af414fa64ac3c4516e4533f777f59ae1889fa68..e35b11ef260261ca8b986ee25303b9e9aa283af6 100644 (file)
@@ -456,6 +456,12 @@ struct arch_domain
     /* Don't unconditionally inject #GP for unhandled MSRs. */
     bool msr_relaxed;
 
+    /*
+     * Run the guest without sensitive information permanently mapped in the
+     * VMM page-tables.
+     */
+    bool asi;
+
     /* Emulated devices enabled bitmap. */
     uint32_t emulation_flags;
 } __cacheline_aligned;
index 72347ef2b959731c38da17164ab2a3aa9d10f644..39963c00431254549e3fc811e62ecfb45a46e667 100644 (file)
@@ -88,6 +88,8 @@ extern uint8_t default_scf;
 
 extern int8_t opt_xpti_hwdom, opt_xpti_domu;
 
+extern int8_t opt_asi_pv, opt_asi_hwdom, opt_asi_hvm;
+
 extern bool cpu_has_bug_l1tf;
 extern int8_t opt_pv_l1tf_hwdom, opt_pv_l1tf_domu;
 
index 75a4177a75d2094eff0a33de6db50cd801f97e5e..fb45c92683d473923c8788133ba061d4a63174a0 100644 (file)
@@ -84,6 +84,11 @@ static bool __ro_after_init opt_verw_mmio;
 static int8_t __initdata opt_gds_mit = -1;
 static int8_t __initdata opt_div_scrub = -1;
 
+/* Address Space Isolation for PV/HVM. */
+int8_t __ro_after_init opt_asi_pv = -1;
+int8_t __ro_after_init opt_asi_hwdom = -1;
+int8_t __ro_after_init opt_asi_hvm = -1;
+
 static int __init cf_check parse_spec_ctrl(const char *s)
 {
     const char *ss;
@@ -145,6 +150,10 @@ static int __init cf_check parse_spec_ctrl(const char *s)
             opt_unpriv_mmio = false;
             opt_gds_mit = 0;
             opt_div_scrub = 0;
+
+            opt_asi_pv = 0;
+            opt_asi_hwdom = 0;
+            opt_asi_hvm = 0;
         }
         else if ( val > 0 )
             rc = -EINVAL;
@@ -164,6 +173,7 @@ static int __init cf_check parse_spec_ctrl(const char *s)
             opt_verw_pv = val;
             opt_ibpb_entry_pv = val;
             opt_bhb_entry_pv = val;
+            opt_asi_pv = val;
         }
         else if ( (val = parse_boolean("hvm", s, ss)) >= 0 )
         {
@@ -172,6 +182,7 @@ static int __init cf_check parse_spec_ctrl(const char *s)
             opt_verw_hvm = val;
             opt_ibpb_entry_hvm = val;
             opt_bhb_entry_hvm = val;
+            opt_asi_hvm = val;
         }
         else if ( (val = parse_boolean("msr-sc", s, ss)) != -1 )
         {
@@ -281,6 +292,27 @@ static int __init cf_check parse_spec_ctrl(const char *s)
                 break;
             }
         }
+        else if ( (val = parse_boolean("asi", s, ss)) != -1 )
+        {
+            switch ( val )
+            {
+            case 0:
+            case 1:
+                opt_asi_pv = opt_asi_hwdom = opt_asi_hvm = val;
+                break;
+
+            case -2:
+                s += strlen("asi=");
+                if ( (val = parse_boolean("pv", s, ss)) >= 0 )
+                    opt_asi_pv = val;
+                else if ( (val = parse_boolean("hvm", s, ss)) >= 0 )
+                    opt_asi_hvm = val;
+                else
+            default:
+                    rc = -EINVAL;
+                break;
+            }
+        }
 
         /* Xen's speculative sidechannel mitigation settings. */
         else if ( !strncmp(s, "bti-thunk=", 10) )
@@ -380,6 +412,13 @@ int8_t __ro_after_init opt_xpti_domu = -1;
 
 static __init void xpti_init_default(void)
 {
+    ASSERT(opt_asi_pv >= 0 && opt_asi_hwdom >= 0);
+    if ( (opt_xpti_hwdom == 1 || opt_xpti_domu == 1) && opt_asi_pv == 1 )
+    {
+        printk(XENLOG_ERR
+               "XPTI is incompatible with ASI - disabling ASI\n");
+        opt_asi_pv = 0;
+    }
     if ( (boot_cpu_data.x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON)) ||
          cpu_has_rdcl_no )
     {
@@ -391,9 +430,9 @@ static __init void xpti_init_default(void)
     else
     {
         if ( opt_xpti_hwdom < 0 )
-            opt_xpti_hwdom = 1;
+            opt_xpti_hwdom = !opt_asi_hwdom;
         if ( opt_xpti_domu < 0 )
-            opt_xpti_domu = 1;
+            opt_xpti_domu = !opt_asi_pv;
     }
 }
 
@@ -632,12 +671,13 @@ static void __init print_details(enum ind_thunk thunk)
      * mitigation support for guests.
      */
 #ifdef CONFIG_HVM
-    printk("  Support for HVM VMs:%s%s%s%s%s%s%s%s\n",
+    printk("  Support for HVM VMs:%s%s%s%s%s%s%s%s%s\n",
            (boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ||
             boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ||
             boot_cpu_has(X86_FEATURE_IBPB_ENTRY_HVM) ||
             opt_bhb_entry_hvm || amd_virt_spec_ctrl ||
-            opt_eager_fpu || opt_verw_hvm)           ? ""               : " None",
+            opt_eager_fpu || opt_verw_hvm ||
+            opt_asi_hvm)                             ? ""               : " None",
            boot_cpu_has(X86_FEATURE_SC_MSR_HVM)      ? " MSR_SPEC_CTRL" : "",
            (boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ||
             amd_virt_spec_ctrl)                      ? " MSR_VIRT_SPEC_CTRL" : "",
@@ -645,27 +685,30 @@ static void __init print_details(enum ind_thunk thunk)
            opt_eager_fpu                             ? " EAGER_FPU"     : "",
            opt_verw_hvm                              ? " VERW"          : "",
            boot_cpu_has(X86_FEATURE_IBPB_ENTRY_HVM)  ? " IBPB-entry"    : "",
-           opt_bhb_entry_hvm                         ? " BHB-entry"     : "");
+           opt_bhb_entry_hvm                         ? " BHB-entry"     : "",
+           opt_asi_hvm                               ? " ASI"           : "");
 
 #endif
 #ifdef CONFIG_PV
-    printk("  Support for PV VMs:%s%s%s%s%s%s%s\n",
+    printk("  Support for PV VMs:%s%s%s%s%s%s%s%s\n",
            (boot_cpu_has(X86_FEATURE_SC_MSR_PV) ||
             boot_cpu_has(X86_FEATURE_SC_RSB_PV) ||
             boot_cpu_has(X86_FEATURE_IBPB_ENTRY_PV) ||
-            opt_bhb_entry_pv ||
+            opt_bhb_entry_pv || opt_asi_pv ||
             opt_eager_fpu || opt_verw_pv)            ? ""               : " None",
            boot_cpu_has(X86_FEATURE_SC_MSR_PV)       ? " MSR_SPEC_CTRL" : "",
            boot_cpu_has(X86_FEATURE_SC_RSB_PV)       ? " RSB"           : "",
            opt_eager_fpu                             ? " EAGER_FPU"     : "",
            opt_verw_pv                               ? " VERW"          : "",
            boot_cpu_has(X86_FEATURE_IBPB_ENTRY_PV)   ? " IBPB-entry"    : "",
-           opt_bhb_entry_pv                          ? " BHB-entry"     : "");
+           opt_bhb_entry_pv                          ? " BHB-entry"     : "",
+           opt_asi_pv                                ? " ASI"           : "");
 
-    printk("  XPTI (64-bit PV only): Dom0 %s, DomU %s (with%s PCID)\n",
-           opt_xpti_hwdom ? "enabled" : "disabled",
-           opt_xpti_domu  ? "enabled" : "disabled",
-           xpti_pcid_enabled() ? "" : "out");
+    if ( !opt_asi_pv || (!opt_dom0_pvh && !opt_asi_hwdom) )
+        printk("  XPTI (64-bit PV only): Dom0 %s, DomU %s (with%s PCID)\n",
+               opt_xpti_hwdom ? "enabled" : "disabled",
+               opt_xpti_domu  ? "enabled" : "disabled",
+               xpti_pcid_enabled() ? "" : "out");
 
     printk("  PV L1TF shadowing: Dom0 %s, DomU %s\n",
            opt_pv_l1tf_hwdom ? "enabled"  : "disabled",
@@ -1752,6 +1795,9 @@ void spec_ctrl_init_domain(struct domain *d)
     if ( pv )
         d->arch.pv.xpti = is_hardware_domain(d) ? opt_xpti_hwdom
                                                 : opt_xpti_domu;
+
+    d->arch.asi = is_hardware_domain(d) ? opt_asi_hwdom
+                                        : pv ? opt_asi_pv : opt_asi_hvm;
 }
 
 void __init init_speculation_mitigations(void)
@@ -2048,6 +2094,19 @@ void __init init_speculation_mitigations(void)
          hw_smt_enabled && default_xen_spec_ctrl )
         setup_force_cpu_cap(X86_FEATURE_SC_MSR_IDLE);
 
+    /* Disable ASI by default until feature is finished. */
+    if ( opt_asi_pv == -1 )
+        opt_asi_pv = 0;
+    if ( opt_asi_hwdom == -1 )
+        opt_asi_hwdom = 0;
+    if ( opt_asi_hvm == -1 )
+        opt_asi_hvm = 0;
+
+    if ( opt_asi_pv || opt_asi_hvm )
+        warning_add(
+            "Address Space Isolation is not functional, this option is\n"
+            "intended to be used only for development purposes.\n");
+
     xpti_init_default();
 
     l1tf_calculations();