From patchwork Wed Dec 7 13:00:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 9464447 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 30DFD60512 for ; Wed, 7 Dec 2016 13:01:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 30DC128497 for ; Wed, 7 Dec 2016 13:01:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 25D67284E5; Wed, 7 Dec 2016 13:01:17 +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 C371228497 for ; Wed, 7 Dec 2016 13:01:16 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id C863C81F20 for ; Wed, 7 Dec 2016 05:01:16 -0800 (PST) X-Original-To: intel-sgx-kernel-dev@lists.01.org Delivered-To: intel-sgx-kernel-dev@lists.01.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) (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 CB07D81F20 for ; Wed, 7 Dec 2016 05:01:15 -0800 (PST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 07 Dec 2016 05:01:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.33,310,1477983600"; d="scan'208"; a="1095857297" Received: from jsakkine-mobl1.tm.intel.com (HELO localhost) ([10.237.50.54]) by fmsmga002.fm.intel.com with ESMTP; 07 Dec 2016 05:01:04 -0800 From: Jarkko Sakkinen To: intel-sgx-kernel-dev@lists.01.org Date: Wed, 7 Dec 2016 15:00:43 +0200 Message-Id: <20161207130045.22615-8-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20161207130045.22615-1-jarkko.sakkinen@linux.intel.com> References: <20161207130045.22615-1-jarkko.sakkinen@linux.intel.com> Subject: [intel-sgx-kernel-dev] [PATCH v7 7/9] intel_sgx: invalidate enclave when the user threads cease to exist 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 Page table should not be manipulated after all user processes cease to exist. This can result page table inconsistency errors: BUG: non-zero nr_ptes on freeing mm: 1 This commit fixes the issue by invalidating the enclave after all user processes have been died. Reported-by: Sean Christopherson Suggested-by: Sean Christopherson Signed-off-by: Jarkko Sakkinen --- drivers/platform/x86/Kconfig | 1 + drivers/platform/x86/intel_sgx.h | 2 ++ drivers/platform/x86/intel_sgx_ioctl.c | 23 +++++++++++++++++++++++ drivers/platform/x86/intel_sgx_page_cache.c | 3 ++- drivers/platform/x86/intel_sgx_util.c | 4 ++++ 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index b8db914..f53a759 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1031,6 +1031,7 @@ config INTEL_SGX tristate "Intel(R) SGX Driver" default n depends on X86 + select MMU_NOTIFIER ---help--- Intel(R) SGX is a set of CPU instructions that can be used by applications to set aside private regions of code and data. The code diff --git a/drivers/platform/x86/intel_sgx.h b/drivers/platform/x86/intel_sgx.h index 35c03fc..add3565 100644 --- a/drivers/platform/x86/intel_sgx.h +++ b/drivers/platform/x86/intel_sgx.h @@ -67,6 +67,7 @@ #include #include #include +#include #define SGX_EINIT_SPIN_COUNT 20 #define SGX_EINIT_SLEEP_COUNT 50 @@ -152,6 +153,7 @@ struct sgx_encl { struct sgx_encl_page secs_page; struct sgx_tgid_ctx *tgid_ctx; struct list_head encl_list; + struct mmu_notifier mmu_notifier; }; extern struct workqueue_struct *sgx_add_page_wq; diff --git a/drivers/platform/x86/intel_sgx_ioctl.c b/drivers/platform/x86/intel_sgx_ioctl.c index 0c3fd29..ab0a4a3 100644 --- a/drivers/platform/x86/intel_sgx_ioctl.c +++ b/drivers/platform/x86/intel_sgx_ioctl.c @@ -471,6 +471,21 @@ static int sgx_init_page(struct sgx_encl *encl, return 0; } +static void sgx_mmu_notifier_release(struct mmu_notifier *mn, + struct mm_struct *mm) +{ + struct sgx_encl *encl = + container_of(mn, struct sgx_encl, mmu_notifier); + + mutex_lock(&encl->lock); + encl->flags |= SGX_ENCL_INVALIDATED; + mutex_unlock(&encl->lock); +} + +static const struct mmu_notifier_ops sgx_mmu_notifier_ops = { + .release = sgx_mmu_notifier_release, +}; + /** * sgx_ioc_enclave_create - handler for SGX_IOC_ENCLAVE_CREATE * @@ -572,6 +587,14 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, if (secs->flags & SGX_SECS_A_DEBUG) encl->flags |= SGX_ENCL_DEBUG; + + encl->mmu_notifier.ops = &sgx_mmu_notifier_ops; + ret = mmu_notifier_register(&encl->mmu_notifier, encl->mm); + if (ret) { + encl->mmu_notifier.ops = NULL; + goto out; + } + down_read(¤t->mm->mmap_sem); vma = find_vma(current->mm, secs->base); if (!vma || vma->vm_ops != &sgx_vm_ops || diff --git a/drivers/platform/x86/intel_sgx_page_cache.c b/drivers/platform/x86/intel_sgx_page_cache.c index f2a2ed1..49dd664 100644 --- a/drivers/platform/x86/intel_sgx_page_cache.c +++ b/drivers/platform/x86/intel_sgx_page_cache.c @@ -227,12 +227,13 @@ static bool sgx_ewb(struct sgx_encl *encl, { int ret = __sgx_ewb(encl, entry, backing); - /* Only kick out threads with an IPI if needed. */ + /* fast path */ if (ret == SGX_NOT_TRACKED) { smp_call_function(sgx_ipi_cb, NULL, 1); ret = __sgx_ewb(encl, entry, backing); } + /* slow path */ if (ret) { /* Make enclave inaccessible. */ sgx_invalidate(encl); diff --git a/drivers/platform/x86/intel_sgx_util.c b/drivers/platform/x86/intel_sgx_util.c index 41ccc18..5c96834 100644 --- a/drivers/platform/x86/intel_sgx_util.c +++ b/drivers/platform/x86/intel_sgx_util.c @@ -237,6 +237,10 @@ void sgx_encl_release(struct kref *ref) mutex_unlock(&sgx_tgid_ctx_mutex); + if (encl->mmu_notifier.ops) + mmu_notifier_unregister_no_release(&encl->mmu_notifier, + encl->mm); + rb1 = rb_first(&encl->encl_rb); while (rb1) { entry = container_of(rb1, struct sgx_encl_page, node);