@@ -93,25 +93,33 @@ 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;
- pginfo.srcpge = (unsigned long)kmap_atomic(backing);
+ 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;
+ }
+
if (!is_secs)
secs_ptr = sgx_get_epc_page(encl->secs_page.epc_page);
pginfo.secs = (unsigned long)secs_ptr;
epc_ptr = sgx_get_epc_page(epc_page);
va_ptr = sgx_get_epc_page(encl_page->va_page->epc_page);
+ pginfo.srcpge = (unsigned long)kmap_atomic(backing);
pginfo.linaddr = is_secs ? 0 : encl_page->addr;
pginfo.pcmd = (unsigned long)&encl_page->pcmd;
@@ -121,16 +129,19 @@ static int do_eldu(struct sgx_encl *encl,
(unsigned long)va_ptr +
encl_page->va_offset);
+ kunmap_atomic((void *)(unsigned long)pginfo.srcpge);
sgx_put_epc_page(va_ptr);
sgx_put_epc_page(epc_ptr);
if (!is_secs)
sgx_put_epc_page(secs_ptr);
- kunmap_atomic((void *)(unsigned long)pginfo.srcpge);
- WARN_ON(ret);
- if (ret)
+ sgx_put_backing(backing, false);
+
+ if (ret) {
+ sgx_err(encl, "ELDU returned %d\n", ret);
return -EFAULT;
+ }
return 0;
}
@@ -142,7 +153,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;
@@ -201,15 +211,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;
@@ -220,24 +222,15 @@ 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;
}
+ free_flags = 0;
rc = vm_insert_pfn(vma, entry->addr, PFN_DOWN(epc_page->pa));
- sgx_put_backing(backing, 0);
-
if (rc) {
- free_flags = 0;
entry = ERR_PTR(rc);
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 | 53 ++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 30 deletions(-)