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
f9a246cc
Commit
f9a246cc
authored
Mar 08, 2014
by
Muktesh Khole
Committed by
Vikram Narayanan
Oct 25, 2016
Browse files
Capability Module
parent
37074480
Changes
2
Hide whitespace changes
Inline
Side-by-side
xcap/capability.c
View file @
f9a246cc
#undef __KERNEL__
#define __KERNEL__
...
...
@@ -18,43 +17,78 @@ void cleanup_module(void)
printk
(
KERN_INFO
"Cleaning up LCD Module
\n
"
);
}
void
initialize_freelist
(
cte
*
cnode
,
int
size
,
bool
bFirstCNode
=
false
)
void
lcd_
initialize_freelist
(
struct
cte
*
cnode
,
int
size
,
bool
bFirstCNode
)
{
int
startid
=
1
;
int
i
=
startid
;
if
(
cnode
==
NULL
)
return
;
int
max_slots
=
(
size
/
sizeof
(
cte
));
int
startid
=
1
;
if
(
bFirstCNode
)
{
startid
=
LCD_CapFirstFreeSlot
;
}
cnode
[
0
].
ctetype
=
lcd_type_free
;
cnode
[
0
].
next_free_slot
=
startid
;
cnode
[
startid
].
ctetype
=
lcd_type_free
;
for
(
int
i
=
startid
;
i
<
max_slots
-
1
;
i
++
)
i
=
startid
;
for
(
;
i
<
MAX_SLOTS
-
1
;
i
++
)
{
cnode
[
i
].
next_free_slot
=
i
+
1
;
cnode
[
i
+
1
].
ctetype
=
lcd_type_free
;
}
cnode
[
i
].
next_free_slot
=
0
;
}
// caller responsible for locking cspace.
// free slot will be booked for the caller.
// ie. it will not longer be free once this function returns it.
cap_id
lcd_lookup_free_slot
(
struct
cap_space
*
cspace
,
struct
cte
**
cap
)
{
cap_id
cid
=
0
;
struct
cte
*
cnode
;
bool
found
=
false
;
if
(
cspace
==
NULL
)
return
0
;
cnode
=
cspace
->
root_cnode
;
while
(
!
found
)
{
int
nxt
=
cnode
[
0
].
next_free_slot
;
// check if only one free slot is available
if
(
cnode
[
nxt
].
next_free_slot
==
0
)
{
// only one free slot is available, allocate a new cnode and set free_cnode
}
}
return
cid
;
}
cap_space
*
lcd_create_cspace
(
)
struct
cte
*
lcd_lookup_capability
(
struct
cap_space
*
cspace
,
cap_id
cid
)
{
cap_space
*
cspace
=
(
cap_space
*
)
vmalloc
(
sizeof
(
cap_space
));
struct
cte
*
cap
;
return
cap
;
}
struct
cap_space
*
lcd_create_cspace
()
{
struct
cap_space
*
cspace
=
vmalloc
(
sizeof
(
struct
cap_space
));
SAFE_EXIT_IF_ALLOC_FAILED
(
cspace
,
alloc_failure
);
// initialize semaphore
sema_init
(
&
(
cspace
->
sem_cspace
),
1
);
// allocate memory for the first cnode.
cspace
->
root_cnode
=
(
cte
*
)
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
cspace
->
root_cnode
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
SAFE_EXIT_IF_ALLOC_FAILED
(
cspace
->
root_cnode
,
alloc_failure
);
// initialize the free list
initialize_freelist
(
cspace
->
root_cnode
,
PAGE_SIZE
,
true
);
lcd_
initialize_freelist
(
cspace
->
root_cnode
,
PAGE_SIZE
,
true
);
goto
success
;
...
...
@@ -78,12 +112,81 @@ success:
cap_id
lcd_create_cap
(
void
*
ptcb
,
void
*
hobject
,
lcd_cap_rights
crights
)
{
struct
task_struct
*
tcb
=
(
struct
task_struct
*
)
ptcb
;
struct
cap_space
*
cspace
;
struct
cte
*
cap
;
cap_id
cid
;
if
(
ptcb
==
NULL
)
return
0
;
cspace
=
tcb
->
cspace
;
if
(
cspace
==
NULL
||
cspace
->
root_cnode
==
NULL
)
return
0
;
//1. lock the cspace.
//2. walk the cspace to find empty slots.
// if only one empty slot left in cnode, create a new cnode, initialize its free list.
//3. Get the first free slot, set its type to capability.
// set its hObject, and rights.
//4. return the cap_id within this cspace.
down_interruptible
(
&
cspace
->
sem_cspace
);
cid
=
lcd_lookup_free_slot
(
cspace
,
&
cap
);
cap
->
ctetype
=
lcd_type_capability
;
cap
->
cap
.
crights
=
crights
;
cap
->
cap
.
hobject
=
hobject
;
cap
->
cap
.
cdt_list
=
NULL
;
up
(
&
(
cspace
->
sem_cspace
));
return
cid
;
}
cap_id
lcd_cap_grant
(
void
*
src_tcb
,
cap_id
src_cid
,
void
*
dst_tcb
,
lcd_cap_rights
crights
)
{
cap_id
cid
=
0
;
struct
task_struct
*
stcb
,
*
dtcb
;
struct
cte
*
src_cte
=
NULL
,
*
dst_cte
=
NULL
;
bool
done
=
false
;
if
(
src_tcb
==
NULL
||
dst_tcb
==
NULL
||
src_cid
<=
0
)
return
0
;
stcb
=
(
struct
task_struct
*
)
src_tcb
;
dtcb
=
(
struct
task_struct
*
)
dst_tcb
;
while
(
!
done
)
{
// if (down_trylock() == 0) Lock source cspace.
if
(
down_trylock
(
stcb
->
cspace
->
sem_cspace
)
==
0
)
{
// if (down_trylock() == 0) lock dst cspace
if
(
down_trylock
(
dtcb
->
cspace
->
sem_cspace
)
==
0
)
{
// Lookup the source TCB and get a pointer to capability.
src_cte
=
lcd_lookup_capability
(
stcb
->
cspace
,
src_cid
);
// get a free slot in destination.
cid
=
lcd_lookup_free_slot
(
dtcb
->
cspace
,
&
dst_cte
);
if
(
cid
!=
0
){
struct
cap_derivation_list
*
cdt_node
;
// add the capability to destination.
dst_cte
->
ctetype
=
lcd_type_capability
;
dst_cte
->
cap
.
crights
=
crights
;
dst_cte
->
cap
.
hobject
=
src_cte
->
cap
.
hobject
;
dst_cte
->
cap
.
cdt_list
=
NULL
;
// update the CDT of source
cdt_node
=
kmalloc
(
sizeof
(
struct
cap_derivation_list
),
GFP_KERNEL
);
if
(
cdt_node
!=
NULL
){
cdt_node
->
next
=
src_cte
->
cap
.
cdt_list
;
src_cte
->
cap
.
cdt_list
=
cdt_node
;
cdt_node
->
remote_cid
=
src_cid
;
cdt_node
->
remote_TCB
=
src_tcb
;
}
else
{
ASSERT
(
false
,
"cdt_node allocation failed"
);
}
done
=
true
;
}
// release lock on dst cspace.
up
(
dtcb
->
cspace
->
sem_cspace
);
}
// release lock on source cspace.
up
(
stcb
->
cspace
->
sem_cspace
);
}
if
(
!
done
)
msleep_interruptible
(
1
);
}
return
cid
;
}
\ No newline at end of file
xcap/capability.h
View file @
f9a246cc
#ifndef __LCD_CAPABILITY_H__
#define __LCD_CAPABILITY_H__
#include
<linux/sched.h>
#include
<linux/types.h>
#include
<linux/module.h>
#include
<linux/kernel.h>
#include
<linux/slab_def.h>
#include
<linux/mm.h>
#include
<linux/slab.h>
#include
<linux/fs.h>
#include
<linux/kthread.h>
#include
<linux/sched.h>
#include
<linux/semaphore.h>
#include
<linux/log2.h>
#include
<linux/delay.h>
#include
<asm/page.h>
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"FLUX-LAB University of Utah"
);
#define LCD_CAPABILITY
#define MAX_SLOTS (PAGE_SIZE/sizeof(struct cte))
#define CNODE_INDEX_BITS (ilog2(MAX_SLOTS))
#define SAFE_EXIT_IF_ALLOC_FAILED(ptr, label) \
if (ptr == NULL) \
...
...
@@ -22,10 +27,16 @@ if (ptr == NULL) \
goto label; \
} \
#define ASSERT(condition, expr) \
if(!(condition)) { \
printk("\nAssertion Failed at: %d\n",__LINE__); \
panic(#expr); \
}
typedef
enum
_lcd_cap_type
{
lcd_type_free
,
lcd_type_
untyped
,
lcd_type_
capability
,
lcd_type_cnode
,
lcd_type_endpoint
}
lcd_cap_type
;
...
...
@@ -42,7 +53,7 @@ enum {
};
typedef
uint32_t
lcd_cnode
;
// a pointer to the cnode
typedef
uint
32
_t
cap_id
;
// a locally unique identifier (address within cspace)
typedef
uint
64
_t
cap_id
;
// a locally unique identifier (address within cspace)
typedef
uint32_t
lcd_cnode_entry
;
// a pointer to an entry within a cnode
typedef
uint64_t
lcd_tcb
;
// a pointer/handle to the thread contrl block
typedef
uint16_t
lcd_cap_rights
;
// holds the rights associated with a capability.
...
...
@@ -58,70 +69,64 @@ typedef uint16_t lcd_cap_rights; // holds the rights associated with a capabil
#define CAPRIGHTS_RWX (CAPRIGHTS_RW | CAPRIGHTS_EXECUTE)
#define CAPRIGHTS_NORIGHTS 0
typedef
struct
_
cap_derivation_list
struct
cap_derivation_list
{
void
*
remote_TCB
;
// reference to the thread which was granted this capability
cap_id
remote_cid
;
// address in the remote threads capability space where this
// capability is stored.
struct
_
cap_derivation_list
*
next
;
}
cap_derivation_list
;
struct
cap_derivation_list
*
next
;
};
typedef
struct
_
capability
struct
capability
{
cap_id
cid
;
// locally unique to each thread
}
capability
;
};
typedef
struct
_
capability_internal
struct
capability_internal
{
void
*
hobject
;
// a pointer to a kernel object
struct
cap_derivation_list
*
cdt_list
;
// list of domain ids to whom this capability is granted
lcd_cap_rights
crights
;
// specifies the rights the domain has over this capability
}
capability_internal
;
};
struct
_cap_node
;
struct
cte
;
struct
cap_node
{
struct
cte
*
cap_entry
;
/* may point to another cnode or to a capability */
};
typedef
struct
_
cte
// capability table entry
struct
cte
// capability table entry
{
lcd_cap_type
ctetype
;
union
{
struct
_
cap_node
*
cnode
;
capability_internal
*
cap
;
struct
cap_node
cnode
;
struct
capability_internal
cap
;
int
next_free_slot
;
};
}
cte
;
};
typedef
struct
_cap_node
{
struct
_guard
{
int32_t
guard_bits
:
27
;
// actual guard bits
int32_t
guard_size
:
5
;
// number of valid bits in guard_bits
}
guard
;
int
max_slots
;
cte
*
cap_entry
;
/* may point to another cnode or to a capability */
}
cap_node
;
typedef
struct
_cap_space
struct
cap_space
{
struct
cte
*
root_cnode
;
struct
semaphore
sem_cspace
;
}
cap_space
;
};
/* Helper Functions */
// initializes the free slots available in the cnode structure.
void
initialize_freelist
(
cap_nod
e
*
cnode
,
int
size
,
bool
bFirstCNode
=
false
);
void
lcd_
initialize_freelist
(
struct
ct
e
*
cnode
,
int
size
,
bool
bFirstCNode
);
// will be used to search for the cnode which has a free slot available.
// if no such cnode exists will make a call to create lcd_create_cnode to create an
// empty cnode.
cap_id
lcd_lookup_free_slot
();
cap_id
lcd_lookup_free_slot
(
struct
cap_space
*
cspace
,
struct
cte
**
cap
);
struct
cte
*
lcd_lookup_capability
(
struct
cap_space
*
cspace
,
cap_id
cid
);
// will be used to allocate memory for a cnode.
cap_node
*
lcd_create_cnode
(
uint16_t
size
);
struct
cap_node
*
lcd_create_cnode
(
uint16_t
size
);
// will be used to de-allocate memory of a cnode.
uint32_t
lcd_delete_cnode
(
cap_id
cid
);
...
...
@@ -136,7 +141,7 @@ uint32_t lcd_delete_cnode(cap_id cid);
// one for its cspace
// one for the endpoint.
// the returned value goes into the TCB of the caller.
cap_space
*
lcd_create_cspace
();
struct
cap_space
*
lcd_create_cspace
(
void
);
// creates a new capability, inserts it into cspace of caller and
// returns the capability identifier.
...
...
@@ -147,7 +152,7 @@ cap_id lcd_create_cap(void * ptcb, void * hobject, lcd_cap_rights crights);
// returns the address of the capability within the cspace of the receiver thread.
// a logical AND of the crights and rights on the capability being granted will decide the
// final rights the granted capability will have.
cap_id
lcd_cap_grant
(
void
*
dst
_tcb
,
cap_id
src_cid
,
lcd_cap_rights
crights
);
cap_id
lcd_cap_grant
(
void
*
src
_tcb
,
cap_id
src_cid
,
void
*
dst_tcb
,
lcd_cap_rights
crights
);
// will be called to delete a particular capability in the calling threads
// cspace. threads have right to delete capabilities in their own cspace.
...
...
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