Commit 7f0585cd authored by Jithu Joseph's avatar Jithu Joseph Committed by Vikram Narayanan
Browse files

Moving IPC code to a separate file for cleaner interface.

parent 290dfa65
......@@ -12,8 +12,10 @@
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <asm/vmx.h>
#include "../ipc.h"
#include "../lcd_defs.h"
#include "../ipc_common_defs.h"
//#include "../ipc_common_defs.h"
......
// Sync IPC specific routines
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include "ipc.h"
#include "lcd_defs.h"
void display_mr(utcb_t *p_utcb) {
printk(KERN_ERR "Message Regs at utcb %p - %d ,%d , %d\n", p_utcb, p_utcb->mr[0], p_utcb->mr[1], p_utcb->mr[3]);
}
int ipc_send(u32 myself, u32 recv_capid)
{
lcd_struct *recv_lcd, *snd_lcd;
ipc_wait_list_elem stack_elem;
printk(KERN_ERR "ipc_send : myself %d reciever %d\n", myself, recv_capid);
//chk if the reciever is ready
// fetch the reciever task struct from if
recv_lcd = (lcd_struct *) get_cap_obj(recv_capid);
if (recv_lcd == NULL) {
printk(KERN_ERR "ipc_send : Cant get object for reciever %d\n", recv_capid);
return -1;
}
snd_lcd = (lcd_struct *) get_cap_obj(myself);
if (snd_lcd == NULL) {
printk(KERN_ERR "ipc_send : Cant get object for myself %d\n", myself);
return -1;
}
if (recv_lcd->sync_ipc.state == IPC_RCV_WAIT && \
recv_lcd->sync_ipc.expected_sender == myself) {
printk(KERN_ERR "ipc_send : partner %d expecting me\n", recv_capid);
//copy the message registers
memcpy(recv_lcd->shared, snd_lcd->shared, sizeof(utcb_t));
//awaken the thread
wake_up_process(recv_lcd->sync_ipc.task);
//looks like there is no need for a reciever queue
//as if a process invokes a recv and finds no
//corresponding senders , then it puts itself to sleep
recv_lcd->sync_ipc.state = IPC_DONT_CARE;
recv_lcd->sync_ipc.expected_sender = 0;
//No case of
} else {
// put him in the Q
recv_lcd->sync_ipc.snd_sleepers++;
set_current_state(TASK_INTERRUPTIBLE);
stack_elem.peer = myself;
stack_elem.task = current;
// recv_lcd->sync_ipc.status = IPC_SND_WAIT;
list_add_tail(&stack_elem.list, &recv_lcd->sync_ipc.snd_q);
printk(KERN_ERR "ipc_send : putting myself to sleep %p\n", current);
schedule();
}
printk(KERN_ERR "ipc_send : Finished\n");
return 0;
}
int ipc_recv(u32 myself, u32 send_capid)
{
lcd_struct *recv_lcd, *snd_lcd;
struct list_head *ptr;
ipc_wait_list_elem *entry;
printk(KERN_ERR "ipc_recv : myself %d sender %d\n", myself, send_capid);
recv_lcd = (lcd_struct *) get_cap_obj(myself);
if (recv_lcd == NULL) {
printk(KERN_ERR "ipc_recv : Cant get object for my id %d\n", myself);
return -1;
}
snd_lcd = (lcd_struct *) get_cap_obj(send_capid);
if (snd_lcd == NULL) {
printk(KERN_ERR "ipc_recv : Cant get object for peer id %d\n", send_capid);
//return -1;
}
//check if one of the senders in the snd q is our intended
// recipient
if (recv_lcd->sync_ipc.snd_sleepers > 0) {
printk(KERN_ERR "ipc_recv : Num of senders in Q %d \n", \
recv_lcd->sync_ipc.snd_sleepers);
list_for_each(ptr, &recv_lcd->sync_ipc.snd_q) {
entry = list_entry(ptr, ipc_wait_list_elem, list);
if (entry->peer == send_capid) {
printk(KERN_ERR "ipc_recv : Found expected sender %d\n", send_capid);
recv_lcd->sync_ipc.snd_sleepers--;
//copy the message registers
memcpy(recv_lcd->shared, snd_lcd->shared, sizeof(utcb_t));
//remove the entry
list_del(ptr);
//wakeup
wake_up_process(entry->task);
// we dont care for state in snd_wait
//recv_lcd->sync_ipc.status = IPC_RUNNING;
printk(KERN_ERR "ipc_recv : Returning after waking up sender\n");
return 0;
}
}
}
printk(KERN_ERR "ipc_recv : Scheduling out myself\n");
// we cant proceed further
recv_lcd->sync_ipc.state = IPC_RCV_WAIT ;
recv_lcd->sync_ipc.expected_sender = send_capid;
set_current_state(TASK_INTERRUPTIBLE);
schedule();
printk(KERN_ERR "ipc_recv : Somebody woke me\n");
return 0;
}
#ifndef HOST_IPC_H
#define HOST_IPC_H
#include "ipc_common_defs.h"
enum ipc_state {
IPC_DONT_CARE = 0,
IPC_RCV_WAIT = 1,
IPC_SND_WAIT = 2,
IPC_RUNNING = 3,
};
typedef struct {
u32 peer;
struct list_head list;
struct task_struct *task;
} ipc_wait_list_elem;
typedef struct {
// either we put an explicit capid here
// so that given the capid we can fetch
// the peers sync_ipc or lcd_struct
u32 state;
u32 my_capid;
//u32 dir;
u32 expected_sender;
// void *waiting_on; -> this might not be reqd as we are modelling spl states
//struct lcd_struct *lcd_mine;
//struct lcd_struct *lcd_partner;
// some waitq
spinlock_t snd_lock;
u32 snd_sleepers;
struct list_head snd_q;
struct task_struct *task;
//spinlock_t rcv_lock;
// struct list_head rcv_q;
} sync_ipc_t;
//headers used by host for ipc
int ipc_send(u32 myself, u32 recv_capid);
int ipc_recv(u32 myself, u32 send_capid);
void display_mr(utcb_t *p_utcb);
#endif
#ifndef LCD_GUEST_DEFS_H
#define LCD_GUEST_DEFS_H
#ifndef LCD_IPC_GUEST_DEFS_H
#define LCD_IPC_GUEST_DEFS_H
typedef struct {
......@@ -41,8 +41,6 @@ union utcb_union {
char kstack[PAGE_SIZE];
};
void display_mr(utcb_t *p_utcb) {
printk(KERN_ERR "Message Regs at utcb %p - %d ,%d , %d\n", p_utcb, p_utcb->mr[0], p_utcb->mr[1], p_utcb->mr[3]);
}
#endif
......@@ -151,21 +151,6 @@ struct ipc_waitq {
struct list_head list;
};
typedef struct {
u32 peer;
struct list_head list;
struct task_struct *task;
} ipc_wait_list_elem;
/* Task states */
enum ipc_state {
IPC_DONT_CARE = 0,
IPC_RCV_WAIT = 1,
IPC_SND_WAIT = 2,
IPC_RUNNING = 3,
};
typedef struct {
int cpu;
......@@ -212,26 +197,7 @@ typedef struct {
struct vmx_msr_entry host[NR_AUTOLOAD_MSRS];
} msr_autoload;
struct sync_ipc {
// either we put an explicit capid here
// so that given the capid we can fetch
// the peers sync_ipc or lcd_struct
u32 state;
u32 my_capid;
//u32 dir;
u32 expected_sender;
// void *waiting_on; -> this might not be reqd as we are modelling spl states
//struct lcd_struct *lcd_mine;
//struct lcd_struct *lcd_partner;
// some waitq
spinlock_t snd_lock;
u32 snd_sleepers;
struct list_head snd_q;
struct task_struct *task;
//spinlock_t rcv_lock;
// struct list_head rcv_q;
} sync_ipc;
sync_ipc_t sync_ipc;
struct vmcs *vmcs;
void *shared;
......@@ -305,6 +271,7 @@ const char* lcd_exit_reason(int exit_code);
// Inside LCD:
int lcd_read_mod_file(const char* filepath, void** content, long* size);
void * get_cap_obj(u32 cap_id);
int lcd_load_vmlinux(const char* kfile, lcd_struct *lcd, u64 *elf_entry);
......
......@@ -41,8 +41,8 @@ MODULE_PARM_DESC(vmlinux_file, "vmlinux or vmlinuz path");
/* #include "lcd.h" */
#include "ipc.h"
#include "lcd_defs.h"
#include "ipc_common_defs.h"
MODULE_AUTHOR("Weibin Sun");
MODULE_LICENSE("GPL");
......@@ -2087,119 +2087,6 @@ static void vmx_handle_external_interrupt(lcd_struct *lcd) {
}
int ipc_send(u32 myself, u32 recv_capid)
{
lcd_struct *recv_lcd, *snd_lcd;
ipc_wait_list_elem stack_elem;
printk(KERN_ERR "ipc_send : myself %d reciever %d\n", myself, recv_capid);
//chk if the reciever is ready
// fetch the reciever task struct from if
recv_lcd = (lcd_struct *) get_cap_obj(recv_capid);
if (recv_lcd == NULL) {
printk(KERN_ERR "ipc_send : Cant get object for reciever %d\n", recv_capid);
return -1;
}
snd_lcd = (lcd_struct *) get_cap_obj(myself);
if (snd_lcd == NULL) {
printk(KERN_ERR "ipc_send : Cant get object for myself %d\n", myself);
return -1;
}
if (recv_lcd->sync_ipc.state == IPC_RCV_WAIT && \
recv_lcd->sync_ipc.expected_sender == myself) {
printk(KERN_ERR "ipc_send : partner %d expecting me\n", current);
//copy the message registers
memcpy(recv_lcd->shared, snd_lcd->shared, sizeof(utcb_t));
//awaken the thread
wake_up_process(recv_lcd->sync_ipc.task);
//looks like there is no need for a reciever queue
//as if a process invokes a recv and finds no
//corresponding senders , then it puts itself to sleep
recv_lcd->sync_ipc.state = IPC_DONT_CARE;
recv_lcd->sync_ipc.expected_sender = 0;
//No case of
} else {
// put him in the Q
recv_lcd->sync_ipc.snd_sleepers++;
set_current_state(TASK_INTERRUPTIBLE);
stack_elem.peer = myself;
stack_elem.task = current;
// recv_lcd->sync_ipc.status = IPC_SND_WAIT;
list_add_tail(&stack_elem.list, &recv_lcd->sync_ipc.snd_q);
printk(KERN_ERR "ipc_send : putting myself to sleep %p\n", current);
schedule();
}
printk(KERN_ERR "ipc_send : Finished\n");
return 0;
}
int ipc_recv(u32 myself, u32 send_capid)
{
lcd_struct *recv_lcd, *snd_lcd;
struct list_head *ptr;
ipc_wait_list_elem *entry;
printk(KERN_ERR "ipc_recv : myself %d sender %d\n", myself, send_capid);
recv_lcd = (lcd_struct *) get_cap_obj(myself);
if (recv_lcd == NULL) {
printk(KERN_ERR "ipc_recv : Cant get object for my id %d\n", myself);
return -1;
}
snd_lcd = (lcd_struct *) get_cap_obj(send_capid);
if (snd_lcd == NULL) {
printk(KERN_ERR "ipc_recv : Cant get object for peer id %d\n", send_capid);
//return -1;
}
//check if one of the senders in the snd q is our intended
// recipient
if (recv_lcd->sync_ipc.snd_sleepers > 0) {
printk(KERN_ERR "ipc_recv : Num of senders in Q %d \n", \
recv_lcd->sync_ipc.snd_sleepers);
list_for_each(ptr, &recv_lcd->sync_ipc.snd_q) {
entry = list_entry(ptr, ipc_wait_list_elem, list);
if (entry->peer == send_capid) {
printk(KERN_ERR "ipc_recv : Found expected sender %d\n", send_capid);
recv_lcd->sync_ipc.snd_sleepers--;
//copy the message registers
memcpy(recv_lcd->shared, snd_lcd->shared, sizeof(utcb_t));
//remove the entry
list_del(ptr);
//wakeup
wake_up_process(entry->task);
// we dont care for state in snd_wait
//recv_lcd->sync_ipc.status = IPC_RUNNING;
printk(KERN_ERR "ipc_recv : Returning after waking up sender\n");
return 0;
}
}
}
printk(KERN_ERR "ipc_recv : Scheduling out myself\n");
// we cant proceed further
recv_lcd->sync_ipc.state = IPC_RCV_WAIT ;
recv_lcd->sync_ipc.expected_sender = send_capid;
set_current_state(TASK_INTERRUPTIBLE);
schedule();
printk(KERN_ERR "ipc_recv : Somebody woke me\n");
return 0;
}
static void vmx_handle_vmcall(lcd_struct *lcd) {
u32 ipc_dir, ipc_peer;
......
......@@ -12,7 +12,7 @@
#include <asm/vmx.h>
#include <uapi/linux/elf.h>
#include "ipc.h"
#include "lcd_defs.h"
int lcd_read_mod_file(const char* filepath,
......
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