diff --git a/drivers/platform/x86/intel_sgx.h b/drivers/platform/x86/intel_sgx.h
index 23cfd63..fe48313 100644
--- a/drivers/platform/x86/intel_sgx.h
+++ b/drivers/platform/x86/intel_sgx.h
@@ -93,19 +93,27 @@ static inline void sgx_free_va_slot(struct sgx_va_page *page,
 	clear_bit(offset >> 3, page->slots);
 }
 
+
+struct sgx_evicted_page {
+	struct sgx_pcmd pcmd;
+	struct sgx_va_page *va_page;
+	unsigned int va_offset;
+};
+
 enum sgx_encl_page_flags {
 	SGX_ENCL_PAGE_TCS	= BIT(0),
 	SGX_ENCL_PAGE_RESERVED	= BIT(1),
+	SGX_ENCL_PAGE_IN_EPC   	= BIT(2),
 };
 
 struct sgx_encl_page {
 	unsigned long addr;
 	unsigned int flags;
-	struct sgx_epc_page *epc_page;
+	union {
+		struct sgx_epc_page *epc_page;
+		struct sgx_evicted_page *evicted_page;
+	};
 	struct list_head load_list;
-	struct sgx_va_page *va_page;
-	unsigned int va_offset;
-	struct sgx_pcmd pcmd;
 };
 
 struct sgx_tgid_ctx {
diff --git a/drivers/platform/x86/intel_sgx_ioctl.c b/drivers/platform/x86/intel_sgx_ioctl.c
index a5849c6..dbb29ab 100644
--- a/drivers/platform/x86/intel_sgx_ioctl.c
+++ b/drivers/platform/x86/intel_sgx_ioctl.c
@@ -268,6 +268,7 @@ static bool sgx_process_add_page_req(struct sgx_add_page_req *req)
 		goto out;
 	}
 
+	encl_page->flags |= SGX_ENCL_PAGE_IN_EPC;
 	encl_page->epc_page = epc_page;
 	sgx_test_and_clear_young(encl_page, encl);
 	list_add_tail(&encl_page->load_list, &encl->load_list);
@@ -546,6 +547,7 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd,
 		goto out;
 	}
 
+	encl->secs_page.flags |= SGX_ENCL_PAGE_IN_EPC;
 	encl->secs_page.epc_page = secs_epc;
 	createp->src = (unsigned long)encl->base;
 
