From patchwork Thu Dec 15 14:49:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 9476381 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 F072F60825 for ; Thu, 15 Dec 2016 14:50:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EAAA228820 for ; Thu, 15 Dec 2016 14:50:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DFA7B28824; Thu, 15 Dec 2016 14:50:32 +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 7918028820 for ; Thu, 15 Dec 2016 14:50:32 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 8F92381D58 for ; Thu, 15 Dec 2016 06:50:32 -0800 (PST) X-Original-To: intel-sgx-kernel-dev@lists.01.org Delivered-To: intel-sgx-kernel-dev@lists.01.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (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 941F681D58 for ; Thu, 15 Dec 2016 06:50:31 -0800 (PST) Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP; 15 Dec 2016 06:50:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,352,1477983600"; d="scan'208";a="42871878" Received: from gstoettn-mobl2.ger.corp.intel.com (HELO localhost) ([10.252.55.163]) by fmsmga005.fm.intel.com with ESMTP; 15 Dec 2016 06:50:29 -0800 From: Jarkko Sakkinen To: intel-sgx-kernel-dev@lists.01.org Date: Thu, 15 Dec 2016 16:49:57 +0200 Message-Id: <20161215144959.31245-9-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20161215144959.31245-1-jarkko.sakkinen@linux.intel.com> References: <20161215144959.31245-1-jarkko.sakkinen@linux.intel.com> Subject: [intel-sgx-kernel-dev] [PATCH v9 08/10] 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 Reviewed-by: Sean Christopherson Tested-by: Sean Christopherson --- 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_util.c | 4 ++++ 4 files changed, 30 insertions(+) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 411616b..b722230 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1032,6 +1032,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 018cd03..f1ff194 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 @@ -151,6 +152,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 d0113b0..aaccbc8 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_DEAD; + 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_util.c b/drivers/platform/x86/intel_sgx_util.c index d5238c2..f6f7dde0 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);