Commit 0426f515 authored by Charles Jacobsen's avatar Charles Jacobsen Committed by Vikram Narayanan

test-v2: All existing examples working!

Basic load all the way through pmfs.

The solution for struct module for now is - this struct is
treated as caller allocated (non-isolated no longer has a copy
since I dup the module bits and then unload the module).

The tweaks we have to make to "unmodified" code are not pretty
(setting up the container structs), but they work for now.
parent 4d8a543a
......@@ -119,7 +119,9 @@ fail1:
}
static int do_kernel_module_grant_map(cptr_t lcd, struct lcd_create_ctx *ctx,
gva_t m_init_link_addr, gva_t m_core_link_addr)
gva_t m_init_link_addr, gva_t m_core_link_addr,
unsigned long m_init_size,
unsigned long m_core_size)
{
unsigned long offset;
cptr_t *c;
......@@ -151,13 +153,20 @@ static int do_kernel_module_grant_map(cptr_t lcd, struct lcd_create_ctx *ctx,
if (ret)
goto fail2;
lcd_to_boot_info(ctx)->module_init_base = m_init_link_addr;
lcd_to_boot_info(ctx)->module_core_base = m_core_link_addr;
lcd_to_boot_info(ctx)->module_init_size = m_init_size;
lcd_to_boot_info(ctx)->module_core_size = m_core_size;
fail2:
fail1:
return ret;
}
static int setup_phys_addr_space(cptr_t lcd, struct lcd_create_ctx *ctx,
gva_t m_init_link_addr, gva_t m_core_link_addr)
gva_t m_init_link_addr, gva_t m_core_link_addr,
unsigned long m_init_size,
unsigned long m_core_size)
{
int ret;
cptr_t *c;
......@@ -183,7 +192,8 @@ static int setup_phys_addr_space(cptr_t lcd, struct lcd_create_ctx *ctx,
* Map and grant kernel module
*/
ret = do_kernel_module_grant_map(lcd, ctx,
m_init_link_addr, m_core_link_addr);
m_init_link_addr, m_core_link_addr,
m_init_size, m_core_size);
if (ret)
goto fail4;
......@@ -339,7 +349,9 @@ static void setup_virt_addr_space(struct lcd_create_ctx *ctx)
}
static int setup_addr_spaces(cptr_t lcd, struct lcd_create_ctx *ctx,
gva_t m_init_link_addr, gva_t m_core_link_addr)
gva_t m_init_link_addr, gva_t m_core_link_addr,
unsigned long m_init_size,
unsigned long m_core_size)
{
int ret;
/*
......@@ -347,7 +359,8 @@ static int setup_addr_spaces(cptr_t lcd, struct lcd_create_ctx *ctx,
* via lcd_config)
*/
ret = setup_phys_addr_space(lcd, ctx, m_init_link_addr,
m_core_link_addr);
m_core_link_addr,
m_init_size, m_core_size);
if (ret) {
LIBLCD_ERR("error setting up phys addr space");
goto fail1;
......@@ -507,6 +520,7 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
int ret;
cptr_t m_init_cptr, m_core_cptr;
gva_t m_init_link_addr, m_core_link_addr;
unsigned long m_init_size, m_core_size;
struct lcd_create_ctx *ctx;
cptr_t lcd;
/*
......@@ -531,7 +545,8 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
ret = lcd_load_module(mdir, mname,
&ctx->m_init_bits, &ctx->m_core_bits,
&m_init_cptr, &m_core_cptr,
&m_init_link_addr, &m_core_link_addr);
&m_init_link_addr, &m_core_link_addr,
&m_init_size, &m_core_size);
if (ret) {
LIBLCD_ERR("error loading kernel module");
goto fail3;
......@@ -551,7 +566,8 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
* Set up address spaces
*/
ret = setup_addr_spaces(lcd, ctx, m_init_link_addr,
m_core_link_addr);
m_core_link_addr,
m_init_size, m_core_size);
if (ret) {
LIBLCD_ERR("error setting up address spaces");
goto fail5;
......
......@@ -28,6 +28,13 @@ struct lcd_boot_info {
* Bootstrap cptr cache
*/
struct cptr_cache cptr_cache;
/*
* Module init and core addresses and sizes
*/
gva_t module_init_base;
gva_t module_core_base;
unsigned long module_init_size;
unsigned long module_core_size;
/*
* Capabilities to memory objects
*/
......
......@@ -17,6 +17,8 @@
* virtual address space
* @m_init_pages: cptr to memory object capability for init bits
* @m_init_link_addr: the address that the module's init code was linked for
* @m_init_size: size in bytes of the module init part of the image
* @m_core_size: size in bytes of the module core part of the image
*
* The *_core_* out params have similar meaning.
*
......@@ -35,7 +37,9 @@ int lcd_load_module(char *mdir, char *mname,
cptr_t *m_init_pages,
cptr_t *m_core_pages,
gva_t *m_init_link_addr,
gva_t *m_core_link_addr);
gva_t *m_core_link_addr,
unsigned long *m_init_size,
unsigned long *m_core_size);
/**
* lcd_release_module -- Unmap module bits and cap delete the pages
* @m_init_bits: virtual address of pages that contain module's init
......
......@@ -20,7 +20,7 @@ int lcd_enter(void)
* threads.
*
* First, if we weren't created by another klcd, then we
* need to init our cspace, utcb, and so on.
* need to init our lcd, cspace, utcb, and so on.
*/
if (!current->lcd) {
ret = __lcd_create_no_vm_no_thread(&lcd);
......@@ -106,7 +106,9 @@ static void do_destroy_lcd(struct lcd *lcd)
{
switch (lcd->type) {
case LCD_TYPE_NONISOLATED:
__lcd_destroy_no_vm(lcd);
/*
* The guy who created us will tear our LCD down
*/
return;
case LCD_TYPE_TOP:
__lcd_destroy_no_vm_no_thread(lcd);
......
......@@ -173,7 +173,9 @@ int lcd_load_module(char *mdir, char *mname,
cptr_t *m_init_pages,
cptr_t *m_core_pages,
gva_t *m_init_link_addr,
gva_t *m_core_link_addr)
gva_t *m_core_link_addr,
unsigned long *m_init_size,
unsigned long *m_core_size)
{
int ret;
struct module *m;
......@@ -207,6 +209,8 @@ int lcd_load_module(char *mdir, char *mname,
*/
*m_init_link_addr = __gva((unsigned long)m->module_init);
*m_core_link_addr = __gva((unsigned long)m->module_core);
*m_init_size = m->init_size;
*m_core_size = m->core_size;
LIBLCD_MSG("Loaded %s.ko: ", mname);
printk(" init addr 0x%p init size 0x%x\n",
......
......@@ -183,8 +183,8 @@ static int add_boot_memory(void)
n = alloc_itree_node();
if (!n)
goto fail1;
n->start = __liblcd_pa(THIS_MODULE->module_init);
n->last = n->start + THIS_MODULE->init_size - 1;
n->start = gpa_val(lcd_gva2gpa(lcd_get_boot_info()->module_init_base));
n->last = n->start + lcd_get_boot_info()->module_init_size - 1;
n->cptr = lcd_get_boot_info()->lcd_boot_cptrs.module_init;
lcd_resource_tree_insert(&itree, n);
/*
......@@ -193,8 +193,8 @@ static int add_boot_memory(void)
n = alloc_itree_node();
if (!n)
goto fail2;
n->start = __liblcd_pa(THIS_MODULE->module_core);
n->last = n->start + THIS_MODULE->core_size - 1;
n->start = gpa_val(lcd_gva2gpa(lcd_get_boot_info()->module_core_base));
n->last = n->start + lcd_get_boot_info()->module_core_size - 1;
n->cptr = lcd_get_boot_info()->lcd_boot_cptrs.module_core;
lcd_resource_tree_insert(&itree, n);
/*
......
......@@ -19,7 +19,9 @@ int lcd_load_module(char *mdir, char *mname,
cptr_t *m_init_pages,
cptr_t *m_core_pages,
gva_t *m_init_link_addr,
gva_t *m_core_link_addr)
gva_t *m_core_link_addr,
unsigned long *m_init_size,
unsigned long *m_core_size)
{
return -ENOSYS; /* not implemented */
}
......
......@@ -18,13 +18,19 @@ static int foo(void)
static int __init my_init(void)
{
/*
* Unlike other examples, the kLCD is already running in "LCD" mode,
* so we don't do lcd_enter / lcd_exit.
*/
int ret;
ret = lcd_enter();
if (ret) {
LIBLCD_ERR("enter failed");
goto out;
}
foo();
return 0;
out:
lcd_exit(ret);
return ret;
}
/*
......
......@@ -25,6 +25,7 @@ struct type_ops_id {
enum glue_type {
GLUE_TYPE_FILE_SYSTEM_TYPE,
GLUE_TYPE_BACKING_DEV_INFO,
GLUE_TYPE_MODULE,
GLUE_NR_TYPES,
};
......@@ -49,6 +50,13 @@ static struct type_ops_id glue_libcap_type_ops[GLUE_NR_TYPES] = {
.revoke = dummy_func,
}
},
{
{
.name = "struct module",
.delete = dummy_func,
.revoke = dummy_func,
}
},
};
int glue_cap_init(void)
......@@ -140,6 +148,16 @@ int glue_cap_insert_backing_dev_info_type(
c_out);
}
int glue_cap_insert_module_type(
struct glue_cspace *cspace,
struct module_container *module_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, module_container,
glue_libcap_type_ops[GLUE_TYPE_MODULE].libcap_type,
c_out);
}
int glue_cap_lookup_file_system_type_type(
struct glue_cspace *cspace,
cptr_t c,
......@@ -161,6 +179,17 @@ int glue_cap_lookup_backing_dev_info_type(
(void **)backing_dev_info_container);
}
int glue_cap_lookup_module_type(
struct glue_cspace *cspace,
cptr_t c,
struct module_container **module_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_MODULE].libcap_type,
(void **)module_container);
}
void glue_cap_remove(
struct glue_cspace *cspace,
cptr_t c)
......
......@@ -65,14 +65,18 @@ void glue_vfs_exit(void)
int register_filesystem(struct file_system_type *fs)
{
struct file_system_type_container *fs_container;
struct module_container *module_container;
int ret;
cptr_t endpoint;
/*
* Get container
* Get containers
*/
fs_container = container_of(fs,
struct file_system_type_container,
file_system_type);
module_container = container_of(fs->owner,
struct module_container,
module);
/*
* SET UP CHANNEL ----------------------------------------
*
......@@ -101,11 +105,21 @@ int register_filesystem(struct file_system_type *fs)
LIBLCD_ERR("insert");
lcd_exit(ret); /* abort */
}
ret = glue_cap_insert_module_type(
vfs_cspace,
module_container,
&module_container->my_ref);
if (ret) {
LIBLCD_ERR("insert");
lcd_exit(ret); /* abort */
}
/*
* IPC MARSHALING --------------------------------------------------
*
*/
lcd_set_r1(cptr_val(fs_container->my_ref));
lcd_set_r2(cptr_val(module_container->my_ref));
/*
* XXX: We don't even pass the name string (otherwise the callee
* needs to keep track of a pesky 5 byte alloc). We just hard
......@@ -131,6 +145,7 @@ int register_filesystem(struct file_system_type *fs)
* We expect a remote ref coming back
*/
fs_container->vfs_ref = __cptr(lcd_r1());
module_container->vfs_ref = __cptr(lcd_r2());
/* Clear capability register */
lcd_set_cr1(CAP_CPTR_NULL);
......@@ -145,17 +160,22 @@ int unregister_filesystem(struct file_system_type *fs)
{
int ret;
struct file_system_type_container *fs_container;
struct module_container *module_container;
fs_container = container_of(fs,
struct file_system_type_container,
file_system_type);
module_container = container_of(fs->owner,
struct module_container,
module);
/* IPC MARSHALING ---------------------------------------- */
/*
* Pass remote ref to vfs's copy
* Pass remote refs to vfs's copies
*/
lcd_set_r1(cptr_val(fs_container->vfs_ref));
lcd_set_r2(cptr_val(module_container->vfs_ref));
/* IPC CALL ---------------------------------------- */
......@@ -175,9 +195,10 @@ int unregister_filesystem(struct file_system_type *fs)
lcd_cap_delete(fs_container->chnl.channel_cptr);
/*
* Remove fs type from data store
* Remove fs type and module from data store
*/
glue_cap_remove(vfs_cspace, fs_container->my_ref);
glue_cap_remove(vfs_cspace, module_container->my_ref);
/*
* Pass back return value
*/
......
......@@ -6,6 +6,7 @@
#include <linux/fs.h>
#include <linux/backing-dev.h>
#include <linux/module.h>
#include <libcap.h>
#include <liblcd/glue_cspace.h>
......@@ -39,6 +40,12 @@ struct backing_dev_info_container {
/* no channel since pmfs doesn't implement function ptrs */
};
struct module_container {
struct module module;
cptr_t my_ref;
cptr_t vfs_ref;
};
/* FUNCTIONS -------------------------------------------------- */
int glue_vfs_init(cptr_t _vfs_channel, struct dispatch_ctx *ctx);
......@@ -69,6 +76,11 @@ int glue_cap_insert_backing_dev_info_type(
struct backing_dev_info_container *backing_dev_info_container,
cptr_t *c_out);
int glue_cap_insert_module_type(
struct glue_cspace *cspace,
struct module_container *module_container,
cptr_t *c_out);
int glue_cap_lookup_file_system_type_type(
struct glue_cspace *cspace,
cptr_t c,
......@@ -79,6 +91,11 @@ int glue_cap_lookup_backing_dev_info_type(
cptr_t c,
struct backing_dev_info_container **backing_dev_info_container);
int glue_cap_lookup_module_type(
struct glue_cspace *cspace,
cptr_t c,
struct module_container **module_container);
void glue_cap_remove(
struct glue_cspace *cspace,
cptr_t c);
......
......@@ -1181,9 +1181,17 @@ struct file_system_type_container {
struct ipc_channel c;
};
struct module_container {
struct module module;
u64 ref1;
u64 ref2;
};
static struct module_container module_container;
static struct file_system_type_container pmfs_fs_type_container = {
.file_system_type = {
.owner = THIS_MODULE,
.owner = &module_container.module,
.name = "pmfs",
.mount = pmfs_mount,
.kill_sb = kill_anon_super,
......
......@@ -25,6 +25,7 @@ struct type_ops_id {
enum glue_type {
GLUE_TYPE_FILE_SYSTEM_TYPE,
GLUE_TYPE_BACKING_DEV_INFO,
GLUE_TYPE_MODULE,
GLUE_NR_TYPES,
};
......@@ -49,6 +50,13 @@ static struct type_ops_id glue_libcap_type_ops[GLUE_NR_TYPES] = {
.revoke = dummy_func,
}
},
{
{
.name = "struct module",
.delete = dummy_func,
.revoke = dummy_func,
}
},
};
int glue_cap_init(void)
......@@ -140,6 +148,16 @@ int glue_cap_insert_backing_dev_info_type(
c_out);
}
int glue_cap_insert_module_type(
struct glue_cspace *cspace,
struct module_container *module_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, module_container,
glue_libcap_type_ops[GLUE_TYPE_MODULE].libcap_type,
c_out);
}
int glue_cap_lookup_file_system_type_type(
struct glue_cspace *cspace,
cptr_t c,
......@@ -161,6 +179,17 @@ int glue_cap_lookup_backing_dev_info_type(
(void **)backing_dev_info_container);
}
int glue_cap_lookup_module_type(
struct glue_cspace *cspace,
cptr_t c,
struct module_container **module_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_MODULE].libcap_type,
(void **)module_container);
}
void glue_cap_remove(
struct glue_cspace *cspace,
cptr_t c)
......
......@@ -76,11 +76,11 @@ void glue_vfs_exit(void)
int register_filesystem_callee(void)
{
struct file_system_type_container *fs_container;
struct module_container *module_container;
int ret;
struct module *pmfs_module;
/*
* SET UP CONTAINER ----------------------------------------
* SET UP CONTAINERS ----------------------------------------
*/
fs_container = kzalloc(sizeof(*fs_container), GFP_KERNEL);
if (!fs_container) {
......@@ -98,14 +98,33 @@ int register_filesystem_callee(void)
goto fail2;
}
module_container = kzalloc(sizeof(*module_container), GFP_KERNEL);
if (!module_container) {
LIBLCD_ERR("kzalloc module container");
ret = -ENOMEM;
goto fail3;
}
ret = glue_cap_insert_module_type(
pmfs_cspace,
module_container,
&module_container->my_ref);
if (ret) {
LIBLCD_ERR("insert");
goto fail4;
}
/* IPC UNMARSHALING ---------------------------------------- */
/*
* Ref comes first.
* Refs come first.
*
* XXX: We don't even bother passing the name for
* now, and just hard code it for pmfs. (Otherwise, we have to
* track a pesky 5 byte alloc.)
* struct file_system_type
* -----------------------
*
* XXX: We don't bother passing fs name for now. Just hard code
* it to "pmfs".
*/
fs_container->pmfs_ref = __cptr(lcd_r1());
fs_container->file_system_type.name = "pmfs";
......@@ -115,17 +134,13 @@ int register_filesystem_callee(void)
*/
fs_container->pmfs_channel = lcd_cr1();
/*
* XXX Hack: Look up struct module for pmfs
* struct module
* -------------
*
* Pull out remote ref, and link with fs type
*/
mutex_lock(&module_mutex);
pmfs_module = find_module("lcd_test_mod_pmfs_lcd");
mutex_unlock(&module_mutex);
if (!pmfs_module) {
LIBLCD_ERR("couldn't find module");
ret = -EIO;
goto fail3;
}
fs_container->file_system_type.owner = pmfs_module;
module_container->pmfs_ref = __cptr(lcd_r2());
fs_container->file_system_type.owner = &module_container->module;
/*
* CALL REAL REGISTER_FILESYSTEM ------------------------------
......@@ -134,7 +149,7 @@ int register_filesystem_callee(void)
ret = register_filesystem(&fs_container->file_system_type);
if (ret) {
LIBLCD_ERR("register fs failed");
goto fail4;
goto fail5;
}
/*
......@@ -146,9 +161,10 @@ int register_filesystem_callee(void)
*/
lcd_set_r0(ret);
/*
* Pass back a ref to our copy
* Pass back a ref to our copies
*/
lcd_set_r1(cptr_val(fs_container->my_ref));
lcd_set_r2(cptr_val(module_container->my_ref));
/*
* Clear cr1
*/
......@@ -159,15 +175,18 @@ int register_filesystem_callee(void)
ret = lcd_sync_reply();
if (ret) {
LIBLCD_ERR("lcd_reply");
goto fail5;
goto fail6;
}
return 0;
fail5:
fail6:
if (unregister_filesystem(&fs_container->file_system_type) != 0)
LIBLCD_ERR("double fault");
fail5:
glue_cap_remove(pmfs_cspace, module_container->my_ref);
fail4:
kfree(module_container);
fail3:
glue_cap_remove(pmfs_cspace, fs_container->my_ref);
fail2:
......@@ -185,8 +204,9 @@ fail1:
int unregister_filesystem_callee(void)
{
struct file_system_type_container *fs_container;
struct module_container *module_container;
int ret;
cptr_t ref;
cptr_t fs_ref, m_ref;
/* CLEAR UNUSED SLOT ------------------------------ */
......@@ -202,22 +222,32 @@ int unregister_filesystem_callee(void)
/* IPC UNMARSHALING ---------------------------------------- */
/*
* We expect one ref to our copy
* We expect refs to our copies
*/