From patchwork Fri Aug 23 16:16:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 11112047 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B872014DB for ; Fri, 23 Aug 2019 16:16:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A131922CEC for ; Fri, 23 Aug 2019 16:16:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2436676AbfHWQQh (ORCPT ); Fri, 23 Aug 2019 12:16:37 -0400 Received: from mga12.intel.com ([192.55.52.136]:17322 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2436661AbfHWQQh (ORCPT ); Fri, 23 Aug 2019 12:16:37 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Aug 2019 09:16:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,421,1559545200"; d="scan'208";a="263231702" Received: from unknown (HELO localhost) ([10.252.39.229]) by orsmga001.jf.intel.com with ESMTP; 23 Aug 2019 09:16:24 -0700 From: Jarkko Sakkinen To: linux-sgx@vger.kernel.org Cc: sean.j.christopherson@intel.com, serge.ayoun@intel.com, shay.katz-zamir@intel.com, Jarkko Sakkinen Subject: [PATCH 1/4] x86/sgx: Replace @is_secs_child with @pt in sgx_encl_ewb() Date: Fri, 23 Aug 2019 19:16:13 +0300 Message-Id: <20190823161616.27644-2-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190823161616.27644-1-jarkko.sakkinen@linux.intel.com> References: <20190823161616.27644-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org Sean complained about boolean parameters so I though that maybe it would be good to rework the EWB flow in a way that it operates by a page type and here is the result. The contract is and will be that as long as you give the correct page type, you will get what you want. That is why I set REG and TCS appropriately even though they are treated the same way at this point of time. Cc: Sean Christopherson Signed-off-by: Jarkko Sakkinen --- arch/x86/kernel/cpu/sgx/reclaim.c | 43 +++++++++++++++++++------------ 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/reclaim.c b/arch/x86/kernel/cpu/sgx/reclaim.c index 00f596c64a2d..3f10a8ff00b7 100644 --- a/arch/x86/kernel/cpu/sgx/reclaim.c +++ b/arch/x86/kernel/cpu/sgx/reclaim.c @@ -221,7 +221,7 @@ static void sgx_reclaimer_block(struct sgx_epc_page *epc_page) static int __sgx_encl_ewb(struct sgx_encl *encl, struct sgx_epc_page *epc_page, struct sgx_va_page *va_page, unsigned int va_offset, - bool is_secs_child) + unsigned int pt) { struct sgx_encl_page *encl_page = epc_page->owner; struct sgx_pageinfo pginfo; @@ -232,10 +232,14 @@ static int __sgx_encl_ewb(struct sgx_encl *encl, struct sgx_epc_page *epc_page, struct page *pcmd; int ret; - if (is_secs_child) - page_index = SGX_ENCL_PAGE_INDEX(encl_page); - else + if (pt != SGX_SECINFO_SECS && pt != SGX_SECINFO_TCS && + pt != SGX_SECINFO_REG) + return -EINVAL; + + if (pt == SGX_SECINFO_SECS) page_index = PFN_DOWN(encl->size); + else + page_index = SGX_ENCL_PAGE_INDEX(encl_page); pcmd_index = sgx_pcmd_index(encl, page_index); pcmd_offset = sgx_pcmd_offset(page_index); @@ -300,7 +304,7 @@ static const cpumask_t *sgx_encl_ewb_cpumask(struct sgx_encl *encl) return cpumask; } -static void sgx_encl_ewb(struct sgx_epc_page *epc_page, bool is_secs_child) +static void sgx_encl_ewb(struct sgx_epc_page *epc_page, unsigned int pt) { struct sgx_encl_page *encl_page = epc_page->owner; struct sgx_encl *encl = encl_page->encl; @@ -317,8 +321,7 @@ static void sgx_encl_ewb(struct sgx_epc_page *epc_page, bool is_secs_child) if (sgx_va_page_full(va_page)) list_move_tail(&va_page->list, &encl->va_pages); - ret = __sgx_encl_ewb(encl, epc_page, va_page, va_offset, - is_secs_child); + ret = __sgx_encl_ewb(encl, epc_page, va_page, va_offset, pt); if (ret == SGX_NOT_TRACKED) { ret = __etrack(sgx_epc_addr(encl->secs.epc_page)); if (ret) { @@ -327,8 +330,8 @@ static void sgx_encl_ewb(struct sgx_epc_page *epc_page, bool is_secs_child) ENCLS_WARN(ret, "ETRACK"); } - ret = __sgx_encl_ewb(encl, epc_page, va_page, - va_offset, is_secs_child); + ret = __sgx_encl_ewb(encl, epc_page, va_page, va_offset, + pt); if (ret == SGX_NOT_TRACKED) { /* * Slow path, send IPIs to kick cpus out of the @@ -340,7 +343,7 @@ static void sgx_encl_ewb(struct sgx_epc_page *epc_page, bool is_secs_child) on_each_cpu_mask(sgx_encl_ewb_cpumask(encl), sgx_ipi_cb, NULL, 1); ret = __sgx_encl_ewb(encl, epc_page, va_page, - va_offset, is_secs_child); + va_offset, pt); } } @@ -350,12 +353,13 @@ static void sgx_encl_ewb(struct sgx_epc_page *epc_page, bool is_secs_child) encl_page->desc |= va_offset; encl_page->va_page = va_page; - } else if (is_secs_child) { + } else if (pt != SGX_SECINFO_SECS) { ret = __eremove(sgx_epc_addr(epc_page)); WARN(ret, "EREMOVE returned %d\n", ret); } - if (!is_secs_child) + /* The reclaimer is not aware of SECS pages. */ + if (pt == SGX_SECINFO_SECS) sgx_free_page(epc_page); encl_page->epc_page = NULL; @@ -365,15 +369,22 @@ static void sgx_reclaimer_write(struct sgx_epc_page *epc_page) { struct sgx_encl_page *encl_page = epc_page->owner; struct sgx_encl *encl = encl_page->encl; + unsigned int pt; + + if (encl_page->desc & SGX_ENCL_PAGE_TCS) + pt = SGX_SECINFO_TCS; + else + pt = SGX_SECINFO_REG; mutex_lock(&encl->lock); - sgx_encl_ewb(epc_page, true); + sgx_encl_ewb(epc_page, pt); + encl->secs_child_cnt--; + if (!encl->secs_child_cnt && - (encl->flags & (SGX_ENCL_DEAD | SGX_ENCL_INITIALIZED))) { - sgx_encl_ewb(encl->secs.epc_page, false); - } + (encl->flags & (SGX_ENCL_DEAD | SGX_ENCL_INITIALIZED))) + sgx_encl_ewb(encl->secs.epc_page, SGX_SECINFO_SECS); mutex_unlock(&encl->lock); } From patchwork Fri Aug 23 16:16:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 11112049 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DA7021813 for ; Fri, 23 Aug 2019 16:16:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C34032339D for ; Fri, 23 Aug 2019 16:16:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2436661AbfHWQQh (ORCPT ); Fri, 23 Aug 2019 12:16:37 -0400 Received: from mga12.intel.com ([192.55.52.136]:17322 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2436675AbfHWQQh (ORCPT ); Fri, 23 Aug 2019 12:16:37 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Aug 2019 09:16:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,421,1559545200"; d="scan'208";a="263231706" Received: from unknown (HELO localhost) ([10.252.39.229]) by orsmga001.jf.intel.com with ESMTP; 23 Aug 2019 09:16:30 -0700 From: Jarkko Sakkinen To: linux-sgx@vger.kernel.org Cc: sean.j.christopherson@intel.com, serge.ayoun@intel.com, shay.katz-zamir@intel.com, Jarkko Sakkinen Subject: [PATCH 2/4] x86/sgx: Validate TCS permssions in sgx_validate_secinfo() Date: Fri, 23 Aug 2019 19:16:14 +0300 Message-Id: <20190823161616.27644-3-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190823161616.27644-1-jarkko.sakkinen@linux.intel.com> References: <20190823161616.27644-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org The validation of TCS permissions was missing from sgx_validate_secinfo(). This patch adds the validation. Signed-off-by: Jarkko Sakkinen --- arch/x86/kernel/cpu/sgx/ioctl.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index f9eef0f2125f..5423d7c45d5e 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -298,6 +298,13 @@ static int sgx_validate_secinfo(struct sgx_secinfo *secinfo) if ((perm & SGX_SECINFO_W) && !(perm & SGX_SECINFO_R)) return -EINVAL; + /* + * CPU will silently overwrite the permissions as zero, which means + * that we need to validate it ourselves. + */ + if (pt == SGX_SECINFO_TCS && perm) + return -EINVAL; + if (secinfo->flags & SGX_SECINFO_RESERVED_MASK) return -EINVAL; From patchwork Fri Aug 23 16:16:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 11112051 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 17649184E for ; Fri, 23 Aug 2019 16:17:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F250A22CE3 for ; Fri, 23 Aug 2019 16:17:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2436678AbfHWQRJ (ORCPT ); Fri, 23 Aug 2019 12:17:09 -0400 Received: from mga09.intel.com ([134.134.136.24]:47957 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2436675AbfHWQRJ (ORCPT ); Fri, 23 Aug 2019 12:17:09 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Aug 2019 09:17:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,421,1559545200"; d="scan'208";a="263231717" Received: from unknown (HELO localhost) ([10.252.39.229]) by orsmga001.jf.intel.com with ESMTP; 23 Aug 2019 09:16:35 -0700 From: Jarkko Sakkinen To: linux-sgx@vger.kernel.org Cc: sean.j.christopherson@intel.com, serge.ayoun@intel.com, shay.katz-zamir@intel.com, Jarkko Sakkinen Subject: [PATCH 3/4] x86/sgx: Remove a deperecated enum Date: Fri, 23 Aug 2019 19:16:15 +0300 Message-Id: <20190823161616.27644-4-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190823161616.27644-1-jarkko.sakkinen@linux.intel.com> References: <20190823161616.27644-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org &sgx_encl_mm_iter is no longer used for anything. Signed-off-by: Jarkko Sakkinen --- arch/x86/kernel/cpu/sgx/encl.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h index cc1f8c4b1472..37b5c4bcda7a 100644 --- a/arch/x86/kernel/cpu/sgx/encl.h +++ b/arch/x86/kernel/cpu/sgx/encl.h @@ -109,12 +109,6 @@ static inline unsigned long sgx_pcmd_offset(pgoff_t page_index) sizeof(struct sgx_pcmd); } -enum sgx_encl_mm_iter { - SGX_ENCL_MM_ITER_DONE = 0, - SGX_ENCL_MM_ITER_NEXT = 1, - SGX_ENCL_MM_ITER_RESTART = 2, -}; - int sgx_encl_find(struct mm_struct *mm, unsigned long addr, struct vm_area_struct **vma); void sgx_encl_destroy(struct sgx_encl *encl); From patchwork Fri Aug 23 16:16:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 11112053 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F1BFB184E for ; Fri, 23 Aug 2019 16:17:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DA46922CEC for ; Fri, 23 Aug 2019 16:17:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2436675AbfHWQRK (ORCPT ); Fri, 23 Aug 2019 12:17:10 -0400 Received: from mga09.intel.com ([134.134.136.24]:47957 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2436677AbfHWQRK (ORCPT ); Fri, 23 Aug 2019 12:17:10 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Aug 2019 09:17:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,421,1559545200"; d="scan'208";a="263231729" Received: from unknown (HELO localhost) ([10.252.39.229]) by orsmga001.jf.intel.com with ESMTP; 23 Aug 2019 09:16:40 -0700 From: Jarkko Sakkinen To: linux-sgx@vger.kernel.org Cc: sean.j.christopherson@intel.com, serge.ayoun@intel.com, shay.katz-zamir@intel.com, Jarkko Sakkinen Subject: [PATCH 4/4] x86/sgx: Move VM prot bits calculation to sgx_encl_page_alloc() Date: Fri, 23 Aug 2019 19:16:16 +0300 Message-Id: <20190823161616.27644-5-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190823161616.27644-1-jarkko.sakkinen@linux.intel.com> References: <20190823161616.27644-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org Move full VM prot bits calculation to sgx_encl_page_alloc() so that we don't pass duplicate data in the add page flow (@prot and @secinfo hold intersecting data). Signed-off-by: Jarkko Sakkinen --- arch/x86/kernel/cpu/sgx/ioctl.c | 44 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index 5423d7c45d5e..ead9fb2d9b69 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -130,10 +130,10 @@ static int sgx_validate_secs(const struct sgx_secs *secs, static struct sgx_encl_page *sgx_encl_page_alloc(struct sgx_encl *encl, unsigned long addr, - unsigned long prot, - u64 page_type) + u64 secinfo_flags) { struct sgx_encl_page *encl_page; + unsigned long prot; encl_page = kzalloc(sizeof(*encl_page), GFP_KERNEL); if (!encl_page) @@ -142,9 +142,22 @@ static struct sgx_encl_page *sgx_encl_page_alloc(struct sgx_encl *encl, encl_page->desc = addr; encl_page->encl = encl; - if (page_type == SGX_SECINFO_TCS) + if (secinfo_flags & SGX_SECINFO_TCS) encl_page->desc |= SGX_ENCL_PAGE_TCS; + + prot = _calc_vm_trans(secinfo_flags, SGX_SECINFO_R, PROT_READ) | + _calc_vm_trans(secinfo_flags, SGX_SECINFO_W, PROT_WRITE) | + _calc_vm_trans(secinfo_flags, SGX_SECINFO_X, PROT_EXEC); + + /* + * TCS pages must always RW set for CPU access while the SECINFO + * permissions are *always* zero - the CPU ignores the user provided + * values and silently overwrites them with zero permissions. + */ + if ((secinfo_flags & SGX_SECINFO_PAGE_TYPE_MASK) == SGX_SECINFO_TCS) + prot |= PROT_READ | PROT_WRITE; + /* Calculate maximum of the VM flags for the page. */ encl_page->vm_max_prot_bits = calc_vm_prot_bits(prot, 0); @@ -318,7 +331,7 @@ static int __sgx_encl_add_page(struct sgx_encl *encl, struct sgx_encl_page *encl_page, struct sgx_epc_page *epc_page, struct sgx_secinfo *secinfo, unsigned long src, - unsigned long prot, unsigned long mrmask) + unsigned long mrmask) { struct sgx_pageinfo pginfo; struct vm_area_struct *vma; @@ -375,15 +388,14 @@ static int __sgx_encl_add_page(struct sgx_encl *encl, static int sgx_encl_add_page(struct sgx_encl *encl, struct sgx_enclave_add_page *addp, - struct sgx_secinfo *secinfo, unsigned long prot) + struct sgx_secinfo *secinfo) { - u64 page_type = secinfo->flags & SGX_SECINFO_PAGE_TYPE_MASK; struct sgx_encl_page *encl_page; struct sgx_epc_page *epc_page; struct sgx_va_page *va_page; int ret; - encl_page = sgx_encl_page_alloc(encl, addp->addr, prot, page_type); + encl_page = sgx_encl_page_alloc(encl, addp->addr, secinfo->flags); if (IS_ERR(encl_page)) return PTR_ERR(encl_page); @@ -407,7 +419,7 @@ static int sgx_encl_add_page(struct sgx_encl *encl, goto err_out_shrink; ret = __sgx_encl_add_page(encl, encl_page, epc_page, secinfo, - addp->src, prot, addp->mrmask); + addp->src, addp->mrmask); if (ret) goto err_out; @@ -450,7 +462,6 @@ static long sgx_ioc_enclave_add_page(struct file *filep, void __user *arg) struct sgx_encl *encl = filep->private_data; struct sgx_enclave_add_page addp; struct sgx_secinfo secinfo; - unsigned long prot; if (!(encl->flags & SGX_ENCL_CREATED)) return -EINVAL; @@ -472,20 +483,7 @@ static long sgx_ioc_enclave_add_page(struct file *filep, void __user *arg) if (sgx_validate_secinfo(&secinfo)) return -EINVAL; - /* Set prot bits matching to the SECINFO permissions. */ - prot = _calc_vm_trans(secinfo.flags, SGX_SECINFO_R, PROT_READ) | - _calc_vm_trans(secinfo.flags, SGX_SECINFO_W, PROT_WRITE) | - _calc_vm_trans(secinfo.flags, SGX_SECINFO_X, PROT_EXEC); - - /* - * TCS pages must always RW set for CPU access while the SECINFO - * permissions are *always* zero - the CPU ignores the user provided - * values and silently overwrites with zero permissions. - */ - if ((secinfo.flags & SGX_SECINFO_PAGE_TYPE_MASK) == SGX_SECINFO_TCS) - prot |= PROT_READ | PROT_WRITE; - - return sgx_encl_add_page(encl, &addp, &secinfo, prot); + return sgx_encl_add_page(encl, &addp, &secinfo); } static int __sgx_get_key_hash(struct crypto_shash *tfm, const void *modulus,