From patchwork Thu Jun 20 00:30:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christopher Clark X-Patchwork-Id: 11005587 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7436976 for ; Thu, 20 Jun 2019 00:32:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 59363288BE for ; Thu, 20 Jun 2019 00:32:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4C6DB288CB; Thu, 20 Jun 2019 00:32:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 85611288BE for ; Thu, 20 Jun 2019 00:32:42 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hdkz5-0000A9-G3; Thu, 20 Jun 2019 00:31:23 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hdkz4-00009X-1s for xen-devel@lists.xenproject.org; Thu, 20 Jun 2019 00:31:22 +0000 X-Inumbo-ID: b9b198cf-92f2-11e9-8980-bc764e045a96 Received: from mail-io1-xd44.google.com (unknown [2607:f8b0:4864:20::d44]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id b9b198cf-92f2-11e9-8980-bc764e045a96; Thu, 20 Jun 2019 00:31:20 +0000 (UTC) Received: by mail-io1-xd44.google.com with SMTP id i10so127155iol.13 for ; Wed, 19 Jun 2019 17:31:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Vx7lhmTYaFpyhfeLiRC8+jqYuuCwLj5xxTvw1bCxbdw=; b=CDPzr4zF+hZv8Ais64ygWktsbiW0ERN+GrSU3nHkpvwQL9uAS6/BbzLZiREZT+QWIH HLWwmtf2VIqVU0v3AfOphwLQp4rtGisw2boVBEmhoT5TPxtQ/3gymGg3rphp+II1Kb6T ReX4bjGlv8poE2Qs9M+i3AL95L6fdQd3Zf77vdPhqHe1LugfN6RM1ylYBQ1O4k5bsBYv ucJPAQgBWZkMXXjQWcsnaSpSFdeXmHjvoX7RiIroCp7xPv82CXQgEyklxJqDESte4Gpq jzxzJSh3euzUDPTDJK6kA9KY5PHHxlzu/M3NkvTFRadlKBOQjdtCM/UsWSK1lbJ5xDLx n4/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Vx7lhmTYaFpyhfeLiRC8+jqYuuCwLj5xxTvw1bCxbdw=; b=CwecK+zw4ruoKTBPp6DcSOcbGUrXUfYtxF8pix/ZQZMLq40o1IZ1mryrE5E4v2dKNZ XtyR0uT+gDhusLrWHgjle6kCDMgwmmipKgKxPYSPWCxziyD5GT0gUuXFuovWbJ2V2QfB b0+UTeTLD75g7JtSC9tw7VOSbKojQ7L/lZJv0at5gwfXUX3NBfW0xGfHQAZoRi4aKzVs fvIRbwHKvPKpfgBDN1S2huM4Ud7FS7dJqXrL8zhFJ/Fk3csHznwa1Xazrck6hJahpixW IWgfobulf2rEw+NYeuE6T2QxvHHLhdwprABhwMlsCC1W3+doS9Cv6sdKVtkDCGtRXa4w YaCQ== X-Gm-Message-State: APjAAAWMYOtwvtbNqe0/xCakqLPZFB9dd/rMdzR+yebyQhiTKJRI/ulr UTI0xhw61yQxB2bsHZh7lCeFQpnYvko= X-Google-Smtp-Source: APXvYqw7oPcEQYXkmeDWyCvgkXsudPrwKOQ6iLQBbB7Aq0zQqWFFBy+FXDdGkavivTm0SZ2jaOUwnw== X-Received: by 2002:a5d:9b1a:: with SMTP id y26mr12033494ion.238.1560990679906; Wed, 19 Jun 2019 17:31:19 -0700 (PDT) Received: from desktop.ice.pyrology.org (static-50-53-74-115.bvtn.or.frontiernet.net. [50.53.74.115]) by smtp.gmail.com with ESMTPSA id e188sm22579016ioa.3.2019.06.19.17.31.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Jun 2019 17:31:19 -0700 (PDT) From: Christopher Clark To: xen-devel@lists.xenproject.org Date: Wed, 19 Jun 2019 17:30:47 -0700 Message-Id: <20190620003053.21993-4-christopher.w.clark@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190620003053.21993-1-christopher.w.clark@gmail.com> References: <20190620003053.21993-1-christopher.w.clark@gmail.com> Subject: [Xen-devel] [RFC 3/9] x86/nested: add nested_xen_version hypercall X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Rich Persaud , Tim Deegan , Julien Grall , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 +#include +#include +#include +#include +#include + +#include + +#include +#include + +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 @@ -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