Commit 0de25ed1 authored by Anton Burtsev's avatar Anton Burtsev Committed by Vikram Narayanan

Rewriting capability code -- kmalloc -> slab -- split public header in two

parent b7ddc26c
......@@ -17,6 +17,7 @@
#include <linux/kthread.h>
#include <lcd/lcd.h>
#include <lcd/cap-internal.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LCD ping-pong IPC test (sender)");
......
#ifndef __LCD_CAP_INTERNAL_H__
#define __LCD_CAP_INTERNAL_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>
#include <linux/log2.h>
#include <linux/delay.h>
#include <linux/kfifo.h>
#include <asm/page.h>
#include <lcd/cap.h>
#define MAX_SLOTS (PAGE_SIZE/sizeof(struct cte))
#define CNODE_SLOTS_PER_CNODE 64
#define CNODE_SLOTS_START (MAX_SLOTS - CNODE_SLOTS_PER_CNODE)
#define CNODE_INDEX_BITS (ilog2(MAX_SLOTS))
#define CAP_ID_SIZE (sizeof(capability_t) * 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 LCD_PANIC(expr) \
panic(#expr);
/* caps with fixed slot potitions in the root CNode */
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_CapFirstFreeSlot
};
#define CAPRIGHTS_READ (1 << 0)
#define CAPRIGHTS_WRITE (1 << 1)
#define CAPRIGHTS_EXECUTE (1 << 2)
#define CAPRIGHTS_GRANT (1 << 3)
#define CAPRIGHTS_NUM 4
#define CAPRIGHTS_ALL ((1 << CAPRIGHTS_NUM) - 1)
#define CAPRIGHTS_RW (CAPRIGHTS_READ | CAPRIGHTS_WRITE)
#define CAPRIGHTS_RWX (CAPRIGHTS_RW | CAPRIGHTS_EXECUTE)
#define CAPRIGHTS_NORIGHTS 0
int lcd_cap_init(void);
int lcd_cap_exit(void);
////////////////////////////////////////////////////////////////////////////////////////////
/* Helper Functions */
////////////////////////////////////////////////////////////////////////////////////////////
static inline int lcd_get_bits_at_level(capability_t id, int level)
{
int bits = 0;
id = id << ((MAX_DEPTH - level - 1) * CNODE_INDEX_BITS);
id = id >> ((MAX_DEPTH - 1) * CNODE_INDEX_BITS);
bits = (int) id;
return bits;
}
static inline void lcd_clear_bits_at_level(capability_t *id, int level)
{
capability_t mask = (~0);
// clear all higher order bits.
mask = mask << ((MAX_DEPTH - 1) * CNODE_INDEX_BITS);
// clear lower order 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;
}
static inline void lcd_set_bits_at_level(struct cte *cnode, capability_t *cid, int free_slot)
{
int level = cnode->cnode.table_level;
capability_t id = free_slot;
*cid = cnode->cnode.cnode_id;
lcd_clear_bits_at_level(cid, level);
id = id << (level * CNODE_INDEX_BITS);
*cid = *cid | id;
}
struct cte * lcd_cap_reserve_slot(struct cte *cnode, capability_t *cid, int free_slot);
bool lcd_cap_initialize_freelist(struct cap_space *cspace, struct cte *cnode, bool bFirstCNode);
capability_t lcd_cap_lookup_freeslot(struct cap_space *cspace, struct cte **cap);
void lcd_cap_update_cdt(struct task_struct *tcb);
bool lcd_cap_delete_internal(struct cte *cap, bool *last_reference);
bool lcd_cap_delete_internal_lockless(struct cte *cap, bool *last_reference);
////////////////////////////////////////////////////////////////////////////////////////////
/* 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)
// 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 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.
// pointer to the cspace is also added to the TCB of the caller.
// Output:
// pointer to the newly created cspace.
int lcd_cap_init_cspace(struct cap_space *cspace);
// 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.
// keep_locked: whether or not to keep the semaphore protecting cdt locked.
// Output:
// pointer to the capability table entry if the cid is valid else NULL is returned.
struct cte * lcd_cap_lookup_capability(struct cap_space *cspace, capability_t cid, bool keep_locked);
// 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.
// 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
capability_t lcd_cap_create_capability(struct cap_space *cspace, 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 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.
capability_t lcd_cap_grant_capability(struct cap_space *src_space, capability_t src_cid, struct cap_space *dst_space, 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.
// 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_capability(struct cap_space *cspace, capability_t 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.
// 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
// Any other value indicates failure.
uint32_t lcd_cap_revoke_capability(struct cap_space *cspace, capability_t cid);
// should be called when the thread exits.
// this is extremely heavy function which updates the CDT for all capabilities present
// in the cspace of the exiting thread.
// Input:
// ptcb: pointer to the task_struct of the thread which is getting terminated.
void lcd_cap_destroy_cspace(struct cap_space *cspace);
// will be used to get the rights available with a capability.
// Input:
// ptcb: pointer to the task_struct of the thread in whose cspace the capability resides.
// cid : capability identifier of the capability whose rights are being queried.
// rights: The rights will be saved in this variable.
// Output:
// Return Value: 0 = Success, Any other value indicates failure.
// The rights associated with the capability will be saved in the rights ouput paramter.
uint32_t lcd_cap_get_rights(struct cap_space *cspace, capability_t cid, lcd_cap_rights *rights);
// will be used to craete a copy of the capability identified by cid within the same cspace
// the rights of the copied capability could be modified using the rights parameter.
// Input:
// tcb: pointer to the thread control block whose cspace has the capability to be copied.
// cid: the capability identifier of the capability to be copied.
// rights: the new rights for the copied capability, the final rights the capability will
// be the Logical AND of the original rights and the parameter rights.
// Output:
// the capability identifier for the copied capability is returned.
// 0 indicates failure.
capability_t lcd_cap_mint_capability(struct cap_space *cspace, capability_t cid, lcd_cap_rights rights);
#endif // __LCD_CAP_H__
......@@ -2,24 +2,9 @@
#define __LCD_CAP_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>
#include <linux/semaphore.h>
#include <linux/log2.h>
#include <linux/delay.h>
#include <linux/kfifo.h>
#include <asm/page.h>
#include <uapi/linux/lcd-cap.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Flux Research Group, University of Utah");
/* XXX: some temporary crap from Jithu to test IPC */
void * get_cap_obj(u32 cap_id);
#include <uapi/linux/lcd-cap.h>
typedef uint32_t lcd_cnode; // a pointer to the cnode
typedef uint32_t lcd_cnode_entry; // a pointer to an entry within a cnode
......@@ -27,30 +12,6 @@ typedef uint64_t lcd_tcb; // a pointer/handle to the thread contrl b
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))
#define CNODE_SLOTS_PER_CNODE 64
#define CNODE_SLOTS_START (MAX_SLOTS - CNODE_SLOTS_PER_CNODE)
#define CNODE_INDEX_BITS (ilog2(MAX_SLOTS))
#define CAP_ID_SIZE (sizeof(capability_t) * 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 LCD_PANIC(expr) \
panic(#expr);
enum __lcd_cap_type
{
......@@ -62,29 +23,6 @@ enum __lcd_cap_type
lcd_type_separator
};
/* caps with fixed slot potitions in the root CNode */
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_CapFirstFreeSlot = 5
};
#define CAPRIGHTS_READ (1 << 0)
#define CAPRIGHTS_WRITE (1 << 1)
#define CAPRIGHTS_EXECUTE (1 << 2)
#define CAPRIGHTS_GRANT (1 << 3)
#define CAPRIGHTS_NUM 4
#define CAPRIGHTS_ALL ((1 << CAPRIGHTS_NUM) - 1)
#define CAPRIGHTS_RW (CAPRIGHTS_READ | CAPRIGHTS_WRITE)
#define CAPRIGHTS_RWX (CAPRIGHTS_RW | CAPRIGHTS_EXECUTE)
#define CAPRIGHTS_NORIGHTS 0
struct cap_derivation_tree
{
......@@ -139,160 +77,4 @@ struct cap_space
};
////////////////////////////////////////////////////////////////////////////////////////////
/* Helper Functions */
////////////////////////////////////////////////////////////////////////////////////////////
static inline int lcd_get_bits_at_level(capability_t id, int level)
{
int bits = 0;
id = id << ((MAX_DEPTH - level - 1) * CNODE_INDEX_BITS);
id = id >> ((MAX_DEPTH - 1) * CNODE_INDEX_BITS);
bits = (int) id;
return bits;
}
static inline void lcd_clear_bits_at_level(capability_t *id, int level)
{
capability_t mask = (~0);
// clear all higher order bits.
mask = mask << ((MAX_DEPTH - 1) * CNODE_INDEX_BITS);
// clear lower order 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;
}
static inline void lcd_set_bits_at_level(struct cte *cnode, capability_t *cid, int free_slot)
{
int level = cnode->cnode.table_level;
capability_t id = free_slot;
*cid = cnode->cnode.cnode_id;
lcd_clear_bits_at_level(cid, level);
id = id << (level * CNODE_INDEX_BITS);
*cid = *cid | id;
}
struct cte * lcd_cap_reserve_slot(struct cte *cnode, capability_t *cid, int free_slot);
bool lcd_cap_initialize_freelist(struct cap_space *cspace, struct cte *cnode, bool bFirstCNode);
capability_t lcd_cap_lookup_freeslot(struct cap_space *cspace, struct cte **cap);
void lcd_cap_update_cdt(struct task_struct *tcb);
bool lcd_cap_delete_internal(struct cte *cap, bool *last_reference);
bool lcd_cap_delete_internal_lockless(struct cte *cap, bool *last_reference);
////////////////////////////////////////////////////////////////////////////////////////////
/* 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)
// 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 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.
// pointer to the cspace is also added to the TCB of the caller.
// Output:
// pointer to the newly created cspace.
int lcd_cap_init_cspace(struct cap_space *cspace);
// 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.
// keep_locked: whether or not to keep the semaphore protecting cdt locked.
// Output:
// pointer to the capability table entry if the cid is valid else NULL is returned.
struct cte * lcd_cap_lookup_capability(struct cap_space *cspace, capability_t cid, bool keep_locked);
// 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.
// 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
capability_t lcd_cap_create_capability(struct cap_space *cspace, 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 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.
capability_t lcd_cap_grant_capability(struct cap_space *src_space, capability_t src_cid, struct cap_space *dst_space, 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.
// 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_capability(struct cap_space *cspace, capability_t 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.
// 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
// Any other value indicates failure.
uint32_t lcd_cap_revoke_capability(struct cap_space *cspace, capability_t cid);
// should be called when the thread exits.
// this is extremely heavy function which updates the CDT for all capabilities present
// in the cspace of the exiting thread.
// Input:
// ptcb: pointer to the task_struct of the thread which is getting terminated.
void lcd_cap_destroy_cspace(struct cap_space *cspace);
// will be used to get the rights available with a capability.
// Input:
// ptcb: pointer to the task_struct of the thread in whose cspace the capability resides.
// cid : capability identifier of the capability whose rights are being queried.
// rights: The rights will be saved in this variable.
// Output:
// Return Value: 0 = Success, Any other value indicates failure.
// The rights associated with the capability will be saved in the rights ouput paramter.
uint32_t lcd_cap_get_rights(struct cap_space *cspace, capability_t cid, lcd_cap_rights *rights);
// will be used to craete a copy of the capability identified by cid within the same cspace
// the rights of the copied capability could be modified using the rights parameter.
// Input:
// tcb: pointer to the thread control block whose cspace has the capability to be copied.
// cid: the capability identifier of the capability to be copied.
// rights: the new rights for the copied capability, the final rights the capability will
// be the Logical AND of the original rights and the parameter rights.
// Output:
// the capability identifier for the copied capability is returned.
// 0 indicates failure.
capability_t lcd_cap_mint_capability(struct cap_space *cspace, capability_t cid, lcd_cap_rights rights);
#endif // __LCD_CAP_H__
#endif
......@@ -20,6 +20,9 @@ union utcb_union {
struct sync_ipc * alloc_sync_ipc(void);
int lcd_ipc_init(void);
int lcd_ipc_exit(void);
int ipc_send(capability_t cap, struct message_info *msg);
int ipc_recv(capability_t rvp_cap, struct message_info *msg);
......
......@@ -60,7 +60,7 @@ struct sched_param {
#include <linux/magic.h>
#include <linux/cgroup-defs.h>
#ifdef CONFIG_LCD
#ifdef CONFIG_HAVE_LCD
#include <lcd/cap.h>
#include <lcd/ipc.h>
#endif
......@@ -1468,7 +1468,7 @@ struct task_struct {
atomic_t usage;
unsigned int flags; /* per process flags, defined below */
unsigned int ptrace;
#ifdef CONFIG_LCD
#ifdef CONFIG_HAVE_LCD
struct cap_space cspace;
struct list_head sync_rendezvous;
struct utcb *utcb;
......
#include <lcd/cap.h>
#include <linux/slab.h>
#include <lcd/cap-internal.h>
struct kmem_cache *cte_cache;
struct kmem_cache *cdt_cache;
int lcd_cap_init(void){
cte_cache = KMEM_CACHE(cte, 0);
if(!cte_cache){
printk(KERN_ERR "Failed to allocate cte slab\n");
return -ENOMEM;
};
cdt_cache = KMEM_CACHE(cap_derivation_tree, 0);
if(!cdt_cache){
printk(KERN_ERR "Failed to allocate cte slab\n");
return -ENOMEM;
};
return 0;
};
int lcd_cap_exit(void) {
if (cte_cache)
kmem_cache_destroy(cte_cache);
if (cdt_cache)
kmem_cache_destroy(cdt_cache);
return 0;
}
// this function will not lock any semaphore.
// assumption is that cdt and cspace are already locked.
......@@ -68,7 +97,7 @@ bool lcd_cap_delete_internal_lockless(struct cte *cap, bool *last_reference)
}
// delete the capability
kfree(cdt);
kmem_cache_free(cdt_cache, cdt);
cap->ctetype = lcd_type_free;
table = cap - cap->index;
cap->slot.next_free_cap_slot = table[0].slot.next_free_cap_slot;
......@@ -287,7 +316,7 @@ void lcd_cap_destroy_cspace(struct cap_space *cspace)
}
if (i == CNODE_SLOTS_START)
{
kfree(node);
kmem_cache_free(cte_cache, node);
table_visited = false;
}
else
......@@ -314,7 +343,7 @@ capability_t lcd_cap_grant_capability(struct cap_space *src_space, capability_t
BUG_ON(src_space == NULL || dst_space == NULL || src_cid == 0);
dst_cdt_node = kmalloc(sizeof(struct cap_derivation_tree), GFP_KERNEL);
dst_cdt_node = kmem_cache_alloc(cdt_cache, GFP_KERNEL);
if(!dst_cdt_node) {
LCD_PANIC("Allocation failed\n");
return 0;
......@@ -332,7 +361,7 @@ capability_t lcd_cap_grant_capability(struct cap_space *src_space, capability_t
LCD_PANIC("lcd_cap_grant_capability: Invalid Capability\n");
if (src_cte != NULL)
up(src_cte->cap.cdt_node->sem_cdt);
kfree(dst_cdt_node);
kmem_cache_free(cdt_cache, dst_cdt_node);
return 0;
}
......@@ -340,7 +369,7 @@ capability_t lcd_cap_grant_capability(struct cap_space *src_space, capability_t
{
LCD_PANIC("lcd_cap_grant_capability: Source does not have grant permissions\n");
up(src_cte->cap.cdt_node->sem_cdt);
kfree(dst_cdt_node);
kmem_cache_free(cdt_cache, dst_cdt_node);
return 0;
}
......@@ -354,7 +383,7 @@ capability_t lcd_cap_grant_capability(struct cap_space *src_space, capability_t
LCD_PANIC("lcd_cap_grant_capability: Destroy may be in progress, aborting operation\n");
up(&(dst_space->sem_cspace));
up(src_cte->cap.cdt_node->sem_cdt);
kfree(dst_cdt_node);
kmem_cache_free(cdt_cache, dst_cdt_node);
return 0;
}
......@@ -368,7 +397,7 @@ capability_t lcd_cap_grant_capability(struct cap_space *src_space, capability_t
LCD_PANIC("lcd_cap_grant_capability: No free slot\n");
up(&(dst_space->sem_cspace));
up(src_cte->cap.cdt_node->sem_cdt);
kfree(dst_cdt_node);
kmem_cache_free(cdt_cache, dst_cdt_node);
return 0;
}
......@@ -481,7 +510,7 @@ capability_t lcd_cap_create_capability(struct cap_space *cspace, void * hobject,
BUG_ON(cspace == NULL || cspace->root_cnode.cnode.table == NULL);
cdtnode = kmalloc(sizeof(struct cap_derivation_tree), GFP_KERNEL);
cdtnode = kmem_cache_alloc(cdt_cache, GFP_KERNEL);
if (cdtnode == NULL)
{
LCD_PANIC("lcd_cap_create_capability: CDT Node allocation failed\n");
......@@ -492,18 +521,18 @@ capability_t lcd_cap_create_capability(struct cap_space *cspace, void * hobject,
if (cdtnode == NULL)
{
LCD_PANIC("lcd_cap_create_capability: CDT Semaphore allocation failed\n");
kfree(cdtnode);
kmem_cache_free(cdt_cache, cdtnode);
return 0;
}
if (down_interruptible(&(cspace->sem_cspace)))
if (down_interruptible(&(cspace->sem_cspace)) == 0)
{
if (cspace->root_cnode.ctetype == lcd_type_invalid)
{
LCD_PANIC("lcd_cap_create_capability: Destroy may be in progress, operation aborted\n");
up(&(cspace->sem_cspace));
kfree(cdtnode->sem_cdt);
kfree(cdtnode);
kmem_cache_free(cdt_cache, cdtnode);
return 0;
}
cid = lcd_cap_lookup_freeslot(cspace, &cap);
......@@ -511,7 +540,7 @@ capability_t lcd_cap_create_capability(struct cap_space *cspace, void * hobject,
{
LCD_PANIC("lcd_cap_create_capability: No Free Slot found\n");
kfree(cdtnode->sem_cdt);
kfree(cdtnode);
kmem_cache_free(cdt_cache, cdtnode);
up(&(cspace->sem_cspace));
return 0;
}
......@@ -532,7 +561,7 @@ capability_t lcd_cap_create_capability(struct cap_space *cspace, void * hobject,
{
LCD_PANIC("lcd_cap_create_capability: Signal interrupted cspace lock acquire\n");
kfree(cdtnode->sem_cdt);
kfree(cdtnode);
kmem_cache_free(cdt_cache, cdtnode);
}
return cid;
}
......@@ -540,98 +569,42 @@ EXPORT_SYMBOL(lcd_cap_create_capability);
int lcd_cap_init_cspace(struct cap_space *cspace)
{
bool success = false;
int ret;
struct cte *table;