All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kai Huang <kaih.linux@gmail.com>
To: pbonzini@redhat.com, rkrcmar@redhat.com, kvm@vger.kernel.org
Subject: [PATCH 03/10] kvm: vmx: detect presence of host SGX driver
Date: Mon,  8 May 2017 17:24:26 +1200	[thread overview]
Message-ID: <20170508052434.3627-4-kai.huang@linux.intel.com> (raw)
In-Reply-To: <20170508052434.3627-1-kai.huang@linux.intel.com>

At host side there's SGX driver which serves host SGX applications. It detects
SGX feature and manages all EPC pages. KVM needs to co-work with SGX driver in
terms of EPC management, because they are both EPC consumers. We should go for
'unified model', in which SGX driver manages all EPC pages and KVM simply calls
driver's APIs to allocate/free EPC page, etc. However KVM cannot call driver's
APIs directly, as on machines without SGX feature, SGX driver won't be loaded,
and calling driver's APIs directly will make KVM unable to be loaded either.
Instead, KVM uses symbol_get to get driver's APIs at runtime thus avoids this
issue.

This patch adds new functions to initialize and destroy KVM SGX support, where
currently KVM simply calls symbol_get{put} for all necessary driver's APIs.
The symbols will only be released when KVM exits to prevent SGX driver being
unloaded during KVM's lifetime. Note KVM compeletely trusts SGX driver in SGX
feature and EPC resource detection and won't detect SGX by itself.

Two new files arch/x86/kvm/sgx.c{h} are added for holding bulk of KVM SGX code.

Signed-off-by: Kai Huang <kai.huang@linux.intel.com>
---
 arch/x86/kvm/Makefile |   2 +-
 arch/x86/kvm/sgx.c    | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/x86/kvm/sgx.h    |  34 +++++++++++
 arch/x86/kvm/vmx.c    |  10 ++++
 4 files changed, 208 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/kvm/sgx.c
 create mode 100644 arch/x86/kvm/sgx.h

diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index 3bff20710471..015712e666fd 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -17,7 +17,7 @@ kvm-y			+= x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
 
 kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT)	+= assigned-dev.o iommu.o
 
-kvm-intel-y		+= vmx.o pmu_intel.o
+kvm-intel-y		+= vmx.o pmu_intel.o sgx.o
 kvm-amd-y		+= svm.o pmu_amd.o
 
 obj-$(CONFIG_KVM)	+= kvm.o
