Commit bbc8ed92 authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan
Browse files

libcap-integration: Re-factor capability granting, page mapping.

All about the same, modified to use more general memory object
and new libcap interface.
parent a0ca5275
......@@ -384,6 +384,102 @@ fail1:
return ret;
}
/* CSPACE AND ADDRESS SPACE CONFIG ------------------------------ */
int __lcd_memory_grant_and_map(struct lcd *caller, cptr_t lcd,
cptr_t mo_cptr, cptr_t dest_slot, gpa_t base)
{
struct lcd *lcd_struct;
struct lcd_memory_object *mo;
struct cnode *lcd_cnode;
struct cnode *mo_cnode;
int ret;
/*
* Look up and lock lcd
*/
ret = __lcd_get(caller, lcd, &lcd_cnode, &lcd_struct);
if (ret)
goto fail1;
/*
* If lcd is not an embryo, fail - we only allow direct grants when
* the lcd is being set up
*/
if (!lcd_status_embryo(lcd_struct)) {
LCD_ERR("lcd is not an embryo");
ret = -EINVAL;
goto fail2;
}
/*
* Grant lcd a capability to memory object
*/
ret = __lcd_grant_memory_object(caller, lcd, mo_cptr, dest_slot);
if (ret)
goto fail2;
/*
* Map in lcd's address space
*
* (There are a couple redundant cspace lookups here. Rather
* than optimize prematurely and mash some of these operations
* together, I'll keep things more sane and understandable,
* separated.)
*/
ret = __lcd_map_memory_object(lcd, dest_slot, base);
if (ret)
goto fail3;
/*
* Put lcd
*/
__lcd_put(caller, lcd_cnode, lcd_struct);
return 0;
fail3:
cap_delete(lcd->cspace, dest_cptr);
fail2:
__lcd_put(lcd_cnode, lcd_struct);
fail1:
return ret;
}
int __lcd_cap_grant(struct lcd *caller, cptr_t lcd, cptr_t src, cptr_t dest)
{
struct lcd *lcd_struct;
struct cnode *lcd_cnode;
int ret;
/*
* Look up and lock lcd
*/
ret = __lcd_get(caller, lcd, &lcd_cnode, &lcd_struct);
if (ret)
goto fail1;
/*
* If lcd is not an embryo, fail - we only allow direct grants when
* the lcd is being set up
*/
if (!lcd_status_embryo(lcd_struct)) {
LCD_ERR("lcd is not an embryo");
ret = -EINVAL;
goto fail2;
}
/*
* Grant lcd the capability
*/
ret = cap_grant(caller->cspace, src, lcd->cspace, dest);
if (ret)
goto fail2;
/*
* Put lcd
*/
__lcd_put(caller, lcd_cnode, lcd_struct);
return 0;
fail2:
__lcd_put(lcd_cnode, lcd_struct);
fail1:
return ret;
}
/* DESTROY -------------------------------------------------- */
static void mark_lcd_as_dead(struct lcd *lcd)
......
This diff is collapsed.
......@@ -18,13 +18,13 @@ static void do_insert_pages(struct lcd *caller, struct page *p,
/*
* Set up metadata
*/
mo = kmalloc(sizeof(*mo));
mo = kmalloc(sizeof(*mo), GFP_KERNEL);
if (!mo) {
LCD_ERR("kmalloc error");
ret = -ENOMEM;
goto fail1;
}
meta = kzalloc(sizeof(*meta)); /* set is_mapped = 0 */
meta = kzalloc(sizeof(*meta), GFP_KERNEL); /* set is_mapped = 0 */
if (!meta) {
LCD_ERR("kmalloc error");
ret = -ENOMEM;
......@@ -369,3 +369,55 @@ fail2:
fail1:
return;
}
/* GRANT -------------------------------------------------- */
int __lcd_grant_memory_object(struct lcd *src, struct lcd *dest,
cptr_t c_src, cptr_t c_dest)
{
int ret;
struct lcd_mapping_metadata *meta;
struct cnode *cnode;
/*
* Do grant
*/
ret = cap_grant(src->cspace, c_src,
dest->cspace, c_dest);
if (ret) {
LCD_DEBUG(LCD_DEBUG_ERR,
"grant failed");
goto fail1;
}
/*
* Init metadata
*/
meta = kzalloc(sizeof(*meta), GFP_KERNEL); /* sets is_mapped = 0 */
if (!meta) {
LCD_ERR("malloc failed");
goto fail2;
}
/*
* Look up cnode in dest so we can store metadata
*/
ret = cap_cnode_get(dest->cspace, c_dest, &cnode);
if (ret) {
LCD_DEBUG(LCD_DEBUG_ERR, "cnode get failed");
goto fail3;
}
cap_cnode_set_metadata(cnode, meta);
cap_cnode_put(cnode);
/*
* ==================================================
* After this point, meta is owned by libcap and will be
* freed when the capability is revoked (via the revoke callback).
*/
return 0;
fail3:
kfree(meta);
fail2:
cap_delete(dest->cspace, c_dest);
fail1:
return ret;
}
......@@ -37,7 +37,7 @@ static int handle_syscall_cap_delete(struct lcd *lcd)
return cap_delete(lcd->cspace, object);
}
static int handle_syscall_pages_map(struct lcd *lcd)
static int handle_syscall_munmap(struct lcd *lcd)
{
cptr_t mem_object;
/*
......@@ -50,7 +50,7 @@ static int handle_syscall_pages_map(struct lcd *lcd)
return __lcd_unmap_memory_object(caller, mem_object);
}
static int handle_syscall_pages_map(struct lcd *lcd)
static int handle_syscall_mmap(struct lcd *lcd)
{
cptr_t mem_object;
gpa_t base;
......@@ -207,11 +207,11 @@ static int handle_syscall(struct lcd *lcd, int *lcd_ret)
case LCD_SYSCALL_PAGES_ALLOC:
ret = handle_syscall_pages_alloc(lcd);
break;
case LCD_SYSCALL_PAGES_MAP:
ret = handle_syscall_pages_map(lcd);
case LCD_SYSCALL_MMAP:
ret = handle_syscall_mmap(lcd);
break;
case LCD_SYSCALL_PAGE_UNMAP:
ret = handle_syscall_pages_unmap(lcd);
case LCD_SYSCALL_MUNMAP:
ret = handle_syscall_munmap(lcd);
break;
case LCD_SYSCALL_CAP_DELETE:
ret = handle_syscall_cap_delete(lcd);
......@@ -372,3 +372,44 @@ int __lcd_kthread_main(void *data) /* data is NULL */
return -EINVAL;
}
}
/* RUN -------------------------------------------------- */
int __lcd_run(struct lcd *caller, cptr_t lcd)
{
struct lcd *lcd_struct;
struct cnode *cnode;
int ret;
/*
* Look up and lock
*/
ret = __lcd_get(caller, lcd, &cnode, &lcd_struct);
if (ret)
goto fail1;
/*
* If lcd is not in config state, fail
*/
if (!lcd_status_configed(lcd_struct)) {
LCD_DEBUG(LCD_DEBUG_ERR,
"cannot run: lcd is in state %d",
get_lcd_status(lcd_struct));
ret = -EINVAL;
goto fail2;
}
/*
* This will run the kthread for the first time
*/
set_lcd_status(lcd_struct, LCD_STATUS_RUNNING);
wake_up_process(lcd_struct->kthread);
/*
* Unlock
*/
__lcd_put(caller, cnode, lcd_struct);
return 0;
fail2:
__lcd_put(caller, cnode, lcd_struct);
fail1:
return ret;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment