Commit c6d4015f authored by Pankaj Kumar's avatar Pankaj Kumar

Add hook to lookup/verify cnode in cspace

1. Added a function cap_cnode_verify for cnodes lookup in cspace.
   Earlier cap_cnode_get was called to verify the cnode. It imposed
   extra restrictions on the user of libcap to release cnode lock.
   Now, cap_cnode_verify will itself take care of cnode lock.
2. Updated testcases to use cap_cnode_verify.
Signed-off-by: Pankaj Kumar's avatarPankaj Kumar <pankajk@cs.utah.edu>
parent 43d24e14
Pipeline #100 passed with stage
......@@ -140,19 +140,14 @@ int cap_revoke(struct cspace *cspace, cptr_t c);
*/
void cap_destroy_cspace(struct cspace *cspace);
/**
* Looks up and locks cnode at c in cspace.
* Looks up cnode at cap in cspace.
*
* ** Must match with lcd_cnode_put. **
* ** Frees the cnode lock itself without relying on user.
*
* ** Interrupts and preemption *are not* disabled. **
* (so we can easily get out of deadlocks while debugging)
*/
int cap_cnode_get(struct cspace *cspace, cptr_t cap, struct cnode **cnode);
/**
* Unlocks cnode.
*/
void cap_cnode_put(struct cnode *c);
int cap_cnode_verify(struct cspace *cspace, cptr_t cap);
/**
* For now, put debug macros in the user-accessible part; convenient.
*/
......
......@@ -438,6 +438,18 @@ void cap_cnode_put(struct cnode *cnode)
cap_mutex_unlock(&cnode->lock);
}
int cap_cnode_verify(struct cspace *cspace, cptr_t c)
{
struct cnode *cnode;
int ret;
ret = cap_cnode_get(cspace, c, &cnode);
if (ret == 0)
cap_cnode_put(cnode);
return ret;
}
int cap_insert(struct cspace *cspace, cptr_t c, void *object, cap_type_t type)
{
struct cnode *cnode;
......
......@@ -41,12 +41,9 @@ int testcase1()
{
int ret = 0;
struct cspace *csp;
struct cnode *cnode;
cptr_t slot_out, slot_out_orig;
struct cptr_cache *cache;
char *p;
struct cnode *check;
struct cnode *check1;
/* Initialize a cspace */
csp = malloc(1 * sizeof(*csp));
......@@ -78,18 +75,12 @@ int testcase1()
}
/* Verification if capability is properly inserted in the cspace. */
ret = cap_cnode_get(csp, slot_out, &check);
ret = cap_cnode_verify(csp, slot_out);
if (ret < 0) {
CAP_ERR("Lookup failed");
goto fail;
} else {
if (check->object == p)
printf("Capability Addition & Lookup Passed\n");
else
printf("Capability Addition & Lookup Failed!!!\n");
}
/* Release cnode Lock */
cap_cnode_put(check);
} else
printf("Capability Addition & Lookup Passed\n");
/* Capability deletion from cspace.
*/
......@@ -98,19 +89,11 @@ int testcase1()
/*Lookup after deleting capability. It should Fail!!
*/
ret = cap_cnode_get(csp, slot_out, &check1);
ret = cap_cnode_verify(csp, slot_out);
if (ret < 0) {
CAP_ERR("Lookup failed\n");
printf("Capability Deletion Passed\n");
} else {
if (check1->object == p)
printf("Screwed!!!\n");
else
printf("Yippiee!!!\n");
}
/* Release cnode Lock */
if (check1)
cap_cnode_put(check1);
/* Free the cspace
* Here we will destory the cspace.
......@@ -143,12 +126,9 @@ int testcase_grant()
{
int ret;
struct cspace *scsp, *dcsp;
struct cnode *cnode;
cptr_t sslot, dslot;
struct cptr_cache *scache, *dcache;
char *p;
struct cnode *scnode;
struct cnode *dcnode;
/* Initialize Source cspace */
scsp = malloc(1 * sizeof(*scsp));
......@@ -207,20 +187,15 @@ int testcase_grant()
goto fail2;
}
ret = cap_cnode_get(dcsp, dslot, &dcnode);
ret = cap_cnode_verify(dcsp, dslot);
if (ret < 0) {
CAP_ERR("Lookup failed\n");
goto fail2;
} else {
if (dcnode->object == p) {
printf("Capability granted successfully from Cspace[%p] at slot 0x%lx \
to Cspace[%p] at slot 0x%lx\n", scsp, cptr_val(sslot),
dcsp, cptr_val(dslot));
} else
printf("Failed to grant capability!!\n");
printf("Capability granted successfully from Cspace[%p] at slot 0x%lx \
to Cspace[%p] at slot 0x%lx\n", scsp, cptr_val(sslot),
dcsp, cptr_val(dslot));
}
/* Release cnode Lock */
cap_cnode_put(dcnode);
fail2:
cap_destroy_cspace(dcsp);
......@@ -272,13 +247,11 @@ int grant(struct cspace *scsp, struct cspace *dcsp, cptr_t sslot, cptr_t dslot)
*/
int get_cnode(struct cspace *csp, cptr_t sslot) {
int ret = 0;
struct cnode *dcnode;
ret = cap_cnode_get(csp, sslot, &dcnode);
ret = cap_cnode_verify(csp, sslot);
if (ret < 0)
CAP_ERR("Destination CSPACE Lookup failed\n");
/* Release cnode Lock */
cap_cnode_put(dcnode);
return ret;
}
......@@ -308,7 +281,6 @@ int testcase_revoke() {
struct cspace *scsp, *dcsp;
struct cptr_cache *scache, *dcache;
cptr_t sslot, dslot;
struct cnode *scnode = NULL;
printf("\nTestcase : Capability Revocation\n");
/* 1st CSPACE */
......@@ -365,10 +337,9 @@ int testcase_revoke() {
ret = revoke(scsp, sslot, scache);
if (ret < 0)
goto fail2;
ret = cap_cnode_get(dcsp, dslot, &scnode);
ret = cap_cnode_verify(dcsp, dslot);
if (ret < 0) {
printf("\nTestcase Capability Revocation Passed\n");
ret = 0;
goto fail2;
}
printf("\nTestcase capability Revocation Failed\n");
......
......@@ -11,8 +11,8 @@
* Accessing cspace by multiple threads [Done]
* Accessing cptr cache by multiple threads [Done]
* capability insertion by multiple threads [Done]
* Grant [Todo]
* Revoke [Todo]
* Grant [Done]
* Revoke [Done]
*
* Test execution:
* ./<obj>/test/user/multi_thrd_cap
......@@ -166,8 +166,6 @@ void *thread_revoke(void* arg)
if (ret < 0)
printf("Revoke failed\n");
cap_delete(scsp, sslot_arr[i]);
if (ret < 0)
printf("Delete failed\n");
cptr_free(scache, sslot_arr[i]);
sslot_arr[i] = CAP_CPTR_NULL;
......@@ -222,7 +220,6 @@ void *thread_get(void * arg) {
n = THREAD_COUNT - 4;
while (i < n) {
struct cnode *dcnode;
if (cptr_is_null(dslot_arr[i])) {
printf("Thread Get : null cptr slot %d, stalling...\n",
i);
......@@ -232,14 +229,11 @@ void *thread_get(void * arg) {
printf("Thread Get : unstalled cptr slot %d\n",
i);
}
ret = cap_cnode_get(dcsp, dslot_arr[i], &dcnode);
if (ret < 0) {
ret = cap_cnode_verify(dcsp, dslot_arr[i]);
if (ret < 0)
CAP_ERR("Destination CSPACE Lookup failed\n");
} else {
else
printf("Lookup PASS\n");
/* Release cnode Lock */
cap_cnode_put(dcnode);
}
i++;
}
}
......
Markdown is supported
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