The VA page creation is illogically split in-between sgx_encl_grow() and sgx_alloc_va_page(). Move it fully to sgx_alloc_va_page(). Signed-off-by: Jarkko Sakkinen <jarkko@xxxxxxxxxx> --- arch/x86/kernel/cpu/sgx/encl.c | 36 +++++++++++++++++++++++---------- arch/x86/kernel/cpu/sgx/encl.h | 2 +- arch/x86/kernel/cpu/sgx/ioctl.c | 20 ++++-------------- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c index 7449ef33f081..42eb879c167a 100644 --- a/arch/x86/kernel/cpu/sgx/encl.c +++ b/arch/x86/kernel/cpu/sgx/encl.c @@ -671,26 +671,40 @@ int sgx_encl_test_and_clear_young(struct mm_struct *mm, * Allocate a free EPC page and convert it to a Version Array (VA) page. * * Return: - * a VA page, - * -errno otherwise + * - A VA page: On success. + * - ERR_PTR(-errno): Otherwise. */ -struct sgx_epc_page *sgx_alloc_va_page(void) +struct sgx_va_page *sgx_alloc_va_page(void) { - struct sgx_epc_page *epc_page; + struct sgx_va_page *va_page; int ret; - epc_page = sgx_alloc_epc_page(NULL, true); - if (IS_ERR(epc_page)) - return ERR_CAST(epc_page); + va_page = kzalloc(sizeof(*va_page), GFP_KERNEL); + if (!va_page) + return ERR_PTR(-ENOMEM); - ret = __epa(sgx_get_epc_virt_addr(epc_page)); + va_page->epc_page = sgx_alloc_epc_page(NULL, true); + if (IS_ERR(va_page->epc_page)) { + ret = PTR_ERR(va_page->epc_page); + goto err_va_page; + } + + ret = __epa(sgx_get_epc_virt_addr(va_page->epc_page)); if (ret) { WARN_ONCE(1, "EPA returned %d (0x%x)", ret, ret); - sgx_free_epc_page(epc_page); - return ERR_PTR(-EFAULT); + ret = -EFAULT; + goto err_epc_page; } - return epc_page; + return va_page; + +err_epc_page: + sgx_free_epc_page(va_page->epc_page); + +err_va_page: + kfree(va_page); + + return ERR_PTR(ret); } /** diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h index d8d30ccbef4c..315e87fcc142 100644 --- a/arch/x86/kernel/cpu/sgx/encl.h +++ b/arch/x86/kernel/cpu/sgx/encl.h @@ -111,7 +111,7 @@ void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write); int sgx_encl_test_and_clear_young(struct mm_struct *mm, struct sgx_encl_page *page); -struct sgx_epc_page *sgx_alloc_va_page(void); +struct sgx_va_page *sgx_alloc_va_page(void); unsigned int sgx_alloc_va_slot(struct sgx_va_page *va_page); void sgx_free_va_slot(struct sgx_va_page *va_page, unsigned int offset); bool sgx_va_page_full(struct sgx_va_page *va_page); diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index 90a5caf76939..db6e2c6ad42d 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -19,26 +19,14 @@ static struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl) { struct sgx_va_page *va_page = NULL; - void *err; - BUILD_BUG_ON(SGX_VA_SLOT_COUNT != - (SGX_ENCL_PAGE_VA_OFFSET_MASK >> 3) + 1); + BUILD_BUG_ON(SGX_VA_SLOT_COUNT != (SGX_ENCL_PAGE_VA_OFFSET_MASK >> 3) + 1); - if (!(encl->page_cnt % SGX_VA_SLOT_COUNT)) { - va_page = kzalloc(sizeof(*va_page), GFP_KERNEL); - if (!va_page) - return ERR_PTR(-ENOMEM); + if (!(encl->page_cnt % SGX_VA_SLOT_COUNT)) + va_page = sgx_alloc_va_page(); - va_page->epc_page = sgx_alloc_va_page(); - if (IS_ERR(va_page->epc_page)) { - err = ERR_CAST(va_page->epc_page); - kfree(va_page); - return err; - } - - WARN_ON_ONCE(encl->page_cnt % SGX_VA_SLOT_COUNT); - } encl->page_cnt++; + return va_page; } -- 2.30.1