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
904364c9
Commit
904364c9
authored
Mar 14, 2014
by
Muktesh Khole
Committed by
Vikram Narayanan
Oct 25, 2016
Browse files
Documenting external interfaces
parent
06a58b9b
Changes
2
Hide whitespace changes
Inline
Side-by-side
xcap/lcd_cap.c
View file @
904364c9
...
...
@@ -9,16 +9,18 @@
int
init_module
(
void
)
{
printk
(
KERN_INFO
"Initializing LCD Module
\n
"
);
printk
(
KERN_INFO
"Initializing LCD
-Capability
Module
\n
"
);
return
0
;
// Non-zero return means that the module couldn't be loaded.
}
void
cleanup_module
(
void
)
{
printk
(
KERN_INFO
"Cleaning up LCD Module
\n
"
);
printk
(
KERN_INFO
"Cleaning up LCD
-Capability
Module
\n
"
);
}
// does not lock the cspace.
// First entry of every cnode table will be the head of the free slots available
// in the table. This function will just populate the free list.
void
lcd_initialize_freelist
(
struct
cte
*
cnode
,
bool
bFirstCNode
)
{
int
startid
=
1
;
...
...
@@ -59,6 +61,7 @@ void lcd_initialize_freelist(struct cte *cnode, bool bFirstCNode)
cnode
[
i
].
index
=
i
;
}
// Removes the free_slot from free list.
struct
cte
*
lcd_reserve_cap_slot
(
struct
cte
*
cnode
,
cap_id
*
cid
,
int
free_slot
)
{
struct
cte
*
node
=
cnode
->
cnode
.
table
;
...
...
@@ -173,39 +176,50 @@ free_kfifo:
}
// does not lock the cspace caller responsbile for the same.
// Given a task_struct and a capability identifier, will return the pointer to the
// capability table entry associated with that identifier within the cspace of the thread.
struct
cte
*
lcd_lookup_capability
(
struct
task_struct
*
tcb
,
cap_id
cid
)
{
struct
cte
*
cap
=
NULL
,
*
c
node
=
NULL
;
struct
cte
*
cap
=
NULL
,
*
node
=
NULL
;
struct
cap_space
*
cspace
;
cap_id
id
=
cid
;
int
index
=
0
;
int
mask
=
(
~
0
);
mask
=
mask
<<
(
CNODE_INDEX_BITS
);
mask
=
~
mask
;
// check if input is valid
if
(
tcb
==
NULL
||
cid
==
0
)
{
ASSERT
(
false
,
"lcd_lookup_capability: Invalid Inputs
\n
"
);
return
NULL
;
}
cspace
=
tcb
->
cspace
;
// check if input is valid
mask
=
mask
<<
(
CNODE_INDEX_BITS
);
mask
=
~
mask
;
if
(
cspace
==
NULL
||
cspace
->
root_cnode
.
cnode
.
table
==
NULL
)
{
ASSERT
(
false
,
"lcd_lookup_capability: Invalid/Corrupted cspace
\n
"
);
return
NULL
;
cnode
=
cspace
->
root_cnode
.
cnode
.
table
;
}
node
=
cspace
->
root_cnode
.
cnode
.
table
;
while
(
id
>
0
)
{
index
=
(
int
)(
id
)
&
mask
;
id
=
id
>>
(
CNODE_INDEX_BITS
);
if
(
c
node
[
index
].
ctetype
==
lcd_type_capability
&&
id
==
0
)
if
(
node
[
index
].
ctetype
==
lcd_type_capability
&&
id
==
0
)
{
cap
=
&
c
node
[
index
];
cap
=
&
node
[
index
];
break
;
}
else
if
(
c
node
[
index
].
ctetype
==
lcd_type_cnode
&&
id
!=
0
)
else
if
(
node
[
index
].
ctetype
==
lcd_type_cnode
&&
id
!=
0
)
{
c
node
=
c
node
[
index
].
cnode
.
table
;
node
=
node
[
index
].
cnode
.
table
;
}
else
{
ASSERT
(
false
,
"lcd_lookup_capability: Invalid Capability Identifier
\n
"
);
break
;
}
}
...
...
@@ -214,17 +228,23 @@ struct cte * lcd_lookup_capability(struct task_struct *tcb, cap_id cid)
}
// caller should not lock the cspace.
void
lcd_update_cdt
(
void
*
ptcb
)
// On a thread exit/termination all the capabilities in its cspace will have to be delted.
// This affects the capability derivation tre (CDT), this function tries to patch the CDT.
void
lcd_update_cdt
(
struct
task_struct
*
tcb
)
{
struct
task_struct
*
tcb
=
ptcb
;
struct
cte
*
cnode
,
*
node
;
struct
kfifo
cnode_q
;
struct
cap_space
*
tcb_cspace
;
bool
cspace_locked
;
int
i
=
0
;
int
i
;
if
(
tcb
==
NULL
)
{
ASSERT
(
false
,
"lcd_update_cdt: Invalid Input
\n
"
);
return
;
}
tcb_cspace
=
tcb
->
cspace
;
// lock the cspace.
if
(
down_interruptible
(
&
(
tcb_cspace
->
sem_cspace
)))
{
...
...
@@ -232,6 +252,7 @@ void lcd_update_cdt(void *ptcb)
return
;
}
cspace_locked
=
true
;
cnode
=
&
(
tcb_cspace
->
root_cnode
);
if
(
cnode
==
NULL
)
goto
safe_return
;
...
...
@@ -283,19 +304,12 @@ loop:
// lock acquired
if
(
down_trylock
(
&
(
c_cdt
->
cspace
->
sem_cspace
))
==
0
)
{
struct
cap_space
*
child_cspace
=
c_cdt
->
cspace
;
// all locks are acquired
// update parent pointer of child to point to parent of cdt.
c_cdt
->
parent_ptr
=
p_cdt
;
if
(
p_cdt
&&
p_cdt
->
child_ptr
==
cdt
)
{
p_cdt
->
child_ptr
=
c_cdt
;
}
lcd_cap_delete_internal
(
cdt
->
cap
);
cdt
->
child_ptr
=
c_cdt
->
next
;
up
(
&
(
c_cdt
->
cspace
->
sem_cspace
));
next_cdt
=
c_cdt
->
next
;
c_cdt
->
cap
->
cap
.
cdt_node
=
NULL
;
kfree
(
c_cdt
);
c_cdt
=
next_cdt
;
c_cdt
=
c_cdt
->
next
;
up
(
&
(
child_cspace
->
sem_cspace
));
continue
;
}
else
...
...
@@ -480,13 +494,12 @@ success:
}
cap_id
lcd_create_cap
(
void
*
p
tcb
,
void
*
hobject
,
lcd_cap_rights
crights
)
cap_id
lcd_create_cap
(
struct
task_struct
*
tcb
,
void
*
hobject
,
lcd_cap_rights
crights
)
{
struct
task_struct
*
tcb
=
ptcb
;
struct
cap_space
*
cspace
;
struct
cte
*
cap
;
struct
cte
*
cap
;
cap_id
cid
;
struct
cap_derivation_tree
*
cdtnode
=
kmalloc
(
sizeof
(
struct
cap_derivation_tree
),
GFP_KERNEL
);
cap_id
cid
;
if
(
cdtnode
==
NULL
)
{
...
...
@@ -494,8 +507,9 @@ cap_id lcd_create_cap(void * ptcb, void * hobject, lcd_cap_rights crights)
return
0
;
}
if
(
p
tcb
==
NULL
)
if
(
tcb
==
NULL
)
{
ASSERT
(
false
,
"lcd_create_cap: Invalid Input
\n
"
);
kfree
(
cdtnode
);
return
0
;
}
...
...
@@ -533,11 +547,10 @@ cap_id lcd_create_cap(void * ptcb, void * hobject, lcd_cap_rights crights)
return
cid
;
}
cap_id
lcd_cap_grant
(
void
*
src_tcb
,
cap_id
src_cid
,
void
*
dst_
tcb
,
lcd_cap_rights
crights
)
cap_id
lcd_cap_grant
(
struct
task_struct
*
stcb
,
cap_id
src_cid
,
struct
task_struct
*
d
tcb
,
lcd_cap_rights
crights
)
{
cap_id
cid
=
0
;
struct
task_struct
*
stcb
,
*
dtcb
;
struct
cap_space
*
stcb_cspace
,
*
dtcb_cspace
;
struct
cap_space
*
src_cspace
,
*
dst_cspace
;
struct
cte
*
src_cte
=
NULL
,
*
dst_cte
=
NULL
;
bool
done
=
false
;
struct
cap_derivation_tree
*
dst_cdt_node
=
kmalloc
(
sizeof
(
struct
cap_derivation_tree
),
GFP_KERNEL
);
...
...
@@ -547,28 +560,26 @@ cap_id lcd_cap_grant(void *src_tcb, cap_id src_cid, void * dst_tcb, lcd_cap_righ
return
0
;
}
if
(
s
rc_
tcb
==
NULL
||
d
st_
tcb
==
NULL
||
src_cid
<=
0
)
if
(
stcb
==
NULL
||
dtcb
==
NULL
||
src_cid
<=
0
)
{
ASSERT
(
false
,
"lcd_cap_grant: Invalid Inputs
\n
"
);
kfree
(
dst_cdt_node
);
return
0
;
}
stcb
=
(
struct
task_struct
*
)
src_tcb
;
dtcb
=
(
struct
task_struct
*
)
dst_tcb
;
stcb_cspace
=
stcb
->
cspace
;
dtcb_cspace
=
dtcb
->
cspace
;
src_cspace
=
stcb
->
cspace
;
dst_cspace
=
dtcb
->
cspace
;
while
(
!
done
)
{
// Lock source cspace.
if
(
down_trylock
(
&
(
s
tcb
_cspace
->
sem_cspace
))
==
0
)
if
(
down_trylock
(
&
(
s
rc
_cspace
->
sem_cspace
))
==
0
)
{
// if (down_trylock() == 0) lock dst cspace
if
(
down_trylock
(
&
(
dt
cb
_cspace
->
sem_cspace
))
==
0
)
if
(
down_trylock
(
&
(
d
s
t_cspace
->
sem_cspace
))
==
0
)
{
// Lookup the source TCB and get a pointer to capability.
src_cte
=
lcd_lookup_capability
(
stcb
,
src_cid
);
// get a free slot in destination.
cid
=
lcd_lookup_free_slot
(
dt
cb
_cspace
,
&
dst_cte
);
cid
=
lcd_lookup_free_slot
(
d
s
t_cspace
,
&
dst_cte
);
if
(
cid
!=
0
&&
src_cte
!=
NULL
&&
dst_cte
!=
NULL
)
{
struct
cap_derivation_tree
*
src_cdt_node
=
src_cte
->
cap
.
cdt_node
;
...
...
@@ -576,12 +587,12 @@ cap_id lcd_cap_grant(void *src_tcb, cap_id src_cid, void * dst_tcb, lcd_cap_righ
// add the capability to destination.
dst_cte
->
ctetype
=
lcd_type_capability
;
dst_cte
->
cap
.
crights
=
crights
;
dst_cte
->
cap
.
crights
=
(
crights
&
src_cte
->
cap
.
crights
)
;
dst_cte
->
cap
.
hobject
=
src_cte
->
cap
.
hobject
;
dst_cte
->
cap
.
cdt_node
=
dst_cdt_node
;
src_cdt_node
->
child_ptr
=
dst_cdt_node
;
dst_cdt_node
->
cspace
=
dt
cb
_cspace
;
dst_cdt_node
->
cspace
=
d
s
t_cspace
;
dst_cdt_node
->
parent_ptr
=
src_cdt_node
;
dst_cdt_node
->
child_ptr
=
NULL
;
dst_cdt_node
->
next
=
cdtnode
;
...
...
@@ -598,10 +609,10 @@ cap_id lcd_cap_grant(void *src_tcb, cap_id src_cid, void * dst_tcb, lcd_cap_righ
ASSERT
(
false
,
"Source capability not found or no free slot in destination"
);
}
// release lock on dst cspace.
up
(
&
(
dt
cb
_cspace
->
sem_cspace
));
up
(
&
(
d
s
t_cspace
->
sem_cspace
));
}
// release lock on source cspace.
up
(
&
(
s
tcb
_cspace
->
sem_cspace
));
up
(
&
(
s
rc
_cspace
->
sem_cspace
));
}
if
(
!
done
)
msleep_interruptible
(
1
);
...
...
@@ -609,16 +620,19 @@ cap_id lcd_cap_grant(void *src_tcb, cap_id src_cid, void * dst_tcb, lcd_cap_righ
return
cid
;
}
uint32_t
lcd_cap_delete
(
void
*
p
tcb
,
cap_id
cid
)
uint32_t
lcd_cap_delete
(
struct
task_struct
*
tcb
,
cap_id
cid
)
{
int
ret
;
struct
cte
*
cap_cte
;
struct
task_struct
*
tcb
=
ptcb
;
struct
cap_space
*
tcb_cspace
;
if
(
ptcb
==
NULL
||
cid
==
0
)
struct
cap_space
*
cspace
;
if
(
tcb
==
NULL
||
cid
==
0
)
{
ASSERT
(
false
,
"lcd_cap_delete: Invalid Inputs
\n
"
);
return
-
1
;
tcb_cspace
=
tcb
->
cspace
;
if
(
down_interruptible
(
&
(
tcb_cspace
->
sem_cspace
)))
}
cspace
=
tcb
->
cspace
;
if
(
down_interruptible
(
&
(
cspace
->
sem_cspace
)))
{
ASSERT
(
false
,
"lcd_cap_delete: Failed to acquire lock, cannot delete capability
\n
"
);
return
-
1
;
...
...
@@ -627,24 +641,26 @@ uint32_t lcd_cap_delete(void * ptcb, cap_id cid)
cap_cte
=
lcd_lookup_capability
(
tcb
,
cid
);
if
(
cap_cte
==
NULL
||
cap_cte
->
cap
.
cdt_node
==
NULL
)
{
up
(
&
(
tcb_
cspace
->
sem_cspace
));
up
(
&
(
cspace
->
sem_cspace
));
return
0
;
}
ret
=
lcd_cap_delete_internal
(
cap_cte
);
up
(
&
(
tcb_
cspace
->
sem_cspace
));
up
(
&
(
cspace
->
sem_cspace
));
return
ret
;
}
uint32_t
lcd_cap_revoke
(
void
*
p
tcb
,
cap_id
cid
)
uint32_t
lcd_cap_revoke
(
struct
task_struct
*
tcb
,
cap_id
cid
)
{
struct
task_struct
*
tcb
=
ptcb
;
struct
cap_derivation_tree
*
cdt
;
struct
cap_space
*
tcb_cspace
;
struct
kfifo
cdt_q
;
struct
cte
*
cap
;
if
(
ptcb
==
NULL
||
cid
==
0
)
if
(
tcb
==
NULL
||
cid
==
0
)
{
ASSERT
(
false
,
"lcd_cap_revoke: Invalid Inputs
\n
"
);
return
-
1
;
}
tcb_cspace
=
tcb
->
cspace
;
if
(
kfifo_alloc
(
&
cdt_q
,
sizeof
(
struct
cap_derivation_tree
)
*
512
,
GFP_KERNEL
)
!=
0
)
...
...
@@ -701,15 +717,18 @@ uint32_t lcd_cap_revoke(void * ptcb, cap_id cid)
return
0
;
}
void
lcd_destroy_cspace
(
void
*
p
tcb
)
void
lcd_destroy_cspace
(
struct
task_struct
*
tcb
)
{
struct
task_struct
*
tcb
=
ptcb
;
struct
cte
*
node
,
level_separator
;
struct
kfifo
node_q
;
struct
cap_space
*
tcb_cspace
;
int
depth_count
=
0
;
if
(
tcb
==
NULL
)
{
ASSERT
(
false
,
"lcd_destroy_cspace: Invalid Input
\n
"
);
return
;
}
tcb_cspace
=
tcb
->
cspace
;
// patch the cdt
lcd_update_cdt
(
tcb
);
...
...
@@ -717,13 +736,13 @@ void lcd_destroy_cspace(void *ptcb)
// free all the cnodes.
if
(
kfifo_alloc
(
&
node_q
,
sizeof
(
struct
cte
)
*
512
,
GFP_KERNEL
)
!=
0
)
{
ASSERT
(
false
,
"lcd_
update
_cdt: Failed to allcoate kfifo, CDT will be corrupted
\n
"
);
ASSERT
(
false
,
"lcd_
destroy
_cdt: Failed to allcoate kfifo, CDT will be corrupted
\n
"
);
return
;
}
level_separator
.
ctetype
=
lcd_type_separator
;
if
(
down_interruptible
(
&
(
tcb_cspace
->
sem_cspace
)))
{
ASSERT
(
false
,
"lcd_
update
_cdt: Signal interrupted lock, CDT will be corrupted
\n
"
);
ASSERT
(
false
,
"lcd_
destroy
_cdt: Signal interrupted lock, CDT will be corrupted
\n
"
);
kfifo_free
(
&
node_q
);
return
;
}
...
...
@@ -766,24 +785,31 @@ void lcd_destroy_cspace(void *ptcb)
kfifo_free
(
&
node_q
);
}
uint32_t
lcd_get_cap_rights
(
void
*
p
tcb
,
cap_id
cid
,
lcd_cap_rights
*
rights
)
uint32_t
lcd_get_cap_rights
(
struct
task_struct
*
tcb
,
cap_id
cid
,
lcd_cap_rights
*
rights
)
{
struct
task_struct
*
tcb
=
ptcb
;
struct
c
te
*
cap
;
struct
cap_space
*
tcb_cspace
;
struct
cte
*
cap
;
struct
c
ap_space
*
cspace
;
if
(
tcb
==
NULL
||
tcb
->
cspace
==
NULL
||
cid
==
0
||
rights
==
NULL
)
{
ASSERT
(
false
,
"lcd_get_cap_rights: Invalid Inputs
\n
"
);
return
-
1
;
tcb_cspace
=
tcb
->
cspace
;
if
(
down_interruptible
(
&
(
tcb_cspace
->
sem_cspace
)))
}
cspace
=
tcb
->
cspace
;
if
(
down_interruptible
(
&
(
cspace
->
sem_cspace
)))
{
ASSERT
(
false
,
"lcd_get_cap_rights: Signal interrupted lock acquire, exiting
\n
"
);
return
-
1
;
}
cap
=
lcd_lookup_capability
(
tcb
,
cid
);
if
(
cap
==
NULL
||
cap
->
ctetype
!=
lcd_type_capability
)
{
up
(
&
(
tcb_cspace
->
sem_cspace
));
ASSERT
(
false
,
"lcd_get_cap_rights: Invalid capability identifier
\n
"
);
up
(
&
(
cspace
->
sem_cspace
));
return
-
1
;
}
*
rights
=
cap
->
cap
.
crights
;
up
(
&
(
tcb_
cspace
->
sem_cspace
));
up
(
&
(
cspace
->
sem_cspace
));
return
0
;
}
\ No newline at end of file
xcap/lcd_cap.h
View file @
904364c9
#ifndef __LCD_CAP_H__
#define __LCD_CAP_H__
#include
<linux/sched.h>
#include
<linux/types.h>
#include
<linux/module.h>
#include
<linux/kernel.h>
#include
<linux/sched.h>
#include
<linux/mm.h>
#include
<linux/slab.h>
#include
<linux/fs.h>
...
...
@@ -17,11 +17,11 @@
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"FLUX-LAB University of Utah"
);
typedef
uint32_t
lcd_cnode
;
// a pointer to the cnode
typedef
uint64_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.
typedef
uint32_t
lcd_cnode
;
// a pointer to the cnode
typedef
uint64_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.
typedef
uint16_t
lcd_cap_type
;
#define MAX_SLOTS (PAGE_SIZE/sizeof(struct cte))
...
...
@@ -31,17 +31,18 @@ typedef uint16_t lcd_cap_type;
#define CAP_ID_SIZE (sizeof(cap_id) * 8)
#define MAX_DEPTH ((CAP_ID_SIZE + 1)/CNODE_INDEX_BITS)
#define SAFE_EXIT_IF_ALLOC_FAILED(ptr, label) \
if (ptr == NULL) \
{ \
goto label; \
} \
#define ASSERT(condition, expr) \
if(!(condition)) { \
printk("\nAssertion Failed at: %d\n",__LINE__); \
panic(#expr); \
}
#define SAFE_EXIT_IF_ALLOC_FAILED(ptr, label) \
if (ptr == NULL) \
{ \
goto label; \
} \
#define ASSERT(condition, expr) \
if(!(condition)) \
{ \
printk("\nAssertion Failed at: %d\n",__LINE__); \
panic(#expr); \
}
enum
__lcd_cap_type
{
...
...
@@ -53,12 +54,13 @@ enum __lcd_cap_type
};
/* caps with fixed slot potitions in the root CNode */
enum
{
enum
{
LCD_CapNull
=
0
,
/* null cap */
LCD_CapInitThreadTCB
=
1
,
/* initial thread's TCB cap */
LCD_CapInitThreadPD
=
2
,
/* initial thread' page directory */
LCD_CapIRQControl
=
3
,
/* global IRQ controller */
LCD_CapInitThreadIPCBuffer
=
4
,
/* initial thread's IPC buffer frame cap */
LCD_CapInitThreadIPCBuffer
=
4
,
/* initial thread's IPC buffer frame cap */
LCD_CapFirstFreeSlot
=
5
};
...
...
@@ -77,33 +79,29 @@ enum {
struct
cap_derivation_tree
{
struct
cte
*
cap
;
struct
cap_space
*
cspace
;
struct
cte
*
cap
;
struct
cap_space
*
cspace
;
struct
cap_derivation_tree
*
next
;
struct
cap_derivation_tree
*
prev
;
struct
cap_derivation_tree
*
parent_ptr
;
struct
cap_derivation_tree
*
child_ptr
;
};
struct
capability
{
cap_id
cid
;
// locally unique to each thread
};
struct
capability_internal
{
void
*
hobject
;
// a pointer to a kernel object
struct
cap_derivation_tree
*
cdt_node
;
// list of domain ids to whom this capability is granted
lcd_cap_rights
crights
;
// specifies the rights the domain has over this capability
void
*
hobject
;
// a pointer to a kernel object
struct
cap_derivation_tree
*
cdt_node
;
// list of domain ids to whom this
//capability is granted
lcd_cap_rights
crights
;
// specifies the rights the domain has over this capability
};
struct
cte
;
struct
cap_node
{
cap_id
cnode_id
;
cap_id
cnode_id
;
struct
cte
*
table
;
/* points to another cnode table */
uint16_t
table_level
;
uint16_t
table_level
;
};
struct
free_slot_t
...
...
@@ -114,24 +112,26 @@ struct free_slot_t
struct
cte
// capability table entry
{
union
{
union
{
struct
cap_node
cnode
;
struct
capability_internal
cap
;
struct
free_slot_t
slot
;
};
lcd_cap_type
ctetype
;
uint16_t
index
;
uint16_t
index
;
};
struct
cap_space
{
struct
cte
root_cnode
;
struct
cte
root_cnode
;
struct
semaphore
sem_cspace
;
};
/* Helper Functions */
////////////////////////////////////////////////////////////////////////////////////////////
/* Helper Functions */
////////////////////////////////////////////////////////////////////////////////////////////
static
inline
int
lcd_get_bits_at_level
(
cap_id
id
,
int
level
)
{
int
bits
=
0
;
...
...
@@ -167,65 +167,107 @@ static inline void lcd_set_bits_at_level(struct cte *cnode, cap_id *cid, int fre
struct
cte
*
lcd_reserve_cap_slot
(
struct
cte
*
cnode
,
cap_id
*
cid
,
int
free_slot
);
// initializes the free slots available in the cnode structure.
void
lcd_initialize_freelist
(
struct
cte
*
cnode
,
bool
bFirstCNode
);
void
lcd_initialize_freelist
(
struct
cte
*
cnode
,
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
(
struct
cap_space
*
cspace
,
struct
cte
**
cap
);
cap_id
lcd_lookup_free_slot
(
struct
cap_space
*
cspace
,
struct
cte
**
cap
);
void
lcd_update_cdt
(
void
*
p
tcb
);
void
lcd_update_cdt
(
struct
task_struct
*
tcb
);
uint32_t
lcd_cap_delete_internal
(
struct
cte
*
cap_cte
);
uint32_t
lcd_cap_delete_internal
(
struct
cte
*
cap_cte
);
/* External Interface */
// creates a cspace for a thread. should be called during lcd creation.
////////////////////////////////////////////////////////////////////////////////////////////
/* External Interface */
////////////////////////////////////////////////////////////////////////////////////////////
// creates a cspace for a thread. should be called during lcd/thread creation.
// expects the following objects as input with the rights for those objects:
// ****(LCD_CapInitThreadTCB is compulsory)
// Objects Index within input array Comments
// Input:
// objects: array of pointers where each pointer is as follows:
// objects[index] Index within input array Comments
// LCD_CapNull 0 Should be a NULL entry in objects array
// ****LCD_CapInitThreadTCB 1 Pointer to task_struct of thread.
// LCD_CapInitThreadPD 2 Pointer to the page directory of process.
// LCD_CapIRQControl 3 ?? will be used later.
// LCD_CapInitThreadIPCBuffer 4 Pointer to the IPC buffer which will be used.
// total number of object pointers expected is equal to LCD_CapFirstFreeSlot.
// total number of object pointers expected
in array
is equal to LCD_CapFirstFreeSlot.
// Put a NULL pointer for entries which the thread is not expected to have.
// e.g. if the thread does not need an IPC buffer then objects[4] should be NULL.
// the returned value goes into the TCB of the caller.
// pointer to the cspace is also added to the TCB of the caller.
// Output:
// pointer to the newly created cspace.
struct
cap_space
*
lcd_create_cspace
(
void
*
objects
[],
lcd_cap_rights
rights
[]);
// will be used to access the object on which a method is to be invoked.
// the returned value is a pointer to the entry in the table where the capability
// maps. This contains the handle to the object which can be used by the invoked method.
// Input:
// tcb: pointer to the thread control block of the thread which invokes method.
// cid: capability identifier of the object on which the method is to be invoked.
// Output:
// pointer to the capability table entry if the cid is valid else NULL is returned.
struct
cte
*
lcd_lookup_capability
(
struct
task_struct
*
tcb
,
cap_id
cid
);
// creates a new capability, inserts it into cspace of caller and
// returns the capability identifier.
// it is unclear who will have the right to perform this operation.
cap_id
lcd_create_cap
(
void
*
ptcb
,
void
*
hobject
,
lcd_cap_rights
crights
);
// Input:
// ptcb: pointer to the task_struct of the thread which intends to create the capability.
// hobject: pointer to the underlying kernel object for which capability is being created.
// crights: the rights associated with the capability for the object.
// Output:
// capability identifier within the cspace of the thread which intended to create this capability.
// 0 = Failure
cap_id
lcd_create_cap
(
struct
task_struct
*
tcb
,
void
*
hobject
,
lcd_cap_rights
crights
);
// will be used to grant a capability to another thread
// 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
*
src_tcb
,
cap_id
src_cid
,
void
*
dst_tcb
,
lcd_cap_rights
crights
);
// a logical AND of the input parameter crights and the rights on the capability
// being granted will decide the final rights the granted capability will have.
// Input:
// src_tcb: pointer to the task_struct of the thread which internds to grant the capability.
// src_cid: capability identifier of the capability being granted.
// dst_tcb: pointer to the task_struct of the receiver thread.
// crights: the rights on the capability to be granted to the receiver.
cap_id
lcd_cap_grant
(
struct
task_struct
*
stcb
,
cap_id
src_cid
,
struct
task_struct
*
dtcb
,
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.
uint32_t
lcd_cap_delete
(
void
*
ptcb
,
cap_id
cid
);
// Input:
// ptcb: pointer to the task_struct of the thread intending to delete a capability.
// cid : capability identifier of the capability to be deleted.
// Output:
// 0 = Success
// Any other value indicates failure.
uint32_t
lcd_cap_delete
(
struct
task_struct
*
tcb
,
cap_id
cid
);
// will be called to delete the capability and all its children.
// the children can be present in cspace belonging to different threads.
// as such the thread owning the parent capability has a right to delete
// a capability which is its child or was derieved from it.
uint32_t
lcd_cap_revoke
(
void
*
ptcb
,
cap_id
cid
);
// Input:
// ptcb: pointer to the task_struct of the thread which is invoking this revoke operation.
// cid : the capability identifier of the capability being revoked.
// Ouptput:
// 0 = Success