mirror of
https://github.com/drasko/codezero.git
synced 2026-03-16 01:01:50 +01:00
Implemented a protocol between client and pager for requesting caps.
In posix, test0 makes inter-space ipc for testing extended ipc. This correctly fails when only the cap to ipc to pager is given to all tasks in the container. In order to overcome this problem, the tasks who fork for doing ipc to each other make a request to the pager to get capabilities to do so. Pager finds its own widened ipc capability over the container, replicates it, validates and reduces it to desired boundaries (i.e. just ipc betw. two spaces) and grants it as IMMUTABLE to requesting tasks. This protocol may be useful in implementing a client/server capability request relationship. Code builds but untested.
This commit is contained in:
@@ -10,6 +10,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <tests.h>
|
||||
#include <l4/api/capability.h>
|
||||
#include <l4/generic/cap-types.h>
|
||||
#include <l4lib/capability.h>
|
||||
|
||||
/*
|
||||
* Full ipc test. Sends/receives full utcb, done with the pager.
|
||||
@@ -45,16 +48,39 @@ void ipc_full_test(void)
|
||||
printf("FULL IPC TEST: -- FAILED --\n");
|
||||
}
|
||||
|
||||
int cap_request_pager(struct capability *cap)
|
||||
{
|
||||
int err;
|
||||
|
||||
write_mr(L4SYS_ARG0, (u32)cap);
|
||||
|
||||
if ((err = l4_sendrecv(pagerid, pagerid,
|
||||
L4_REQUEST_CAPABILITY)) < 0) {
|
||||
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Check if syscall itself was successful */
|
||||
if ((err = l4_get_retval()) < 0) {
|
||||
printf("%s: Error: %d\n", __FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is an extended ipc test that is done between 2 tasks that fork.
|
||||
*/
|
||||
void ipc_extended_test(void)
|
||||
{
|
||||
pid_t child, parent;
|
||||
struct capability cap;
|
||||
void *base;
|
||||
char *ipcbuf;
|
||||
int err;
|
||||
|
||||
memset(&cap, 0, sizeof(cap));
|
||||
|
||||
/* Get parent pid */
|
||||
parent = getpid();
|
||||
|
||||
@@ -71,6 +97,25 @@ void ipc_extended_test(void)
|
||||
/* This test makes this assumption */
|
||||
BUG_ON(L4_IPC_EXTENDED_MAX_SIZE > PAGE_SIZE);
|
||||
|
||||
/*
|
||||
* Request capability to ipc to each other from pager
|
||||
* (Actually only the sender needs it)
|
||||
*/
|
||||
if (child) {
|
||||
cap.owner = parent;
|
||||
cap.resid = child;
|
||||
} else {
|
||||
cap.owner = child;
|
||||
cap.resid = parent;
|
||||
}
|
||||
cap.type = CAP_TYPE_IPC | CAP_RTYPE_THREAD;
|
||||
cap.access = CAP_IPC_EXTENDED;
|
||||
if ((err = cap_request_pager(&cap)) < 0) {
|
||||
printf("Ipc capability request failed. "
|
||||
"err = %d\n", err);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Both child and parent gets 2 pages
|
||||
* of privately mapped anonymous memory
|
||||
|
||||
Reference in New Issue
Block a user