From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
To: x86@kernel.org, linux-sgx@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>,
Jethro Beekman <jethro@fortanix.com>,
Haitao Huang <haitao.huang@linux.intel.com>,
Chunyang Hui <sanqian.hcy@antfin.com>,
Jordan Hand <jorhand@linux.microsoft.com>,
Nathaniel McCallum <npmccallum@redhat.com>,
Seth Moore <sethmo@google.com>,
Darren Kenny <darren.kenny@oracle.com>,
Sean Christopherson <sean.j.christopherson@intel.com>,
Suresh Siddha <suresh.b.siddha@intel.com>,
akpm@linux-foundation.org, andriy.shevchenko@linux.intel.com,
asapek@google.com, bp@alien8.de, cedric.xing@intel.com,
chenalexchen@google.com, conradparker@google.com,
cyhanish@google.com, dave.hansen@intel.com,
haitao.huang@intel.com, kai.huang@intel.com, kai.svahn@intel.com,
kmoy@google.com, ludloff@google.com, luto@kernel.org,
nhorman@redhat.com, puiterwijk@redhat.com, rientjes@google.com,
tglx@linutronix.de, yaozhangx@google.com, mikko.ylinen@intel.com
Subject: [PATCH v40 12/24] x86/sgx: Add SGX_IOC_ENCLAVE_CREATE
Date: Wed, 4 Nov 2020 16:54:18 +0200 [thread overview]
Message-ID: <20201104145430.300542-13-jarkko.sakkinen@linux.intel.com> (raw)
In-Reply-To: <20201104145430.300542-1-jarkko.sakkinen@linux.intel.com>
Add an ioctl() that performs ECREATE function of ENCLS instruction, which
creates SGX Enclave Control Structure (SECS).
Although the SECS is an in-memory data structure, it is present in enclave
memory and is not directly accessible by software.
Acked-by: Jethro Beekman <jethro@fortanix.com>
Tested-by: Jethro Beekman <jethro@fortanix.com>
Tested-by: Haitao Huang <haitao.huang@linux.intel.com>
Tested-by: Chunyang Hui <sanqian.hcy@antfin.com>
Tested-by: Jordan Hand <jorhand@linux.microsoft.com>
Tested-by: Nathaniel McCallum <npmccallum@redhat.com>
Tested-by: Seth Moore <sethmo@google.com>
Tested-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Co-developed-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Co-developed-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
Changes from v39:
* Remove sgx_validate_secs() and let ECREATE do the validation. If it
fails, return -EIO.
.../userspace-api/ioctl/ioctl-number.rst | 1 +
arch/x86/include/uapi/asm/sgx.h | 25 ++++
arch/x86/kernel/cpu/sgx/Makefile | 1 +
arch/x86/kernel/cpu/sgx/driver.c | 12 ++
arch/x86/kernel/cpu/sgx/driver.h | 3 +
arch/x86/kernel/cpu/sgx/encl.c | 8 ++
arch/x86/kernel/cpu/sgx/encl.h | 7 +
arch/x86/kernel/cpu/sgx/ioctl.c | 123 ++++++++++++++++++
8 files changed, 180 insertions(+)
create mode 100644 arch/x86/include/uapi/asm/sgx.h
create mode 100644 arch/x86/kernel/cpu/sgx/ioctl.c
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 55a2d9b2ce33..a4c75a28c839 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -323,6 +323,7 @@ Code Seq# Include File Comments
<mailto:tlewis@mindspring.com>
0xA3 90-9F linux/dtlk.h
0xA4 00-1F uapi/linux/tee.h Generic TEE subsystem
+0xA4 00-1F uapi/asm/sgx.h <mailto:linux-sgx@vger.kernel.org>
0xAA 00-3F linux/uapi/linux/userfaultfd.h
0xAB 00-1F linux/nbd.h
0xAC 00-1F linux/raw.h
diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h
new file mode 100644
index 000000000000..f31bb17e27c3
--- /dev/null
+++ b/arch/x86/include/uapi/asm/sgx.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Copyright(c) 2016-20 Intel Corporation.
+ */
+#ifndef _UAPI_ASM_X86_SGX_H
+#define _UAPI_ASM_X86_SGX_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define SGX_MAGIC 0xA4
+
+#define SGX_IOC_ENCLAVE_CREATE \
+ _IOW(SGX_MAGIC, 0x00, struct sgx_enclave_create)
+
+/**
+ * struct sgx_enclave_create - parameter structure for the
+ * %SGX_IOC_ENCLAVE_CREATE ioctl
+ * @src: address for the SECS page data
+ */
+struct sgx_enclave_create {
+ __u64 src;
+};
+
+#endif /* _UAPI_ASM_X86_SGX_H */
diff --git a/arch/x86/kernel/cpu/sgx/Makefile b/arch/x86/kernel/cpu/sgx/Makefile
index 3fc451120735..91d3dc784a29 100644
--- a/arch/x86/kernel/cpu/sgx/Makefile
+++ b/arch/x86/kernel/cpu/sgx/Makefile
@@ -1,4 +1,5 @@
obj-y += \
driver.o \
encl.o \
+ ioctl.o \
main.o
diff --git a/arch/x86/kernel/cpu/sgx/driver.c b/arch/x86/kernel/cpu/sgx/driver.c
index 248213dea78e..9878b542c616 100644
--- a/arch/x86/kernel/cpu/sgx/driver.c
+++ b/arch/x86/kernel/cpu/sgx/driver.c
@@ -88,10 +88,22 @@ static unsigned long sgx_get_unmapped_area(struct file *file,
return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
}
+#ifdef CONFIG_COMPAT
+static long sgx_compat_ioctl(struct file *filep, unsigned int cmd,
+ unsigned long arg)
+{
+ return sgx_ioctl(filep, cmd, arg);
+}
+#endif
+
static const struct file_operations sgx_encl_fops = {
.owner = THIS_MODULE,
.open = sgx_open,
.release = sgx_release,
+ .unlocked_ioctl = sgx_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = sgx_compat_ioctl,
+#endif
.mmap = sgx_mmap,
.get_unmapped_area = sgx_get_unmapped_area,
};
diff --git a/arch/x86/kernel/cpu/sgx/driver.h b/arch/x86/kernel/cpu/sgx/driver.h
index cda9c43b7543..a728e8e848bd 100644
--- a/arch/x86/kernel/cpu/sgx/driver.h
+++ b/arch/x86/kernel/cpu/sgx/driver.h
@@ -9,8 +9,11 @@
#include <linux/rwsem.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
+#include <uapi/asm/sgx.h>
#include "sgx.h"
+long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
+
int sgx_drv_init(void);
#endif /* __ARCH_X86_SGX_DRIVER_H__ */
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
index d47caa106350..dfcc306d297c 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
@@ -46,6 +46,7 @@ static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
struct sgx_encl_page *entry;
unsigned long phys_addr;
struct sgx_encl *encl;
+ unsigned long pfn;
vm_fault_t ret;
encl = vma->vm_private_data;
@@ -61,6 +62,13 @@ static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
phys_addr = sgx_get_epc_phys_addr(entry->epc_page);
+ /* Check if another thread got here first to insert the PTE. */
+ if (!follow_pfn(vma, addr, &pfn)) {
+ mutex_unlock(&encl->lock);
+
+ return VM_FAULT_NOPAGE;
+ }
+
ret = vmf_insert_pfn(vma, addr, PFN_DOWN(phys_addr));
if (ret != VM_FAULT_NOPAGE) {
mutex_unlock(&encl->lock);
diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h
index 8eb34e95feda..ad0d73f63bc9 100644
--- a/arch/x86/kernel/cpu/sgx/encl.h
+++ b/arch/x86/kernel/cpu/sgx/encl.h
@@ -26,9 +26,16 @@ struct sgx_encl_page {
struct sgx_encl *encl;
};
+enum sgx_encl_flags {
+ SGX_ENCL_IOCTL = BIT(0),
+ SGX_ENCL_DEBUG = BIT(1),
+ SGX_ENCL_CREATED = BIT(2),
+};
+
struct sgx_encl {
unsigned long base;
unsigned long size;
+ unsigned long flags;
unsigned int page_cnt;
unsigned int secs_child_cnt;
struct mutex lock;
diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
new file mode 100644
index 000000000000..1355490843d1
--- /dev/null
+++ b/arch/x86/kernel/cpu/sgx/ioctl.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2016-20 Intel Corporation. */
+
+#include <asm/mman.h>
+#include <linux/mman.h>
+#include <linux/delay.h>
+#include <linux/file.h>
+#include <linux/hashtable.h>
+#include <linux/highmem.h>
+#include <linux/ratelimit.h>
+#include <linux/sched/signal.h>
+#include <linux/shmem_fs.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include "driver.h"
+#include "encl.h"
+#include "encls.h"
+
+static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs)
+{
+ struct sgx_epc_page *secs_epc;
+ struct sgx_pageinfo pginfo;
+ struct sgx_secinfo secinfo;
+ unsigned long encl_size;
+ long ret;
+
+ /* The extra page goes to SECS. */
+ encl_size = secs->size + PAGE_SIZE;
+
+ secs_epc = __sgx_alloc_epc_page();
+ if (IS_ERR(secs_epc))
+ return PTR_ERR(secs_epc);
+
+ encl->secs.epc_page = secs_epc;
+
+ pginfo.addr = 0;
+ pginfo.contents = (unsigned long)secs;
+ pginfo.metadata = (unsigned long)&secinfo;
+ pginfo.secs = 0;
+ memset(&secinfo, 0, sizeof(secinfo));
+
+ ret = __ecreate((void *)&pginfo, sgx_get_epc_virt_addr(secs_epc));
+ if (ret) {
+ ret = -EIO;
+ goto err_out;
+ }
+
+ if (secs->attributes & SGX_ATTR_DEBUG)
+ set_bit(SGX_ENCL_DEBUG, &encl->flags);
+
+ encl->secs.encl = encl;
+ encl->base = secs->base;
+ encl->size = secs->size;
+
+ /* Set only after completion, as encl->lock has not been taken. */
+ set_bit(SGX_ENCL_CREATED, &encl->flags);
+
+ return 0;
+
+err_out:
+ sgx_free_epc_page(encl->secs.epc_page);
+ encl->secs.epc_page = NULL;
+
+ return ret;
+}
+
+/**
+ * sgx_ioc_enclave_create() - handler for %SGX_IOC_ENCLAVE_CREATE
+ * @encl: An enclave pointer.
+ * @arg: The ioctl argument.
+ *
+ * Allocate kernel data structures for the enclave and invoke ECREATE.
+ *
+ * Return:
+ * - 0: Success.
+ * - -EIO: ECREATE failed.
+ * - -errno: POSIX error.
+ */
+static long sgx_ioc_enclave_create(struct sgx_encl *encl, void __user *arg)
+{
+ struct sgx_enclave_create create_arg;
+ void *secs;
+ int ret;
+
+ if (test_bit(SGX_ENCL_CREATED, &encl->flags))
+ return -EINVAL;
+
+ if (copy_from_user(&create_arg, arg, sizeof(create_arg)))
+ return -EFAULT;
+
+ secs = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!secs)
+ return -ENOMEM;
+
+ if (copy_from_user(secs, (void __user *)create_arg.src, PAGE_SIZE))
+ ret = -EFAULT;
+ else
+ ret = sgx_encl_create(encl, secs);
+
+ kfree(secs);
+ return ret;
+}
+
+long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+ struct sgx_encl *encl = filep->private_data;
+ int ret;
+
+ if (test_and_set_bit(SGX_ENCL_IOCTL, &encl->flags))
+ return -EBUSY;
+
+ switch (cmd) {
+ case SGX_IOC_ENCLAVE_CREATE:
+ ret = sgx_ioc_enclave_create(encl, (void __user *)arg);
+ break;
+ default:
+ ret = -ENOIOCTLCMD;
+ break;
+ }
+
+ clear_bit(SGX_ENCL_IOCTL, &encl->flags);
+ return ret;
+}
--
2.27.0
next prev parent reply other threads:[~2020-11-04 14:55 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-04 14:54 [PATCH v40 00/24] Intel SGX foundations Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 01/24] x86/sgx: Add SGX architectural data structures Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 02/24] x86/sgx: Add wrappers for ENCLS functions Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 03/24] x86/sgx: Initialize metadata for Enclave Page Cache (EPC) sections Jarkko Sakkinen
2020-11-04 18:21 ` Borislav Petkov
2020-11-04 19:04 ` Jarkko Sakkinen
2020-11-04 19:09 ` Jarkko Sakkinen
2020-11-04 19:12 ` Borislav Petkov
2020-11-04 14:54 ` [PATCH v40 04/24] x86/cpufeatures: x86/msr: Add Intel SGX hardware bits Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 05/24] x86/cpufeatures: x86/msr: Add Intel SGX Launch Control " Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 06/24] x86/mm: x86/sgx: Signal SIGSEGV with PF_SGX Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 07/24] x86/cpu/intel: Detect SGX support Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 08/24] x86/cpu/intel: Add nosgx kernel parameter Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 09/24] x86/sgx: Add SGX page allocator functions Jarkko Sakkinen
2020-11-05 15:08 ` Borislav Petkov
2020-11-04 14:54 ` [PATCH v40 10/24] mm: Add 'mprotect' hook to struct vm_operations_struct Jarkko Sakkinen
2020-11-05 16:04 ` Borislav Petkov
2020-11-05 17:33 ` Dave Hansen
2020-11-06 10:04 ` Mel Gorman
2020-11-06 16:51 ` Jarkko Sakkinen
2020-11-06 20:37 ` Borislav Petkov
2020-11-06 22:04 ` Jarkko Sakkinen
2020-11-06 22:31 ` Borislav Petkov
2020-11-06 17:43 ` Dr. Greg
2020-11-06 17:54 ` Dave Hansen
2020-11-07 15:09 ` Dr. Greg
2020-11-07 19:16 ` Dave Hansen
2020-11-12 20:58 ` Dr. Greg
2020-11-12 21:31 ` Dave Hansen
2020-11-12 22:41 ` Andy Lutomirski
2020-11-16 18:00 ` Dr. Greg
2020-11-19 1:39 ` Haitao Huang
2020-11-20 17:31 ` Dr. Greg
2020-11-15 18:59 ` Dr. Greg
2020-11-06 21:13 ` Matthew Wilcox
2020-11-06 21:23 ` Dave Hansen
2020-11-07 15:27 ` Dr. Greg
2020-11-04 14:54 ` [PATCH v40 11/24] x86/sgx: Add SGX misc driver interface Jarkko Sakkinen
2020-11-05 1:10 ` Jarkko Sakkinen
2020-11-05 1:16 ` Jarkko Sakkinen
2020-11-05 16:05 ` Borislav Petkov
2020-11-05 17:57 ` Jarkko Sakkinen
2020-11-05 18:10 ` Borislav Petkov
2020-11-06 16:07 ` Jarkko Sakkinen
2020-11-06 17:09 ` Borislav Petkov
2020-11-06 22:01 ` Jarkko Sakkinen
2020-11-04 14:54 ` Jarkko Sakkinen [this message]
2020-11-04 14:54 ` [PATCH v40 13/24] x86/sgx: Add SGX_IOC_ENCLAVE_ADD_PAGES Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 14/24] x86/sgx: Add SGX_IOC_ENCLAVE_INIT Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 15/24] x86/sgx: Add SGX_IOC_ENCLAVE_PROVISION Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 16/24] x86/vdso: Add support for exception fixup in vDSO functions Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 17/24] x86/fault: Add helper function to sanitize error code Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 18/24] x86/traps: Attempt to fixup exceptions in vDSO before signaling Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 19/24] x86/vdso: Implement a vDSO for Intel SGX enclave call Jarkko Sakkinen
2020-11-08 18:24 ` Jethro Beekman
2020-11-08 20:08 ` Jethro Beekman
2020-11-08 20:26 ` Dave Hansen
2020-11-08 20:20 ` Jethro Beekman
2020-11-08 20:30 ` Dave Hansen
2020-11-04 14:54 ` [PATCH v40 20/24] selftests/x86: Add a selftest for SGX Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 21/24] x86/sgx: Add a page reclaimer Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 22/24] x86/sgx: Add ptrace() support for the SGX driver Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 23/24] docs: x86/sgx: Document SGX kernel architecture Jarkko Sakkinen
2020-11-04 14:54 ` [PATCH v40 24/24] x86/sgx: Update MAINTAINERS Jarkko Sakkinen
2020-11-08 20:48 ` [PATCH v40 00/24] Intel SGX foundations Jethro Beekman
[not found] ` <20201108035630.11540-1-hdanton@sina.com>
2020-11-09 19:59 ` [PATCH v40 21/24] x86/sgx: Add a page reclaimer Jarkko Sakkinen
2020-11-21 15:12 ` [PATCH v40 00/24] Intel SGX foundations Dr. Greg
2020-11-21 16:25 ` Dave Hansen
2020-11-24 10:55 ` Dr. Greg
2020-11-24 17:49 ` Andy Lutomirski
2020-11-21 18:36 ` Andy Lutomirski
2020-11-24 18:40 ` Dr. Greg
2020-11-24 21:57 ` Andy Lutomirski
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=20201104145430.300542-13-jarkko.sakkinen@linux.intel.com \
--to=jarkko.sakkinen@linux.intel.com \
--cc=akpm@linux-foundation.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=asapek@google.com \
--cc=bp@alien8.de \
--cc=cedric.xing@intel.com \
--cc=chenalexchen@google.com \
--cc=conradparker@google.com \
--cc=cyhanish@google.com \
--cc=darren.kenny@oracle.com \
--cc=dave.hansen@intel.com \
--cc=haitao.huang@intel.com \
--cc=haitao.huang@linux.intel.com \
--cc=jethro@fortanix.com \
--cc=jorhand@linux.microsoft.com \
--cc=kai.huang@intel.com \
--cc=kai.svahn@intel.com \
--cc=kmoy@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sgx@vger.kernel.org \
--cc=ludloff@google.com \
--cc=luto@kernel.org \
--cc=mikko.ylinen@intel.com \
--cc=nhorman@redhat.com \
--cc=npmccallum@redhat.com \
--cc=puiterwijk@redhat.com \
--cc=rientjes@google.com \
--cc=sanqian.hcy@antfin.com \
--cc=sean.j.christopherson@intel.com \
--cc=sethmo@google.com \
--cc=suresh.b.siddha@intel.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
--cc=yaozhangx@google.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).