@@ -160,7 +160,6 @@ static struct sgx_encl_page *sgx_vma_do_fault(struct vm_area_struct *vma,
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;
/* If process was forked, VMA is still there but vm_private_data is set
@@ -253,8 +252,11 @@ static struct sgx_encl_page *sgx_vma_do_fault(struct vm_area_struct *vma,
rc = vm_insert_pfn(vma, entry->addr, PFN_DOWN(epc_page->pa));
sgx_put_backing(backing, 0);
+ /* failure to insert a pfn after ELDU is fatal to the enclave */
if (rc) {
- free_flags = 0;
+ sgx_warn(encl, "vm_insert_pfn in fault returned %d\n", rc);
+ zap_vma_ptes(vma, vma->vm_start, vma->vm_end - vma->vm_start);
+ encl->flags |= SGX_ENCL_DEAD;
entry = ERR_PTR(rc);
goto out;
}
@@ -274,7 +276,7 @@ static struct sgx_encl_page *sgx_vma_do_fault(struct vm_area_struct *vma,
out:
mutex_unlock(&encl->lock);
if (epc_page)
- sgx_free_page(epc_page, encl, free_flags);
+ sgx_free_page(epc_page, encl, SGX_FREE_SKIP_EREMOVE);
if (secs_epc_page)
sgx_free_page(secs_epc_page, encl, SGX_FREE_SKIP_EREMOVE);
return entry;
Log a warning and kill the enclave if vm_insert_pfn fails while handling a page fault. Removing the page from the EPC via EREMOVE can result in kernel panics as EREMOVE will fail if there are active threads in the enclave. Retrying vm_insert_pfn at a later date won't succeed as calls to vm_insert_pfn are protected by encl->lock, i.e. there are no valid scenarios where EBUSY can be returned, failure indicates a driver bug. Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> --- drivers/platform/x86/intel_sgx_vma.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)