Commit b61f236b authored by Vikram Narayanan's avatar Vikram Narayanan
Browse files

fix channel crashes


Signed-off-by: Vikram Narayanan's avatarVikram Narayanan <vikram186@gmail.com>
parent 77dfe7f4
......@@ -29,6 +29,7 @@ enum glue_type {
GLUE_TYPE_RTNL_LINK_OPS,
GLUE_TYPE_RTNL_LINK_STATS64,
GLUE_TYPE_SK_BUFF,
GLUE_TYPE_SETUP,
GLUE_NR_TYPES,
};
......@@ -81,6 +82,14 @@ static struct type_ops_id glue_libcap_type_ops[GLUE_NR_TYPES] = {
.revoke = dummy_func,
}
},
{
{
.name = "alloc_netdev_mqs: setup",
.delete = dummy_func,
.revoke = dummy_func,
}
},
};
int glue_cap_init(void)
......@@ -212,6 +221,16 @@ int glue_cap_insert_sk_buff_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,
......@@ -276,6 +295,17 @@ int glue_cap_lookup_sk_buff_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)
......
......@@ -145,6 +145,8 @@ static const struct ethtool_ops dummy_ethtool_ops = {
.get_drvinfo = dummy_get_drvinfo,
};
extern int dummy_done;
static void dummy_setup(struct net_device *dev)
{
printk("%s, called\n", __func__);
......@@ -178,6 +180,7 @@ static void dummy_setup(struct net_device *dev)
dev->addr_assign_type = NET_ADDR_RANDOM;
//eth_hw_addr_random(dev);
dummy_done = 1;
}
static int dummy_validate(struct nlattr *tb[], struct nlattr *data[])
......@@ -209,7 +212,7 @@ static struct rtnl_link_ops dummy_link_ops __read_mostly = {
module_param(numdummies, int, 0);
MODULE_PARM_DESC(numdummies, "Number of dummy pseudo devices");
#endif
#if 0
#ifdef LCD_ISOLATE
static int dummy_init_one(void)
#else
......@@ -219,21 +222,28 @@ static int __init dummy_init_one(void)
struct net_device *dev_dummy;
int err;
dev_dummy = alloc_netdev(0, "dummy%d", NET_NAME_UNKNOWN, dummy_setup);
/*
* we need alloc_netdev to allocate more memory for us
* due to alignment this might be larger that the size of net_device_container
*/
dev_dummy = alloc_netdev(0
, "dummy%d", NET_NAME_UNKNOWN, dummy_setup);
if (!dev_dummy)
return -ENOMEM;
dev_dummy->rtnl_link_ops = &dummy_link_ops_container.rtnl_link_ops;
err = register_netdevice(dev_dummy);
/* err = register_netdevice(&dev_dummy->net_device);
if (err < 0)
goto err;
goto err;*/
return 0;
err:
free_netdev(dev_dummy);
//err:
// free_netdev(&dev_dummy_container->net_device);
return err;
}
#endif
extern int dummy_done;
#ifndef LCD_ISOLATE
static int __init dummy_init_module(void)
#else
......@@ -247,7 +257,8 @@ int dummy_init_module(void)
err = __rtnl_link_register(&dummy_link_ops_container.rtnl_link_ops);
if (err < 0)
goto out;
// else
// dummy_done = 1;
for (i = 0; i < numdummies && !err; i++) {
// err = dummy_init_one();
// cond_resched();
......
......@@ -11,7 +11,7 @@
struct cptr sync_ep;
static struct glue_cspace *c_cspace;
struct thc_channel *net_async;
extern struct thc_channel *net_async;
int glue_nullnet_init(void)
{
......@@ -270,14 +270,13 @@ int __rtnl_link_register(struct rtnl_link_ops *ops)
fail5:
fail4:
glue_cap_remove(c_cspace, ops_container->my_ref);
//glue_cap_remove(c_cspace, ops_container->my_ref);
fail3:
destroy_async_channel(chnl);
//destroy_async_channel(chnl);
fail2:
lcd_cap_delete(nullnet_sync_endpoint);
fail1:
return ret;
}
void __rtnl_link_unregister(struct rtnl_link_ops *ops)
......@@ -551,39 +550,71 @@ fail1:
return;
}
struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, unsigned char name_assign_type, void (*setup)(struct net_device*), unsigned int txqs, unsigned int rxqs)
struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, unsigned char name_assign_type, void (*setup)(struct net_device* dev), unsigned int txqs, unsigned int rxqs)
{
struct setup_container *temp;
struct setup_container *setup_container;
int ret;
int err;
struct fipc_message *request;
struct fipc_message *response;
struct net_device *ret1;
temp = kzalloc(sizeof( struct setup_container ), GFP_KERNEL);
if (!temp) {
struct net_device_container *ret1;
struct rtnl_link_ops *rtnl_ops;
struct rtnl_link_ops_container *rtnl_ops_cnt;
ret1 = kzalloc(sizeof( struct net_device_container ), GFP_KERNEL);
if (!ret1) {
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
goto fail_alloc;
}
setup_container = kzalloc(sizeof(*setup_container), GFP_KERNEL);
if (!setup_container) {
LIBLCD_ERR("kzalloc");
goto fail_alloc;
}
setup_container->setup = setup;
ret = glue_cap_insert_setup_type(c_cspace, setup_container, &setup_container->my_ref);
if (ret) {
LIBLCD_ERR("lcd insert");
goto fail_insert;
}
ret = glue_cap_insert_net_device_type(c_cspace, ret1, &ret1->my_ref);
if (ret) {
LIBLCD_ERR("lcd insert");
goto fail_insert;
}
ret = async_msg_blocking_send_start(net_async, &request);
if (ret) {
LIBLCD_ERR("failed to get a send slot");
lcd_exit(-1);
goto fail_async;
}
async_msg_set_fn_type(request, ALLOC_NETDEV_MQS);
fipc_set_reg1(request, sizeof_priv);
// fipc_set_reg2(request, name);
fipc_set_reg2(request, setup_container->other_ref.cptr);
fipc_set_reg3(request, name_assign_type);
fipc_set_reg4(request, txqs);
fipc_set_reg5(request, rxqs);
err = thc_ipc_call(net_async, request, &response);
if (err) {
LIBLCD_ERR("thc_ipc_call");
lcd_exit(-1);
goto fail_ipc;
}
ret = fipc_get_reg5(response);
ret1->other_ref.cptr = fipc_get_reg5(response);
fipc_recv_msg_end(thc_channel_to_fipc(net_async), response);
return ret1;
fail_ipc:
fail_async:
fail_alloc:
fail_insert:
return &ret1->net_device;
}
void consume_skb(struct sk_buff *skb)
......@@ -817,19 +848,36 @@ int ndo_change_carrier_callee(struct fipc_message *request, struct thc_channel *
int setup_callee(struct fipc_message *request, struct thc_channel *channel, struct glue_cspace *cspace, struct cptr sync_ep)
{
//struct net_device *dev;
int ret;
struct fipc_message *response;
unsigned int request_cookie;
struct setup_container *setup_container;
struct net_device_container *net_dev_container;
request_cookie = thc_get_request_cookie(request);
fipc_recv_msg_end(thc_channel_to_fipc(net_async), request);
fipc_recv_msg_end(thc_channel_to_fipc(channel), request);
//setup(dev);
if (async_msg_blocking_send_start(net_async, &response)) {
ret = glue_cap_lookup_setup_type(c_cspace, __cptr(fipc_get_reg2(request)), &setup_container);
if (ret) {
LIBLCD_ERR("lookup");
goto fail_lookup;
}
ret = glue_cap_lookup_net_device_type(c_cspace, __cptr(fipc_get_reg1(response)), &net_dev_container);
if (ret) {
LIBLCD_ERR("lookup");
goto fail_lookup;
}
setup_container->setup(&net_dev_container->net_device);
if (async_msg_blocking_send_start(channel, &response)) {
LIBLCD_ERR("error getting response msg");
return -EIO;
}
thc_ipc_reply(net_async, request_cookie, response);
thc_ipc_reply(channel, request_cookie, response);
fail_lookup:
return ret;
}
......
......@@ -13,10 +13,10 @@
#include <lcd_config/post_hook.h>
cptr_t nullnet_register_channel;
struct thc_channel *nullnet_async_chnl;
struct thc_channel *net_async;
struct glue_cspace *nullnet_cspace;
cptr_t nullnet_sync_endpoint;
int dummy_done;
int dummy_done = 0;
int dummy_init_module(void);
void dummy_cleanup_module(void);
......@@ -48,7 +48,7 @@ static void main_and_loop(void)
/*
* Do one async receive
*/
ret = thc_ipc_poll_recv(nullnet_async_chnl, &msg);
ret = thc_ipc_poll_recv(net_async, &msg);
if (ret) {
if (ret == -EWOULDBLOCK) {
continue;
......@@ -62,7 +62,7 @@ static void main_and_loop(void)
*/
ASYNC(
ret = dispatch_async_loop(nullnet_async_chnl, msg,
ret = dispatch_async_loop(net_async, msg,
nullnet_cspace,
nullnet_sync_endpoint);
if (ret) {
......
......@@ -125,6 +125,11 @@ int glue_cap_insert_sk_buff_type(
struct sk_buff_container *sk_buff_container,
cptr_t *c_out);
int glue_cap_insert_setup_type(
struct glue_cspace *cspace,
struct setup_container *setup_container,
cptr_t *c_out);
int glue_cap_lookup_net_device_type(
struct glue_cspace *cspace,
cptr_t c,
......@@ -156,6 +161,10 @@ int glue_cap_lookup_sk_buff_type(
cptr_t c,
struct sk_buff_container **sk_buff_container);
int glue_cap_lookup_setup_type(
struct glue_cspace *cspace,
cptr_t c,
struct setup_container **setup_container);
/* ASYNC HELPERS -------------------------------------------------- */
......
......@@ -528,21 +528,31 @@ void setup(struct net_device *dev, struct trampoline_hidden_args *hidden_args)
int err;
struct fipc_message *request;
struct fipc_message *response;
ret = async_msg_blocking_send_start(net_async, &request);
struct setup_container *setup_container;
struct net_device_container *net_dev_container;
net_dev_container = container_of(dev, struct net_device_container, net_device);
ret = async_msg_blocking_send_start(hidden_args->async_chnl, &request);
if (ret) {
LIBLCD_ERR("failed to get a send slot");
lcd_exit(-1);
goto fail_async;
}
async_msg_set_fn_type(request, SETUP);
/*fipc_set_reg1(request, netdev_ops_container->my_ref.cptr);
fipc_set_reg3(request, rtnl_link_ops_container->my_ref.cptr);
fipc_set_reg2(request, dev->rtnl_link_ops->kind);*/
err = thc_ipc_call(net_async, request, &response);
fipc_set_reg3(request, rtnl_link_ops_container->my_ref.cptr);*/
setup_container = (struct setup_container*)hidden_args->struct_container;
LIBLCD_MSG("sending setup_container cptr: other_ref %lu", setup_container->other_ref.cptr);
fipc_set_reg1(request, net_dev_container->other_ref.cptr);
fipc_set_reg2(request, setup_container->other_ref.cptr);
err = thc_ipc_call(hidden_args->async_chnl, request, &response);
if (err) {
LIBLCD_ERR("thc_ipc_call");
lcd_exit(-1);
goto fail_ipc;
}
fipc_recv_msg_end(thc_channel_to_fipc(net_async), response);
fipc_recv_msg_end(thc_channel_to_fipc(hidden_args->async_chnl), response);
fail_async:
fail_ipc:
return;
}
......@@ -967,7 +977,7 @@ int __rtnl_link_register_callee(void)
goto fail7;
}
ops_container->fs_info = fs_info;
setup_hidden_args = kzalloc(sizeof( *setup_hidden_args ), GFP_KERNEL);
/*setup_hidden_args = kzalloc(sizeof( *setup_hidden_args ), GFP_KERNEL);
if (!setup_hidden_args) {
LIBLCD_ERR("kzalloc hidden args");
lcd_exit(-1);
......@@ -990,7 +1000,7 @@ int __rtnl_link_register_callee(void)
LIBLCD_ERR("set mem nx");
goto fail3;
}
*/
validate_hidden_args = kzalloc(sizeof( *validate_hidden_args ), GFP_KERNEL);
if (!validate_hidden_args) {
LIBLCD_ERR("kzalloc hidden args");
......@@ -1083,9 +1093,9 @@ int rtnl_link_unregister_callee(struct fipc_message *request, struct thc_channel
LIBLCD_MSG("Calling real function %s", __func__);
rtnl_link_unregister(( &ops_container->rtnl_link_ops ));
glue_cap_remove(c_cspace, ops_container->my_ref);
setup_hidden_args = LCD_TRAMPOLINE_TO_HIDDEN_ARGS(ops_container->rtnl_link_ops.setup);
/*setup_hidden_args = LCD_TRAMPOLINE_TO_HIDDEN_ARGS(ops_container->rtnl_link_ops.setup);
kfree(setup_hidden_args->t_handle);
kfree(setup_hidden_args);
kfree(setup_hidden_args);*/
validate_hidden_args = LCD_TRAMPOLINE_TO_HIDDEN_ARGS(ops_container->rtnl_link_ops.validate);
kfree(validate_hidden_args->t_handle);
kfree(validate_hidden_args);
......@@ -1110,51 +1120,80 @@ int alloc_netdev_mqs_callee(struct fipc_message *request, struct thc_channel *ch
int rxqs;
struct fipc_message *response;
unsigned int request_cookie;
struct net_device *ret1;
struct net_device_ops_container *netdev_ops_container;
struct rtnl_link_ops_container *rtnl_link_ops_container;
struct net_device_container *dev_container;
struct net_device *net_device;
struct trampoline_hidden_args *setup_hidden_args;
request_cookie = thc_get_request_cookie(request);
fipc_recv_msg_end(thc_channel_to_fipc(net_async), request);
fipc_recv_msg_end(thc_channel_to_fipc(channel), request);
temp = kzalloc(sizeof( struct setup_container ), GFP_KERNEL);
if (!temp) {
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
}
name = kzalloc(sizeof( char ), GFP_KERNEL);
if (!name) {
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
goto fail_alloc;
}
sizeof_priv = fipc_get_reg1(request);
//name = fipc_get_reg2(request);
name = "dummy%d";
name_assign_type = fipc_get_reg3(request);
txqs = fipc_get_reg4(request);
rxqs = fipc_get_reg5(request);
ret1 = kzalloc(sizeof( ret ), GFP_KERNEL);
if (!ret1) {
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
temp->other_ref = __cptr(fipc_get_reg2(request));
LIBLCD_MSG("received setup_container cptr: other_ref %lu", temp->other_ref.cptr);
ret = glue_cap_insert_setup_type(c_cspace, temp, &temp->my_ref);
if (ret) {
LIBLCD_ERR("insert");
goto fail_insert;
}
ret1->netdev_ops = kzalloc(sizeof( ret1->netdev_ops ), GFP_KERNEL);
if (!ret1->netdev_ops) {
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
setup_hidden_args = kzalloc(sizeof( *setup_hidden_args ), GFP_KERNEL);
if (!setup_hidden_args) {
LIBLCD_ERR("kzalloc hidden args");
goto fail_alloc;
}
ret1->rtnl_link_ops = kzalloc(sizeof( ret1->rtnl_link_ops ), GFP_KERNEL);
if (!ret1->rtnl_link_ops) {
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
setup_hidden_args->t_handle = LCD_DUP_TRAMPOLINE(setup_trampoline);
if (!setup_hidden_args->t_handle) {
LIBLCD_ERR("duplicate trampoline");
goto fail_alloc;
}
ret1 = alloc_netdev_mqs(sizeof_priv, name, name_assign_type, ( temp->setup ), txqs, rxqs);
if (async_msg_blocking_send_start(net_async, &response)) {
setup_hidden_args->t_handle->hidden_args = setup_hidden_args;
setup_hidden_args->struct_container = temp;
setup_hidden_args->cspace = c_cspace;
setup_hidden_args->sync_ep = sync_ep;
setup_hidden_args->async_chnl = channel;
temp->setup = LCD_HANDLE_TO_TRAMPOLINE(setup_hidden_args->t_handle);
ret = set_memory_x(((unsigned long)setup_hidden_args->t_handle) & PAGE_MASK,
ALIGN(LCD_TRAMPOLINE_SIZE(setup_trampoline),
PAGE_SIZE) >> PAGE_SHIFT);
if (ret) {
LIBLCD_ERR("set mem nx");
goto fail3;
}
net_device = alloc_netdev_mqs(sizeof_priv, name, name_assign_type, (temp->setup ), txqs, rxqs);
dev_container = container_of(net_device, struct net_device_container, net_device);
ret = glue_cap_insert_net_device_type(c_cspace, dev_container , &dev_container->my_ref);
if (!ret) {
LIBLCD_ERR("lcd insert");
goto fail_insert;
}
if (async_msg_blocking_send_start(channel, &response)) {
LIBLCD_ERR("error getting response msg");
return -EIO;
}
fipc_set_reg1(response, netdev_ops_container->other_ref.cptr);
fipc_set_reg5(response, rtnl_link_ops_container->other_ref.cptr);
thc_ipc_reply(net_async, request_cookie, response);
fipc_set_reg5(response, dev_container->my_ref.cptr);
thc_ipc_reply(channel, request_cookie, response);
return ret;
fail_insert:
fail3:
fail_alloc:
return ret;
}
int consume_skb_callee(struct fipc_message *request, struct thc_channel *channel, struct glue_cspace *cspace, struct cptr sync_ep)
......
#include <lcd_config/pre_hook.h>
#include <linux/module.h>
#include <linux/kernel.h>
......
Supports Markdown
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