@@ -469,14 +469,19 @@ void sgx_encl_destroy(struct sgx_encl *encl)
radix_tree_for_each_slot(slot, &encl->page_tree, &iter, 0) {
entry = *slot;
if (entry->epc_page) {
- if (!sgx_free_page(entry->epc_page)) {
- encl->secs_child_cnt--;
- entry->epc_page = NULL;
- }
-
- radix_tree_delete(&entry->encl->page_tree,
- PFN_DOWN(entry->desc));
+ /*
+ * The page and its radix tree entry cannot be freed
+ * if the page is being held by the reclaimer.
+ */
+ if (sgx_free_page(entry->epc_page))
+ continue;
+ encl->secs_child_cnt--;
+ entry->epc_page = NULL;
}
+
+ radix_tree_delete(&entry->encl->page_tree,
+ PFN_DOWN(entry->desc));
+ kfree(entry);
}
if (!encl->secs_child_cnt && encl->secs.epc_page) {
Delete an enclave page's entry in the radix tree regardless of whether or not it has an associated EPC page, and free the page itself when it's deleted from the radix tree. Don't free/delete anything if the page is held by the reclaimer, as the reclaimer needs the page itself and the driver needs the radix entry to re-process the entry during sgx_encl_release(). Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> --- arch/x86/kernel/cpu/sgx/encl.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)