Skip to content

Commit

Permalink
Merge pull request #25 from keystone-enclave/dev-user-pt
Browse files Browse the repository at this point in the history
Dev user pt
  • Loading branch information
dayeol authored Aug 1, 2019
2 parents 43f0fd2 + 6b24cbf commit 9110f7b
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 348 deletions.
1 change: 1 addition & 0 deletions keystone-enclave.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct enclave* create_enclave(unsigned long min_pages)
enclave->close_on_pexit = 1;

enclave->epm = kmalloc(sizeof(struct epm), GFP_KERNEL);
enclave->is_init = true;
if (!enclave->epm)
{
keystone_err("failed to allocate epm\n");
Expand Down
126 changes: 19 additions & 107 deletions keystone-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "keystone-sbi-arg.h"
#include "keystone_user.h"
#include <linux/uaccess.h>
#include <keystone_user.h>

int __keystone_destroy_enclave(unsigned int ueid);

Expand All @@ -21,6 +22,10 @@ int keystone_create_enclave(struct file *filep, unsigned long arg)
return -ENOMEM;
}

/* Pass base page table */
enclp->pt_ptr = __pa(enclave->epm->root_page_table);
enclp->epm_size = enclave->epm->size;

/* allocate UID */
enclp->eid = enclave_idr_alloc(enclave);

Expand All @@ -45,6 +50,8 @@ int keystone_finalize_enclave(unsigned long arg)
return -EINVAL;
}

enclave->is_init = false;

/* SBI Call */
create_args.epm_region.paddr = enclave->epm->pa;
create_args.epm_region.size = enclave->epm->size;
Expand All @@ -62,7 +69,15 @@ int keystone_finalize_enclave(unsigned long arg)
// physical addresses for runtime, user, and freemem
create_args.runtime_paddr = epm_va_to_pa(enclave->epm, enclp->runtime_vaddr);
create_args.user_paddr = epm_va_to_pa(enclave->epm, enclp->user_vaddr);
create_args.free_paddr = epm_get_free_pa(enclave->epm);
create_args.free_paddr = enclp->free_paddr;

enclp->runtime_paddr = create_args.runtime_paddr;
enclp->user_paddr = create_args.user_paddr;
enclp->epm_paddr = create_args.epm_region.paddr;
enclp->utm_paddr = create_args.utm_region.paddr;
enclp->epm_size = create_args.epm_region.size;
enclp->utm_size = create_args.utm_region.size;


create_args.params = enclp->params;

Expand All @@ -75,11 +90,6 @@ int keystone_finalize_enclave(unsigned long arg)
goto error_destroy_enclave;
}

/* We cleanup the free lists here since the kernel will no longer be
managing them, they are part of the enclave now. */
utm_clean_free_list(utm);
epm_clean_free_list(enclave->epm);

return 0;

error_destroy_enclave:
Expand Down Expand Up @@ -116,79 +126,6 @@ int keystone_run_enclave(unsigned long arg)
return ret;
}

int keystone_add_page(unsigned long arg)
{
int ret = 0;
vaddr_t epm_page;
struct addr_packed *addr = (struct addr_packed *) arg;
unsigned long ueid = addr->eid;
unsigned int mode = addr->mode;
struct enclave *enclave;

enclave = get_enclave_by_id(ueid);

if(!enclave) {
keystone_err("invalid enclave id\n");
return -EINVAL;
}

switch (mode) {
case USER_NOEXEC: {
epm_alloc_user_page_noexec(enclave->epm, addr->va);
break;
}
case RT_NOEXEC: {
epm_alloc_rt_page_noexec(enclave->epm, addr->va);
break;
}
case RT_FULL: {
epm_page = epm_alloc_rt_page(enclave->epm, addr->va);
if (copy_from_user((void *) epm_page, (void *) addr->copied, PAGE_SIZE) != 0)
ret = -ENOEXEC;
break;
}
case USER_FULL: {
epm_page = epm_alloc_user_page(enclave->epm, addr->va);
if (copy_from_user((void *) epm_page, (void *) addr->copied, PAGE_SIZE) != 0)
ret = -ENOEXEC;
break;
}
default:
ret = -ENOSYS;
}

return ret;
}

/* This IOCTL allows user to prepare page tables prior to the actual page allocation.
* This is needed when an enclave requires linear physical layout.
* The user must call this before allocating pages */
int keystone_alloc_vspace(unsigned long arg)
{
int ret = 0;
vaddr_t va;
size_t num_pages;
struct enclave* enclave;
struct keystone_ioctl_alloc_vspace* enclp = (struct keystone_ioctl_alloc_vspace *) arg;

va = enclp->vaddr;
num_pages = PAGE_UP(enclp->size)/PAGE_SIZE;

enclave = get_enclave_by_id(enclp->eid);

if(!enclave) {
keystone_err("invalid enclave id\n");
return -EINVAL;
}

if (epm_alloc_vspace(enclave->epm, va, num_pages) != num_pages) {
keystone_err("failed to allocate vspace\n");
return -ENOMEM;
}

return ret;
}

int utm_init_ioctl(struct file *filp, unsigned long arg)
{
int ret = 0;
Expand All @@ -215,24 +152,7 @@ int utm_init_ioctl(struct file *filp, unsigned long arg)
/* prepare for mmap */
enclave->utm = utm;

return ret;
}

int utm_alloc(unsigned long arg)
{
int ret = 0;
struct enclave *enclave;
struct addr_packed *addr = (struct addr_packed *) arg;
unsigned long ueid = addr->eid;

enclave = get_enclave_by_id(ueid);

if(!enclave) {
keystone_err("invalid enclave id\n");
return -EINVAL;
}

utm_alloc_page(enclave->utm, enclave->epm, addr->va, PTE_D | PTE_A | PTE_R | PTE_W);
enclp->utm_free_ptr = __pa(utm->ptr);

return ret;
}
Expand Down Expand Up @@ -299,7 +219,8 @@ int keystone_resume_enclave(unsigned long arg)
long keystone_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
long ret;
char data[256];
char data[512];

size_t ioc_size;

if (!arg)
Expand All @@ -315,12 +236,6 @@ long keystone_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
case KEYSTONE_IOC_CREATE_ENCLAVE:
ret = keystone_create_enclave(filep, (unsigned long) data);
break;
case KEYSTONE_IOC_ADD_PAGE:
ret = keystone_add_page((unsigned long) data);
break;
case KEYSTONE_IOC_ALLOC_VSPACE:
ret = keystone_alloc_vspace((unsigned long) data);
break;
case KEYSTONE_IOC_FINALIZE_ENCLAVE:
ret = keystone_finalize_enclave((unsigned long) data);
break;
Expand All @@ -337,9 +252,6 @@ long keystone_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
* However, there was a weird bug in compiler that generates a wrong control flow
* that ends up with an illegal instruction if we combine switch-case and if statements.
* We didn't identified the exact problem, so we'll have these until we figure out */
case KEYSTONE_IOC_UTM_ALLOC:
ret = utm_alloc((unsigned long) data);
break;
case KEYSTONE_IOC_UTM_INIT:
ret = utm_init_ioctl(filep, (unsigned long) data);
break;
Expand Down
Loading

0 comments on commit 9110f7b

Please sign in to comment.