summarylogtreecommitdiffstats
path: root/0020-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch
diff options
context:
space:
mode:
Diffstat (limited to '0020-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch')
-rw-r--r--0020-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch101
1 files changed, 101 insertions, 0 deletions
diff --git a/0020-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch b/0020-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch
new file mode 100644
index 000000000000..bd86089962d2
--- /dev/null
+++ b/0020-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch
@@ -0,0 +1,101 @@
+From 0ed2b241836b30d344da4f8f73ce87878aea5c87 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Wed, 13 Apr 2022 14:10:20 -0700
+Subject: [PATCH 20/31] 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.
+
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ arch/x86/kernel/cpu/sgx/ioctl.c | 6 ++++++
+ arch/x86/kernel/cpu/sgx/main.c | 11 +++++++++++
+ arch/x86/kernel/cpu/sgx/sgx.h | 1 +
+ 3 files changed, 18 insertions(+)
+
+diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
+index f9a1654a49b7..83674d054c13 100644
+--- a/arch/x86/kernel/cpu/sgx/ioctl.c
++++ b/arch/x86/kernel/cpu/sgx/ioctl.c
+@@ -745,6 +745,8 @@ sgx_enclave_restrict_permissions(struct sgx_encl *encl,
+ for (c = 0 ; c < modp->length; c += PAGE_SIZE) {
+ addr = encl->base + modp->offset + c;
+
++ sgx_reclaim_direct();
++
+ mutex_lock(&encl->lock);
+
+ entry = sgx_encl_load_page(encl, addr);
+@@ -910,6 +912,8 @@ static long sgx_enclave_modify_type(struct sgx_encl *encl,
+ for (c = 0 ; c < modt->length; c += PAGE_SIZE) {
+ addr = encl->base + modt->offset + c;
+
++ sgx_reclaim_direct();
++
+ mutex_lock(&encl->lock);
+
+ entry = sgx_encl_load_page(encl, addr);
+@@ -1095,6 +1099,8 @@ static long sgx_encl_remove_pages(struct sgx_encl *encl,
+ for (c = 0 ; c < params->length; c += PAGE_SIZE) {
+ addr = encl->base + params->offset + c;
+
++ sgx_reclaim_direct();
++
+ mutex_lock(&encl->lock);
+
+ entry = sgx_encl_load_page(encl, addr);
+diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
+index 1a3014aec490..c6adb7edebca 100644
+--- a/arch/x86/kernel/cpu/sgx/main.c
++++ b/arch/x86/kernel/cpu/sgx/main.c
+@@ -378,6 +378,17 @@ static bool sgx_should_reclaim(unsigned long watermark)
+ !list_empty(&sgx_active_page_list);
+ }
+
++/*
++ * sgx_reclaim_direct() should be called (without enclave's mutex held)
++ * in locations where SGX memory resources might be low and might be
++ * needed in order to make forward progress.
++ */
++void sgx_reclaim_direct(void)
++{
++ if (sgx_should_reclaim(SGX_NR_LOW_PAGES))
++ sgx_reclaim_pages();
++}
++
+ static int ksgxd(void *p)
+ {
+ set_freezable();
+diff --git a/arch/x86/kernel/cpu/sgx/sgx.h b/arch/x86/kernel/cpu/sgx/sgx.h
+index b30cee4de903..0f2020653fba 100644
+--- a/arch/x86/kernel/cpu/sgx/sgx.h
++++ b/arch/x86/kernel/cpu/sgx/sgx.h
+@@ -86,6 +86,7 @@ static inline void *sgx_get_epc_virt_addr(struct sgx_epc_page *page)
+ struct sgx_epc_page *__sgx_alloc_epc_page(void);
+ void sgx_free_epc_page(struct sgx_epc_page *page);
+
++void sgx_reclaim_direct(void);
+ void sgx_mark_page_reclaimable(struct sgx_epc_page *page);
+ int sgx_unmark_page_reclaimable(struct sgx_epc_page *page);
+ struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim);
+--
+2.35.2
+