diff --git a/arch/x86/kvm/sgx.c b/arch/x86/kvm/sgx.c
new file mode 100644
index 000000000000..4b65b1bb1f30
--- /dev/null
+++ b/arch/x86/kvm/sgx.c
@@ -0,0 +1,163 @@
+/*
+ * KVM SGX Virtualization support.
+ *
+ * Copyright (c) 2015, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * Author:	Kai Huang <kai.huang@linux.intel.com>
+ */
+
+#include <linux/kvm_host.h>
+#include <asm/cpufeature.h>	/* boot_cpu_has */
+#include <asm/processor.h>	/* cpuid */
+#include <linux/smp.h>
+#include <linux/module.h>
+#include "sgx.h"
+
+/* Debug helpers... */
+#define	sgx_debug(fmt, ...)	\
+	printk(KERN_DEBUG "KVM: SGX: %s: "fmt, __func__, ## __VA_ARGS__)
+#define	sgx_info(fmt, ...)	\
+	printk(KERN_INFO "KVM: SGX: "fmt, ## __VA_ARGS__)
+#define	sgx_err(fmt, ...)	\
+	printk(KERN_ERR "KVM: SGX: "fmt, ## __VA_ARGS__)
+
+/*
+ * EPC pages are managed by SGX driver. KVM needs to call SGX driver's APIs
+ * to allocate/free EPC page, etc.
+ *
+ * However KVM cannot call SGX driver's APIs directly. As on machine without
+ * SGX support, SGX driver cannot be loaded, therefore if KVM calls driver's
+ * APIs directly, KVM won't be able to be loaded either, which is not
+ * acceptable. Instead, KVM uses symbol_get{put} pair to get driver's APIs
+ * at runtime and simply disable SGX if those symbols cannot be found.
+ */
+struct required_sgx_driver_symbols {
+	struct sgx_epc_page *(*alloc_epc_page)(unsigned int flags);
+	/*
+	 * Currently SGX driver's sgx_free_page has 'struct sgx_encl *encl'
+	 * as parameter. We need to honor that.
+	 */
+	int (*free_epc_page)(struct sgx_epc_page *epg, struct sgx_encl *encl);
+	/*
+	 * get/put (map/unmap) kernel virtual address of given EPC page.
+	 * The namings are aligned to SGX driver's APIs.
+	 */
+	void *(*get_epc_page)(struct sgx_epc_page *epg);
+	void (*put_epc_page)(void *epc_page_vaddr);
+};
+
+static struct required_sgx_driver_symbols sgx_driver_symbols = {
+	.alloc_epc_page = NULL,
+	.free_epc_page = NULL,
+	.get_epc_page = NULL,
+	.put_epc_page = NULL,
+};
+
+static inline struct sgx_epc_page *sgx_alloc_epc_page(unsigned int flags)
+{
+	struct sgx_epc_page *epg;
+
+	BUG_ON(!sgx_driver_symbols.alloc_epc_page);
+
+	epg = sgx_driver_symbols.alloc_epc_page(flags);
+
+	/* sgx_alloc_page returns ERR_PTR(error_code) instead of NULL */
+	return IS_ERR_OR_NULL(epg) ? NULL : epg;
+}
+
+static inline void sgx_free_epc_page(struct sgx_epc_page *epg)
+{
+	BUG_ON(!sgx_driver_symbols.free_epc_page);
+
+	sgx_driver_symbols.free_epc_page(epg, NULL);
+}
+
+static inline void *sgx_kmap_epc_page(struct sgx_epc_page *epg)
+{
+	BUG_ON(!sgx_driver_symbols.get_epc_page);
+
+	return sgx_driver_symbols.get_epc_page(epg);
+}
+
+static inline void sgx_kunmap_epc_page(void *addr)
+{
+	BUG_ON(!sgx_driver_symbols.put_epc_page);
+
+	sgx_driver_symbols.put_epc_page(addr);
+}
+
+static inline u64 sgx_epc_page_to_pfn(struct sgx_epc_page *epg)
+{
+	return (u64)(epg->pa >> PAGE_SHIFT);
+}
+
+static void put_sgx_driver_symbols(void);
+
+static int get_sgx_driver_symbols(void)
+{
+	sgx_driver_symbols.alloc_epc_page = symbol_get(sgx_alloc_page);
+	if (!sgx_driver_symbols.alloc_epc_page)
+		goto error;
+	sgx_driver_symbols.free_epc_page = symbol_get(sgx_free_page);
+	if (!sgx_driver_symbols.free_epc_page)
+		goto error;
+	sgx_driver_symbols.get_epc_page = symbol_get(sgx_get_page);
+	if (!sgx_driver_symbols.get_epc_page)
+		goto error;
+	sgx_driver_symbols.put_epc_page = symbol_get(sgx_put_page);
+	if (!sgx_driver_symbols.put_epc_page)
+		goto error;
+
+	return 0;
+
+error:
+	put_sgx_driver_symbols();
+	return -EFAULT;
+}
+
+static void put_sgx_driver_symbols(void)
+{
+	if (sgx_driver_symbols.alloc_epc_page)
+		symbol_put(sgx_alloc_page);
+	if (sgx_driver_symbols.free_epc_page)
+		symbol_put(sgx_free_page);
+	if (sgx_driver_symbols.get_epc_page)
+		symbol_put(sgx_get_page);
+	if (sgx_driver_symbols.put_epc_page)
+		symbol_put(sgx_put_page);
+
+	memset(&sgx_driver_symbols, 0, sizeof (sgx_driver_symbols));
+}
+
+int sgx_init(void)
+{
+	int r;
+
+	r = get_sgx_driver_symbols();
+	if (r) {
+		sgx_err("SGX driver is not loaded.\n");
+		return r;
+	}
+
+	sgx_info("SGX virtualization supported.\n");
+
+	return 0;
+}
+
+void sgx_destroy(void)
+{
+	put_sgx_driver_symbols();
+}
diff --git a/arch/x86/kvm/sgx.h b/arch/x86/kvm/sgx.h
new file mode 100644
index 000000000000..ff2766eeae33
--- /dev/null
+++ b/arch/x86/kvm/sgx.h
@@ -0,0 +1,34 @@
+/*
+ * KVM SGX Virtualization support.
+ *
+ * Copyright (c) 2015, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * Author:	Kai Huang <kai.huang@linux.intel.com>
+ */
+
+#ifndef	ARCH_X86_KVM_SGX_H
+#define	ARCH_X86_KVM_SGX_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/bitops.h>
+#include <linux/kvm_host.h>
+#include <asm/sgx.h>
+
+int sgx_init(void);
+void sgx_destroy(void);
+
+#endif
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 050a143414e1..4b368a0af9bd 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -52,6 +52,8 @@
 #include "trace.h"
 #include "pmu.h"
 
+#include "sgx.h"
+
 #define __ex(x) __kvm_handle_fault_on_reboot(x)
 #define __ex_clear(x, reg) \
 	____kvm_handle_fault_on_reboot(x, "xor " reg " , " reg)
@@ -11657,6 +11659,11 @@ static int __init vmx_init(void)
 	if (r)
 		return r;
 
+	if (enable_sgx) {
+		if (sgx_init())
+			enable_sgx = 0;
+	}
+
 #ifdef CONFIG_KEXEC_CORE
 	rcu_assign_pointer(crash_vmclear_loaded_vmcss,
 			   crash_vmclear_local_loaded_vmcss);
@@ -11672,6 +11679,9 @@ static void __exit vmx_exit(void)
 	synchronize_rcu();
 #endif
 
+	if (enable_sgx)
+		sgx_destroy();
+
 	kvm_exit();
 }
 
-- 
2.11.0

  parent reply	other threads:[~2017-05-08  5:24 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-08  5:24 [RFC PATCH 00/10] Basic KVM SGX Virtualization support Kai Huang
2017-05-08  5:24 ` [PATCH 01/10] x86: add SGX Launch Control definition to cpufeature Kai Huang
2017-05-08  5:24 ` [PATCH 02/10] kvm: vmx: add ENCLS VMEXIT detection Kai Huang
2017-05-08  5:24 ` Kai Huang [this message]
2017-05-08  5:24 ` [PATCH 04/10] kvm: sgx: new functions to init and destory SGX for guest Kai Huang
2017-05-08  5:24 ` [PATCH 05/10] kvm: x86: add KVM_GET_SUPPORTED_CPUID SGX support Kai Huang
2017-05-08  5:24 ` [PATCH 06/10] kvm: x86: add KVM_SET_CPUID2 " Kai Huang
2017-05-08  5:24 ` [PATCH 07/10] kvm: vmx: add SGX IA32_FEATURE_CONTROL MSR emulation Kai Huang
2017-05-08  5:24 ` [PATCH 08/10] kvm: vmx: add guest's IA32_SGXLEPUBKEYHASHn runtime switch support Kai Huang
2017-05-12  0:32   ` Huang, Kai
2017-05-12  3:28     ` [intel-sgx-kernel-dev] " Andy Lutomirski
2017-05-12  4:56       ` Huang, Kai
2017-05-12  6:11         ` Andy Lutomirski
2017-05-12 18:48           ` Christopherson, Sean J
2017-05-12 20:50             ` Christopherson, Sean J
2017-05-16  0:59             ` Huang, Kai
2017-05-16  1:22             ` Huang, Kai
2017-05-16  0:48           ` Huang, Kai
2017-05-16 14:21             ` Paolo Bonzini
2017-05-18  7:54               ` Huang, Kai
2017-05-18  8:58                 ` Paolo Bonzini
2017-05-17  0:09             ` Andy Lutomirski
2017-05-18  7:45               ` Huang, Kai
2017-06-06 20:52                 ` Huang, Kai
2017-06-06 21:22                   ` Andy Lutomirski
2017-06-06 22:51                     ` Huang, Kai
2017-06-07 14:45                       ` Cohen, Haim
2017-06-08 12:31                   ` Jarkko Sakkinen
2017-06-08 23:47                     ` Huang, Kai
2017-06-08 23:53                       ` Andy Lutomirski
2017-06-09 15:38                         ` Cohen, Haim
2017-06-10 12:23                       ` Jarkko Sakkinen
2017-06-11 22:45                         ` Huang, Kai
2017-06-12  8:36                           ` Jarkko Sakkinen
2017-06-12  9:53                             ` Huang, Kai
2017-06-12 16:24                               ` Andy Lutomirski
2017-06-12 22:08                                 ` Huang, Kai
2017-06-12 23:00                                   ` Andy Lutomirski
2017-06-16  3:46                                     ` Huang, Kai
2017-06-16  4:11                                       ` Andy Lutomirski
2017-06-16  4:33                                         ` Huang, Kai
2017-06-16  9:34                                           ` Huang, Kai
2017-06-16 16:03                                           ` Andy Lutomirski
2017-06-16 16:25                                           ` Andy Lutomirski
2017-06-16 16:31                                             ` Christopherson, Sean J
2017-06-16 16:43                                               ` Andy Lutomirski
2017-06-13 18:57                               ` Jarkko Sakkinen
2017-06-13 19:05                                 ` Jarkko Sakkinen
2017-06-13 20:13                                   ` Sean Christopherson
2017-06-14  9:37                                     ` Jarkko Sakkinen
2017-06-14 15:11                                       ` Christopherson, Sean J
2017-06-14 17:03                                         ` Jarkko Sakkinen
2017-06-13 23:28                                 ` Huang, Kai
2017-06-14  9:44                                   ` Jarkko Sakkinen
2017-07-19 15:04           ` Sean Christopherson
2017-05-15 12:46       ` Jarkko Sakkinen
2017-05-15 23:56         ` Huang, Kai
2017-05-16 14:23           ` Paolo Bonzini
2017-05-17 14:21           ` Sean Christopherson
2017-05-18  8:14             ` Huang, Kai
2017-05-20 21:55               ` Andy Lutomirski
2017-05-23  5:43                 ` Huang, Kai
2017-05-23  5:55                   ` Huang, Kai
2017-05-23 16:34                   ` Andy Lutomirski
2017-05-23 16:43                     ` Paolo Bonzini
2017-05-24  8:20                       ` Huang, Kai
2017-05-20 13:23           ` Jarkko Sakkinen
2017-05-08  5:24 ` [PATCH 09/10] kvm: vmx: handle ENCLS VMEXIT Kai Huang
2017-05-08  8:08   ` Paolo Bonzini
2017-05-10  1:30     ` Huang, Kai
2017-05-08  5:24 ` [PATCH 10/10] kvm: vmx: handle VMEXIT from SGX Enclave Kai Huang
2017-05-08  8:22   ` Paolo Bonzini
2017-05-11  9:34     ` Huang, Kai
2017-06-19  5:02       ` Huang, Kai
2017-06-27 15:29         ` Radim Krčmář
2017-06-28 22:22           ` Huang, Kai
2017-05-08  5:24 ` [PATCH 11/11] kvm: vmx: workaround FEATURE_CONTROL[17] is not set by BIOS Kai Huang
2017-05-08  5:29   ` Huang, Kai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170508052434.3627-4-kai.huang@linux.intel.com \
    --to=kaih.linux@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.