Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
dayeol committed Jun 18, 2019
2 parents 1ea0cf3 + 1a71e8d commit 43f0fd2
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 102 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# Keystone Enclave Driver

This is a loadable kernel module for Keystone Enclave.
To build the module, make with a proper KDIR path.

```
make KDIR=<path to linux>
```
This is a loadable kernel module for Keystone Enclave. To build the
module, make with the top-level
[Keystone](https://github.com/keystone-enclave/keystone) build
process.

# Compatibility

The driver will always work correctly with the version of riscv-linux
pointed to by the top-level
[Keystone](https://github.com/keystone-enclave/keystone) repository.

For the upstream linux, loadable modules for RISC-V only work on kernel versions later than 4.17.

To use the module in 4.15, please use this version
Expand Down
27 changes: 14 additions & 13 deletions keystone-enclave.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//------------------------------------------------------------------------------
#include <linux/dma-mapping.h>
#include "keystone.h"
/* idr for enclave UID to enclave_t */
/* idr for enclave UID to struct enclave */
DEFINE_IDR(idr_enclave);
DEFINE_SPINLOCK(idr_enclave_lock);

Expand All @@ -31,10 +31,10 @@ unsigned long calculate_required_pages(
}

/* Smart destroy, handles partial initialization of epm and utm etc */
int destroy_enclave(enclave_t* enclave)
int destroy_enclave(struct enclave* enclave)
{
epm_t* epm;
utm_t* utm;
struct epm* epm;
struct utm* utm;
if (enclave == NULL)
return -ENOSYS;

Expand All @@ -55,19 +55,20 @@ int destroy_enclave(enclave_t* enclave)
return 0;
}

enclave_t* create_enclave(unsigned long min_pages)
struct enclave* create_enclave(unsigned long min_pages)
{
enclave_t* enclave;
struct enclave* enclave;

enclave = kmalloc(sizeof(enclave_t), GFP_KERNEL);
enclave = kmalloc(sizeof(struct enclave), GFP_KERNEL);
if (!enclave){
keystone_err("failed to allocate enclave struct\n");
goto error_no_free;
}

enclave->utm = NULL;
enclave->close_on_pexit = 1;

enclave->epm = kmalloc(sizeof(epm_t), GFP_KERNEL);
enclave->epm = kmalloc(sizeof(struct epm), GFP_KERNEL);
if (!enclave->epm)
{
keystone_err("failed to allocate epm\n");
Expand All @@ -86,7 +87,7 @@ enclave_t* create_enclave(unsigned long min_pages)
return NULL;
}

unsigned int enclave_idr_alloc(enclave_t* enclave)
unsigned int enclave_idr_alloc(struct enclave* enclave)
{
unsigned int ueid;

Expand All @@ -102,18 +103,18 @@ unsigned int enclave_idr_alloc(enclave_t* enclave)
return ueid;
}

enclave_t* enclave_idr_remove(unsigned int ueid)
struct enclave* enclave_idr_remove(unsigned int ueid)
{
enclave_t* enclave;
struct enclave* enclave;
spin_lock_bh(&idr_enclave_lock);
enclave = idr_remove(&idr_enclave, ueid);
spin_unlock_bh(&idr_enclave_lock);
return enclave;
}

enclave_t* get_enclave_by_id(unsigned int ueid)
struct enclave* get_enclave_by_id(unsigned int ueid)
{
enclave_t* enclave;
struct enclave* enclave;
spin_lock_bh(&idr_enclave_lock);
enclave = idr_find(&idr_enclave, ueid);
spin_unlock_bh(&idr_enclave_lock);
Expand Down
69 changes: 49 additions & 20 deletions keystone-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
#include "keystone_user.h"
#include <linux/uaccess.h>

int keystone_create_enclave(unsigned long arg)
int __keystone_destroy_enclave(unsigned int ueid);

int keystone_create_enclave(struct file *filep, unsigned long arg)
{
/* create parameters */
struct keystone_ioctl_create_enclave *enclp = (struct keystone_ioctl_create_enclave *) arg;

enclave_t *enclave;
struct enclave *enclave;
enclave = create_enclave(enclp->min_pages);

if (enclave == NULL) {
Expand All @@ -22,21 +24,22 @@ int keystone_create_enclave(unsigned long arg)
/* allocate UID */
enclp->eid = enclave_idr_alloc(enclave);

filep->private_data = (void *) enclp->eid;

return 0;
}


int keystone_finalize_enclave(unsigned long arg)
{
int ret;
enclave_t *enclave;
struct utm_t *utm;
struct enclave *enclave;
struct utm *utm;
struct keystone_sbi_create_t create_args;

struct keystone_ioctl_create_enclave *enclp = (struct keystone_ioctl_create_enclave *) arg;

enclave = get_enclave_by_id(enclp->eid);

if(!enclave) {
keystone_err("invalid enclave id\n");
return -EINVAL;
Expand All @@ -63,7 +66,7 @@ int keystone_finalize_enclave(unsigned long arg)

create_args.params = enclp->params;

// SM will write the eid to enclave_t.eid
// SM will write the eid to struct enclave.eid
create_args.eid_pptr = (unsigned int *) __pa(&enclave->eid);

ret = SBI_CALL_1(SBI_SM_CREATE_ENCLAVE, __pa(&create_args));
Expand Down Expand Up @@ -91,7 +94,7 @@ int keystone_run_enclave(unsigned long arg)
{
int ret = 0;
unsigned long ueid;
enclave_t* enclave;
struct enclave* enclave;
struct keystone_ioctl_run_enclave *run = (struct keystone_ioctl_run_enclave*) arg;

ueid = run->eid;
Expand Down Expand Up @@ -120,7 +123,7 @@ int keystone_add_page(unsigned long arg)
struct addr_packed *addr = (struct addr_packed *) arg;
unsigned long ueid = addr->eid;
unsigned int mode = addr->mode;
enclave_t *enclave;
struct enclave *enclave;

enclave = get_enclave_by_id(ueid);

Expand Down Expand Up @@ -165,7 +168,7 @@ int keystone_alloc_vspace(unsigned long arg)
int ret = 0;
vaddr_t va;
size_t num_pages;
enclave_t* enclave;
struct enclave* enclave;
struct keystone_ioctl_alloc_vspace* enclp = (struct keystone_ioctl_alloc_vspace *) arg;

va = enclp->vaddr;
Expand All @@ -189,8 +192,8 @@ int keystone_alloc_vspace(unsigned long arg)
int utm_init_ioctl(struct file *filp, unsigned long arg)
{
int ret = 0;
struct utm_t *utm;
enclave_t *enclave;
struct utm *utm;
struct enclave *enclave;
struct keystone_ioctl_create_enclave *enclp = (struct keystone_ioctl_create_enclave *) arg;
long long unsigned untrusted_size = enclp->params.untrusted_size;

Expand All @@ -201,7 +204,7 @@ int utm_init_ioctl(struct file *filp, unsigned long arg)
return -EINVAL;
}

utm = kmalloc(sizeof(struct utm_t), GFP_KERNEL);
utm = kmalloc(sizeof(struct utm), GFP_KERNEL);
if (!utm) {
ret = -ENOMEM;
return ret;
Expand All @@ -210,7 +213,6 @@ int utm_init_ioctl(struct file *filp, unsigned long arg)
ret = utm_init(utm, untrusted_size);

/* prepare for mmap */
filp->private_data = utm;
enclave->utm = utm;

return ret;
Expand All @@ -219,7 +221,7 @@ int utm_init_ioctl(struct file *filp, unsigned long arg)
int utm_alloc(unsigned long arg)
{
int ret = 0;
enclave_t *enclave;
struct enclave *enclave;
struct addr_packed *addr = (struct addr_packed *) arg;
unsigned long ueid = addr->eid;

Expand All @@ -236,20 +238,29 @@ int utm_alloc(unsigned long arg)
}


int keystone_destroy_enclave(unsigned long arg)
int keystone_destroy_enclave(struct file *filep, unsigned long arg)
{
int ret;
enclave_t *enclave;
struct keystone_ioctl_create_enclave *enclp = (struct keystone_ioctl_create_enclave *) arg;
unsigned long ueid = enclp->eid;

ret = __keystone_destroy_enclave(ueid);
if (!ret) {
filep->private_data = NULL;
}
return ret;
}

int __keystone_destroy_enclave(unsigned int ueid)
{
int ret;
struct enclave *enclave;
enclave = get_enclave_by_id(ueid);

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

ret = SBI_CALL_1(SBI_SM_DESTROY_ENCLAVE, enclave->eid);
if (ret) {
keystone_err("fatal: cannot destroy enclave: SBI failed\n");
Expand All @@ -267,7 +278,7 @@ int keystone_resume_enclave(unsigned long arg)
int ret = 0;
struct keystone_ioctl_run_enclave *resume = (struct keystone_ioctl_run_enclave*) arg;
unsigned long ueid = resume->eid;
enclave_t* enclave;
struct enclave* enclave;
enclave = get_enclave_by_id(ueid);

if (!enclave)
Expand Down Expand Up @@ -302,7 +313,7 @@ long keystone_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)

switch (cmd) {
case KEYSTONE_IOC_CREATE_ENCLAVE:
ret = keystone_create_enclave((unsigned long) data);
ret = keystone_create_enclave(filep, (unsigned long) data);
break;
case KEYSTONE_IOC_ADD_PAGE:
ret = keystone_add_page((unsigned long) data);
Expand All @@ -314,7 +325,7 @@ long keystone_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
ret = keystone_finalize_enclave((unsigned long) data);
break;
case KEYSTONE_IOC_DESTROY_ENCLAVE:
ret = keystone_destroy_enclave((unsigned long) data);
ret = keystone_destroy_enclave(filep, (unsigned long) data);
break;
case KEYSTONE_IOC_RUN_ENCLAVE:
ret = keystone_run_enclave((unsigned long) data);
Expand All @@ -341,3 +352,21 @@ long keystone_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)

return ret;
}

int keystone_release(struct inode *inode, struct file *file) {
unsigned long ueid = (unsigned long)(file->private_data);

/* pr_info("Releasing enclave: %d\n", ueid); */

/* We need to send destroy enclave just the eid to close. */
struct enclave *enclave = get_enclave_by_id(ueid);

if (!enclave) {
/* If eid is set to the invalid id, then we do not do anything. */
return -EINVAL;
}
if (enclave->close_on_pexit) {
return __keystone_destroy_enclave(ueid);
}
return 0;
}
Loading

0 comments on commit 43f0fd2

Please sign in to comment.