diff --git a/drivers/platform/x86/intel_sgx_page_cache.c b/drivers/platform/x86/intel_sgx_page_cache.c
index e5965b3..ced8128 100644
--- a/drivers/platform/x86/intel_sgx_page_cache.c
+++ b/drivers/platform/x86/intel_sgx_page_cache.c
@@ -262,18 +262,17 @@ static void sgx_free_encl_page(struct sgx_encl_page *encl_page,
 {
 	sgx_free_page(encl_page->epc_page, encl, flags);
 	encl_page->epc_page = NULL;
-	encl_page->flags &= ~SGX_ENCL_PAGE_RESERVED;
+	encl_page->flags &= ~(SGX_ENCL_PAGE_RESERVED | SGX_ENCL_PAGE_IN_EPC);
 }
 
 static int __sgx_ewb(struct sgx_encl *encl,
 		     struct sgx_encl_page *encl_page)
 {
 	struct sgx_page_info pginfo;
-	struct sgx_va_page *va_page;
+	struct sgx_evicted_page *evicted_page;
 	struct page *backing;
 	void *epc;
 	void *va;
-	unsigned int va_offset;
 	int ret;
 
 	backing = sgx_get_backing(encl, encl_page);
@@ -284,31 +283,39 @@ static int __sgx_ewb(struct sgx_encl *encl,
 		return ret;
 	}
 
-	va_offset = sgx_alloc_va_slot(encl, &va_page);
-	if (va_offset == PAGE_SIZE) {
+	evicted_page = kmalloc(sizeof(*evicted_page), GFP_KERNEL);
+	if (!evicted_page) {
+		sgx_put_backing(backing, true);
+		return -ENOMEM;
+	}
+
+	evicted_page->va_offset = sgx_alloc_va_slot(encl, &evicted_page->va_page);
+	if (evicted_page->va_offset == PAGE_SIZE) {
+		kfree(evicted_page);
 		sgx_put_backing(backing, true);
 		return -ENOMEM;
 	}
 
 	epc = sgx_get_epc_page(encl_page->epc_page);
-	va = sgx_get_epc_page(va_page->epc_page);
+	va = sgx_get_epc_page(evicted_page->va_page->epc_page);
 
 	pginfo.srcpge = (unsigned long)kmap_atomic(backing);
-	pginfo.pcmd = (unsigned long)&encl_page->pcmd;
+	pginfo.pcmd = (unsigned long)&evicted_page->pcmd;
 	pginfo.linaddr = 0;
 	pginfo.secs = 0;
 	ret = __ewb(&pginfo, epc,
-		    (void *)((unsigned long)va + va_offset));
+		    (void *)((unsigned long)va + evicted_page->va_offset));
 	kunmap_atomic((void *)(unsigned long)pginfo.srcpge);
 
 	sgx_put_epc_page(va);
 	sgx_put_epc_page(epc);
 
 	if (ret == SGX_SUCCESS) {
-		encl_page->va_page = va_page;
-		encl_page->va_offset = va_offset;
+		sgx_free_encl_page(encl_page, encl, SGX_FREE_SKIP_EREMOVE);
+		encl_page->evicted_page = evicted_page;
 	} else {
-		sgx_free_va_slot(va_page, va_offset);
+		sgx_free_va_slot(evicted_page->va_page, evicted_page->va_offset);
+		kfree(evicted_page);
 	}
 
 	sgx_put_backing(backing, true);
@@ -327,9 +334,7 @@ static void sgx_ewb(struct sgx_encl *encl,
 		ret = __sgx_ewb(encl, encl_page);
 	}
 
-	if (ret == SGX_SUCCESS) {
-		sgx_free_encl_page(encl_page, encl, SGX_FREE_SKIP_EREMOVE);
-	} else {
+	if (ret) {
 		sgx_free_encl_page(encl_page, encl, 0);
 		if (!(encl->flags & SGX_ENCL_DEAD)) {
 			/* make enclave inaccessible */
diff --git a/drivers/platform/x86/intel_sgx_util.c b/drivers/platform/x86/intel_sgx_util.c
index 2c390c5..3234f59 100644
--- a/drivers/platform/x86/intel_sgx_util.c
+++ b/drivers/platform/x86/intel_sgx_util.c
@@ -218,10 +218,10 @@ void sgx_encl_release(struct kref *ref)
 
 	radix_tree_for_each_slot(slot, &encl->page_tree, &iter, 0) {
 		entry = *slot;
-		if (entry->epc_page) {
-			list_del(&entry->load_list);
+		if (entry->flags & SGX_ENCL_PAGE_IN_EPC)
 			sgx_free_page(entry->epc_page, encl, 0);
-		}
+		else if (entry->evicted_page)
+			kfree(entry->evicted_page);
 		radix_tree_delete(&encl->page_tree, entry->addr >> PAGE_SHIFT);
 		kfree(entry);
 	}
@@ -234,10 +234,10 @@ void sgx_encl_release(struct kref *ref)
 		kfree(va_page);
 	}
 
-	if (encl->secs_page.epc_page)
+	if (encl->secs_page.flags & SGX_ENCL_PAGE_IN_EPC)
 		sgx_free_page(encl->secs_page.epc_page, encl, 0);
-
-	encl->secs_page.epc_page = NULL;
+	else if (encl->secs_page.evicted_page)
+		kfree(encl->secs_page.evicted_page);
 
 	if (encl->tgid_ctx)
 		kref_put(&encl->tgid_ctx->refcount, sgx_tgid_ctx_release);
diff --git a/drivers/platform/x86/intel_sgx_vma.c b/drivers/platform/x86/intel_sgx_vma.c
index fd5536c..1a6b45e 100644
--- a/drivers/platform/x86/intel_sgx_vma.c
+++ b/drivers/platform/x86/intel_sgx_vma.c
@@ -128,15 +128,15 @@ static int do_eldu(struct sgx_encl *encl,
 	pginfo.secs = (unsigned long)secs_ptr;
 
 	epc_ptr = sgx_get_epc_page(epc_page);
-	va_ptr = sgx_get_epc_page(encl_page->va_page->epc_page);
+	va_ptr = sgx_get_epc_page(encl_page->evicted_page->va_page->epc_page);
 
 	pginfo.linaddr = is_secs ? 0 : encl_page->addr;
-	pginfo.pcmd = (unsigned long)&encl_page->pcmd;
+	pginfo.pcmd = (unsigned long)&encl_page->evicted_page->pcmd;
 
 	ret = __eldu((unsigned long)&pginfo,
 		     (unsigned long)epc_ptr,
 		     (unsigned long)va_ptr +
-		     encl_page->va_offset);
+		     encl_page->evicted_page->va_offset);
 
 	sgx_put_epc_page(va_ptr);
 	sgx_put_epc_page(epc_ptr);
@@ -149,8 +149,12 @@ static int do_eldu(struct sgx_encl *encl,
 	if (ret)
 		return -EFAULT;
 
-	sgx_free_va_slot(encl_page->va_page, encl_page->va_offset);
+	sgx_free_va_slot(encl_page->evicted_page->va_page,
+			 encl_page->evicted_page->va_offset);
+	kfree(encl_page->evicted_page);
+	encl_page->evicted_page = NULL;
 
+	encl_page->flags |= SGX_ENCL_PAGE_IN_EPC;
 	encl_page->epc_page = epc_page;
 
 	return 0;
@@ -206,14 +210,14 @@ static struct sgx_encl_page *sgx_vma_do_fault(struct vm_area_struct *vma,
 	}
 
 	/* Legal race condition, page is already faulted. */
-	if (entry->epc_page) {
+	if (entry->flags & SGX_ENCL_PAGE_IN_EPC) {
 		if (reserve)
 			entry->flags |= SGX_ENCL_PAGE_RESERVED;
 		goto out;
 	}
 
 	/* If SECS is evicted then reload it first */
-	if (!encl->secs_page.epc_page) {
+	if (!(encl->secs_page.flags & SGX_ENCL_PAGE_IN_EPC)) {
 		secs_epc_page = sgx_alloc_page(encl->tgid_ctx, SGX_ALLOC_ATOMIC);
 		if (IS_ERR(secs_epc_page)) {
 			entry = (void *)secs_epc_page;
