From patchwork Thu Dec 1 20:56:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 9456899 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 873ED60585 for ; Thu, 1 Dec 2016 20:57:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7A9D92841E for ; Thu, 1 Dec 2016 20:57:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F69E2851B; Thu, 1 Dec 2016 20:57:03 +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 D022C2841E for ; Thu, 1 Dec 2016 20:57:02 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id EB37581F1C for ; Thu, 1 Dec 2016 12:57:02 -0800 (PST) X-Original-To: intel-sgx-kernel-dev@lists.01.org Delivered-To: intel-sgx-kernel-dev@lists.01.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (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 D35F181F1C for ; Thu, 1 Dec 2016 12:57:01 -0800 (PST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP; 01 Dec 2016 12:57:01 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.33,726,1477983600"; d="scan'208"; a="1093355364" Received: from wmcsween-mobl.ger.corp.intel.com (HELO localhost) ([10.252.12.30]) by fmsmga002.fm.intel.com with ESMTP; 01 Dec 2016 12:56:58 -0800 From: Jarkko Sakkinen To: intel-sgx-kernel-dev@lists.01.org Date: Thu, 1 Dec 2016 22:56:29 +0200 Message-Id: <20161201205632.8593-6-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20161201205632.8593-1-jarkko.sakkinen@linux.intel.com> References: <20161201205632.8593-1-jarkko.sakkinen@linux.intel.com> Subject: [intel-sgx-kernel-dev] [PATCH v4 5/8] 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 b377200..5a68dbe 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 3878d9a..8ba2abd 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; } @@ -177,7 +177,7 @@ void sgx_invalidate(struct sgx_encl *encl) break; } - 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;