If backing pages are not able to be allocated during sgx_reclaim_pages(), return an error code to the caller. sgx_reclaim_pages() can be called from the reclaimer thread, or when adding pages via an ioctl. When it is called from the kernel thread, it's safe to ignore the return value, however, calls from the ioctls should forward the error. Signed-off-by: Kristen Carlson Accardi <kristen@xxxxxxxxxxxxxxx> --- arch/x86/kernel/cpu/sgx/main.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c index c4030fb608c6..0e95f69ebcb7 100644 --- a/arch/x86/kernel/cpu/sgx/main.c +++ b/arch/x86/kernel/cpu/sgx/main.c @@ -377,17 +377,18 @@ static void sgx_reclaimer_write(struct sgx_epc_page *epc_page, * problematic as it would increase the lock contention too much, which would * halt forward progress. */ -static void sgx_reclaim_pages(void) +static int sgx_reclaim_pages(void) { struct sgx_epc_page *chunk[SGX_NR_TO_SCAN]; struct sgx_backing backing[SGX_NR_TO_SCAN]; struct sgx_epc_section *section; struct sgx_encl_page *encl_page; + int pages_being_reclaimed = 0; struct sgx_epc_page *epc_page; struct sgx_numa_node *node; pgoff_t page_index; int cnt = 0; - int ret; + int ret = 0; int i; spin_lock(&sgx_reclaimer_lock); @@ -422,6 +423,8 @@ static void sgx_reclaim_pages(void) if (ret) goto skip; + pages_being_reclaimed++; + mutex_lock(&encl_page->encl->lock); encl_page->desc |= SGX_ENCL_PAGE_BEING_RECLAIMED; mutex_unlock(&encl_page->encl->lock); @@ -437,6 +440,9 @@ static void sgx_reclaim_pages(void) chunk[i] = NULL; } + if (!pages_being_reclaimed) + return ret; + for (i = 0; i < cnt; i++) { epc_page = chunk[i]; if (epc_page) @@ -463,6 +469,7 @@ static void sgx_reclaim_pages(void) spin_unlock(&node->lock); atomic_long_inc(&sgx_nr_free_pages); } + return ret; } static bool sgx_should_reclaim(unsigned long watermark) @@ -636,6 +643,7 @@ int sgx_unmark_page_reclaimable(struct sgx_epc_page *page) struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim) { struct sgx_epc_page *page; + int ret; for ( ; ; ) { page = __sgx_alloc_epc_page(); @@ -657,7 +665,11 @@ struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim) break; } - sgx_reclaim_pages(); + ret = sgx_reclaim_pages(); + if (ret) { + page = ERR_PTR(-ENOMEM); + break; + } cond_resched(); } -- 2.20.1