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
290dfa65
Commit
290dfa65
authored
Apr 04, 2014
by
Jithu Joseph
Committed by
Vikram Narayanan
Oct 25, 2016
Browse files
Sync IPC changes. Locking to be added.
parent
5c7887d9
Changes
4
Hide whitespace changes
Inline
Side-by-side
arch/x86/lcd/guest/
utility
.c
→
arch/x86/lcd/guest/
rcvr
.c
View file @
290dfa65
...
...
@@ -13,6 +13,7 @@
#include
<linux/init.h>
/* Needed for the macros */
#include
<asm/vmx.h>
#include
"../lcd_defs.h"
#include
"../ipc_common_defs.h"
...
...
@@ -22,6 +23,8 @@
typedef
unsigned
int
uint
;
// The idea is to get the shared page which is
// to be used for IPC . It is the lowest page
// the bottom of the 4 Page Stack block.
...
...
@@ -88,15 +91,27 @@ lcd_putc(char c)
}
#if 1
static
void
lcd_ipc
()
{
asm
volatile
(
"push %rax"
);
//asm volatile("mov $0xdeadbeef, %rax");
// DIR : 2 (RCV) and peer capid 2
asm
volatile
(
"mov $0x0000000200000002, %rax"
);
asm
volatile
(
"vmcall"
);
asm
volatile
(
"pop %rax"
);
// printk(KERN_ERR "%c", c);
}
static
void
printint
(
int
xx
,
int
base
,
int
sgn
)
printint
(
long
xx
,
int
base
,
int
sgn
)
{
static
char
digits
[]
=
"0123456789ABCDEF"
;
char
buf
[
16
];
int
i
,
neg
;
u
int
x
;
u
64
x
;
neg
=
0
;
if
(
sgn
&&
xx
<
0
){
...
...
@@ -117,75 +132,7 @@ printint(int xx, int base, int sgn)
while
(
--
i
>=
0
)
lcd_putc
(
buf
[
i
]);
}
#endif
#if 0
static void
printint(int xx, int base, int sgn)
{
char buf[16];
int i, neg;
int int_digs[16];
uint x;
neg = 0;
if(sgn && xx < 0){
neg = 1;
x = -xx;
} else {
x = xx;
}
i = 0;
do{
int_digs[i++] = x % base;
}while((x /= base) != 0);
if(neg)
buf[i++] = '-';
while(--i >= 0) {
switch(int_digs[i]) {
case 0: lcd_putc('0');
break;
case 1: lcd_putc('1');
break;
case 2: lcd_putc('2');
break;
case 3: lcd_putc('3');
break;
case 4: lcd_putc('4');
break;
case 5: lcd_putc('5');
break;
case 6: lcd_putc('6');
break;
case 7: lcd_putc('7');
break;
case 8: lcd_putc('8');
break;
case 9: lcd_putc('9');
break;
case 10: lcd_putc('a');
break;
case 11: lcd_putc('b');
break;
case 12: lcd_putc('c');
break;
case 13: lcd_putc('d');
break;
case 14: lcd_putc('e');
break;
case 15: lcd_putc('f');
break;
default:
lcd_putc('-');
break;
}
}
}
#endif
// Print to the given fd. Only understands %d, %x, %p, %s.
void
...
...
@@ -207,9 +154,9 @@ my_printf(char *fmt, ...)
}
}
else
if
(
state
==
'%'
){
if
(
c
==
'd'
){
printint
(
va_arg
(
ap
,
int
),
10
,
1
);
printint
(
va_arg
(
ap
,
long
),
10
,
1
);
}
else
if
(
c
==
'x'
||
c
==
'p'
){
printint
(
va_arg
(
ap
,
int
),
16
,
0
);
printint
(
va_arg
(
ap
,
long
),
16
,
0
);
}
else
if
(
c
==
's'
){
s
=
va_arg
(
ap
,
char
*
);
if
(
s
==
0
)
...
...
@@ -232,11 +179,24 @@ my_printf(char *fmt, ...)
}
}
#if 1
void
temp_fn
(
int
var
)
{
int
check
=
107
;
utcb_t
*
p_utcb
=
(
utcb_t
*
)
get_shared
()
;
int
hex
=
0xdeadbeef
;
my_printf
(
"Temp %d here %d and %x
\n
"
,
check
,
var
,
hex
);
char
my_str
[]
=
"lcdstr"
;
p_utcb
->
mr
[
0
]
=
20
;
p_utcb
->
mr
[
1
]
=
21
;
p_utcb
->
mr
[
2
]
=
22
;
p_utcb
->
mr
[
3
]
=
23
;
p_utcb
->
mr
[
4
]
=
24
;
p_utcb
->
mr
[
5
]
=
25
;
// my_printf("Temp %d and %s n %x\n", var, my_str, hex);
//my_printf("shared pg 0x%x\n", p_utcb);
lcd_ipc
();
}
...
...
@@ -273,27 +233,4 @@ static void __exit hello_2_exit(void)
module_init
(
hello_2_init
);
module_exit
(
hello_2_exit
);
#endif
#if 0
static int __init hello_print_init(void)
{
int check = 107;
u64 pp = 45;
printk(KERN_ERR "Hello, world 2\n");
my_printf("Hellow %d World %d done\n", check, pp);
// temp_fn();
return 0;
}
static void __exit hello_print_exit(void)
{
printk(KERN_INFO "Goodbye, world 2\n");
}
module_init(hello_print_init);
module_exit(hello_print_exit);
#endif
arch/x86/lcd/ipc_common_defs.h
0 → 100644
View file @
290dfa65
#ifndef LCD_GUEST_DEFS_H
#define LCD_GUEST_DEFS_H
typedef
struct
{
u32
mr
[
6
];
/* MRs that are mapped to real registers */
u32
saved_tag
;
/* Saved tag field for stacked ipcs */
u32
saved_sender
;
/* Saved sender field for stacked ipcs */
u32
notify
[
8
];
/* Irq notification slots */
u32
mr_rest
[
2
];
/* Complete the utcb for up to 64 words */
}
utcb_t
;
typedef
struct
{
uint
mr0
;
uint
mr1
;
uint
mr2
;
uint
mr3
;
uint
mr4
;
uint
mr5
;
}
msg_regs_t
;
//#define IPC_SEND_SND 1
//#define IPC_SEND_RCV 2
//#define IPC_SEND_SND_RCV 3
#define IPC_PEER_ANY 0xffffffff
#define LCD_IPC_DIR(x) (x >> 32)
#define LCD_IPC_PEER(x) (x & 0xffffffff)
enum
IPC_DIR
{
IPC_INVALID
=
0
,
IPC_SEND
=
1
,
IPC_RECV
=
2
,
IPC_SENDRECV
=
3
,
};
/* Per thread kernel stack unified on a single page. */
union
utcb_union
{
utcb_t
utcb
;
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 @
290dfa65
...
...
@@ -146,6 +146,27 @@ struct lcd_tss_struct {
u8
io_bitmap
[
1
];
}
__attribute__
((
packed
));
struct
ipc_waitq
{
u32
partner_id
;
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
;
int
vpid
;
...
...
@@ -191,10 +212,28 @@ typedef struct {
struct
vmx_msr_entry
host
[
NR_AUTOLOAD_MSRS
];
}
msr_autoload
;
struct
vmcs
*
vmcs
;
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
;
struct
boot_params
*
bp
;
struct
start_info
*
si
;
struct
vmcs
*
vmcs
;
void
*
shared
;
struct
module
*
mod
;
}
lcd_struct
;
...
...
arch/x86/lcd/lcd_main.c
View file @
290dfa65
...
...
@@ -42,6 +42,7 @@ MODULE_PARM_DESC(vmlinux_file, "vmlinux or vmlinuz path");
/* #include "lcd.h" */
#include
"lcd_defs.h"
#include
"ipc_common_defs.h"
MODULE_AUTHOR
(
"Weibin Sun"
);
MODULE_LICENSE
(
"GPL"
);
...
...
@@ -1421,6 +1422,20 @@ static void setup_idt(lcd_struct* vcpu) {
}
}
// Some temporary capability functions for IPC testing
// To be replaced while interfacing with capability module
static
u32
curr_cap
=
1
;
void
*
cap_arr
[
10
]
=
{
0
};
void
*
get_cap_obj
(
u32
cap_id
){
return
cap_arr
[
cap_id
];
}
u32
set_cap
(
void
*
obj
){
cap_arr
[
curr_cap
]
=
obj
;
return
curr_cap
++
;
}
static
lcd_struct
*
vmx_create_vcpu
(
void
)
{
lcd_struct
*
vcpu
=
kmalloc
(
sizeof
(
lcd_struct
),
GFP_KERNEL
);
if
(
!
vcpu
)
...
...
@@ -1498,6 +1513,15 @@ static lcd_struct * vmx_create_vcpu(void) {
setup_idt
(
vcpu
);
vmx_put_cpu
(
vcpu
);
//IPC queues
INIT_LIST_HEAD
(
&
vcpu
->
sync_ipc
.
snd_q
);
vcpu
->
sync_ipc
.
task
=
current
;
vcpu
->
sync_ipc
.
state
=
IPC_DONT_CARE
;
vcpu
->
sync_ipc
.
expected_sender
=
0
;
vcpu
->
sync_ipc
.
my_capid
=
set_cap
(
vcpu
);
// printk(KERN_ERR "=========%d======\n", vcpu->sync_ipc.my_capid);
return
vcpu
;
fail_si:
...
...
@@ -1935,7 +1959,6 @@ static int map_host_page_at_guest_va(lcd_struct *lcd, void* hva,
}
static
char
*
my_shared
;
static
int
lcd_setup_stack
(
lcd_struct
*
lcd
)
{
char
*
sp
=
NULL
;
char
*
stack_top
=
NULL
;
...
...
@@ -1949,9 +1972,10 @@ static int lcd_setup_stack(lcd_struct *lcd) {
return
-
ENOMEM
;
}
my_shared
=
sp
;
//We use low addr page of this block for passing message registers
lcd
->
shared
=
sp
;
stack_top
=
(
sp
+
(
PAGE_SIZE
*
4
)
-
1
);
printk
(
KERN_ERR
"lcd : stack bootm %p , stack top %p and myshare %p"
,
sp
,
stack_top
,
my_shared
);
printk
(
KERN_ERR
"lcd : stack bootm %p , stack top %p and myshare %p"
,
sp
,
stack_top
,
sp
);
// map the stack in the LCD address space
ret
=
__move_host_mapping
(
lcd
,
(
void
*
)
sp
,
(
PAGE_SIZE
*
4
),
0
);
...
...
@@ -2062,9 +2086,146 @@ 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
;
//printk(KERN_ERR "%c", lcd->regs[VCPU_REGS_RAX]);
printk
(
KERN_ERR
"%016llx"
,
lcd
->
regs
[
VCPU_REGS_RAX
]);
ipc_dir
=
LCD_IPC_DIR
(
lcd
->
regs
[
VCPU_REGS_RAX
]);
ipc_peer
=
LCD_IPC_PEER
(
lcd
->
regs
[
VCPU_REGS_RAX
]);
printk
(
KERN_ERR
"vmx_handle_vmcall - dir %d peer %d
\n
"
,
ipc_dir
,
ipc_peer
);
switch
(
ipc_dir
)
{
case
IPC_SEND
:
ipc_send
(
lcd
->
sync_ipc
.
my_capid
,
ipc_peer
);
break
;
case
IPC_RECV
:
ipc_recv
(
lcd
->
sync_ipc
.
my_capid
,
ipc_peer
);
break
;
}
#if 0
//printk(KERN_ERR "lcd_run: got vmcall %llu and %c\n", lcd->regs[VCPU_REGS_RAX], lcd->regs[VCPU_REGS_RAX]);
printk
(
KERN_ERR
"%c"
,
lcd
->
regs
[
VCPU_REGS_RAX
]);
if (lcd->regs[VCPU_REGS_RAX] == 0xdeadbeef) {
display_mr((utcb_t *)lcd->shared);
return;
}
#endif
}
static
void
vmx_handle_page_fault
(
lcd_struct
*
lcd
)
{
...
...
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