[intel-sgx-kernel-dev,6/6] intel_sgx: Combine epc/eviction pages via union
diff mbox

Message ID 1482437735-4722-7-git-send-email-sean.j.christopherson@intel.com
State New
Headers show

Commit Message

Sean Christopherson Dec. 22, 2016, 8:15 p.m. UTC
Add a new struct, sgx_evicted_page, to hold all information about an
evicted enclave page, e.g. VA page, VA offset and PCMD.  Dynamically
allocate the evicted page object at EWB and free it at ELDU.

Combine sgx_encl_page's epc_page and evicted_page into a union, as
on-demand VA and PCMD allocation only epc_page or evicted_page will
be valid at any given time.

Add a new flag, SGX_ENCL_PAGE_IN_EPC, to track if an encl page has
been loaded into the EPC.  If SGX_ENCL_PAGE_IN_EPC is set, then the
epc_page member of the epc_page/evicted_page union is valid, else
va_page *may* be valid, e.g. neither is valid if EADD has not been
completed.

Call sgx_free_encl_page in the success path of __sgx_ewb, as the EPC
page must be freed before updating the encl_page's va_page.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
---
 drivers/platform/x86/intel_sgx.h            | 16 ++++++++++----
 drivers/platform/x86/intel_sgx_ioctl.c      |  2 ++
 drivers/platform/x86/intel_sgx_page_cache.c | 33 +++++++++++++++++------------
 drivers/platform/x86/intel_sgx_util.c       | 12 +++++------
 drivers/platform/x86/intel_sgx_vma.c        | 16 ++++++++------
 5 files changed, 49 insertions(+), 30 deletions(-)

Comments

Jarkko Sakkinen Dec. 29, 2016, 12:30 p.m. UTC | #1
Hi

I'll review most of the patches after the new year but some things in
this patch stroke me.

On Thu, Dec 22, 2016 at 12:15:35PM -0800, Sean Christopherson wrote:
> Add a new struct, sgx_evicted_page, to hold all information about an
> evicted enclave page, e.g. VA page, VA offset and PCMD.  Dynamically
> allocate the evicted page object at EWB and free it at ELDU.
> 
> Combine sgx_encl_page's epc_page and evicted_page into a union, as
> on-demand VA and PCMD allocation only epc_page or evicted_page will
> be valid at any given time.
> 
> Add a new flag, SGX_ENCL_PAGE_IN_EPC, to track if an encl page has
> been loaded into the EPC.  If SGX_ENCL_PAGE_IN_EPC is set, then the
> epc_page member of the epc_page/evicted_page union is valid, else
> va_page *may* be valid, e.g. neither is valid if EADD has not been
> completed.
> 
> Call sgx_free_encl_page in the success path of __sgx_ewb, as the EPC
> page must be freed before updating the encl_page's va_page.
> 
> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> ---
>  drivers/platform/x86/intel_sgx.h            | 16 ++++++++++----
>  drivers/platform/x86/intel_sgx_ioctl.c      |  2 ++
>  drivers/platform/x86/intel_sgx_page_cache.c | 33 +++++++++++++++++------------
>  drivers/platform/x86/intel_sgx_util.c       | 12 +++++------
>  drivers/platform/x86/intel_sgx_vma.c        | 16 ++++++++------
>  5 files changed, 49 insertions(+), 30 deletions(-)
> 
> 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;

The right place for PCMD is a shmem file, not a new kernel data
structure.

>  };
>  
>  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;
> +	}

Get rid of this kmalloc.

Rather than what you are doing something like this would make
factors more sense:

union {
	struct sgx_epc_page *epc_page;
	struct sgx_va_page *va_page;
};
unsigned int va_offset;

What you are doing now just makes the code worse but with this
twist I could accept the patch.

/Jarkko
Jarkko Sakkinen Dec. 29, 2016, 1:05 p.m. UTC | #2
On Thu, Dec 29, 2016 at 02:30:17PM +0200, Jarkko Sakkinen wrote:
> Hi
> 
> I'll review most of the patches after the new year but some things in
> this patch stroke me.

There you go. All six reviewed :-)

/Jarkko

> 
> On Thu, Dec 22, 2016 at 12:15:35PM -0800, Sean Christopherson wrote:
> > Add a new struct, sgx_evicted_page, to hold all information about an
> > evicted enclave page, e.g. VA page, VA offset and PCMD.  Dynamically
> > allocate the evicted page object at EWB and free it at ELDU.
> > 
> > Combine sgx_encl_page's epc_page and evicted_page into a union, as
> > on-demand VA and PCMD allocation only epc_page or evicted_page will
> > be valid at any given time.
> > 
> > Add a new flag, SGX_ENCL_PAGE_IN_EPC, to track if an encl page has
> > been loaded into the EPC.  If SGX_ENCL_PAGE_IN_EPC is set, then the
> > epc_page member of the epc_page/evicted_page union is valid, else
> > va_page *may* be valid, e.g. neither is valid if EADD has not been
> > completed.
> > 
> > Call sgx_free_encl_page in the success path of __sgx_ewb, as the EPC
> > page must be freed before updating the encl_page's va_page.
> > 
> > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> > ---
> >  drivers/platform/x86/intel_sgx.h            | 16 ++++++++++----
> >  drivers/platform/x86/intel_sgx_ioctl.c      |  2 ++
> >  drivers/platform/x86/intel_sgx_page_cache.c | 33 +++++++++++++++++------------
> >  drivers/platform/x86/intel_sgx_util.c       | 12 +++++------
> >  drivers/platform/x86/intel_sgx_vma.c        | 16 ++++++++------
> >  5 files changed, 49 insertions(+), 30 deletions(-)
> > 
> > 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;
> 
> The right place for PCMD is a shmem file, not a new kernel data
> structure.
> 
> >  };
> >  
> >  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;
> > +	}
> 
> Get rid of this kmalloc.
> 
> Rather than what you are doing something like this would make
> factors more sense:
> 
> union {
> 	struct sgx_epc_page *epc_page;
> 	struct sgx_va_page *va_page;
> };
> unsigned int va_offset;
> 
> What you are doing now just makes the code worse but with this
> twist I could accept the patch.
> 
> /Jarkko

Patch
diff mbox

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;