Commit 1082137e authored by aftabhussain's avatar aftabhussain
Browse files

Add foobar glue code in test_mods dir

parent 8a08b934
obj-$(LCD_CONFIG_BUILD_FOOBAR_BOOT) += boot/
obj-$(LCD_CONFIG_BUILD_FOOBAR_DUMMY_LCD) += dummy_lcd/
obj-$(LCD_CONFIG_BUILD_FOOBAR_NET_KLCD) += net_klcd/
obj-m += lcd_test_mod_foobar_boot.o
lcd_test_mod_foobar_boot-y += main.o
ccflags-y += $(NONISOLATED_CFLAGS)
/*
* boot.c - non-isolated kernel module, does setup
* when fake minix and vfs are to be launched
* in isolated containers
*/
#include <lcd_config/pre_hook.h>
#include <liblcd/liblcd.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include "../glue_helper.h"
#include <lcd_config/post_hook.h>
cptr_t net_klcd, dummy_lcd;
struct lcd_create_ctx *dummy_ctx;
cptr_t net_chnl;
cptr_t net_chnl_domain_cptr, dummy_chnl_domain_cptr;
static int boot_main(void)
{
int ret;
/*
* Enter lcd mode
*/
ret = lcd_enter();
if (ret) {
LIBLCD_ERR("lcd enter failed");
goto fail1;
}
/* ---------- Create vfs channel ---------- */
ret = lcd_create_sync_endpoint(&net_chnl);
if (ret) {
LIBLCD_ERR("lcd create sync endpoint");
goto fail2;
}
/* ---------- Create LCDs ---------- */
ret = lcd_create_module_klcd(LCD_DIR("foobar/net_klcd"),
"lcd_test_mod_foobar_net_klcd",
&net_klcd);
if (ret) {
LIBLCD_ERR("failed to create net klcd");
goto fail3;
}
ret = lcd_create_module_lcd(LCD_DIR("foobar/dummy_lcd"),
"lcd_test_mod_foobar_dummy_lcd",
&dummy_lcd,
&dummy_ctx);
if (ret) {
LIBLCD_ERR("failed to create dummy lcd");
goto fail4;
}
ret = cptr_alloc(lcd_to_boot_cptr_cache(dummy_ctx),
&dummy_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("alloc cptr");
goto fail5;
}
ret = lcd_cap_grant(dummy_lcd, net_chnl, dummy_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("grant");
goto fail6;
}
/* ---------- Set up boot info ---------- */
// HACK: But WTF is this?
net_chnl_domain_cptr = __cptr(3);
ret = lcd_cap_grant(net_klcd, net_chnl, net_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("grant");
goto fail7;
}
lcd_to_boot_info(dummy_ctx)->cptrs[0] = dummy_chnl_domain_cptr;
/* ---------- RUN! ---------- */
LIBLCD_MSG("starting network...");
ret = lcd_run(net_klcd);
if (ret) {
LIBLCD_ERR("failed to start vfs lcd");
goto fail8;
}
LIBLCD_MSG("starting dummy ethernet...");
ret = lcd_run(dummy_lcd);
if (ret) {
LIBLCD_ERR("failed to start dummy lcd");
goto fail9;
}
/*
* Wait for 4 seconds
*/
//msleep(100000);
/*
* Tear everything down
*/
ret = 0;
// return
goto fail1;
/* The destroy's will free up everything ... */
fail9:
fail8:
fail7:
lcd_cap_delete(dummy_lcd);
lcd_destroy_create_ctx(dummy_ctx);
fail6:
fail5:
fail4:
//lcd_cap_delete(net_klcd);
lcd_destroy_module_klcd(net_klcd, "lcd_test_mod_foobar_net_klcd");
fail3:
fail2:
lcd_exit(0); /* will free endpoints */
fail1:
return ret;
}
static DECLARE_WAIT_QUEUE_HEAD(wq);
static int shutdown = 0;
int boot_lcd_thread(void *data)
{
static unsigned once = 0;
int ret;
while (!kthread_should_stop()) {
if (!once) {
LCD_MAIN({
ret = boot_main();
});
}
once = 1;
wait_event_interruptible(wq, shutdown != 0);
}
msleep(2000);
LIBLCD_MSG("Exiting thread");
lcd_destroy_module_klcd(net_klcd,
"lcd_test_mod_foobar_net_klcd");
if (current->lcd)
lcd_cap_delete(dummy_lcd);
if (dummy_ctx)
lcd_destroy_create_ctx(dummy_ctx);
lcd_exit(0);
return 0;
}
struct task_struct *boot_task;
static int boot_init(void)
{
LIBLCD_MSG("%s: entering", __func__);
boot_task = kthread_create(boot_lcd_thread, NULL, "boot_lcd_thread");
if (!IS_ERR(boot_task))
wake_up_process(boot_task);
return 0;
}
static void boot_exit(void)
{
/* nothing to do */
if (!IS_ERR(boot_task)) {
LIBLCD_MSG("%s: exiting", __func__);
shutdown = 1;
wake_up_interruptible(&wq);
kthread_stop(boot_task);
}
}
module_init(boot_init);
module_exit(boot_exit);
MODULE_LICENSE("GPL");
/*
* cap.c
*
* cspace code for pmfs/vfs
*/
#include <lcd_config/pre_hook.h>
#include <libcap.h>
#include <liblcd/liblcd.h>
#include <linux/slab.h>
#include "glue_helper.h"
#include <lcd_config/post_hook.h>
/* ------------------------------------------------------------ */
static struct cap_type_system *glue_libcap_type_system;
struct type_ops_id {
struct cap_type_ops ops;
cap_type_t libcap_type;
};
enum glue_type {
GLUE_TYPE_NET_DEVICE,
GLUE_TYPE_NET_DEVICE_OPS,
GLUE_TYPE_NLATTR,
GLUE_TYPE_RTNL_LINK_OPS,
GLUE_TYPE_RTNL_LINK_STATS64,
GLUE_TYPE_SK_BUFF,
GLUE_TYPE_SETUP,
GLUE_NR_TYPES,
};
static int dummy_func(struct cspace *cspace, struct cnode *cnode,
void *object)
{
return 0;
}
static struct type_ops_id glue_libcap_type_ops[GLUE_NR_TYPES] = {
{
{
.name = "struct net_device",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "struct net_device_ops",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "struct nlattr",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "struct rtnl_link_ops",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "struct rtnl_link_stats64",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "struct sk_buff",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "alloc_netdev_mqs: setup",
.delete = dummy_func,
.revoke = dummy_func,
}
},
};
int glue_cap_init(void)
{
int ret;
int i;
cap_type_t libcap_type;
/*
* Alloc and init microkernel type system
*/
ret = cap_type_system_alloc(&glue_libcap_type_system);
if (ret) {
LIBLCD_ERR("alloc glue type system failed");
goto fail1;
}
ret = cap_type_system_init(glue_libcap_type_system);
if (ret) {
LIBLCD_ERR("init glue type system failed");
goto fail2;
}
/*
* Add types
*/
for (i = 0; i < GLUE_NR_TYPES; i++) {
libcap_type = cap_register_private_type(
glue_libcap_type_system,
0,
&glue_libcap_type_ops[i].ops);
if (libcap_type == CAP_TYPE_ERR) {
LIBLCD_ERR("failed to register glue cap type %s",
glue_libcap_type_ops[i].ops.name);
ret = -EIO;
goto fail3;
}
glue_libcap_type_ops[i].libcap_type = libcap_type;
}
return 0;
fail3:
cap_type_system_destroy(glue_libcap_type_system);
fail2:
cap_type_system_free(glue_libcap_type_system);
glue_libcap_type_system = NULL;
fail1:
return ret;
}
int glue_cap_create(struct glue_cspace **cspace_out)
{
return glue_cspace_alloc_init(glue_libcap_type_system, cspace_out);
}
void glue_cap_destroy(struct glue_cspace *cspace)
{
glue_cspace_destroy_free(cspace);
}
void glue_cap_exit(void)
{
/*
* Destroy and free type system if necessary
*/
if (glue_libcap_type_system) {
cap_type_system_destroy(glue_libcap_type_system);
cap_type_system_free(glue_libcap_type_system);
glue_libcap_type_system = NULL;
}
}
int glue_cap_insert_net_device_type(
struct glue_cspace *cspace,
struct net_device_container *net_device_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, net_device_container,
glue_libcap_type_ops[GLUE_TYPE_NET_DEVICE].libcap_type,
c_out);
}
int glue_cap_insert_net_device_ops_type(
struct glue_cspace *cspace,
struct net_device_ops_container *net_device_ops_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, net_device_ops_container,
glue_libcap_type_ops[GLUE_TYPE_NET_DEVICE_OPS].libcap_type,
c_out);
}
int glue_cap_insert_nlattr_type(
struct glue_cspace *cspace,
struct nlattr_container *nlattr_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, nlattr_container,
glue_libcap_type_ops[GLUE_TYPE_NLATTR].libcap_type,
c_out);
}
int glue_cap_insert_rtnl_link_ops_type(
struct glue_cspace *cspace,
struct rtnl_link_ops_container *rtnl_link_ops_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, rtnl_link_ops_container,
glue_libcap_type_ops[GLUE_TYPE_RTNL_LINK_OPS].libcap_type,
c_out);
}
int glue_cap_insert_rtnl_link_stats64_type(
struct glue_cspace *cspace,
struct rtnl_link_stats64_container *rtnl_link_stats64_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, rtnl_link_stats64_container,
glue_libcap_type_ops[GLUE_TYPE_RTNL_LINK_STATS64].libcap_type,
c_out);
}
int glue_cap_insert_sk_buff_type(
struct glue_cspace *cspace,
struct sk_buff_container *sk_buff_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, sk_buff_container,
glue_libcap_type_ops[GLUE_TYPE_SK_BUFF].libcap_type,
c_out);
}
int glue_cap_insert_setup_type(
struct glue_cspace *cspace,
struct setup_container *setup_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, setup_container,
glue_libcap_type_ops[GLUE_TYPE_SETUP].libcap_type,
c_out);
}
int glue_cap_lookup_net_device_type(
struct glue_cspace *cspace,
cptr_t c,
struct net_device_container **net_device_container)
{
return glue_cspace_lookup(cspace, c,
glue_libcap_type_ops[GLUE_TYPE_NET_DEVICE].libcap_type,
(void **)net_device_container);
}
int glue_cap_lookup_net_device_ops_type(
struct glue_cspace *cspace,
cptr_t c,
struct net_device_ops_container **net_device_ops_container)
{
return glue_cspace_lookup(cspace, c,
glue_libcap_type_ops[GLUE_TYPE_NET_DEVICE_OPS].libcap_type,
(void **)net_device_ops_container);
}
int glue_cap_lookup_nlattr_type(
struct glue_cspace *cspace,
cptr_t c,
struct nlattr_container **nlattr_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_NLATTR].libcap_type,
(void **)nlattr_container);
}
int glue_cap_lookup_rtnl_link_ops_type(
struct glue_cspace *cspace,
cptr_t c,
struct rtnl_link_ops_container **rtnl_link_ops_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_RTNL_LINK_OPS].libcap_type,
(void **)rtnl_link_ops_container);
}
int glue_cap_lookup_rtnl_link_stats64_type(
struct glue_cspace *cspace,
cptr_t c,
struct rtnl_link_stats64_container **rtnl_link_stats64_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_RTNL_LINK_STATS64].libcap_type,
(void **)rtnl_link_stats64_container);
}
int glue_cap_lookup_sk_buff_type(
struct glue_cspace *cspace,
cptr_t c,
struct sk_buff_container **sk_buff_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_SK_BUFF].libcap_type,
(void **)sk_buff_container);
}
int glue_cap_lookup_setup_type(
struct glue_cspace *cspace,
cptr_t c,
struct setup_container **setup_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_SETUP].libcap_type,
(void **)setup_container);
}
void glue_cap_remove(
struct glue_cspace *cspace,
cptr_t c)
{
glue_cspace_remove(cspace, c);
}
obj-m += lcd_test_mod_foobar_dummy_lcd.o
lcd_test_mod_foobar_dummy_lcd-y += main.o
# Original code
lcd_test_mod_foobar_dummy_lcd-y += dummy.o
lcd_test_mod_foobar_dummy_lcd-y += $(LIBLCD)
# glue code
lcd_test_mod_foobar_dummy_lcd-y += $(addprefix glue/, foobar.o)
lcd_test_mod_foobar_dummy_lcd-y += $(addprefix ../, cap.o)
ccflags-y += $(ISOLATED_CFLAGS)
/* dummy.c: a dummy foobar driver */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/foobar_device.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#define DRV_NAME "foobardummy"
#define DRV_VERSION "1.0"
static int dummy_dev_init(struct foobar_device *dev)
{
dev->dstats = kmalloc(sizeof(struct foo_stats), GFP_KERNEL);
if (!dev->dstats)
return -ENOMEM;
return 0;
}
static void dummy_dev_uninit(struct foobar_device *dev)
{
kfree(dev->dstats);
}
static const struct foobar_device_ops dummy_foobardev_ops = {
.init = dummy_dev_init,
.uninit = dummy_dev_uninit,
};
int numdummies = 0;
/* Number of dummy devices to be set up by this module. */
module_param(numdummies, int, 0);
MODULE_PARM_DESC(numdummies, "Number of dummy pseudo devices");
struct foobar_device *dev_dummy;
static int __init dummy_init_module(void)// the entry point to the dummy device driver
{
int err;
dev_dummy = alloc_foobardev(0, "dummy0");
if (!dev_dummy)
return -ENOMEM;
dev_dummy->foobardev_ops = &dummy_foobardev_ops;
dev_dummy->features = FOOBAR_PRIV_ALLOC;
dev_dummy->flags = FOO_LOOPBACK;
err = register_foobar(dev_dummy);//the call to dev.c fn to register dummy
if (err < 0)
goto err;
return 0;
err:
free_foobardev(dev_dummy);// free the foobar device if an error code is received
return err;
}
static void __exit dummy_cleanup_module(void)
{
unregister_foobar(dev_dummy);
}
module_init(dummy_init_module);
module_exit(dummy_cleanup_module);
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
#include <lcd_config/pre_hook.h>
#include "../../foobar.h"
#include <libcap.h>
#include <liblcd/liblcd.h>
#include <liblcd/sync_ipc_poll.h>
#include <liblcd/glue_cspace.h>
#include "../../glue_helper.h"
#include <linux/hashtable.h>
#include "../../rdtsc_helper.h"
#include <lcd_config/post_hook.h>