Commit 84067c4d authored by Anton Burtsev's avatar Anton Burtsev Committed by Vikram Narayanan

Client-server example... getting really wild (checkpoint)

parent c4fc774c
......@@ -26,7 +26,7 @@ struct sync_ipc *rvp;
int lcd_client_server_init_client(void) {
int ret;
capability_t rvp_cap = 0;
capability_t server;
struct cnode *cnode;
ret = lcd_enter();
......@@ -35,55 +35,68 @@ int lcd_client_server_init_client(void) {
return ret;
};
rvp = alloc_sync_ipc();
if(!rvp) {
printk(KERN_ERR "Failed to allocate memory\n");
return -ENOMEM;
ret = lcd_api_connect(lcd_get_api());
if (ret) {
printk(KERN_ERR "Failed to connect to LCD API\n");
return ret;
};
api_cap = current->utcb->boot_info.boot_caps[LCD_BOOT_API_CAP];
reply_cap = current->utcb->boot_info.boot_caps[LCD_BOOT_REPLY_CAP];
ret = lcd_alloc_cap(&current->cap_cache, &server);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
return -ENOSPC;
};
cnode = lcd_cnode_lookup(&current->cspace, rvp_cap);
if(cnode == 0) {
ret = lcd_api_create_sync_endpoint(api_cap, reply_cap, server);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
return -ENOSPC;
};
current->utcb->boot_info.boot_caps[LCD_BOOT_FREE_CAP0] = server;
cnode = lcd_cnode_lookup(&current->cspace, server);
if(cnode == NULL || cnode->type != LCD_TYPE_SYNC_EP) {
printk(KERN_ERR "Failed to create capability\n");
kfree(rvp);
return -ENOMEM;
};
cnode->type = LCD_TYPE_SYNC_EP;
cnode->object = rvp;
rvp = cnode->object;
lcd_cnode_release(cnode);
current->utcb->boot_info.boot_rvp = rvp_cap;
return 0;
};
int lcd_client_server_init_server(void)
{
int ret;
capability_t rvp_cap = 0;
struct cnode *cnode;
capability_t client;
ret = lcd_enter();
if (ret) {
printk(KERN_ERR "Failed to enter LCD environment\n");
return ret;
};
BUG_ON(rvp == NULL);
cnode = lcd_cnode_lookup(&current->cspace, rvp_cap);
if(cnode == 0) {
printk(KERN_ERR "Failed to create capability\n");
kfree(rvp);
return -ENOMEM;
ret = lcd_api_connect(lcd_get_api());
if (ret) {
printk(KERN_ERR "Failed to connect to LCD API\n");
return ret;
};
cnode->type = LCD_TYPE_SYNC_EP;
cnode->object = rvp;
ret = lcd_alloc_cap(&current->cap_cache, &client);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
return -ENOSPC;
};
lcd_cnode_release(cnode);
lcd_cap_insert_object(&current->cspace, client, rvp, LCD_TYPE_SYNC_EP);
current->utcb->boot_info.boot_rvp = rvp_cap;
current->utcb->boot_caps[LCD_BOOT_FREE_CAP0] = client;
return 0;
};
EXPORT_SYMBOL(lcd_client_server_init_server);
......@@ -91,29 +104,45 @@ EXPORT_SYMBOL(lcd_client_server_init_server);
int module_execution_loop(void) {
int ret;
capability_t boot_cap = current->utcb->boot_info.boot_rvp;
capability_t server_cap;
capability_t api_cap = current->utcb->boot_info.boot_caps[LCD_BOOT_API_CAP];
capability_t reply_cap = current->utcb->boot_info.boot_caps[LCD_BOOT_REPLY_CAP];
capability_t server = current->utcb->boot_info.boot_caps[LCD_BOOT_FREE_CAP0];
capability_t server_interface;
capability_t server_reply;
struct message_info *msg = &current->utcb->msg_info;
server_cap = boot_cap + 1;
msg->cap_regs[0] = server_cap;
ret = lcd_alloc_cap(&current->cap_cache, &server_interface);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
return -ENOSPC;
};
msg->cap_regs[0] = server_interface;
msg->valid_cap_regs = 1;
ret = ipc_recv(boot_cap, msg);
ret = ipc_recv(server, msg);
if (ret) {
printk(KERN_ERR "client failed to receive from the server:%d\n", ret);
return ret;
};
ret = lcd_api_alloc_reply_cap(api_cap, reply_cap, &server_reply);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
return -ENOSPC;
};
msg->regs[0] = 0 /* FUNC_TYPE_1*/;
msg->regs[1] = 1;
msg->regs[2] = 2;
msg->regs[3] = 3;
msg->valid_regs = 4;
ret = ipc_send(server_cap, msg);
msg->cap_regs[0] = server_reply;
msg->valid_cap_regs = 1;
ret = ipc_call(server_interface, msg);
if (ret) {
printk(KERN_ERR "client failed to ivoke server:%d\n", ret);
return ret;
......
......@@ -11,9 +11,9 @@
#include <lcd/cap-cache.h>
struct lcd_api {
struct cap_cache cap_cache;
int api_thread_exit;
capability_t rvp;
bool exit_flag;
capability_t ep_cap;
struct sync_ipc *ep;
};
......
/*
* Author: Anton Burtsev <aburtsev@flux.utah.edu>
* Copyright: University of Utah
*/
#ifndef _LCD_BOOT_H_
#define _LCD_BOOT_H_
enum lcd_boot_caps = {
LCD_BOOT_API_CAP = 0,
LCD_BOOT_REPLY_CAP = 1,
LCD_BOOT_FREE_CAP0,
LCD_BOOT_FREE_CAP1,
LCD_BOOT_FREE_CAP2,
LCD_BOOT_FREE_CAP3,
LCD_BOOT_FREE_CAP4,
LCD_BOOT_FREE_CAP5,
}
#endif
......@@ -29,6 +29,12 @@ struct cspace {
int lcd_cap_init(void);
int lcd_cap_exit(void);
int lcd_cap_insert_object(struct cspace *cspace, capability_t cap,
void *object, enum ... type);
struct sync_ipc *lcd_cap_make_sync_endpoint(struct cspace *cspace,
struct cap_cache *cache, capability_t *cap);
void lcd_cnode_release(struct cnode *cnode);
int lcd_init_cspace(struct cspace *cspace);
......
......@@ -106,6 +106,7 @@ int lcd_run(struct lcd *lcd);
const char* lcd_exit_reason(int exit_code);
int lcd_enter(void);
int lcd_api_connect(struct lcd_api *api);
struct lcd_api *lcd_get_api(void);
#endif /* LCD_LCD_H */
......@@ -63,6 +63,7 @@ struct sched_param {
#ifdef CONFIG_HAVE_LCD
#include <lcd/cap.h>
#include <lcd/ipc.h>
#include <lcd/cap-cache.h>
#endif
#include <asm/processor.h>
......@@ -1470,6 +1471,7 @@ struct task_struct {
unsigned int ptrace;
#ifdef CONFIG_HAVE_LCD
struct cspace cspace;
struct cap_cache cap_cache;
struct list_head sync_rendezvous;
struct utcb *utcb;
#endif
......
......@@ -14,7 +14,7 @@ enum lcd_api_calls {
struct utcb *utcb(void);
static inline int lcd_create_sync_endpoint(capability_t cap, capability_t reply_cap, capability_t ep_cap) {
static inline int lcd_api_create_sync_endpoint(capability_t cap, capability_t reply_cap, capability_t ep_cap) {
struct message_info *msg = &utcb()->msg_info;
......@@ -29,5 +29,4 @@ static inline int lcd_create_sync_endpoint(capability_t cap, capability_t reply_
};
#endif
......@@ -19,7 +19,7 @@ struct message_info {
};
struct boot_info {
capability_t boot_rvp;
capability_t boot_caps[8];
};
struct utcb {
......
......@@ -33,6 +33,50 @@ int lcd_cap_exit(void) {
return 0;
}
int lcd_cap_insert_object(struct cspace *cspace, capability_t cap,
void *object, enum lcd_cap_type type)
{
struct cnode *cnode;
cnode = lcd_cnode_lookup(cspace, cap);
if(cnode == 0) {
printk(KERN_ERR "Failed to create capability\n");
return -ENOMEM;
};
cnode->type = type;
cnode->object = object;
lcd_cnode_release(cnode);
return 0;
}
struct sync_ipc * lcd_cap_make_sync_endpoint(struct cspace *cspace, struct cap_cache *cache, capability_t *cap) {
struct sync_ipc *rvp;
rvp = alloc_sync_ipc();
if(!rvp) {
printk(KERN_ERR "Failed to allocate memory\n");
return NULL;
};
ret = lcd_alloc_cap(cache, cap);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
kfree(rvp);
return NULL;
};
ret = lcd_cap_insert_object(cspace, *cap, rvp, LCD_TYPE_SYNC_EP);
if(ret) {
printk(KERN_ERR "Failed to insert endpoint into the cspace:%d\n", ret);
kfree(rvp);
return NULL;
};
return rvp;
};
int lcd_init_cspace(struct cspace *cspace) {
cspace->cnode = kmalloc(sizeof(struct cnode) * LCD_MAX_CAPS, GFP_KERNEL);
......
struct cap_cache *cap_cache() {
return &current->cap_cache;
};
int lcd_api_alloc_reply_cap(capability_t api, capability_t api_reply, capability_t *reply) {
ret = lcd_alloc_cap(cap_cache(), reply);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
return -ENOSPC;
};
ret = lcd_api_create_sync_endpoint(api_cap, reply_cap, reply);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
return -ENOSPC;
};
return 0;
}
......@@ -25,7 +25,7 @@ int lcd_api_create_sync_endpoint(struct lcd_api *api, capability_t reply_cap) {
goto err;
};
ret = lcd_alloc_cap(&api->cap_cache, &free_cap);
ret = lcd_alloc_cap(&current->cap_cache, &free_cap);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
ret = -ENOSPC;
......@@ -33,26 +33,19 @@ int lcd_api_create_sync_endpoint(struct lcd_api *api, capability_t reply_cap) {
goto err;
};
cnode = lcd_cnode_lookup(&current->cspace, free_cap);
ret = lcd_cap_insert_object(&current->cspace, free_cap, rvp, LCD_TYPE_SYNC_EP);
if(cnode == 0) {
printk(KERN_ERR "Failed to create capability\n");
kfree(rvp);
ret = -ENOMEM;
goto err;
};
cnode->type = LCD_TYPE_SYNC_EP;
cnode->object = rvp;
lcd_cnode_release(cnode);
msg->cap_regs[0] = free_cap;
msg->valid_cap_regs = 1;
ipc_reply(reply_cap, msg);
lcd_cap_drop(&current->cspace, free_cap);
lcd_free_cap(&api->cap_cache, free_cap);
lcd_free_cap(&current->cap_cache, free_cap);
return 0;
err:
msg->err = ret;
......@@ -66,13 +59,13 @@ int lcd_api_execution_loop(struct lcd_api *lcd_api) {
enum lcd_api_calls call;
int ret;
ret = lcd_alloc_cap(&lcd_api->cap_cache, &reply_cap);
ret = lcd_alloc_cap(&current->cap_cache, &reply_cap);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
return -ENOSPC;
};
while (!lcd_api->api_thread_exit)
while (!lcd_api->exit_flag)
{
msg->valid_regs = sizeof(msg->regs)/sizeof(msg->regs[0]);
ret = ipc_recv(lcd_api->rvp, msg);
......@@ -109,54 +102,38 @@ int lcd_api_execution_loop(struct lcd_api *lcd_api) {
};
lcd_free_cap(&lcd_api->cap_cache, reply_cap);
lcd_free_cap(&current->cap_cache, reply_cap);
return 0;
};
int lcd_api_thread(void *p) {
int ret;
struct lcd_api *api = (struct lcd_api*) p;
return lcd_api_execution_loop((struct lcd_api*) p);
};
int lcd_api_init(struct lcd_api *api) {
int ret;
struct task_struct *t;
struct sync_ipc *rvp;
struct cnode *cnode;
ret = lcd_init_list_cache(&api->cap_cache, LCD_MAX_CAPS);
if (ret) {
printk(KERN_ERR "Failed to initialize cap cache:%d\n", ret);
return ret;
}
rvp = alloc_sync_ipc();
if(!rvp) {
printk(KERN_ERR "Failed to allocate memory\n");
return -ENOMEM;
};
ret = lcd_alloc_cap(&api->cap_cache, &api->rvp);
ret = lcd_enter();
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
kfree(rvp);
return -ENOSPC;
printk(KERN_ERR "Failed to enter LCD:%d\n", ret);
return ret;
};
cnode = lcd_cnode_lookup(&current->cspace, api->rvp);
if(cnode == 0) {
printk(KERN_ERR "Failed to create capability\n");
kfree(rvp);
return -ENOMEM;
api->ep = lcd_make_sync_endpoint(&current->cspace, &current->cap_cache, &api->ep_cap);
if(api->ep) {
printk(KERN_ERR "Failed to create API endpoint:%d\n", ret);
return -EINVAL;
};
cnode->type = LCD_TYPE_SYNC_EP;
cnode->object = rvp;
ret = lcd_api_execution_loop(api);
lcd_cnode_release(cnode);
return ret;
};
int lcd_api_init(struct lcd_api *api) {
int ret;
struct task_struct *t;
t = kthread_create(lcd_api_thread, api, "lcd-api");
if (!t) {
printk(KERN_ERR "Failed to create LCD API thread\n");
......@@ -168,6 +145,6 @@ int lcd_api_init(struct lcd_api *api) {
}
int lcd_api_exit(struct lcd_api *api) {
api->api_thread_exit = 1;
api->exit_flag = 1;
};
......@@ -19,22 +19,78 @@
#include <lcd/lcd.h>
#include <lcd/cap.h>
#include <lcd/api.h>
#include <lcd/boot.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LCD driver");
struct lcd_api lcd_api;
struct lcd_api *lcd_get_api(void) {
return &lcd_api;
};
EXPORT_SYMBOL(lcd_get_api);
int lcd_enter(void) {
int ret;
current->utcb = kmalloc(sizeof(struct utcb), GFP_KERNEL);
if (!current->utcb)
return -ENOMEM;
return lcd_init_cspace(&current->cspace);
ret = lcd_init_list_cache(&current->cap_cache, LCD_MAX_CAPS);
if (ret) {
printk(KERN_ERR "Failed to initialize cap cache:%d\n", ret);
return ret;
}
ret = lcd_init_cspace(&current->cspace);
if(ret) {
printk(KERN_ERR "Failed to init cspace:%d\n", ret);
return ret;
};
return 0;
};
EXPORT_SYMBOL(lcd_enter);
int lcd_api_connect(struct lcd_api *api) {
capability_t reply_cap;
capability_t api_cap;
/* Frist: we take an existing endpoint for the API and insert it into
* the connecting cspace */
ret = lcd_alloc_cap(&current->cap_cache, &api_cap);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
kfree(rvp);
return -ENOSPC;
};
ret = lcd_cap_insert_object(&current->cspace, api_cap, api->ep, LCD_TYPE_SYNC_EP);
if(ret) {
printk(KERN_ERR "Failed to insert endpoint into the cspace:%d\n", ret);
kfree(rvp);
return -ENOSPC;
};
/* Second: make a new endpoint so the connecting cspace can use call/reply
* primitives */
ret = lcd_make_sync_endpoint(&current->cspace, &current->cap_cache, &reply_cap);
if(ret) {
printk(KERN_ERR "Failed to create API endpoint:%d\n", ret);
return ret;
};
current->utcb->boot_info.boot_caps[LCD_BOOT_API_CAP] = api_cap;
current->utcb->boot_info.boot_caps[LCD_BOOT_REPLY_CAP] = reply_cap;
return 0;
};
EXPORT_SYMBOL(lcd_api_connect);
static long lcd_dev_ioctl(struct file *filp ,
unsigned int ioctl, unsigned long arg)
{
......
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