|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 05/17] x86: add a xpti command line parameter
Add a command line parameter for controlling Xen page table isolation
(XPTI): per default it is on for non-AMD systems in 64 bit pv domains.
Possible settings are:
- true: switched on even on AMD systems
- false: switched off for all
- nodom0: switched off for dom0
As we don't want to set XPTI for 32 bit pv domains we have to delay
XPTI initialization until XEN_DOMCTL_set_address_size has been called
for the domain. Dom0 needs a specific init call.
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
V3:
- move XPTI initialization call to XEN_DOMCTL_set_address_size handling
- move XPTI code into arch/x86/pv/xpti.c
- replace xpti flag in struct domain by pointer
- add is_*_xpti_active() helpers
---
docs/misc/xen-command-line.markdown | 18 ++++++
xen/arch/x86/domctl.c | 4 ++
xen/arch/x86/pv/Makefile | 1 +
xen/arch/x86/pv/dom0_build.c | 3 +
xen/arch/x86/pv/domain.c | 3 +
xen/arch/x86/pv/xpti.c | 111 ++++++++++++++++++++++++++++++++++++
xen/include/asm-x86/domain.h | 4 ++
xen/include/asm-x86/pv/mm.h | 20 +++++++
8 files changed, 164 insertions(+)
create mode 100644 xen/arch/x86/pv/xpti.c
diff --git a/docs/misc/xen-command-line.markdown
b/docs/misc/xen-command-line.markdown
index 6df39dae0b..f96bb6342d 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -1926,6 +1926,24 @@ In the case that x2apic is in use, this option switches
between physical and
clustered mode. The default, given no hint from the **FADT**, is cluster
mode.
+### xpti
+> `= nodom0 | default | <boolean>`
+
+> Default: `false` on AMD hardware, `true` everywhere else.
+
+> Can be modified at runtime
+
+Override default selection of whether to isolate 64-bit PV guest page
+tables.
+
+`true` activates page table isolation even on AMD hardware.
+
+`false` deactivates page table isolation on all systems.
+
+`nodom0` deactivates page table isolation for dom0.
+
+`default` switch to default settings.
+
### xsave
> `= <boolean>`
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 8fbbf3aeb3..0b448e411d 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -31,6 +31,7 @@
#include <xen/vm_event.h>
#include <public/vm_event.h>
#include <asm/mem_sharing.h>
+#include <asm/pv/mm.h>
#include <asm/xstate.h>
#include <asm/debugger.h>
#include <asm/psr.h>
@@ -610,6 +611,9 @@ long arch_do_domctl(
ret = switch_compat(d);
else
ret = -EINVAL;
+
+ if ( ret == 0 )
+ ret = xpti_domain_init(d);
break;
case XEN_DOMCTL_get_address_size:
diff --git a/xen/arch/x86/pv/Makefile b/xen/arch/x86/pv/Makefile
index 65bca04175..a12e4fbd1a 100644
--- a/xen/arch/x86/pv/Makefile
+++ b/xen/arch/x86/pv/Makefile
@@ -13,6 +13,7 @@ obj-y += mm.o
obj-y += ro-page-fault.o
obj-$(CONFIG_PV_SHIM) += shim.o
obj-y += traps.o
+obj-y += xpti.o
obj-bin-y += dom0_build.init.o
obj-bin-y += gpr_switch.o
diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c
index 0bd2f1bf90..6e7bc435ab 100644
--- a/xen/arch/x86/pv/dom0_build.c
+++ b/xen/arch/x86/pv/dom0_build.c
@@ -707,6 +707,9 @@ int __init dom0_construct_pv(struct domain *d,
cpu = p->processor;
}
+ if ( !is_pv_32bit_domain(d) )
+ xpti_domain_init(d);
+
d->arch.paging.mode = 0;
/* Set up CR3 value for write_ptbase */
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 2c784fb3cc..a007af94dd 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -10,6 +10,7 @@
#include <xen/sched.h>
#include <asm/pv/domain.h>
+#include <asm/pv/mm.h>
/* Override macros from asm/page.h to make them work with mfn_t */
#undef mfn_to_page
@@ -174,6 +175,8 @@ void pv_domain_destroy(struct domain *d)
free_xenheap_page(d->arch.pv_domain.gdt_ldt_l1tab);
d->arch.pv_domain.gdt_ldt_l1tab = NULL;
+
+ xpti_domain_destroy(d);
}
diff --git a/xen/arch/x86/pv/xpti.c b/xen/arch/x86/pv/xpti.c
new file mode 100644
index 0000000000..0b17d77d74
--- /dev/null
+++ b/xen/arch/x86/pv/xpti.c
@@ -0,0 +1,111 @@
+/******************************************************************************
+ * arch/x86/mm/xpti.c
+ *
+ * Xen Page Table Isolation support.
+ *
+ * Copyright (c) 2018 SUSE Linux GmbH (Juergen Gross)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/errno.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/sched.h>
+
+struct xpti_domain {
+ int pad;
+};
+
+static __read_mostly enum {
+ XPTI_DEFAULT,
+ XPTI_ON,
+ XPTI_OFF,
+ XPTI_NODOM0
+} opt_xpti = XPTI_DEFAULT;
+
+static int parse_xpti(const char *s)
+{
+ int rc = 0;
+
+ switch ( parse_bool(s, NULL) )
+ {
+ case 0:
+ opt_xpti = XPTI_OFF;
+ break;
+ case 1:
+ opt_xpti = XPTI_ON;
+ break;
+ default:
+ if ( !strcmp(s, "default") )
+ opt_xpti = XPTI_DEFAULT;
+ else if ( !strcmp(s, "nodom0") )
+ opt_xpti = XPTI_NODOM0;
+ else
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
+custom_runtime_param("xpti", parse_xpti);
+
+void xpti_domain_destroy(struct domain *d)
+{
+ xfree(d->arch.pv_domain.xpti);
+ d->arch.pv_domain.xpti = NULL;
+}
+
+int xpti_domain_init(struct domain *d)
+{
+ bool xpti = false;
+ int ret = 0;
+
+ if ( !is_pv_domain(d) || is_pv_32bit_domain(d) )
+ return 0;
+
+ switch ( opt_xpti )
+ {
+ case XPTI_OFF:
+ xpti = false;
+ break;
+ case XPTI_ON:
+ xpti = true;
+ break;
+ case XPTI_NODOM0:
+ xpti = boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
+ d->domain_id != 0 && d->domain_id != hardware_domid;
+ break;
+ case XPTI_DEFAULT:
+ xpti = boot_cpu_data.x86_vendor != X86_VENDOR_AMD;
+ break;
+ }
+
+ if ( !xpti )
+ return 0;
+
+ d->arch.pv_domain.xpti = xmalloc(struct xpti_domain);
+ if ( !d->arch.pv_domain.xpti )
+ {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ printk("Enabling Xen Pagetable protection (XPTI) for Domain %d\n",
+ d->domain_id);
+
+ done:
+ return ret;
+}
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 4679d5477d..b33c286807 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -247,6 +247,8 @@ struct time_scale {
u32 mul_frac;
};
+struct xpti_domain;
+
struct pv_domain
{
l1_pgentry_t **gdt_ldt_l1tab;
@@ -257,6 +259,8 @@ struct pv_domain
struct mapcache_domain mapcache;
struct cpuidmasks *cpuidmasks;
+
+ struct xpti_domain *xpti;
};
struct monitor_write_data {
diff --git a/xen/include/asm-x86/pv/mm.h b/xen/include/asm-x86/pv/mm.h
index 246b99014c..dfac89df0b 100644
--- a/xen/include/asm-x86/pv/mm.h
+++ b/xen/include/asm-x86/pv/mm.h
@@ -31,6 +31,19 @@ void pv_destroy_gdt(struct vcpu *v);
bool pv_map_ldt_shadow_page(unsigned int off);
bool pv_destroy_ldt(struct vcpu *v);
+int xpti_domain_init(struct domain *d);
+void xpti_domain_destroy(struct domain *d);
+
+static inline bool is_domain_xpti_active(const struct domain *d)
+{
+ return is_pv_domain(d) && d->arch.pv_domain.xpti;
+}
+
+static inline bool is_vcpu_xpti_active(const struct vcpu *v)
+{
+ return is_domain_xpti_active(v->domain);
+}
+
#else
#include <xen/errno.h>
@@ -52,6 +65,13 @@ static inline bool pv_map_ldt_shadow_page(unsigned int off)
{ return false; }
static inline bool pv_destroy_ldt(struct vcpu *v)
{ ASSERT_UNREACHABLE(); return false; }
+static inline int xpti_domain_init(struct domain *d) { return 0; }
+static inline void xpti_domain_destroy(struct domain *d) { }
+
+static inline bool is_domain_xpti_active(const struct domain *d)
+{ return false; }
+static inline bool is_vcpu_xpti_active(const struct vcpu *v) { return false; }
+
#endif
#endif /* __X86_PV_MM_H__ */
--
2.13.6
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |