Skip to content

Commit a0506b3

Browse files
rchatrehansendc
authored andcommitted
x86/sgx: Free up EPC pages directly to support large page ranges
The page reclaimer ensures availability of EPC pages across all enclaves. In support of this it runs independently from the individual enclaves in order to take locks from the different enclaves as it writes pages to swap. When needing to load a page from swap an EPC page needs to be available for its contents to be loaded into. Loading an existing enclave page from swap does not reclaim EPC pages directly if none are available, instead the reclaimer is woken when the available EPC pages are found to be below a watermark. When iterating over a large number of pages in an oversubscribed environment there is a race between the reclaimer woken up and EPC pages reclaimed fast enough for the page operations to proceed. Ensure there are EPC pages available before attempting to load a page that may potentially be pulled from swap into an available EPC page. Signed-off-by: Reinette Chatre <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Acked-by: Jarkko Sakkinen <[email protected]> Link: https://lkml.kernel.org/r/a0d8f037c4a075d56bf79f432438412985f7ff7a.1652137848.git.reinette.chatre@intel.com
1 parent 9849bb2 commit a0506b3

File tree

3 files changed

+18
-0
lines changed

3 files changed

+18
-0
lines changed

arch/x86/kernel/cpu/sgx/ioctl.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,8 @@ sgx_enclave_restrict_permissions(struct sgx_encl *encl,
745745
for (c = 0 ; c < modp->length; c += PAGE_SIZE) {
746746
addr = encl->base + modp->offset + c;
747747

748+
sgx_reclaim_direct();
749+
748750
mutex_lock(&encl->lock);
749751

750752
entry = sgx_encl_load_page(encl, addr);
@@ -910,6 +912,8 @@ static long sgx_enclave_modify_types(struct sgx_encl *encl,
910912
for (c = 0 ; c < modt->length; c += PAGE_SIZE) {
911913
addr = encl->base + modt->offset + c;
912914

915+
sgx_reclaim_direct();
916+
913917
mutex_lock(&encl->lock);
914918

915919
entry = sgx_encl_load_page(encl, addr);
@@ -1096,6 +1100,8 @@ static long sgx_encl_remove_pages(struct sgx_encl *encl,
10961100
for (c = 0 ; c < params->length; c += PAGE_SIZE) {
10971101
addr = encl->base + params->offset + c;
10981102

1103+
sgx_reclaim_direct();
1104+
10991105
mutex_lock(&encl->lock);
11001106

11011107
entry = sgx_encl_load_page(encl, addr);

arch/x86/kernel/cpu/sgx/main.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,17 @@ static bool sgx_should_reclaim(unsigned long watermark)
375375
!list_empty(&sgx_active_page_list);
376376
}
377377

378+
/*
379+
* sgx_reclaim_direct() should be called (without enclave's mutex held)
380+
* in locations where SGX memory resources might be low and might be
381+
* needed in order to make forward progress.
382+
*/
383+
void sgx_reclaim_direct(void)
384+
{
385+
if (sgx_should_reclaim(SGX_NR_LOW_PAGES))
386+
sgx_reclaim_pages();
387+
}
388+
378389
static int ksgxd(void *p)
379390
{
380391
set_freezable();

arch/x86/kernel/cpu/sgx/sgx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page)
8686
struct sgx_epc_page *__sgx_alloc_epc_page(void);
8787
void sgx_free_epc_page(struct sgx_epc_page *page);
8888

89+
void sgx_reclaim_direct(void);
8990
void sgx_mark_page_reclaimable(struct sgx_epc_page *page);
9091
int sgx_unmark_page_reclaimable(struct sgx_epc_page *page);
9192
struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim);

0 commit comments

Comments
 (0)