]> xenbits.xensource.com Git - people/dariof/xen.git/commitdiff
x86/pv: Options to disable and/or compile out 32bit PV support
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 17 Apr 2020 11:39:40 +0000 (12:39 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 29 Apr 2020 20:13:00 +0000 (21:13 +0100)
This is the start of some performance and security-hardening improvements,
based on the fact that 32bit PV guests are few and far between these days.

Ring1 is full of architectural corner cases, such as counting as supervisor
from a paging point of view.  This accounts for a substantial performance hit
on processors from the last 8 years (adjusting SMEP/SMAP on every privilege
transition), and the gap is only going to get bigger with new hardware
features.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Wei Liu <wl@xen.org>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
docs/misc/xen-command-line.pandoc
xen/arch/x86/Kconfig
xen/arch/x86/pv/domain.c
xen/arch/x86/setup.c
xen/include/asm-x86/pv/domain.h
xen/include/xen/param.h

index acd0b3d99446b5583696cb31d2e3e3d10cb7a37d..ee12b0f53f69d55e2326f030edb5ea5f9a140200 100644 (file)
@@ -1694,7 +1694,17 @@ The following resources are available:
     CDP, one COS will corespond two CBMs other than one with CAT, due to the
     sum of CBMs is fixed, that means actual `cos_max` in use will automatically
     reduce to half when CDP is enabled.
-       
+
+### pv
+    = List of [ 32=<bool> ]
+
+    Applicability: x86
+
+Controls for aspects of PV guest support.
+
+*   The `32` boolean controls whether 32bit PV guests can be created.  It
+    defaults to `true`, and is ignored when `CONFIG_PV32` is compiled out.
+
 ### pv-linear-pt (x86)
 > `= <boolean>`
 
index a69be983d6f3aa02dbec60754a2c71b2b441850e..96432f1f69ac02fdeb6534a651577ea4325a80c9 100644 (file)
@@ -49,6 +49,22 @@ config PV
 
          If unsure, say Y.
 
+config PV32
+       bool "Support for 32bit PV guests"
+       depends on PV
+       default y
+       ---help---
+         The 32bit PV ABI uses Ring1, an area of the x86 architecture which
+         was deprecated and mostly removed in the AMD64 spec.  As a result,
+         it occasionally conflicts with newer x86 hardware features, causing
+         overheads for Xen to maintain backwards compatibility.
+
+         People may wish to disable 32bit PV guests for attack surface
+         reduction, or performance reasons.  Backwards compatibility can be
+         provided via the PV Shim mechanism.
+
+         If unsure, say Y.
+
 config PV_LINEAR_PT
        bool "Support for PV linear pagetables"
        depends on PV
index 43da5c179f7a2e33095dee99fc9becddfee15187..3579dc063ea5ea7d9e7d1f29edca52bb4c7c2039 100644 (file)
 #include <asm/pv/domain.h>
 #include <asm/shadow.h>
 
+#ifdef CONFIG_PV32
+int8_t __read_mostly opt_pv32 = -1;
+#endif
+
+static __init int parse_pv(const char *s)
+{
+    const char *ss;
+    int val, rc = 0;
+
+    do {
+        ss = strchr(s, ',');
+        if ( !ss )
+            ss = strchr(s, '\0');
+
+        if ( (val = parse_boolean("32", s, ss)) >= 0 )
+        {
+#ifdef CONFIG_PV32
+            opt_pv32 = val;
+#else
+            no_config_param("PV32", "pv", s, ss);
+#endif
+        }
+        else
+            rc = -EINVAL;
+
+        s = ss + 1;
+    } while ( *ss );
+
+    return rc;
+}
+custom_param("pv", parse_pv);
+
 static __read_mostly enum {
     PCID_OFF,
     PCID_ALL,
@@ -174,6 +206,8 @@ int switch_compat(struct domain *d)
 
     BUILD_BUG_ON(offsetof(struct shared_info, vcpu_info) != 0);
 
+    if ( !opt_pv32 )
+        return -EOPNOTSUPP;
     if ( is_hvm_domain(d) || domain_tot_pages(d) != 0 )
         return -EACCES;
     if ( is_pv_32bit_domain(d) )
index eb56d78c2fbec3c7feb9bee26d08254bbb85ddcc..9e9576344c50eb1745c75701b9badcf2b5f236a9 100644 (file)
@@ -53,6 +53,7 @@
 #include <asm/spec_ctrl.h>
 #include <asm/guest.h>
 #include <asm/microcode.h>
+#include <asm/pv/domain.h>
 
 /* opt_nosmp: If true, secondary processors are ignored. */
 static bool __initdata opt_nosmp;
@@ -1870,8 +1871,12 @@ void arch_get_xen_caps(xen_capabilities_info_t *info)
     {
         snprintf(s, sizeof(s), "xen-%d.%d-x86_64 ", major, minor);
         safe_strcat(*info, s);
-        snprintf(s, sizeof(s), "xen-%d.%d-x86_32p ", major, minor);
-        safe_strcat(*info, s);
+
+        if ( opt_pv32 )
+        {
+            snprintf(s, sizeof(s), "xen-%d.%d-x86_32p ", major, minor);
+            safe_strcat(*info, s);
+        }
     }
     if ( hvm_enabled )
     {
index 7a69bfb303020ea6ec74d5de9cd554a9b4c05079..df9716ff26a87651ad181c808e468743ba8391ba 100644 (file)
 
 #include <xen/sched.h>
 
+#ifdef CONFIG_PV32
+extern int8_t opt_pv32;
+#else
+# define opt_pv32 false
+#endif
+
 /*
  * PCID values for the address spaces of 64-bit pv domains:
  *
index d4578cd27f42db5b500390844cca76fc12e590d4..a1dc3ba8f02447c6a074516e9335b7a1199764a3 100644 (file)
@@ -127,4 +127,13 @@ extern const struct kernel_param __param_start[], __param_end[];
     string_param(_name, _var); \
     string_runtime_only_param(_name, _var)
 
+static inline void no_config_param(const char *cfg, const char *param,
+                                   const char *s, const char *e)
+{
+    int len = e ? ({ ASSERT(e >= s); e - s; }) : strlen(s);
+
+    printk(XENLOG_INFO "CONFIG_%s disabled - ignoring '%s=%*s' setting\n",
+           cfg, param, len, s);
+}
+
 #endif /* _XEN_PARAM_H */