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
8fa32a9b
Commit
8fa32a9b
authored
Mar 10, 2014
by
Muktesh Khole
Committed by
Vikram Narayanan
Oct 25, 2016
Browse files
Fix bug with MAX_SLOTS
parent
6b0abe8c
Changes
2
Hide whitespace changes
Inline
Side-by-side
xcap/capability.c
View file @
8fa32a9b
...
...
@@ -52,27 +52,30 @@ void lcd_initialize_freelist(struct cte *cnode, bool bFirstCNode)
cnode
[
i
].
slot
.
next_free_cnode_slot
=
0
;
}
struct
cte
*
lcd_
in
ser
t
_cap
ability
(
struct
cte
*
cnode
,
cap_id
*
cid
,
int
free_slot
)
struct
cte
*
lcd_
re
ser
ve
_cap
_slot
(
struct
cte
*
cnode
,
cap_id
*
cid
,
int
free_slot
)
{
struct
cte
*
node
=
cnode
->
cnode
.
cap_entry
;
struct
cte
*
node
=
cnode
->
cnode
.
table
;
ASSERT
(
node
[
free_slot
].
ctetype
==
lcd_type_free
,
"Free List is corrupted
\n
"
);
// a valid empty slot
node
[
0
].
slot
.
next_free_cap_slot
=
node
[
free_slot
].
slot
.
next_free_cap_slot
;
lcd_set_level_bits
(
&
cid
,
cnode
->
cnode
.
cnode_id
,
free_slot
,
cnode
->
cnode
.
level
);
lcd_set_level_bits
(
cnode
,
cid
,
free_slot
);
return
&
node
[
free_slot
];
}
// 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.
// naming convention:
// cnode = struct cte entry in the table, which points to another table.
// node = pointer the the array of struct cte entries/capability table i.e. cnode->cnode.table
cap_id
lcd_lookup_free_slot
(
struct
cap_space
*
cspace
,
struct
cte
**
cap
)
{
cap_id
cid
=
0
;
bool
found
=
false
;
int
level
=
0
,
i
=
0
;
int
i
=
0
;
struct
kfifo
cnode_q
;
if
(
cspace
==
NULL
||
cspace
->
root_cnode
.
cnode
.
cap_entry
==
NULL
||
cap
==
NULL
)
if
(
cspace
==
NULL
||
cspace
->
root_cnode
.
cnode
.
table
==
NULL
||
cap
==
NULL
)
return
0
;
if
(
kfifo_alloc
(
&
cnode_q
,
sizeof
(
struct
cte
)
*
512
,
GFP_KERNEL
)
!=
0
)
...
...
@@ -94,15 +97,14 @@ cap_id lcd_lookup_free_slot(struct cap_space *cspace, struct cte **cap)
cid
=
0
;
goto
free_kfifo
;
}
node
=
cnode
->
cnode
.
cap_entry
;
node
=
cnode
->
cnode
.
table
;
free_cap_slot
=
node
[
0
].
slot
.
next_free_cap_slot
;
free_cnode_slot
=
node
[
0
].
slot
.
next_free_cnode_slot
;
level
=
cnode
->
cnode
.
level
;
if
(
free_cap_slot
!=
0
&&
free_cap_slot
<
CNODE_SLOTS_START
)
{
*
cap
=
lcd_
in
ser
t
_cap
ability
(
cnode
,
&
cid
,
free_cap_slot
);
*
cap
=
lcd_
re
ser
ve
_cap
_slot
(
cnode
,
&
cid
,
free_cap_slot
);
goto
free_kfifo
;
}
else
if
(
free_cnode_slot
!=
0
&&
free_cnode_slot
>=
CNODE_SLOTS_START
&&
free_cnode_slot
<
MAX_SLOTS
)
...
...
@@ -114,36 +116,35 @@ cap_id lcd_lookup_free_slot(struct cap_space *cspace, struct cte **cap)
if
(
node
[
i
].
ctetype
==
lcd_type_cnode
)
{
struct
cte
*
next_cnode
=
&
node
[
i
];
struct
cte
*
next_node
=
node
[
i
].
cnode
.
cap_entry
;
free_cap_slot
=
next_node
[
0
].
next_free_cap_slot
;
struct
cte
*
next_node
=
node
[
i
].
cnode
.
table
;
free_cap_slot
=
next_node
[
0
].
slot
.
next_free_cap_slot
;
if
(
free_cap_slot
!=
0
&&
free_cap_slot
<
CNODE_SLOTS_START
)
{
*
cap
=
lcd_
in
ser
t
_cap
ability
(
next_cnode
,
&
cid
,
free_cap_slot
);
*
cap
=
lcd_
re
ser
ve
_cap
_slot
(
next_cnode
,
&
cid
,
free_cap_slot
);
goto
free_kfifo
;
}
}
}
// we will have to allocate a new cnode
node
[
0
].
slot
.
next_free_cnode_slot
=
node
[
free_cnode_slot
].
slot
.
next_free_cnode_slot
;
node
[
free_cnode_slot
].
ctetype
=
lcd_type_cnode
;
node
[
free_cnode_slot
].
cnode
.
cap_entry
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
if
(
node
[
free_cnode_slot
].
cnode
.
cap_entry
==
NULL
)
node
[
free_cnode_slot
].
cnode
.
table
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
if
(
node
[
free_cnode_slot
].
cnode
.
table
==
NULL
)
{
cid
=
0
;
goto
free_kfifo
;
}
lcd_initialize_freelist
(
node
[
free_cnode_slot
].
cnode
.
cap_entry
,
false
);
lcd_set_level_bits
(
&
cid
,
code
->
cnode
.
cnode_id
,
free_cnode_slot
,
cnode
->
cnode
.
level
+
1
);
node
[
0
].
slot
.
next_free_cnode_slot
=
node
[
free_cnode_slot
].
slot
.
next_free_cnode_slot
;
node
[
free_cnode_slot
].
ctetype
=
lcd_type_cnode
;
lcd_initialize_freelist
(
node
[
free_cnode_slot
].
cnode
.
table
,
false
);
node
[
free_cnode_slot
].
cnode
.
table_level
=
cnode
->
cnode
.
table_level
+
1
;
lcd_set_level_bits
(
cnode
,
&
cid
,
free_cnode_slot
);
node
[
free_cnode_slot
].
cnode
.
cnode_id
=
cid
;
node
[
free_cnode_slot
].
cnode
.
level
=
cnode
->
cnode
.
level
+
1
;
node
=
node
[
free_cnode_slot
].
cnode
.
cap_entry
;
cnode
=
&
node
[
free_cnode_slot
];
node
=
node
[
free_cnode_slot
].
cnode
.
table
;
free_cap_slot
=
node
[
0
].
slot
.
next_free_cap_slot
;
if
(
free_cap_slot
!=
0
&&
free_cap_slot
<
CNODE_SLOTS_START
)
{
*
cap
=
lcd_
in
ser
t
_cap
ability
(
node
,
&
cid
,
free_slot
);
*
cap
=
lcd_
re
ser
ve
_cap
_slot
(
c
node
,
&
cid
,
free_
cap_
slot
);
goto
free_kfifo
;
}
cid
=
0
;
...
...
@@ -174,9 +175,9 @@ struct cte * lcd_lookup_capability(struct cap_space *cspace, cap_id cid)
mask
=
~
mask
;
// check if input is valid
if
(
cspace
==
NULL
||
cid
==
0
||
cspace
->
root_cnode
.
cnode
.
cap_entry
==
NULL
)
if
(
cspace
==
NULL
||
cid
==
0
||
cspace
->
root_cnode
.
cnode
.
table
==
NULL
)
return
NULL
;
cnode
=
cspace
->
root_cnode
.
cnode
.
cap_entry
;
cnode
=
cspace
->
root_cnode
.
cnode
.
table
;
while
(
id
>
0
)
{
...
...
@@ -189,7 +190,7 @@ struct cte * lcd_lookup_capability(struct cap_space *cspace, cap_id cid)
}
else
if
(
cnode
[
index
].
ctetype
==
lcd_type_cnode
&&
id
!=
0
)
{
cnode
=
cnode
[
index
].
cnode
.
cap_entry
;
cnode
=
cnode
[
index
].
cnode
.
table
;
}
else
{
...
...
@@ -212,21 +213,21 @@ struct cap_space * lcd_create_cspace()
// allocate memory for the first cnode.
cspace
->
root_cnode
.
ctetype
=
lcd_type_cnode
;
cspace
->
root_cnode
.
cnode
.
cnode_id
=
0
;
cspace
->
root_cnode
.
cnode
.
level
=
0
;
cspace
->
root_cnode
.
cnode
.
cap_entry
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
SAFE_EXIT_IF_ALLOC_FAILED
(
cspace
->
root_cnode
.
cnode
.
cap_entry
,
alloc_failure
);
cspace
->
root_cnode
.
cnode
.
table_
level
=
0
;
cspace
->
root_cnode
.
cnode
.
table
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
SAFE_EXIT_IF_ALLOC_FAILED
(
cspace
->
root_cnode
.
cnode
.
table
,
alloc_failure
);
// initialize the free list
lcd_initialize_freelist
(
cspace
->
root_cnode
.
cnode
.
cap_entry
,
true
);
lcd_initialize_freelist
(
cspace
->
root_cnode
.
cnode
.
table
,
true
);
goto
success
;
alloc_failure:
if
(
cspace
)
{
if
(
cspace
->
root_cnode
.
cnode
.
cap_entry
)
if
(
cspace
->
root_cnode
.
cnode
.
table
)
{
kfree
(
cspace
->
root_cnode
.
cnode
.
cap_entry
);
cspace
->
root_cnode
.
cnode
.
cap_entry
=
NULL
;
kfree
(
cspace
->
root_cnode
.
cnode
.
table
);
cspace
->
root_cnode
.
cnode
.
table
=
NULL
;
}
vfree
(
cspace
);
cspace
=
NULL
;
...
...
@@ -248,7 +249,7 @@ cap_id lcd_create_cap(void * ptcb, void * hobject, lcd_cap_rights crights)
return
0
;
cspace
=
tcb
->
cspace
;
if
(
cspace
==
NULL
||
cspace
->
root_cnode
.
cnode
.
cap_entry
==
NULL
)
if
(
cspace
==
NULL
||
cspace
->
root_cnode
.
cnode
.
table
==
NULL
)
return
0
;
down_interruptible
(
&
cspace
->
sem_cspace
);
...
...
@@ -344,7 +345,7 @@ uint32_t lcd_get_cap_rights(void * ptcb, cap_id cid, lcd_cap_rights *rights)
up
(
tcb
->
cspace
->
sem_cspace
);
return
-
1
;
}
rights
=
cap
->
cap
.
crights
;
*
rights
=
cap
->
cap
.
crights
;
up
(
tcb
->
cspace
->
sem_cspace
);
return
0
;
}
\ No newline at end of file
xcap/capability.h
View file @
8fa32a9b
...
...
@@ -29,7 +29,7 @@ typedef uint16_t lcd_cap_rights; // holds the rights associated with a capabi
#define CNODE_SLOTS_START (MAX_SLOTS - CNODE_SLOTS_PER_CNODE)
#define CNODE_INDEX_BITS (ilog2(MAX_SLOTS))
#define CAP_ID_SIZE (sizeof(cap_id) * 8)
#define MAX_DEPTH ((CAP_ID_SIZE
-
1)/CNODE_INDEX_BITS)
#define MAX_DEPTH ((CAP_ID_SIZE
+
1)/CNODE_INDEX_BITS)
#define SAFE_EXIT_IF_ALLOC_FAILED(ptr, label) \
if (ptr == NULL) \
...
...
@@ -100,8 +100,8 @@ struct cte;
struct
cap_node
{
cap_id
cnode_id
;
int
level
;
struct
cte
*
cap_entry
;
/*
may
point to another cnode
or to a capability
*/
int
table_
level
;
struct
cte
*
table
;
/* point
s
to another cnode
table
*/
};
struct
free_slot_t
...
...
@@ -142,21 +142,27 @@ static inline void clear_bits_at_level(cap_id *id, int level)
{
cap_id
mask
=
(
~
0
);
// clear all higher order bits.
mask
=
mask
<<
((
MAX_DEPTH
-
level
-
1
)
*
CNODE_INDEX_BITS
);
mask
=
mask
<<
((
MAX_DEPTH
-
1
)
*
CNODE_INDEX_BITS
);
// clear lower order bits
mask
=
mask
>>
((
MAX_DEPTH
-
1
)
*
CNODE_INDEX_BITS
);
mask
=
mask
>>
((
MAX_DEPTH
-
1
)
*
CNODE_INDEX_BITS
);
// get the mask to appropriate position
mask
=
mask
<<
(
level
*
CNODE_INDEX_BITS
);
mask
=
~
mask
;
*
id
=
(
*
id
)
&
mask
;
}
void
lcd_set_level_bits
(
cap_id
*
cid
,
node
->
cnode
.
cnode_id
,
free_slot
,
level
)
static
inline
void
lcd_set_level_bits
(
struct
cte
*
cnode
,
cap_id
*
cid
,
int
free_slot
)
{
int
level
=
cnode
->
cnode
.
table_level
;
cap_id
id
=
free_slot
;
*
cid
=
cnode
->
cnode
.
cnode_id
;
clear_bits_at_level
(
cid
,
level
);
id
=
id
<<
(
level
*
CNODE_INDEX_BITS
);
*
cid
=
*
cid
|
id
;
}
struct
cte
*
lcd_
in
ser
t
_cap
ability
(
struct
cte
*
node
,
cap_id
*
cid
,
int
free_slot
);
struct
cte
*
lcd_
re
ser
ve
_cap
_slot
(
struct
cte
*
c
node
,
cap_id
*
cid
,
int
free_slot
);
// initializes the free slots available in the cnode structure.
void
lcd_initialize_freelist
(
struct
cte
*
cnode
,
bool
bFirstCNode
);
...
...
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