[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC 3/9] x86/nested: add nested_xen_version hypercall
Provides proxying to the host hypervisor for XENVER_version and XENVER_get_features ops. The nested PV interface is only enabled when Xen is not running as either the PV shim or booted as PVH, since the initialization performed within the hypervisor in those cases - ie. as a Xen guest - claims resources that are normally operated by the control domain. This nested hypercall only permits access from the control domain. The XSM policy hook implementation is deferred to a subsequent commit. Signed-off-by: Christopher Clark <christopher.clark@xxxxxxxxxx> --- xen/arch/x86/Kconfig | 22 +++++++ xen/arch/x86/guest/Makefile | 5 +- xen/arch/x86/guest/hypercall_page.S | 1 + xen/arch/x86/guest/xen-nested.c | 82 +++++++++++++++++++++++++++ xen/arch/x86/guest/xen.c | 5 +- xen/arch/x86/hypercall.c | 3 + xen/arch/x86/pv/hypercall.c | 3 + xen/include/asm-x86/guest/hypercall.h | 7 ++- xen/include/asm-x86/guest/xen.h | 10 ++++ xen/include/public/xen.h | 1 + xen/include/xen/hypercall.h | 6 ++ 11 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 xen/arch/x86/guest/xen-nested.c diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig index 31e5ffd2f2..e31e8d3434 100644 --- a/xen/arch/x86/Kconfig +++ b/xen/arch/x86/Kconfig @@ -207,6 +207,28 @@ config PV_SHIM_EXCLUSIVE option is only intended for use when building a dedicated PV Shim firmware, and will not function correctly in other scenarios. + If unsure, say N. + +config XEN_NESTED + bool "Xen PV driver interface for nested Xen" if EXPERT = "y" + depends on XEN_DETECT + ---help--- + Enables a second PV driver interface in the hypervisor to support running + two sets of PV drivers within a single privileged guest (eg. guest dom0) + of a system running Xen under Xen: + + 1) host set: frontends to access devices provided by lower hypervisor + 2) guest set: backends to support existing PV drivers in nested guest VMs + + This interface supports the host set of drivers and performs proxying of a + limited set of hypercall operations from the guest to the host hypervisor. + + This feature is for the guest hypervisor and is transparent to the + host hypervisor. Guest VMs of the guest hypervisor use the standard + PV driver interfaces and unmodified drivers. + + Feature is also known as "The Xen-Blanket", presented at Eurosys 2012. + If unsure, say N. endmenu diff --git a/xen/arch/x86/guest/Makefile b/xen/arch/x86/guest/Makefile index d3a7844e61..6d8b0186d4 100644 --- a/xen/arch/x86/guest/Makefile +++ b/xen/arch/x86/guest/Makefile @@ -1,5 +1,8 @@ -obj-$(CONFIG_XEN_GUEST) += hypercall_page.o +ifneq ($(filter y,$(CONFIG_XEN_GUEST) $(CONFIG_XEN_NESTED) $(CONFIG_PVH_GUEST)),) +obj-y += hypercall_page.o +endif obj-y += xen.o obj-$(CONFIG_XEN_GUEST) += xen-guest.o +obj-$(CONFIG_XEN_NESTED) += xen-nested.o obj-bin-$(CONFIG_PVH_GUEST) += pvh-boot.init.o diff --git a/xen/arch/x86/guest/hypercall_page.S b/xen/arch/x86/guest/hypercall_page.S index 6485e9150e..2b1e35803a 100644 --- a/xen/arch/x86/guest/hypercall_page.S +++ b/xen/arch/x86/guest/hypercall_page.S @@ -60,6 +60,7 @@ DECLARE_HYPERCALL(domctl) DECLARE_HYPERCALL(kexec_op) DECLARE_HYPERCALL(argo_op) DECLARE_HYPERCALL(xenpmu_op) +DECLARE_HYPERCALL(nested_xen_version) DECLARE_HYPERCALL(arch_0) DECLARE_HYPERCALL(arch_1) diff --git a/xen/arch/x86/guest/xen-nested.c b/xen/arch/x86/guest/xen-nested.c new file mode 100644 index 0000000000..744592aa0c --- /dev/null +++ b/xen/arch/x86/guest/xen-nested.c @@ -0,0 +1,82 @@ +/* + * arch/x86/guest/xen-nested.c + * + * Hypercall implementations for nested PV drivers interface. + * + * Copyright (c) 2019 Star Lab Corp + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <xen/config.h> +#include <xen/errno.h> +#include <xen/guest_access.h> +#include <xen/hypercall.h> +#include <xen/lib.h> +#include <xen/sched.h> + +#include <public/version.h> + +#include <asm/guest/hypercall.h> +#include <asm/guest/xen.h> + +extern char hypercall_page[]; + +/* xen_nested: support for nested PV interface enabled */ +static bool __read_mostly xen_nested; + +void xen_nested_enable(void) +{ + /* Fill the hypercall page. */ + wrmsrl(cpuid_ebx(hypervisor_cpuid_base() + 2), __pa(hypercall_page)); + + xen_nested = true; +} + +long do_nested_xen_version(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) +{ + long ret; + + if ( !xen_nested ) + return -ENOSYS; + + /* FIXME: apply XSM check here */ + if ( !is_control_domain(current->domain) ) + return -EPERM; + + gprintk(XENLOG_DEBUG, "Nested xen_version: %d.\n", cmd); + + switch ( cmd ) + { + case XENVER_version: + return xen_hypercall_xen_version(XENVER_version, 0); + + case XENVER_get_features: + { + xen_feature_info_t fi; + + if ( copy_from_guest(&fi, arg, 1) ) + return -EFAULT; + + ret = xen_hypercall_xen_version(XENVER_get_features, &fi); + if ( ret ) + return ret; + + if ( __copy_to_guest(arg, &fi, 1) ) + return -EFAULT; + + return 0; + } + + default: + gprintk(XENLOG_ERR, "Nested xen_version op %d not implemented.\n", cmd); + return -EOPNOTSUPP; + } +} diff --git a/xen/arch/x86/guest/xen.c b/xen/arch/x86/guest/xen.c index b0b603a11a..78a5f40b22 100644 --- a/xen/arch/x86/guest/xen.c +++ b/xen/arch/x86/guest/xen.c @@ -74,7 +74,10 @@ void __init probe_hypervisor(void) xen_detected = true; - xen_guest_enable(); + if ( pv_shim || pvh_boot ) + xen_guest_enable(); + else + xen_nested_enable(); } void __init hypervisor_print_info(void) diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/hypercall.c index d483dbaa6b..b22f0ca65a 100644 --- a/xen/arch/x86/hypercall.c +++ b/xen/arch/x86/hypercall.c @@ -72,6 +72,9 @@ const hypercall_args_t hypercall_args_table[NR_hypercalls] = #ifdef CONFIG_HVM ARGS(hvm_op, 2), ARGS(dm_op, 3), +#endif +#ifdef CONFIG_XEN_NESTED + ARGS(nested_xen_version, 2), #endif ARGS(mca, 1), ARGS(arch_1, 1), diff --git a/xen/arch/x86/pv/hypercall.c b/xen/arch/x86/pv/hypercall.c index 0c84c0b3a0..1e00d07273 100644 --- a/xen/arch/x86/pv/hypercall.c +++ b/xen/arch/x86/pv/hypercall.c @@ -83,6 +83,9 @@ const hypercall_table_t pv_hypercall_table[] = { #ifdef CONFIG_HVM HYPERCALL(hvm_op), COMPAT_CALL(dm_op), +#endif +#ifdef CONFIG_XEN_NESTED + HYPERCALL(nested_xen_version), #endif HYPERCALL(mca), HYPERCALL(arch_1), diff --git a/xen/include/asm-x86/guest/hypercall.h b/xen/include/asm-x86/guest/hypercall.h index d548816b30..86e11dd1d1 100644 --- a/xen/include/asm-x86/guest/hypercall.h +++ b/xen/include/asm-x86/guest/hypercall.h @@ -19,7 +19,7 @@ #ifndef __X86_XEN_HYPERCALL_H__ #define __X86_XEN_HYPERCALL_H__ -#ifdef CONFIG_XEN_GUEST +#if defined(CONFIG_XEN_GUEST) || defined (CONFIG_XEN_NESTED) #include <xen/types.h> @@ -123,6 +123,11 @@ static inline long xen_hypercall_hvm_op(unsigned int op, void *arg) return _hypercall64_2(long, __HYPERVISOR_hvm_op, op, arg); } +static inline long xen_hypercall_xen_version(unsigned int op, void *arg) +{ + return _hypercall64_2(long, __HYPERVISOR_xen_version, op, arg); +} + /* * Higher level hypercall helpers */ diff --git a/xen/include/asm-x86/guest/xen.h b/xen/include/asm-x86/guest/xen.h index 27c854ab8a..802aee5edb 100644 --- a/xen/include/asm-x86/guest/xen.h +++ b/xen/include/asm-x86/guest/xen.h @@ -43,6 +43,16 @@ static inline void hypervisor_print_info(void) { #endif /* CONFIG_XEN_DETECT */ +#ifdef CONFIG_XEN_NESTED + +void xen_nested_enable(void); + +#else + +static inline void xen_nested_enable(void) {} + +#endif /* CONFIG_XEN_NESTED */ + #ifdef CONFIG_XEN_GUEST #define XEN_shared_info ((struct shared_info *)fix_to_virt(FIX_XEN_SHARED_INFO)) diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index cb2917e74b..2f5ac5eedc 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -121,6 +121,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); #define __HYPERVISOR_argo_op 39 #define __HYPERVISOR_xenpmu_op 40 #define __HYPERVISOR_dm_op 41 +#define __HYPERVISOR_nested_xen_version 42 /* Architecture-specific hypercall definitions. */ #define __HYPERVISOR_arch_0 48 diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h index fc00a67448..15194002d6 100644 --- a/xen/include/xen/hypercall.h +++ b/xen/include/xen/hypercall.h @@ -150,6 +150,12 @@ do_dm_op( unsigned int nr_bufs, XEN_GUEST_HANDLE_PARAM(xen_dm_op_buf_t) bufs); +#ifdef CONFIG_XEN_NESTED +extern long do_nested_xen_version( + int cmd, + XEN_GUEST_HANDLE_PARAM(void) arg); +#endif + #ifdef CONFIG_COMPAT extern int -- 2.17.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |