Commit beed5c12 authored by Jintack Lim's avatar Jintack Lim Committed by Vikram Narayanan
Browse files

Add capability delete and search function

parent b7914a30
typedef enum {
TYPE_ENDPOINT,
TYPE_ASYNCENDPOINT,
TYPE_TCB,
TYPE_CNODE
}objType_t;
typedef enum {ObjType_Untyped, ObjType_CNode=777, ObjType_EndPoint, ObjType_Null} LCD_Type;
typedef enum {ObjType_Untyped, ObjType_CNode=777, ObjType_EndPoint=888, ObjType_Null} LCD_Type;
/* caps with fixed slot potitions in the root CNode */
enum {
......@@ -19,18 +12,12 @@ enum {
typedef uint32_t LCD_Word;
/*
An address in the capability space refers to a slot which may or may not contain a capability
A capability address is stored in a CPointer
*/
typedef LCD_Word LCD_CPtr;
typedef LCD_CPtr LCD_CNode;
typedef LCD_CPtr LCD_Untyped;
typedef LCD_CPtr LCD_TCB;
int LCD_Untyped_Retype(LCD_Untyped _service, LCD_Type objType, int size_bits, LCD_CNode root, int node_index, int node_depth, int node_offset, int num_objects);
/// Sets the specified number of low-order bits to 1
#define MASK(bits) ((1UL << bits) - 1)
#define OBJBITS_CTE 7
......@@ -87,49 +74,16 @@ struct cte
struct capability cap;
};
/* internal functions */
int caps_lookup_slot(struct capability *cnode_cap, LCD_CPtr cptr, uint8_t vbits, uint8_t resolved_bits, struct cte **ret, CapRights rights);
struct cte * caps_locate_slot(struct cte * topCte, size_t offset);
void print_cnode(struct cte * myCte, int depth);
/*
static int LCD_TCB_SetSpace(LCD_CPtr LCD_CapInitThreadCNode);
static int LCD_Create_Object(objType_t type);
*/
#if 0
#define IWANA_MAX_LEVELS 3
struct iwana_cspace {
/* The caps to the current vertical slice of the cspace we are allocating
* out of. */
struct {
seL4_CPtr cptr;
int offset;
} cnodes[IWANA_MAX_LEVELS];
/* Size (in bits) of each level in the CNode. */
int depths[IWANA_MAX_LEVELS];
/*
* Size (in bits) of each level, taking into account guards.
*
* This is used when:
*
* (i) We are trying to address a slot in a CNode of this level; and
*
* (ii) That CNode was possibly created by an external party, with
* its cap having a guard.
*/
int guarded_depths[IWANA_MAX_LEVELS];
/* Upper limit on the size of the CSpace. */
unsigned long cspace_size_bits;
/* Number of guard bits on the top level. */
int guard_bits;
/* Number of levels in the cspace. */
int levels;
/* First free cap available in the client's CSpace. */
seL4_CPtr next_cap;
};
#endif
LCD_CPtr create_CNode(LCD_Untyped _service, int size_bits, LCD_CNode root, int node_index, int node_depth, int node_offset, int num_objects);
LCD_CPtr create_EndPoint(LCD_Untyped _service, int size_bits, LCD_CNode root, int node_index, int node_depth, int node_offset, int num_objects);
int cnode_create_internal(struct capability *src_cap, int size_bits);
/* externel interface */
static int LCD_Create_CSpace(void);
int LCD_Untyped_Retype(LCD_Untyped _service, LCD_Type objType, int size_bits, LCD_CNode root, int node_index, int node_depth, int node_offset, int num_objects);
static int LCD_CNode_Delete(LCD_CNode _service, int node_index, int node_depth);
static void *LCD_CNode_Search(LCD_CNode _service, int node_index, int node_depth);
// Defining __KERNEL__ and MODULE allows us to access kernel-level code not usually available to userspace programs.
#undef __KERNEL__
#define __KERNEL__
#undef MODULE
#define MODULE
// Linux Kernel/LKM headers: module.h is needed by all modules and kernel.h is needed for KERN_INFO.
#include <linux/module.h> // included for all kernel modules
#include <linux/kernel.h> // included for KERN_INFO
#include <linux/init.h> // included for __init and __exit macros
#include <linux/slab.h> // included for kmalloc
#include <linux/module.h> // included for all kernel modules
#include <linux/kernel.h> // included for KERN_INFO
#include <linux/init.h> // included for __init and __exit macros
#include <linux/slab.h> // included for kmalloc
#include <linux/kthread.h>
#include <linux/sched.h>
#include "cap.h"
struct task_struct *capTask;
struct cte initCte; /* TODO: Copy this cte to TCB */
///////////////////////// Test Program ///////////////////////////////////////////////////////////////////////////////
int thread_fn(void* abc)
{
/* TODO: CSpace for the first thread should be created before it runs */
LCD_Create_CSpace();
/* CSpace test cases */
/* Addr is 0x0 */
LCD_Untyped_Retype(0, ObjType_EndPoint, 0, LCD_CapInitThreadCNode, 0, 0, 0, 0);
print_cnode(&initCte, 0);
/* Addr is 0x400000000 */
LCD_Untyped_Retype(0, ObjType_CNode, 2, LCD_CapInitThreadCNode, 0, 0, 0x2, 0);
print_cnode(&initCte, 0);
/* Addr is 0x480000000 */
LCD_Untyped_Retype(0, ObjType_EndPoint, 0, LCD_CapInitThreadCNode, 0x40000000, 3, 0x1, 0);
print_cnode(&initCte, 0);
LCD_CNode_Search(LCD_CapInitThreadCNode, 0x40000000, 3);
LCD_CNode_Delete(LCD_CapInitThreadCNode, 0x48000000, 5);
print_cnode(&initCte, 0);
LCD_CNode_Delete(LCD_CapInitThreadCNode, 0x40000000, 3);
print_cnode(&initCte, 0);
LCD_CNode_Delete(LCD_CapInitThreadCNode, 0x00000000, 3);
print_cnode(&initCte, 0);
return 0;
}
static int __init hello_init(void)
{
printk(KERN_INFO "Hello world!\n");
capTask = kthread_run(thread_fn, NULL, "CapTest");
return 0; // Non-zero return means that the module couldn't be loaded.
}
static void __exit hello_cleanup(void)
{
printk(KERN_INFO "Cleaning up module.\n");
}
struct cte initCte; /* TODO: Copy this cte to TCB */
//////////////////////////External Interfaces////////////////////////////////////////////////////////////////////////////////
static int LCD_Create_CSpace(void)
{
/* Create CNode and put the capability to a slot in a TCB */
static struct capability *src_cap;
struct cte *objAddr;
struct cte *threadInitCte= NULL;
uint32_t size_bits = 4;
printk(KERN_INFO "LCD_Create_CSpace\n");
/* Create CNode for internal use*/
src_cap = &(initCte.cap);
objAddr = (struct cte*)kmalloc((1UL << size_bits)*sizeof(struct cte), GFP_KERNEL);
memset(src_cap, 0, sizeof(struct capability));
src_cap->type = ObjType_CNode;
src_cap->rights = CAPRIGHTS_ALLRIGHTS;
if (objAddr == 0)
{
printk(KERN_INFO "Fail to Alloc mem for initial CNode\n");
return 1;
}
memset(objAddr, 0, (1UL << size_bits)*sizeof(struct cte));
cnode_create_internal(src_cap, size_bits);
src_cap->u.cnode.cnode = objAddr;
src_cap->u.cnode.bits = size_bits;
src_cap->u.cnode.guard = 0;
src_cap->u.cnode.guard_size = 0;
/* Create CNode for user */
threadInitCte= caps_locate_slot(initCte.cap.u.cnode.cnode, LCD_CapInitThreadCNode);
src_cap = &(threadInitCte->cap);
size_bits= 3;
cnode_create_internal(src_cap, size_bits);
/* Make a CNode for Task */
printk(KERN_INFO "size of cte is: %ld\n", sizeof(struct cte));
printk(KERN_INFO "CSpace is created, InitCte is pointing: %p\n", objAddr);
LCD_Untyped_Retype(0, ObjType_CNode, 4, 0, 0, 0, LCD_CapInitThreadCNode, 1);
printk(KERN_INFO "CSpace is created\n");
print_cnode(&initCte, 0);
return 0;
}
int thread_fn(void* abc)
{
/* TODO: CSpace for the first thread should be created before it runs */
LCD_Create_CSpace();
//LCD_Untyped_Retype(LCD_Untyped _service, LCD_Type objType, int size_bits, LCD_CNode root, int node_index, int node_depth, int node_offset, int num_objects)
//Rights?
// LCD_Untyped_Retype(0, ObjType_CNode, 4, LCD_CapInitThreadCNode, 0x0, 4, 0, 0);
return 0;
}
static int __init hello_init(void)
{
printk(KERN_INFO "Hello world!\n");
capTask = kthread_run(thread_fn, NULL, "CapTest");
return 0; // Non-zero return means that the module couldn't be loaded.
}
/**
* \brief Create capabilities to kernel objects.
*
* This function creates kernel objects of 'type' into the memory
* area, based at 'addr' and of size 2^'bits', so they completely fill the
* area. For each created kernel object, a capability is created to it and
* put consecutively into the array of CTEs pointed to by 'caps'. The array
* needs to have the appropriate size to hold all created caps. Some kernel
* objects can have a variable size. In that case, 'objbits' should be non-zero
* and give the a size multiplier as 2^'objbits'.
*
* \param bits Size of memory area as 2^bits.
* \param dest_caps Pointer to array of CTEs to hold created caps.
*
* \return Error code
GFP_KERNEL
seL4_Untyped_Retype(
untyped_item,
item_type, item_size,
seL4_CapInitThreadCNode,
allocator->root_cnode, allocator->root_cnode_depth,
allocator->cslots.first + allocator->num_slots_used,
num_items);
*/
LCD_CPtr create_CNode(uint32_t objAddr, int size_bits, LCD_CPtr root, int node_index, int node_depth, int node_offset, int num_objects);
int caps_lookup_slot(struct capability * cap, LCD_CPtr cptr,
uint8_t vbits, struct cte **ret, CapRights rights);
/*
TODO: Implement CDT
return value: 0 if successful.
*/
int LCD_Untyped_Retype(LCD_Untyped _service, LCD_Type objType, int size_bits, LCD_CNode root, int node_index, int node_depth, int node_offset, int num_objects)
{
int returnVal = 0;
......@@ -121,12 +90,86 @@ int LCD_Untyped_Retype(LCD_Untyped _service, LCD_Type objType, int size_bits, LC
case ObjType_CNode:
create_CNode(_service, size_bits, root, node_index, node_depth, node_offset, num_objects);
break;
case ObjType_EndPoint:
create_EndPoint(_service, size_bits, root, node_index, node_depth, node_offset, num_objects);
break;
default:
break;
}
return returnVal;
}
static void *LCD_CNode_Search(LCD_CNode _service, int node_index, int node_depth)
{
struct cte *tempCte = NULL;
struct cte *rootCte= NULL;
rootCte = caps_locate_slot(initCte.cap.u.cnode.cnode, _service);
caps_lookup_slot(&rootCte->cap, node_index, node_depth, 0, &tempCte, CAPRIGHTS_ALLRIGHTS);
/* free alloced memory */
switch(tempCte->cap.type)
{
case ObjType_CNode:
return (void*)tempCte->cap.u.cnode.cnode;
break;
case ObjType_EndPoint:
return NULL;
break;
default:
return NULL;
break;
}
return NULL;
}
static int LCD_CNode_Delete(LCD_CNode _service, int node_index, int node_depth)
{
struct cte *tempCte = NULL;
struct cte *rootCte= NULL;
rootCte = caps_locate_slot(initCte.cap.u.cnode.cnode, _service);
caps_lookup_slot(&rootCte->cap, node_index, node_depth, 0, &tempCte, CAPRIGHTS_ALLRIGHTS);
/* free alloced memory */
switch(tempCte->cap.type)
{
case ObjType_CNode:
kfree(tempCte->cap.u.cnode.cnode);
break;
case ObjType_EndPoint:
break;
default:
break;
}
memset(tempCte, 0, sizeof(struct cte));
return 0;
}
////////////////////////Internal Functions///////////////////////////////////////////////////////////////////////////////////////////////
int cnode_create_internal(struct capability *src_cap, int size_bits)
{
struct cte *objAddr;
objAddr = (struct cte*)kmalloc((1UL << size_bits)*sizeof(struct cte), GFP_KERNEL);
if (objAddr == 0)
{
printk(KERN_INFO "Fail to Alloc mem for initial CNode\n");
return 1;
}
memset(objAddr, 0, (1UL << size_bits)*sizeof(struct cte));
memset(src_cap, 0, sizeof(struct capability));
src_cap->type = ObjType_CNode;
src_cap->rights = CAPRIGHTS_ALLRIGHTS;
src_cap->u.cnode.cnode = objAddr;
src_cap->u.cnode.bits = size_bits;
src_cap->u.cnode.guard = 0;
src_cap->u.cnode.guard_size = 0;
return 0;
}
LCD_CPtr create_CNode(LCD_Untyped _service, int size_bits, LCD_CNode root, int node_index, int node_depth, int node_offset, int num_objects)
{
/* Initialize the created capability */
......@@ -140,7 +183,7 @@ LCD_CPtr create_CNode(LCD_Untyped _service, int size_bits, LCD_CNode root, int n
src_cap.rights = CAPRIGHTS_ALLRIGHTS;
objAddr = (struct cte*)kmalloc((1UL << size_bits)*sizeof(struct cte), GFP_KERNEL);
memset(objAddr, 0, 1UL << size_bits*sizeof(struct cte));
memset(objAddr, 0, (1UL << size_bits)*sizeof(struct cte));
// Initialize type specific fields
src_cap.u.cnode.cnode = objAddr;
......@@ -148,20 +191,51 @@ LCD_CPtr create_CNode(LCD_Untyped _service, int size_bits, LCD_CNode root, int n
src_cap.u.cnode.guard = 0;
src_cap.u.cnode.guard_size = 0;
/* tempCte is pointing cnode*/
rootCte = caps_locate_slot(initCte.cap.u.cnode.cnode, root);
caps_lookup_slot (&rootCte->cap, node_index, node_depth, &tempCte, CAPRIGHTS_ALLRIGHTS);
caps_lookup_slot (&rootCte->cap, node_index, node_depth, 0, &tempCte, CAPRIGHTS_ALLRIGHTS);
/* tempCte is pointing the first element in the cnode*/
tempCte = tempCte->cap.u.cnode.cnode;
/* tempCte is pointing the right element in the cnode*/
tempCte = caps_locate_slot(tempCte, node_offset);
memcpy(&tempCte->cap, &src_cap, sizeof(struct capability));
return 0;
}
/*
* cnode_cap: CNode
* vbits: Remaining valid bits
*/
LCD_CPtr create_EndPoint(LCD_Untyped _service, int size_bits, LCD_CNode root, int node_index, int node_depth, int node_offset, int num_objects)
{
/* Initialize the created capability */
static struct capability src_cap;
struct cte *tempCte = NULL;
struct cte *rootCte= NULL;
struct cte *objAddr;
memset(&src_cap, 0, sizeof(struct capability));
src_cap.type = ObjType_EndPoint;
src_cap.rights = CAPRIGHTS_ALLRIGHTS;
objAddr = (struct cte*)kmalloc(100, GFP_KERNEL);
memset(objAddr, 0, 100);
/* tempCte is pointing cnode*/
rootCte = caps_locate_slot(initCte.cap.u.cnode.cnode, root);
caps_lookup_slot (&rootCte->cap, node_index, node_depth, 0, &tempCte, CAPRIGHTS_ALLRIGHTS);
/* tempCte is pointing the first element in the cnode*/
tempCte = tempCte->cap.u.cnode.cnode;
int caps_lookup_slot(struct capability *cnode_cap, LCD_CPtr cptr,
uint8_t vbits, struct cte **ret, CapRights rights)
/* tempCte is pointing the right element in the cnode*/
tempCte = caps_locate_slot(tempCte, node_offset);
memcpy(&tempCte->cap, &src_cap, sizeof(struct capability));
return 0;
}
int caps_lookup_slot(struct capability *cnode_cap, LCD_CPtr cptr, uint8_t vbits, uint8_t resolved_bits, struct cte **ret, CapRights rights)
{
uint8_t bits_resolved;
LCD_CPtr cptr_guard;
......@@ -169,12 +243,15 @@ int caps_lookup_slot(struct capability *cnode_cap, LCD_CPtr cptr,
struct cte *next_slot;
int bitsleft;
// If vbit == 0, it's initialization
// If vbit == 0, return root
if(vbits == 0) {
*ret = initCte.cap.u.cnode.cnode;
*ret = caps_locate_slot(initCte.cap.u.cnode.cnode, LCD_CapInitThreadCNode);
return 0;
}
printk("caps_lookup_slot: Cnode bits = %u, guard size = %u, valid bits = %u\n",
cnode_cap->u.cnode.bits, cnode_cap->u.cnode.guard_size,
vbits);
/* Can only resolve CNode type */
if (cnode_cap->type != ObjType_CNode) {
printk("caps_lookup_slot: Cap to lookup not of type CNode\n"
......@@ -214,7 +291,7 @@ int caps_lookup_slot(struct capability *cnode_cap, LCD_CPtr cptr,
/* Locate capability in this cnode */
// Offset into the cnode
offset = (cptr >> (vbits - bits_resolved)) &
offset = (cptr >> (32 - resolved_bits - bits_resolved)) &
MASK(cnode_cap->u.cnode.bits);
// The capability at the offset
next_slot = caps_locate_slot(cnode_cap->u.cnode.cnode, offset);
......@@ -239,7 +316,7 @@ int caps_lookup_slot(struct capability *cnode_cap, LCD_CPtr cptr,
}
/* Descend to next level */
return caps_lookup_slot(&next_slot->cap, cptr, bitsleft, ret, rights);
return caps_lookup_slot(&next_slot->cap, cptr, bitsleft, bits_resolved+resolved_bits, ret, rights);
}
struct cte * caps_locate_slot(struct cte * topCte, size_t offset)
......@@ -253,6 +330,7 @@ void print_cnode(struct cte * myCte, int depth)
struct capability * iterCap;
struct cte * iterCte;
int i = 0;
int j = 0;
int size = 0;
myCap = &myCte->cap;
......@@ -260,24 +338,26 @@ void print_cnode(struct cte * myCte, int depth)
{
printk(KERN_INFO "=========print_code start=========\n");
}
printk(KERN_INFO "Depth: %d::: Type: %d\n", depth, myCap->type);
if (myCap->type == ObjType_CNode)
{
size = myCap->u.cnode.bits;
size = (1UL<<size);
printk(KERN_INFO "CNode size: %d\n", size);
for (j = 0; j < depth; j++)
printk(" ");
printk("<CNode size: %d>\n", size);
for (i = 0 ; i < size; i++)
{
iterCte = caps_locate_slot(myCap->u.cnode.cnode, i);
iterCap = &iterCte->cap;
printk(KERN_INFO "Depth: %d::: Type: %d\n", depth+1, iterCap->type);
for (j = 0; j < depth; j++)
printk(" ");
printk("Depth: %d::: Type: %d\n", depth+1, iterCap->type);
if (iterCap->type == ObjType_CNode)
{
print_cnode(iterCte, depth+1);
}
}
/*
printk(KERN_INFO "One more depth start\n");
print_cnode(myCap->u.cnode.cnode, depth+1);
printk(KERN_INFO "One more depth end\n");
*/
}
if (depth == 0)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment