[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 |