From patchwork Tue Apr 4 07:29:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai Huang X-Patchwork-Id: 9660905 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 2A7936032D for ; Tue, 4 Apr 2017 07:30:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1091828285 for ; Tue, 4 Apr 2017 07:30:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0191B2849D; Tue, 4 Apr 2017 07:30:01 +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.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, T_DKIM_INVALID autolearn=no 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 1CA47282E2 for ; Tue, 4 Apr 2017 07:30:01 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 1D1382193930D; Tue, 4 Apr 2017 00:30:01 -0700 (PDT) X-Original-To: intel-sgx-kernel-dev@lists.01.org Delivered-To: intel-sgx-kernel-dev@lists.01.org Received: from mail-pg0-x243.google.com (mail-pg0-x243.google.com [IPv6:2607:f8b0:400e:c05::243]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id C397720D77822 for ; Tue, 4 Apr 2017 00:29:59 -0700 (PDT) Received: by mail-pg0-x243.google.com with SMTP id 79so35408487pgf.0 for ; Tue, 04 Apr 2017 00:29:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=EMyTyo+R2KbPASLmQiZWtLmwl5oVSezkh35w54oTfgQ=; b=UfZIUUsWPK/d/9SNS620xujenBSmReWt3C4cvO0xKF+q0k1q8vL6v8L1Wta2X9nOwg dBdyWjaZRaLzgRIRrpT8Oh36qWAHI6C7dBCG+MOPZR+9D4UqUkrAoUn9B/5EWFng3Gw2 m7mBLItlipuWlYXcqiA03QzctIakQVgeD/izHYCe03Xw3JRnV+lYoYQg7DkdSE4mqzwp K16+ohYoYmdu9CM78MQGAsOtt97yqOM9T6sRd5Ny1lPhFyAEibwkU0n+0waKIpMbLGgO ZzFd5ZtV0XymzcUCZ0GklzP6oWCvBc1vs81v2aB61hUMb5mdBF5Cty2ngtzDwq4RY3LV 8R8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=EMyTyo+R2KbPASLmQiZWtLmwl5oVSezkh35w54oTfgQ=; b=mKlwbQjF8zc6uxYP5a390bZKpBvi0g1DAPcfaf//8Kqfz/5gVrW4R9B90yg0jaybUQ LUjfPJkINPDQ/1g1zsUnI/pzExVxh3jrYPX5ZLMNFtcIaB1i1Np3eUAz2pT1kADpWsaN dq+034M6zXlRUTMOENT0eRx6FDZKO6RG2DdQ9NV7mRBPBh03uuq9QZ83XI18Byq7cvLG nxdug+WGKZZuFtP+yEIvLLNMVFOeUtOdYhRY2WqR5zjpZulhWCQj+uClj+/7AuIYjmt0 3Nx85S3MTu8Ejx2NbnSUsandA7aemAo4xzwS/zdUFsPXEYE/T8K2NcLRevz4VCWyEQGR 4muw== X-Gm-Message-State: AFeK/H0dlEChahssiWTkXqdxBhgbh1Qlo9zcHnw5EriDgEO0mtCgAMTXYfy/vkwu7cerZQ== X-Received: by 10.99.107.72 with SMTP id g69mr22286571pgc.149.1491290999266; Tue, 04 Apr 2017 00:29:59 -0700 (PDT) Received: from localhost.localdomain (118-92-235-112.dsl.dyn.ihug.co.nz. [118.92.235.112]) by smtp.gmail.com with ESMTPSA id y7sm29724831pfk.93.2017.04.04.00.29.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Apr 2017 00:29:58 -0700 (PDT) From: Kai Huang X-Google-Original-From: Kai Huang To: intel-sgx-kernel-dev@lists.01.org, jarkko.sakkinen@linux.intel.com Date: Tue, 4 Apr 2017 19:29:36 +1200 Message-Id: <20170404072938.4800-6-kai.huang@linux.intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170404072938.4800-1-kai.huang@linux.intel.com> References: <20170404072938.4800-1-kai.huang@linux.intel.com> Subject: [intel-sgx-kernel-dev] [PATCH 5/7] intel_sgx: expose sgx_alloc{free}_page X-BeenThere: intel-sgx-kernel-dev@lists.01.org X-Mailman-Version: 2.1.22 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 KVM needs to call the two to allocate and free EPC pages. Also removed 'struct sgx_tgid_ctx *ctx' parameter from sgx_alloc_page and removed 'struct sgx_encl *encl' from sgx_free_page, because they are meaningless to KVM. Remove them to make sgx_alloc{free}_page independent of host SGX app. sgx_get{put}_tgid_ctx are introduced and called separately after sgx_alloc{free}_page are called to reflect the original logic. Also introduce SGX_FREE_NO_EREMOVE flag for sgx_free_page, because KVM always assumes EREMOVE to be not part of sgx_free_page. Probably a better way is to remove EREMOVE from sgx_free_page and call it explicitly where it is needed. Note that as there's no OOM of EPC in SGX driver, and we don't support evicting EPC from KVM guests yet, therefore sgx_alloc_page will never return if there's no enough EPC when creating KVM guest. This even applies to host sgx app alone as well as there's no OOM for EPC now. Signed-off-by: Kai Huang --- arch/x86/include/asm/sgx.h | 12 +++++++++ drivers/platform/x86/intel_sgx.h | 14 ++-------- drivers/platform/x86/intel_sgx_ioctl.c | 23 ++++++++++++----- drivers/platform/x86/intel_sgx_page_cache.c | 36 ++++++++++++++------------ drivers/platform/x86/intel_sgx_util.c | 40 +++++++++++++++++++++-------- 5 files changed, 80 insertions(+), 45 deletions(-) diff --git a/arch/x86/include/asm/sgx.h b/arch/x86/include/asm/sgx.h index fe1a2ba..063ff8f 100644 --- a/arch/x86/include/asm/sgx.h +++ b/arch/x86/include/asm/sgx.h @@ -372,4 +372,16 @@ unsigned long sgx_epc_page_to_pfn(struct sgx_epc_page *entry); void *sgx_kmap_epc_page(struct sgx_epc_page *entry); void sgx_kunmap_epc_page(void *epc_page_vaddr); +enum sgx_alloc_flags { + SGX_ALLOC_ATOMIC = BIT(0), +}; + +enum sgx_free_flags { + SGX_FREE_RETURN_ERROR = BIT(0), + SGX_FREE_NO_EREMOVE = BIT(1), +}; + +struct sgx_epc_page *sgx_alloc_page(unsigned int flags); +int sgx_free_page(struct sgx_epc_page *entry, unsigned int flags); + #endif /* _ASM_X86_SGX_H */ diff --git a/drivers/platform/x86/intel_sgx.h b/drivers/platform/x86/intel_sgx.h index b9b81d6..f9fc708 100644 --- a/drivers/platform/x86/intel_sgx.h +++ b/drivers/platform/x86/intel_sgx.h @@ -216,6 +216,8 @@ void sgx_unpin_mm(struct sgx_encl *encl); void sgx_invalidate(struct sgx_encl *encl); int sgx_find_encl(struct mm_struct *mm, unsigned long addr, struct vm_area_struct **vma); +void sgx_get_tgid_ctx(struct sgx_tgid_ctx *ctx); +void sgx_put_tgid_ctx(struct sgx_tgid_ctx *ctx); enum sgx_fault_flags { SGX_FAULT_RESERVE = BIT(0), @@ -237,20 +239,8 @@ extern struct mutex sgx_tgid_ctx_mutex; extern struct list_head sgx_tgid_ctx_list; extern struct task_struct *ksgxswapd_tsk; -enum sgx_alloc_flags { - SGX_ALLOC_ATOMIC = BIT(0), -}; - -enum sgx_free_flags { - SGX_FREE_RETURN_ERROR = BIT(0), -}; - int ksgxswapd(void *p); int sgx_page_cache_init(struct sgx_epc_bank *banks, int nr_banks); void sgx_page_cache_teardown(struct sgx_epc_bank *banks, int nr_banks); -struct sgx_epc_page *sgx_alloc_page(struct sgx_tgid_ctx *tgid_epc_cnt, - unsigned int flags); -int sgx_free_page(struct sgx_epc_page *entry, struct sgx_encl *encl, - unsigned int flags); #endif /* __ARCH_X86_INTEL_SGX_H__ */ diff --git a/drivers/platform/x86/intel_sgx_ioctl.c b/drivers/platform/x86/intel_sgx_ioctl.c index a8729c3..5ff647f 100644 --- a/drivers/platform/x86/intel_sgx_ioctl.c +++ b/drivers/platform/x86/intel_sgx_ioctl.c @@ -216,12 +216,15 @@ static bool sgx_process_add_page_req(struct sgx_add_page_req *req) struct vm_area_struct *vma; int ret; - epc_page = sgx_alloc_page(encl->tgid_ctx, 0); + epc_page = sgx_alloc_page(0); if (IS_ERR(epc_page)) return false; + sgx_get_tgid_ctx(encl->tgid_ctx); + if (!sgx_pin_mm(encl)) { - sgx_free_page(epc_page, encl, 0); + sgx_free_page(epc_page, 0); + sgx_put_tgid_ctx(encl->tgid_ctx); return false; } @@ -275,7 +278,8 @@ static bool sgx_process_add_page_req(struct sgx_add_page_req *req) sgx_unpin_mm(encl); return true; out: - sgx_free_page(epc_page, encl, 0); + sgx_free_page(epc_page, 0); + sgx_put_tgid_ctx(encl->tgid_ctx); mutex_unlock(&encl->lock); sgx_unpin_mm(encl); return false; @@ -405,17 +409,19 @@ static int sgx_init_page(struct sgx_encl *encl, if (!va_page) return -ENOMEM; - epc_page = sgx_alloc_page(encl->tgid_ctx, 0); + epc_page = sgx_alloc_page(0); if (IS_ERR(epc_page)) { kfree(va_page); return PTR_ERR(epc_page); } + sgx_get_tgid_ctx(encl->tgid_ctx); vaddr = sgx_kmap_epc_page(epc_page); if (!vaddr) { sgx_warn(encl, "kmap of a new VA page failed %d\n", ret); - sgx_free_page(epc_page, encl, 0); + sgx_free_page(epc_page, 0); + sgx_put_tgid_ctx(encl->tgid_ctx); kfree(va_page); return -EFAULT; } @@ -425,7 +431,8 @@ static int sgx_init_page(struct sgx_encl *encl, if (ret) { sgx_warn(encl, "EPA returned %d\n", ret); - sgx_free_page(epc_page, encl, 0); + sgx_free_page(epc_page, 0); + sgx_put_tgid_ctx(encl->tgid_ctx); kfree(va_page); return -EFAULT; } @@ -539,12 +546,14 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, encl->backing = backing; encl->pcmd = pcmd; - secs_epc = sgx_alloc_page(encl->tgid_ctx, 0); + secs_epc = sgx_alloc_page(0); if (IS_ERR(secs_epc)) { ret = PTR_ERR(secs_epc); secs_epc = NULL; goto out; } + /* don't need to sgx_get_tgid_ctx(encl->tgid_ctx) as encl->tgid_ctx is + * NULL now */ ret = sgx_add_to_tgid_ctx(encl); if (ret) diff --git a/drivers/platform/x86/intel_sgx_page_cache.c b/drivers/platform/x86/intel_sgx_page_cache.c index 3f9ba9c..71569e7 100644 --- a/drivers/platform/x86/intel_sgx_page_cache.c +++ b/drivers/platform/x86/intel_sgx_page_cache.c @@ -330,7 +330,8 @@ static void sgx_evict_page(struct sgx_encl_page *entry, struct sgx_encl *encl) { sgx_ewb(encl, entry); - sgx_free_page(entry->epc_page, encl, 0); + sgx_free_page(entry->epc_page, 0); + sgx_put_tgid_ctx(encl->tgid_ctx); entry->epc_page = NULL; entry->flags &= ~SGX_ENCL_PAGE_RESERVED; } @@ -554,18 +555,15 @@ static struct sgx_epc_page *sgx_alloc_page_fast(void) * * Return: an EPC page or an error code */ -struct sgx_epc_page *sgx_alloc_page(struct sgx_tgid_ctx *ctx, - unsigned int flags) +struct sgx_epc_page *sgx_alloc_page(unsigned int flags) { struct sgx_epc_page *entry; for ( ; ; ) { entry = sgx_alloc_page_fast(); - if (entry) { - if (ctx) - atomic_inc(&ctx->epc_cnt); + if (entry) break; - } else if (flags & SGX_ALLOC_ATOMIC) { + else if (flags & SGX_ALLOC_ATOMIC) { entry = ERR_PTR(-EBUSY); break; } @@ -584,6 +582,7 @@ struct sgx_epc_page *sgx_alloc_page(struct sgx_tgid_ctx *ctx, return entry; } +EXPORT_SYMBOL_GPL(sgx_alloc_page); /** * sgx_free_page - free an EPC page @@ -591,25 +590,29 @@ struct sgx_epc_page *sgx_alloc_page(struct sgx_tgid_ctx *ctx, * @encl: the enclave who owns the EPC page * @flags: free flags */ -int sgx_free_page(struct sgx_epc_page *entry, struct sgx_encl *encl, - unsigned int flags) +int sgx_free_page(struct sgx_epc_page *entry, unsigned int flags) { void *epc; - int ret; + int ret = 0; - epc = sgx_kmap_epc_page(entry); - ret = __eremove(epc); - sgx_kunmap_epc_page(epc); + if (!(flags & SGX_FREE_NO_EREMOVE)) { + epc = sgx_kmap_epc_page(entry); + ret = __eremove(epc); + sgx_kunmap_epc_page(epc); + } if (ret) { if (flags & SGX_FREE_RETURN_ERROR) return ret; - sgx_crit(encl, "EREMOVE returned %d\n", ret); + /* + * sgx_crit is removed because it takes encl as parameter, + * which sgx_free_page doesn't take anymore. + * TODO: remove encl from sgx_{print} functions and call + * sgx_crit again. + */ } - atomic_dec(&encl->tgid_ctx->epc_cnt); - spin_lock(&sgx_free_list_lock); list_add(&entry->free_list, &sgx_free_list); sgx_nr_free_pages++; @@ -617,3 +620,4 @@ int sgx_free_page(struct sgx_epc_page *entry, struct sgx_encl *encl, return 0; } +EXPORT_SYMBOL_GPL(sgx_free_page); diff --git a/drivers/platform/x86/intel_sgx_util.c b/drivers/platform/x86/intel_sgx_util.c index c63193d..96b3770 100644 --- a/drivers/platform/x86/intel_sgx_util.c +++ b/drivers/platform/x86/intel_sgx_util.c @@ -372,12 +372,13 @@ static struct sgx_encl_page *sgx_do_fault(struct vm_area_struct *vma, goto out; } - epc_page = sgx_alloc_page(encl->tgid_ctx, SGX_ALLOC_ATOMIC); + epc_page = sgx_alloc_page(SGX_ALLOC_ATOMIC); if (IS_ERR(epc_page)) { rc = PTR_ERR(epc_page); epc_page = NULL; goto out; } + sgx_get_tgid_ctx(encl->tgid_ctx); if (encl->flags & SGX_ENCL_DEAD) { rc = -EFAULT; @@ -406,12 +407,13 @@ static struct sgx_encl_page *sgx_do_fault(struct vm_area_struct *vma, /* If SECS is evicted then reload it first */ if (encl->flags & SGX_ENCL_SECS_EVICTED) { - secs_epc_page = sgx_alloc_page(encl->tgid_ctx, SGX_ALLOC_ATOMIC); + secs_epc_page = sgx_alloc_page(SGX_ALLOC_ATOMIC); if (IS_ERR(secs_epc_page)) { rc = PTR_ERR(secs_epc_page); secs_epc_page = NULL; goto out; } + sgx_get_tgid_ctx(encl->tgid_ctx); rc = sgx_eldu(encl, &encl->secs_page, secs_epc_page, true); if (rc) @@ -446,10 +448,14 @@ static struct sgx_encl_page *sgx_do_fault(struct vm_area_struct *vma, list_add_tail(&entry->load_list, &encl->load_list); out: mutex_unlock(&encl->lock); - if (epc_page) - sgx_free_page(epc_page, encl, 0); - if (secs_epc_page) - sgx_free_page(secs_epc_page, encl, 0); + if (epc_page) { + sgx_free_page(epc_page, 0); + sgx_put_tgid_ctx(encl->tgid_ctx); + } + if (secs_epc_page) { + sgx_free_page(secs_epc_page, 0); + sgx_put_tgid_ctx(encl->tgid_ctx); + } return rc ? ERR_PTR(rc) : entry; } @@ -489,7 +495,8 @@ void sgx_encl_release(struct kref *ref) entry = *slot; if (entry->epc_page) { list_del(&entry->load_list); - sgx_free_page(entry->epc_page, encl, 0); + sgx_free_page(entry->epc_page, 0); + sgx_put_tgid_ctx(encl->tgid_ctx); } radix_tree_delete(&encl->page_tree, entry->addr >> PAGE_SHIFT); kfree(entry); @@ -499,12 +506,15 @@ void sgx_encl_release(struct kref *ref) va_page = list_first_entry(&encl->va_pages, struct sgx_va_page, list); list_del(&va_page->list); - sgx_free_page(va_page->epc_page, encl, 0); + sgx_free_page(va_page->epc_page, 0); + sgx_put_tgid_ctx(encl->tgid_ctx); kfree(va_page); } - if (encl->secs_page.epc_page) - sgx_free_page(encl->secs_page.epc_page, encl, 0); + if (encl->secs_page.epc_page) { + sgx_free_page(encl->secs_page.epc_page, 0); + sgx_put_tgid_ctx(encl->tgid_ctx); + } encl->secs_page.epc_page = NULL; @@ -519,3 +529,13 @@ void sgx_encl_release(struct kref *ref) kfree(encl); } + +void sgx_get_tgid_ctx(struct sgx_tgid_ctx *ctx) +{ + atomic_inc(&ctx->epc_cnt); +} + +void sgx_put_tgid_ctx(struct sgx_tgid_ctx *ctx) +{ + atomic_dec(&ctx->epc_cnt); +}