Skip to content

Commit a76e7f1

Browse files
rchatrehansendc
authored andcommitted
x86/sgx: Support VA page allocation without reclaiming
struct sgx_encl should be protected with the mutex sgx_encl->lock. One exception is sgx_encl->page_cnt that is incremented (in sgx_encl_grow()) when an enclave page is added to the enclave. The reason the mutex is not held is to allow the reclaimer to be called directly if there are no EPC pages (in support of a new VA page) available at the time. Incrementing sgx_encl->page_cnt without sgc_encl->lock held is currently (before SGX2) safe from concurrent updates because all paths in which sgx_encl_grow() is called occur before enclave initialization and are protected with an atomic operation on SGX_ENCL_IOCTL. SGX2 includes support for dynamically adding pages after enclave initialization where the protection of SGX_ENCL_IOCTL is not available. Make direct reclaim of EPC pages optional when new VA pages are added to the enclave. Essentially the existing "reclaim" flag used when regular EPC pages are added to an enclave becomes available to the caller when used to allocate VA pages instead of always being "true". When adding pages without invoking the reclaimer it is possible to do so with sgx_encl->lock held, gaining its protection against concurrent updates to sgx_encl->page_cnt after enclave initialization. No functional change. Reported-by: Haitao Huang <haitao.huang@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Link: https://lkml.kernel.org/r/42c5934c229982ee67982bb97c6ab34bde758620.1652137848.git.reinette.chatre@intel.com
1 parent 8123073 commit a76e7f1

3 files changed

Lines changed: 10 additions & 8 deletions

File tree

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -964,19 +964,21 @@ void sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr)
964964

965965
/**
966966
* sgx_alloc_va_page() - Allocate a Version Array (VA) page
967+
* @reclaim: Reclaim EPC pages directly if none available. Enclave
968+
* mutex should not be held if this is set.
967969
*
968970
* Allocate a free EPC page and convert it to a Version Array (VA) page.
969971
*
970972
* Return:
971973
* a VA page,
972974
* -errno otherwise
973975
*/
974-
struct sgx_epc_page *sgx_alloc_va_page(void)
976+
struct sgx_epc_page *sgx_alloc_va_page(bool reclaim)
975977
{
976978
struct sgx_epc_page *epc_page;
977979
int ret;
978980

979-
epc_page = sgx_alloc_epc_page(NULL, true);
981+
epc_page = sgx_alloc_epc_page(NULL, reclaim);
980982
if (IS_ERR(epc_page))
981983
return ERR_CAST(epc_page);
982984

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,14 @@ struct sgx_encl_page *sgx_encl_page_alloc(struct sgx_encl *encl,
116116
unsigned long offset,
117117
u64 secinfo_flags);
118118
void sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr);
119-
struct sgx_epc_page *sgx_alloc_va_page(void);
119+
struct sgx_epc_page *sgx_alloc_va_page(bool reclaim);
120120
unsigned int sgx_alloc_va_slot(struct sgx_va_page *va_page);
121121
void sgx_free_va_slot(struct sgx_va_page *va_page, unsigned int offset);
122122
bool sgx_va_page_full(struct sgx_va_page *va_page);
123123
void sgx_encl_free_epc_page(struct sgx_epc_page *page);
124124
struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl,
125125
unsigned long addr);
126-
struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl);
126+
struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl, bool reclaim);
127127
void sgx_encl_shrink(struct sgx_encl *encl, struct sgx_va_page *va_page);
128128

129129
#endif /* _X86_ENCL_H */

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "encl.h"
1818
#include "encls.h"
1919

20-
struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl)
20+
struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl, bool reclaim)
2121
{
2222
struct sgx_va_page *va_page = NULL;
2323
void *err;
@@ -30,7 +30,7 @@ struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl)
3030
if (!va_page)
3131
return ERR_PTR(-ENOMEM);
3232

33-
va_page->epc_page = sgx_alloc_va_page();
33+
va_page->epc_page = sgx_alloc_va_page(reclaim);
3434
if (IS_ERR(va_page->epc_page)) {
3535
err = ERR_CAST(va_page->epc_page);
3636
kfree(va_page);
@@ -64,7 +64,7 @@ static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs)
6464
struct file *backing;
6565
long ret;
6666

67-
va_page = sgx_encl_grow(encl);
67+
va_page = sgx_encl_grow(encl, true);
6868
if (IS_ERR(va_page))
6969
return PTR_ERR(va_page);
7070
else if (va_page)
@@ -275,7 +275,7 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long src,
275275
return PTR_ERR(epc_page);
276276
}
277277

278-
va_page = sgx_encl_grow(encl);
278+
va_page = sgx_encl_grow(encl, true);
279279
if (IS_ERR(va_page)) {
280280
ret = PTR_ERR(va_page);
281281
goto err_out_free;

0 commit comments

Comments
 (0)