From patchwork Wed Nov 30 14:23:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 9454455 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3087560585 for ; Wed, 30 Nov 2016 14:23:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D0BF28443 for ; Wed, 30 Nov 2016 14:23:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1F3A228447; Wed, 30 Nov 2016 14:23: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=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B1EA128443 for ; Wed, 30 Nov 2016 14:23:42 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id C771A81D97 for ; Wed, 30 Nov 2016 06:23:42 -0800 (PST) X-Original-To: intel-sgx-kernel-dev@lists.01.org Delivered-To: intel-sgx-kernel-dev@lists.01.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 4D65781D97 for ; Wed, 30 Nov 2016 06:23:42 -0800 (PST) Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga101.fm.intel.com with ESMTP; 30 Nov 2016 06:23:41 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,574,1473145200"; d="scan'208";a="37354798" Received: from pstacey-mobl2.ger.corp.intel.com (HELO localhost) ([10.252.3.89]) by fmsmga005.fm.intel.com with ESMTP; 30 Nov 2016 06:23:39 -0800 From: Jarkko Sakkinen To: intel-sgx-kernel-dev@lists.01.org Date: Wed, 30 Nov 2016 16:23:18 +0200 Message-Id: <20161130142323.5324-3-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20161130142323.5324-1-jarkko.sakkinen@linux.intel.com> References: <20161130142323.5324-1-jarkko.sakkinen@linux.intel.com> Subject: [intel-sgx-kernel-dev] [PATCH v3 2/7] intel_sgx: freeze VMAs after EPC pages have been added X-BeenThere: intel-sgx-kernel-dev@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Project: Intel® Software Guard Extensions for Linux*: https://01.org/intel-software-guard-extensions" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-sgx-kernel-dev-bounces@lists.01.org Sender: "intel-sgx-kernel-dev" X-Virus-Scanned: ClamAV using ClamSMTP Added SGX_ENCL_INVALIDATED flag to inform when the enclave is not usable anymore. After pages have been added to the enclave it does not make sense to change the VMA config anymore because permissions of pages cannot changed with SGX1 architecture. Also if any of the VMAs are closed the whole enclave is invalidated. This makes sense for SGX1 architecture as the permissions of pages cannot be changed later on. For SGX2 we might be able to ease the requirement because of EMODP. Signed-off-by: Jarkko Sakkinen --- drivers/platform/x86/intel_sgx.h | 5 +++-- drivers/platform/x86/intel_sgx_ioctl.c | 9 ++++++--- drivers/platform/x86/intel_sgx_util.c | 6 +++--- drivers/platform/x86/intel_sgx_vma.c | 32 ++++++++++++-------------------- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/drivers/platform/x86/intel_sgx.h b/drivers/platform/x86/intel_sgx.h index 464763d..4430012 100644 --- a/drivers/platform/x86/intel_sgx.h +++ b/drivers/platform/x86/intel_sgx.h @@ -130,12 +130,13 @@ enum sgx_encl_flags { SGX_ENCL_DEBUG = BIT(1), SGX_ENCL_SECS_EVICTED = BIT(2), SGX_ENCL_SUSPEND = BIT(3), + SGX_ENCL_PAGES_ADDED = BIT(4), + SGX_ENCL_INVALIDATED = BIT(5), }; struct sgx_encl { - unsigned int flags; + unsigned long flags; unsigned int secs_child_cnt; - unsigned int vma_cnt; struct mutex lock; struct task_struct *owner; struct mm_struct *mm; diff --git a/drivers/platform/x86/intel_sgx_ioctl.c b/drivers/platform/x86/intel_sgx_ioctl.c index db17b9f..7142907 100644 --- a/drivers/platform/x86/intel_sgx_ioctl.c +++ b/drivers/platform/x86/intel_sgx_ioctl.c @@ -255,7 +255,10 @@ static bool sgx_process_add_page_req(struct sgx_add_page_req *req) mutex_lock(&encl->lock); - if (!encl->vma_cnt || sgx_find_encl(encl->mm, encl_page->addr, &vma)) + if (encl->flags & SGX_ENCL_INVALIDATED) + goto out; + + if (sgx_find_encl(encl->mm, encl_page->addr, &vma)) goto out; backing = sgx_get_backing(encl, encl_page); @@ -578,7 +581,6 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, up_read(¤t->mm->mmap_sem); goto out; } - encl->vma_cnt++; vma->vm_private_data = encl; up_read(¤t->mm->mmap_sem); @@ -682,7 +684,7 @@ static int __encl_add_page(struct sgx_encl *encl, mutex_lock(&encl->lock); - if (encl->flags & SGX_ENCL_INITIALIZED) { + if (encl->flags & (SGX_ENCL_INITIALIZED | SGX_ENCL_INVALIDATED)) { ret = -EINVAL; goto out; } @@ -734,6 +736,7 @@ out: } else { ret = encl_rb_insert(&encl->encl_rb, encl_page); WARN_ON(ret); + encl->flags |= SGX_ENCL_PAGES_ADDED; } mutex_unlock(&encl->lock); diff --git a/drivers/platform/x86/intel_sgx_util.c b/drivers/platform/x86/intel_sgx_util.c index d1c4c71..30e9ca6 100644 --- a/drivers/platform/x86/intel_sgx_util.c +++ b/drivers/platform/x86/intel_sgx_util.c @@ -139,7 +139,7 @@ bool sgx_pin_mm(struct sgx_encl *encl) return false; mutex_lock(&encl->lock); - if (encl->vma_cnt) { + if (!(encl->flags & SGX_ENCL_INVALIDATED)) { atomic_inc(&encl->mm->mm_count); } else { mutex_unlock(&encl->lock); @@ -149,7 +149,7 @@ bool sgx_pin_mm(struct sgx_encl *encl) down_read(&encl->mm->mmap_sem); - if (!encl->vma_cnt) { + if (encl->flags & SGX_ENCL_INVALIDATED) { sgx_unpin_mm(encl); return false; } @@ -175,7 +175,7 @@ void sgx_invalidate(struct sgx_encl *encl) sgx_zap_tcs_ptes(encl, vma); } - encl->vma_cnt = 0; + encl->flags |= SGX_ENCL_INVALIDATED; } int sgx_find_encl(struct mm_struct *mm, unsigned long addr, diff --git a/drivers/platform/x86/intel_sgx_vma.c b/drivers/platform/x86/intel_sgx_vma.c index 0649978..88a316a 100644 --- a/drivers/platform/x86/intel_sgx_vma.c +++ b/drivers/platform/x86/intel_sgx_vma.c @@ -72,21 +72,20 @@ static void sgx_vma_open(struct vm_area_struct *vma) { struct sgx_encl *encl; - /* Was vm_private_data nullified as a result of the previous fork? */ + /* fork after fork */ encl = vma->vm_private_data; if (!encl) goto out_fork; - /* Was the process forked? mm_struct changes when the process is - * forked. - */ - mutex_lock(&encl->lock); - if (encl->mm != vma->vm_mm) { - mutex_unlock(&encl->lock); + /* mm_struct changes when the process is forked */ + if (encl->mm != vma->vm_mm) goto out_fork; + + if (test_bit(SGX_ENCL_PAGES_ADDED, &encl->flags)) { + mutex_lock(&encl->lock); + sgx_invalidate(encl); + mutex_unlock(&encl->lock); } - encl->vma_cnt++; - mutex_unlock(&encl->lock); kref_get(&encl->refcount); return; @@ -99,21 +98,13 @@ static void sgx_vma_close(struct vm_area_struct *vma) { struct sgx_encl *encl = vma->vm_private_data; - /* If process was forked, VMA is still there but - * vm_private_data is set to NULL. - */ + /* fork */ if (!encl) return; mutex_lock(&encl->lock); - encl->vma_cnt--; - vma->vm_private_data = NULL; - - sgx_zap_tcs_ptes(encl, vma); - zap_vma_ptes(vma, vma->vm_start, vma->vm_end - vma->vm_start); - + sgx_invalidate(encl); mutex_unlock(&encl->lock); - kref_put(&encl->refcount, sgx_encl_release); } @@ -187,7 +178,7 @@ static struct sgx_encl_page *sgx_vma_do_fault(struct vm_area_struct *vma, mutex_lock(&encl->lock); - if (!encl->vma_cnt) { + if (encl->flags & SGX_ENCL_INVALIDATED) { entry = ERR_PTR(-EFAULT); goto out; } @@ -370,6 +361,7 @@ static int sgx_vma_access(struct vm_area_struct *vma, unsigned long addr, if (!(encl->flags & SGX_ENCL_DEBUG) || !(encl->flags & SGX_ENCL_INITIALIZED) || + (encl->flags & SGX_ENCL_INVALIDATED) || (encl->flags & SGX_ENCL_SUSPEND)) return -EFAULT;