@@ -110,18 +110,26 @@ static void sgx_vma_close(struct vm_area_struct *vma)
kref_put(&encl->refcount, sgx_encl_release);
}
-static int do_eldu(struct sgx_encl *encl,
- struct sgx_encl_page *encl_page,
- struct sgx_epc_page *epc_page,
- struct page *backing,
- bool is_secs)
+static int sgx_eldu(struct sgx_encl *encl,
+ struct sgx_encl_page *encl_page,
+ struct sgx_epc_page *epc_page,
+ bool is_secs)
{
+ struct page *backing;
struct sgx_page_info pginfo;
void *secs_ptr = NULL;
void *epc_ptr;
void *va_ptr;
int ret;
+ backing = sgx_get_backing(encl, encl_page);
+ if (IS_ERR(backing)) {
+ ret = PTR_ERR(backing);
+ sgx_warn(encl, "pinning the backing page for ELDU failed with %d\n",
+ ret);
+ return ret;
+ }
+
pginfo.srcpge = (unsigned long)kmap_atomic(backing);
if (!is_secs)
secs_ptr = sgx_get_epc_page(encl->secs_page.epc_page);
@@ -144,10 +152,13 @@ static int do_eldu(struct sgx_encl *encl,
if (!is_secs)
sgx_put_epc_page(secs_ptr);
+ sgx_put_backing(backing, 0);
+
kunmap_atomic((void *)(unsigned long)pginfo.srcpge);
- WARN_ON(ret);
- if (ret)
+ if (ret) {
+ sgx_err(encl, "ELDU returned %d\n", ret);
return -EFAULT;
+ }
return 0;
}
@@ -159,7 +170,6 @@ static struct sgx_encl_page *sgx_vma_do_fault(struct vm_area_struct *vma,
struct sgx_encl_page *entry;
struct sgx_epc_page *epc_page = NULL;
struct sgx_epc_page *secs_epc_page = NULL;
- struct page *backing;
unsigned int free_flags = SGX_FREE_SKIP_EREMOVE;
int rc;
@@ -218,15 +228,7 @@ static struct sgx_encl_page *sgx_vma_do_fault(struct vm_area_struct *vma,
goto out;
}
- backing = sgx_get_backing(encl, &encl->secs_page);
- if (IS_ERR(backing)) {
- entry = (void *)backing;
- goto out;
- }
-
- rc = do_eldu(encl, &encl->secs_page, secs_epc_page,
- backing, true /* is_secs */);
- sgx_put_backing(backing, 0);
+ rc = sgx_eldu(encl, &encl->secs_page, secs_epc_page, true);
if (rc)
goto out;
@@ -237,22 +239,13 @@ static struct sgx_encl_page *sgx_vma_do_fault(struct vm_area_struct *vma,
secs_epc_page = NULL;
}
- backing = sgx_get_backing(encl, entry);
- if (IS_ERR(backing)) {
- entry = (void *)backing;
- goto out;
- }
-
- rc = do_eldu(encl, entry, epc_page, backing, false /* is_secs */);
+ rc = sgx_eldu(encl, entry, epc_page, false /* is_secs */);
if (rc) {
- sgx_put_backing(backing, 0);
entry = ERR_PTR(rc);
goto out;
}
rc = vm_insert_pfn(vma, entry->addr, PFN_DOWN(epc_page->pa));
- sgx_put_backing(backing, 0);
-
if (rc) {
free_flags = 0;
goto out;
Encapsulted pinning of the backing page into sgx_eldu in order to drop duplicate code. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> --- drivers/platform/x86/intel_sgx_vma.c | 47 +++++++++++++++--------------------- 1 file changed, 20 insertions(+), 27 deletions(-)