mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 00:24:51 +00:00
parent
bee0e11049
commit
b2a8cfde85
11
repos/base-sel4/patches/noise.patch
Normal file
11
repos/base-sel4/patches/noise.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- src/kernel/sel4/src/api/syscall.c
|
||||
+++ src/kernel/sel4/src/api/syscall.c
|
||||
@@ -325,7 +325,7 @@ handleReply(void)
|
||||
}
|
||||
|
||||
case cap_null_cap:
|
||||
- userError("Attempted reply operation when no reply cap present.");
|
||||
+// userError("Attempted reply operation when no reply cap present.");
|
||||
return;
|
||||
|
||||
default:
|
@ -1 +1 @@
|
||||
c8947bc79b1c29d570be6ad917c8310bc79d39e1
|
||||
fa69a91f3d2a79383ec72c8a52ac78ddc68becd5
|
||||
|
@ -110,13 +110,6 @@ static seL4_MessageInfo_t new_seL4_message(Msgbuf_base const &msg)
|
||||
for (size_t i = msg.used_caps(); i < Msgbuf_base::MAX_CAPS_PER_MSG; i++)
|
||||
seL4_SetMR(MR_IDX_CAPS + i, Rpc_obj_key::INVALID);
|
||||
|
||||
/*
|
||||
* Allocate and define receive selector
|
||||
*/
|
||||
|
||||
if (!rcv_sel())
|
||||
rcv_sel() = Capability_space::alloc_rcv_sel();
|
||||
|
||||
/*
|
||||
* Supply data payload
|
||||
*/
|
||||
@ -140,16 +133,64 @@ static seL4_MessageInfo_t new_seL4_message(Msgbuf_base const &msg)
|
||||
static void decode_seL4_message(seL4_MessageInfo_t const &msg_info,
|
||||
Msgbuf_base &dst_msg)
|
||||
{
|
||||
/*
|
||||
* Extract Genode capabilities from seL4 IPC message
|
||||
/**
|
||||
* Read all required data from seL4 IPC message
|
||||
*
|
||||
* You must not use any Genode primitives which may corrupt the IPCBuffer
|
||||
* during this step, e.g. Lock or RPC for output !!!
|
||||
*/
|
||||
dst_msg.reset();
|
||||
size_t const num_caps = seL4_GetMR(MR_IDX_NUM_CAPS);
|
||||
size_t curr_sel4_cap_idx = 0;
|
||||
size_t const num_caps = min(seL4_GetMR(MR_IDX_NUM_CAPS), Msgbuf_base::MAX_CAPS_PER_MSG);
|
||||
uint32_t const caps_extra = seL4_MessageInfo_get_extraCaps(msg_info);
|
||||
uint32_t const caps_unwrapped = seL4_MessageInfo_get_capsUnwrapped(msg_info);
|
||||
uint32_t const num_msg_words = seL4_MessageInfo_get_length(msg_info);
|
||||
|
||||
Rpc_obj_key rpc_obj_keys[Msgbuf_base::MAX_CAPS_PER_MSG];
|
||||
unsigned long arg_badges[Msgbuf_base::MAX_CAPS_PER_MSG];
|
||||
|
||||
for (size_t i = 0; i < num_caps; i++) {
|
||||
rpc_obj_keys[i] = Rpc_obj_key(seL4_GetMR(MR_IDX_CAPS + i));
|
||||
if (!rpc_obj_keys[i].valid())
|
||||
/*
|
||||
* If rpc_obj_key is invalid, avoid calling
|
||||
* seL4_CapData_Badge_get_Badge. It may trigger a assertion if
|
||||
* the lowest bit is set by the garbage badge value we got.
|
||||
*/
|
||||
arg_badges[i] = Rpc_obj_key::INVALID;
|
||||
else
|
||||
arg_badges[i] = seL4_CapData_Badge_get_Badge(seL4_GetBadge(i));
|
||||
}
|
||||
|
||||
Rpc_obj_key const rpc_obj_key(seL4_GetMR(MR_IDX_CAPS + i));
|
||||
/**
|
||||
* Extract message data payload
|
||||
*/
|
||||
|
||||
/* detect malformed message with too small header */
|
||||
if (num_msg_words >= MR_IDX_DATA) {
|
||||
|
||||
/* copy data payload */
|
||||
size_t const max_words = dst_msg.capacity()/sizeof(umword_t);
|
||||
size_t const num_data_words = min(num_msg_words - MR_IDX_DATA, max_words);
|
||||
|
||||
umword_t *dst = (umword_t *)dst_msg.data();
|
||||
for (size_t i = 0; i < num_data_words; i++)
|
||||
*dst++ = seL4_GetMR(MR_IDX_DATA + i);
|
||||
|
||||
dst_msg.data_size(num_data_words*sizeof(umword_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Now we got all data from the IPCBuffer, we may use Native_capability
|
||||
*/
|
||||
|
||||
/**
|
||||
* Construct Genode capabilities from read seL4 IPC message stored in
|
||||
* rpc_opj_keys and arg_badges.
|
||||
*/
|
||||
|
||||
size_t curr_sel4_cap_idx = 0;
|
||||
for (size_t i = 0; i < num_caps; i++) {
|
||||
|
||||
Rpc_obj_key const rpc_obj_key = rpc_obj_keys[i];
|
||||
|
||||
/*
|
||||
* Detect passing of invalid capabilities as arguments
|
||||
@ -166,7 +207,7 @@ static void decode_seL4_message(seL4_MessageInfo_t const &msg_info,
|
||||
* denote a valid capability that is not an RPC-object capability.
|
||||
* Hence it is meaningless as a key.
|
||||
*/
|
||||
if (!rpc_obj_key.valid() && seL4_MessageInfo_get_extraCaps(msg_info) == 0) {
|
||||
if (!rpc_obj_key.valid() && caps_extra == 0) {
|
||||
dst_msg.insert(Native_capability());
|
||||
continue;
|
||||
}
|
||||
@ -175,9 +216,7 @@ static void decode_seL4_message(seL4_MessageInfo_t const &msg_info,
|
||||
* RPC object key as contained in the message data is valid.
|
||||
*/
|
||||
|
||||
unsigned const unwrapped =
|
||||
seL4_MessageInfo_get_capsUnwrapped(msg_info) &
|
||||
(1 << curr_sel4_cap_idx);
|
||||
bool const unwrapped = caps_unwrapped & (1U << curr_sel4_cap_idx);
|
||||
|
||||
/* distinguish unwrapped from delegated cap */
|
||||
if (unwrapped) {
|
||||
@ -189,8 +228,8 @@ static void decode_seL4_message(seL4_MessageInfo_t const &msg_info,
|
||||
* So it is already present within the capability space.
|
||||
*/
|
||||
|
||||
unsigned long const arg_badge =
|
||||
seL4_CapData_Badge_get_Badge(seL4_GetBadge(curr_sel4_cap_idx));
|
||||
ASSERT(curr_sel4_cap_idx < Msgbuf_base::MAX_CAPS_PER_MSG);
|
||||
unsigned long const arg_badge = arg_badges[curr_sel4_cap_idx];
|
||||
|
||||
if (arg_badge != rpc_obj_key.value()) {
|
||||
warning("argument badge (", arg_badge, ") != RPC object key (",
|
||||
@ -219,7 +258,7 @@ static void decode_seL4_message(seL4_MessageInfo_t const &msg_info,
|
||||
* badge mechanism is not in effect.
|
||||
*/
|
||||
|
||||
bool const delegated = seL4_MessageInfo_get_extraCaps(msg_info);
|
||||
bool const delegated = caps_extra;
|
||||
|
||||
ASSERT(delegated);
|
||||
|
||||
@ -256,26 +295,6 @@ static void decode_seL4_message(seL4_MessageInfo_t const &msg_info,
|
||||
}
|
||||
curr_sel4_cap_idx++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract message data payload
|
||||
*/
|
||||
|
||||
size_t const num_msg_words = seL4_MessageInfo_get_length(msg_info);
|
||||
|
||||
/* detect malformed message with too small header */
|
||||
if (num_msg_words < MR_IDX_DATA)
|
||||
return;
|
||||
|
||||
/* copy data payload */
|
||||
size_t const max_words = dst_msg.capacity()/sizeof(umword_t);
|
||||
size_t const num_data_words = min(num_msg_words - MR_IDX_DATA, max_words);
|
||||
|
||||
umword_t *dst = (umword_t *)dst_msg.data();
|
||||
for (size_t i = 0; i < num_data_words; i++)
|
||||
*dst++ = seL4_GetMR(MR_IDX_DATA + i);
|
||||
|
||||
dst_msg.data_size(num_data_words*sizeof(umword_t));
|
||||
}
|
||||
|
||||
|
||||
@ -292,19 +311,26 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst,
|
||||
kernel_debugger_panic("IPC destination is invalid");
|
||||
}
|
||||
|
||||
/* allocate and define receive selector */
|
||||
if (!rcv_sel())
|
||||
rcv_sel() = Capability_space::alloc_rcv_sel();
|
||||
|
||||
seL4_MessageInfo_t const request_msg_info = new_seL4_message(snd_msg);
|
||||
rcv_msg.reset();
|
||||
|
||||
unsigned const dst_sel = Capability_space::ipc_cap_data(dst).sel.value();
|
||||
|
||||
seL4_MessageInfo_t const reply_msg_info =
|
||||
seL4_Call(dst_sel, request_msg_info);
|
||||
/**
|
||||
* Do not use Genode primitives after this point until the return which may
|
||||
* alter the content of the IPCBuffer, e.g. Lock or RPC.
|
||||
*/
|
||||
|
||||
seL4_MessageInfo_t const request = new_seL4_message(snd_msg);
|
||||
seL4_MessageInfo_t const reply_msg_info = seL4_Call(dst_sel, request);
|
||||
Rpc_exception_code const exc_code(seL4_GetMR(MR_IDX_EXC_CODE));
|
||||
|
||||
decode_seL4_message(reply_msg_info, rcv_msg);
|
||||
|
||||
return Rpc_exception_code(seL4_GetMR(MR_IDX_EXC_CODE));
|
||||
return exc_code;
|
||||
}
|
||||
|
||||
|
||||
@ -315,6 +341,15 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst,
|
||||
void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc,
|
||||
Msgbuf_base &snd_msg)
|
||||
{
|
||||
/* allocate and define receive selector */
|
||||
if (!rcv_sel())
|
||||
rcv_sel() = Capability_space::alloc_rcv_sel();
|
||||
|
||||
/**
|
||||
* Do not use Genode primitives after this point until the return which may
|
||||
* alter the content of the IPCBuffer, e.g. Lock or RPC.
|
||||
*/
|
||||
|
||||
/* called when entrypoint thread leaves entry loop and exits */
|
||||
seL4_MessageInfo_t const reply_msg_info = new_seL4_message(snd_msg);
|
||||
seL4_SetMR(MR_IDX_EXC_CODE, exc.value);
|
||||
@ -328,30 +363,28 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller,
|
||||
Msgbuf_base &reply_msg,
|
||||
Msgbuf_base &request_msg)
|
||||
{
|
||||
/* allocate and define receive selector */
|
||||
if (!rcv_sel())
|
||||
rcv_sel() = Capability_space::alloc_rcv_sel();
|
||||
|
||||
seL4_CPtr const dest = Thread::myself()->native_thread().ep_sel;
|
||||
seL4_Word badge = 0;
|
||||
|
||||
if (exc.value == Rpc_exception_code::INVALID_OBJECT) {
|
||||
if (exc.value == Rpc_exception_code::INVALID_OBJECT)
|
||||
reply_msg.reset();
|
||||
|
||||
seL4_MessageInfo_t const request_msg_info =
|
||||
seL4_Recv(Thread::myself()->native_thread().ep_sel, &badge);
|
||||
request_msg.reset();
|
||||
|
||||
decode_seL4_message(request_msg_info, request_msg);
|
||||
|
||||
} else {
|
||||
/**
|
||||
* Do not use Genode primitives after this point until the return which may
|
||||
* alter the content of the IPCBuffer, e.g. Lock or RPC.
|
||||
*/
|
||||
|
||||
seL4_MessageInfo_t const reply_msg_info = new_seL4_message(reply_msg);
|
||||
|
||||
seL4_SetMR(MR_IDX_EXC_CODE, exc.value);
|
||||
seL4_MessageInfo_t const req = seL4_ReplyRecv(dest, reply_msg_info, &badge);
|
||||
|
||||
seL4_MessageInfo_t const request_msg_info =
|
||||
seL4_ReplyRecv(Thread::myself()->native_thread().ep_sel,
|
||||
reply_msg_info, &badge);
|
||||
|
||||
decode_seL4_message(request_msg_info, request_msg);
|
||||
}
|
||||
decode_seL4_message(req, request_msg);
|
||||
|
||||
return Rpc_request(Native_capability(), badge);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user