mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-29 10:08:53 +00:00
54ed373468
Unfortunately, another kernel patch is required for Genode/NOVA to get rid of global unique ids for objects (issue #268). Kernel patch: If a translate of a object capability item inside the same PD (receiver/sender in same PD) is not successful then he very same item is returned instead of the null item. Genode: Some code in Genode try to map/translate the "root" (the first instance of a) object capability within the same PD. The translate fails since it is the first cap and was not delegated beforehand. Instead the cap gets mapped to a new capability index due to xlt_rcv kernel item patch. The new local object capability index is used to lookup manged objects in lists, which however fails because the object is only known by the original object capability index. Unfortunately, this happens not only once. Below one example trace and description is attached. There are several possible solutions possible: * Find all places in Genode and replace normal function calls between objects with IPC calls, such that all capabilities can be translated during IPC. ** Time consuming to find all spots ** Rather platform specific issue requires re-adjustments in generic Genode code ** Not trivial to ever remember this fact during development of new components [other platforms have not such a issue, however have global object ids] ** Neither good in terms of performance. * Use some special system call to the kernel to be able to translate a given capability index as long until you find the requested original index. (Obviously ... no comment). * Kernel patch as this one. * <your proposal> Example trace + code description showing the behavior above: int main(): --- create local services --- int main(): --- start init --- [0] DEL OBJ PD:0xc000aa80->0xc000aa80 SB:0x000000aa RB:0x000000ac O:0x00 A:0x1f int main(): transferred 42 MB to init [0] DEL OBJ PD:0xc000aa80->0xc000aa80 SB:0x00000120 RB:0x0000013c O:0x00 A:0x1f [0] DEL OBJ PD:0xc000aa80->0xc000aa80 SB:0x0000016c RB:0x00000168 O:0x00 A:0x1f Setup ELF failed [0] XLT OBJ PD:0xc000aa80->0xc000aa80 SB:0x00000168 RB:0x0000016c O:0x00 unknown exception? int main(): --- init created, waiting for exit condition --- thread - file - line - text ------------------------------------------------------------------------------- thread A - [ 0] - 228 - new Core_child(... rom_session.dataspace() ...) thread A - [ 1] - 27 - IPC call - ask for dataspace cap thread B - [ 2] - 49 - function - return dataspace cap index 0x120 thread A - [ 1] - 27 - IPC returned - map 0x120 -> 0x13c, translate failed thread A - ... thread A - [ 3] - 231 - call _setup_elf() thread A - [ 3] - 60 - call env->rm_session()->attach() thread A - [ 4] - 35 - do dataspace object lookup (0x13c) thread A - [ 4] - 36 - lookup failed (object known as 0x120), throw Exception thread A - [ 3] - 61 - catch Exception -> return error code "0" thread A - [ 3] - 233 - "Setup ELF failed" - because error code "0" File legend: [0] base/src/core/main.cc [1] base/include/rom_session/client.h [2] base-nova/src/core/include/core_rm_session.h [3] base/src/base/process/process.cc [4] base-nova/src/core/core_rm_session.cc
26 lines
956 B
Diff
26 lines
956 B
Diff
diff --git a/src/pd.cpp b/src/pd.cpp
|
|
index 8160d73..be6fd41 100644
|
|
--- a/src/pd.cpp
|
|
+++ b/src/pd.cpp
|
|
@@ -167,6 +167,20 @@ void Pd::xlt_crd (Pd *pd, Crd xlt, Crd &crd)
|
|
if ((ro = clamp (node->node_base, rb, node->node_order, ro)) != ~0UL)
|
|
break;
|
|
|
|
+ if (!node) {
|
|
+ /* Special handling on Genode:
|
|
+ * If a translate of an item inside the same PD (receiver/sender in same PD)
|
|
+ * are of no success, then return the very same item.
|
|
+ */
|
|
+ Mdb *first = snd->tree_lookup (crd.base());
|
|
+ if (first && first->space == rcv && first == mdb) {
|
|
+ rb = xlt.base();
|
|
+ ro = xlt.order();
|
|
+ if ((ro = clamp (first->node_base, rb, first->node_order, ro)) != ~0UL)
|
|
+ node = first;
|
|
+ }
|
|
+ }
|
|
+
|
|
if (node) {
|
|
|
|
so = clamp (mdb->node_base, sb, mdb->node_order, so);
|