Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xcap
xcap-capability-linux
Commits
7f0585cd
Commit
7f0585cd
authored
Apr 06, 2014
by
Jithu Joseph
Committed by
Vikram Narayanan
Oct 25, 2016
Browse files
Moving IPC code to a separate file for cleaner interface.
parent
290dfa65
Changes
7
Hide whitespace changes
Inline
Side-by-side
arch/x86/lcd/guest/rcvr.c
View file @
7f0585cd
...
...
@@ -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"
...
...
arch/x86/lcd/ipc.c
0 → 100644
View file @
7f0585cd
// 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
;
}
arch/x86/lcd/ipc.h
0 → 100644
View file @
7f0585cd
#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
arch/x86/lcd/ipc_common_defs.h
View file @
7f0585cd
#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
arch/x86/lcd/lcd_defs.h
View file @
7f0585cd
...
...
@@ -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
);
...
...
arch/x86/lcd/lcd_main.c
View file @
7f0585cd
...
...
@@ -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
;
...
...
arch/x86/lcd/utils.c
View file @
7f0585cd
...
...
@@ -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
,
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment