Message ID | 20161230161021.18794-1-jarkko.sakkinen@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, Dec 30, 2016 at 06:10:21PM +0200, Jarkko Sakkinen wrote: > Move PCMD's to a backing storage file in order to give more control > (swapping and discarding mainly) and also to help pack stuff in the > struct sgx_enclave_page tighter in the heap. > > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Sent this by mistake, so please ignore. /Jarkko > --- > drivers/platform/x86/intel_sgx.h | 5 ++++- > drivers/platform/x86/intel_sgx_ioctl.c | 12 ++++++++++++ > drivers/platform/x86/intel_sgx_page_cache.c | 16 ++++++++++++++- > drivers/platform/x86/intel_sgx_util.c | 30 +++++++++++++++++++++++++++++ > 4 files changed, 61 insertions(+), 2 deletions(-) > > diff --git a/drivers/platform/x86/intel_sgx.h b/drivers/platform/x86/intel_sgx.h > index ed9e8e6..1d03606 100644 > --- a/drivers/platform/x86/intel_sgx.h > +++ b/drivers/platform/x86/intel_sgx.h > @@ -115,7 +115,6 @@ struct sgx_encl_page { > struct list_head load_list; > struct sgx_va_page *va_page; > unsigned int va_offset; > - struct sgx_pcmd pcmd; > }; > > struct sgx_tgid_ctx { > @@ -141,6 +140,7 @@ struct sgx_encl { > struct task_struct *owner; > struct mm_struct *mm; > struct file *backing; > + struct file *pcmd; > struct list_head load_list; > struct kref refcount; > unsigned long base; > @@ -198,6 +198,9 @@ void sgx_put_epc_page(void *epc_page_vaddr); > struct page *sgx_get_backing(struct sgx_encl *encl, > struct sgx_encl_page *entry); > void sgx_put_backing(struct page *backing, bool write); > +struct page *sgx_get_pcmd(struct sgx_encl *encl, > + struct sgx_encl_page *entry); > +void sgx_put_pcmd(struct page *pcmd_page, bool write); > void sgx_insert_pte(struct sgx_encl *encl, > struct sgx_encl_page *encl_page, > struct sgx_epc_page *epc_page, > diff --git a/drivers/platform/x86/intel_sgx_ioctl.c b/drivers/platform/x86/intel_sgx_ioctl.c > index 3a4a8fa..dec136a 100644 > --- a/drivers/platform/x86/intel_sgx_ioctl.c > +++ b/drivers/platform/x86/intel_sgx_ioctl.c > @@ -477,6 +477,7 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, > struct vm_area_struct *vma; > void *secs_vaddr = NULL; > struct file *backing; > + struct file *pcmd; > long ret; > > secs = kzalloc(sizeof(*secs), GFP_KERNEL); > @@ -501,9 +502,19 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, > goto out; > } > > + pcmd = shmem_file_setup("dev/sgx", > + ((secs->size >> PAGE_SHIFT) + 1) * 128, > + VM_NORESERVE); > + if (IS_ERR(pcmd)) { > + fput(backing); > + ret = PTR_ERR(pcmd); > + goto out; > + } > + > encl = kzalloc(sizeof(*encl), GFP_KERNEL); > if (!encl) { > fput(backing); > + fput(pcmd); > ret = -ENOMEM; > goto out; > } > @@ -522,6 +533,7 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, > encl->base = secs->base; > encl->size = secs->size; > encl->backing = backing; > + encl->pcmd = pcmd; > > secs_epc = sgx_alloc_page(encl->tgid_ctx, 0); > if (IS_ERR(secs_epc)) { > diff --git a/drivers/platform/x86/intel_sgx_page_cache.c b/drivers/platform/x86/intel_sgx_page_cache.c > index d073057..b264d20 100644 > --- a/drivers/platform/x86/intel_sgx_page_cache.c > +++ b/drivers/platform/x86/intel_sgx_page_cache.c > @@ -237,10 +237,14 @@ static int __sgx_ewb(struct sgx_encl *encl, > { > struct sgx_page_info pginfo; > struct page *backing; > + struct page *pcmd; > + unsigned long pcmd_offset; > void *epc; > void *va; > int ret; > > + pcmd_offset = ((encl_page->addr >> PAGE_SHIFT() & 31) * 128; > + > backing = sgx_get_backing(encl, encl_page); > if (IS_ERR(backing)) { > ret = PTR_ERR(backing); > @@ -249,19 +253,29 @@ static int __sgx_ewb(struct sgx_encl *encl, > return ret; > } > > + pcmd = sgx_get_pcmd(encl, encl_page); > + if (IS_ERR(pcmd)) { > + ret = PTR_ERR(pcmd); > + sgx_warn(encl, "pinning the pcmd page for EWB failed with %d\n", > + ret); > + return ret; > + } > + > epc = sgx_get_epc_page(encl_page->epc_page); > va = sgx_get_epc_page(encl_page->va_page->epc_page); > > pginfo.srcpge = (unsigned long)kmap_atomic(backing); > - pginfo.pcmd = (unsigned long)&encl_page->pcmd; > + pginfo.pcmd = (unsigned long)kamp_atomic(pcmd) + pcmd_offset; > pginfo.linaddr = 0; > pginfo.secs = 0; > ret = __ewb(&pginfo, epc, > (void *)((unsigned long)va + encl_page->va_offset)); > + kunmap_atomic((void *)(unsigned long)(pginfo.pcmd - pcmd_offset)); > kunmap_atomic((void *)(unsigned long)pginfo.srcpge); > > sgx_put_epc_page(va); > sgx_put_epc_page(epc); > + sgx_put_pcmd(pcmd, true); > sgx_put_backing(backing, true); > > return ret; > diff --git a/drivers/platform/x86/intel_sgx_util.c b/drivers/platform/x86/intel_sgx_util.c > index 2c390c5..40f5839 100644 > --- a/drivers/platform/x86/intel_sgx_util.c > +++ b/drivers/platform/x86/intel_sgx_util.c > @@ -105,6 +105,33 @@ void sgx_put_backing(struct page *backing_page, bool write) > put_page(backing_page); > } > > +struct page *sgx_get_pcmd(struct sgx_encl *encl, > + struct sgx_encl_page *entry) > +{ > + struct page *pcmd; > + struct inode *inode; > + struct address_space *mapping; > + gfp_t gfpmask; > + pgoff_t index; > + > + inode = encl->pcmd->f_path.dentry->d_inode; > + mapping = inode->i_mapping; > + gfpmask = mapping_gfp_mask(mapping); > + /* 32 PCMD's per page */ > + index = (entry->addr - encl->base) >> (PAGE_SHIFT + 5); > + pcmd = shmem_read_mapping_page_gfp(mapping, index, gfpmask); > + > + return pcmd; > +} > + > +void sgx_put_pcmd(struct page *pcmd_page, bool write) > +{ > + if (write) > + set_page_dirty(pcmd_page); > + > + put_page(pcmd_page); > +} > + > struct vm_area_struct *sgx_find_vma(struct sgx_encl *encl, unsigned long addr) > { > struct vm_area_struct *vma; > @@ -245,5 +272,8 @@ void sgx_encl_release(struct kref *ref) > if (encl->backing) > fput(encl->backing); > > + if (encl->pcmd) > + fput(encl->pcmd); > + > kfree(encl); > } > -- > 2.9.3 >
diff --git a/drivers/platform/x86/intel_sgx.h b/drivers/platform/x86/intel_sgx.h index ed9e8e6..1d03606 100644 --- a/drivers/platform/x86/intel_sgx.h +++ b/drivers/platform/x86/intel_sgx.h @@ -115,7 +115,6 @@ struct sgx_encl_page { struct list_head load_list; struct sgx_va_page *va_page; unsigned int va_offset; - struct sgx_pcmd pcmd; }; struct sgx_tgid_ctx { @@ -141,6 +140,7 @@ struct sgx_encl { struct task_struct *owner; struct mm_struct *mm; struct file *backing; + struct file *pcmd; struct list_head load_list; struct kref refcount; unsigned long base; @@ -198,6 +198,9 @@ void sgx_put_epc_page(void *epc_page_vaddr); struct page *sgx_get_backing(struct sgx_encl *encl, struct sgx_encl_page *entry); void sgx_put_backing(struct page *backing, bool write); +struct page *sgx_get_pcmd(struct sgx_encl *encl, + struct sgx_encl_page *entry); +void sgx_put_pcmd(struct page *pcmd_page, bool write); void sgx_insert_pte(struct sgx_encl *encl, struct sgx_encl_page *encl_page, struct sgx_epc_page *epc_page, diff --git a/drivers/platform/x86/intel_sgx_ioctl.c b/drivers/platform/x86/intel_sgx_ioctl.c index 3a4a8fa..dec136a 100644 --- a/drivers/platform/x86/intel_sgx_ioctl.c +++ b/drivers/platform/x86/intel_sgx_ioctl.c @@ -477,6 +477,7 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, struct vm_area_struct *vma; void *secs_vaddr = NULL; struct file *backing; + struct file *pcmd; long ret; secs = kzalloc(sizeof(*secs), GFP_KERNEL); @@ -501,9 +502,19 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, goto out; } + pcmd = shmem_file_setup("dev/sgx", + ((secs->size >> PAGE_SHIFT) + 1) * 128, + VM_NORESERVE); + if (IS_ERR(pcmd)) { + fput(backing); + ret = PTR_ERR(pcmd); + goto out; + } + encl = kzalloc(sizeof(*encl), GFP_KERNEL); if (!encl) { fput(backing); + fput(pcmd); ret = -ENOMEM; goto out; } @@ -522,6 +533,7 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, encl->base = secs->base; encl->size = secs->size; encl->backing = backing; + encl->pcmd = pcmd; secs_epc = sgx_alloc_page(encl->tgid_ctx, 0); if (IS_ERR(secs_epc)) { diff --git a/drivers/platform/x86/intel_sgx_page_cache.c b/drivers/platform/x86/intel_sgx_page_cache.c index d073057..b264d20 100644 --- a/drivers/platform/x86/intel_sgx_page_cache.c +++ b/drivers/platform/x86/intel_sgx_page_cache.c @@ -237,10 +237,14 @@ static int __sgx_ewb(struct sgx_encl *encl, { struct sgx_page_info pginfo; struct page *backing; + struct page *pcmd; + unsigned long pcmd_offset; void *epc; void *va; int ret; + pcmd_offset = ((encl_page->addr >> PAGE_SHIFT() & 31) * 128; + backing = sgx_get_backing(encl, encl_page); if (IS_ERR(backing)) { ret = PTR_ERR(backing); @@ -249,19 +253,29 @@ static int __sgx_ewb(struct sgx_encl *encl, return ret; } + pcmd = sgx_get_pcmd(encl, encl_page); + if (IS_ERR(pcmd)) { + ret = PTR_ERR(pcmd); + sgx_warn(encl, "pinning the pcmd page for EWB failed with %d\n", + ret); + return ret; + } + epc = sgx_get_epc_page(encl_page->epc_page); va = sgx_get_epc_page(encl_page->va_page->epc_page); pginfo.srcpge = (unsigned long)kmap_atomic(backing); - pginfo.pcmd = (unsigned long)&encl_page->pcmd; + pginfo.pcmd = (unsigned long)kamp_atomic(pcmd) + pcmd_offset; pginfo.linaddr = 0; pginfo.secs = 0; ret = __ewb(&pginfo, epc, (void *)((unsigned long)va + encl_page->va_offset)); + kunmap_atomic((void *)(unsigned long)(pginfo.pcmd - pcmd_offset)); kunmap_atomic((void *)(unsigned long)pginfo.srcpge); sgx_put_epc_page(va); sgx_put_epc_page(epc); + sgx_put_pcmd(pcmd, true); sgx_put_backing(backing, true); return ret; diff --git a/drivers/platform/x86/intel_sgx_util.c b/drivers/platform/x86/intel_sgx_util.c index 2c390c5..40f5839 100644 --- a/drivers/platform/x86/intel_sgx_util.c +++ b/drivers/platform/x86/intel_sgx_util.c @@ -105,6 +105,33 @@ void sgx_put_backing(struct page *backing_page, bool write) put_page(backing_page); } +struct page *sgx_get_pcmd(struct sgx_encl *encl, + struct sgx_encl_page *entry) +{ + struct page *pcmd; + struct inode *inode; + struct address_space *mapping; + gfp_t gfpmask; + pgoff_t index; + + inode = encl->pcmd->f_path.dentry->d_inode; + mapping = inode->i_mapping; + gfpmask = mapping_gfp_mask(mapping); + /* 32 PCMD's per page */ + index = (entry->addr - encl->base) >> (PAGE_SHIFT + 5); + pcmd = shmem_read_mapping_page_gfp(mapping, index, gfpmask); + + return pcmd; +} + +void sgx_put_pcmd(struct page *pcmd_page, bool write) +{ + if (write) + set_page_dirty(pcmd_page); + + put_page(pcmd_page); +} + struct vm_area_struct *sgx_find_vma(struct sgx_encl *encl, unsigned long addr) { struct vm_area_struct *vma; @@ -245,5 +272,8 @@ void sgx_encl_release(struct kref *ref) if (encl->backing) fput(encl->backing); + if (encl->pcmd) + fput(encl->pcmd); + kfree(encl); }
Move PCMD's to a backing storage file in order to give more control (swapping and discarding mainly) and also to help pack stuff in the struct sgx_enclave_page tighter in the heap. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> --- drivers/platform/x86/intel_sgx.h | 5 ++++- drivers/platform/x86/intel_sgx_ioctl.c | 12 ++++++++++++ drivers/platform/x86/intel_sgx_page_cache.c | 16 ++++++++++++++- drivers/platform/x86/intel_sgx_util.c | 30 +++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-)