genode/base-nova/patches/xlt_rcv.patch
Alexander Boettcher 54ed373468 NOVA: translate item patch, issue #268
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
2012-08-09 10:24:00 +02:00

49 lines
1.4 KiB
Diff

diff --git a/src/pd.cpp b/src/pd.cpp
index 8160d73..be9aa63 100644
--- a/src/pd.cpp
+++ b/src/pd.cpp
@@ -173,6 +173,7 @@ void Pd::xlt_crd (Pd *pd, Crd xlt, Crd &crd)
sb = (sb - mdb->node_base) + (mdb->node_phys - node->node_phys) + node->node_base;
if ((ro = clamp (sb, rb, so, ro)) != ~0UL) {
+ trace (TRACE_DEL, "XLT OBJ PD:%p->%p SB:%#010lx RB:%#010lx O:%#04lx", pd, this, crd.base(), rb, so);
crd = Crd (crd.type(), rb, ro, mdb->node_attr);
return;
}
@@ -245,22 +246,32 @@ void Pd::rev_crd (Crd crd, bool self)
void Pd::xfer_items (Pd *src, Crd xlt, Crd del, Xfer *s, Xfer *d, unsigned long ti)
{
- for (Crd crd; ti--; s--) {
+ mword set_as_del;
+ for (Crd crd; ti--; s--) {
+
crd = *s;
+ set_as_del = 0;
- switch (s->flags() & 1) {
+ switch (s->flags() & 3) {
case 0:
xlt_crd (src, xlt, crd);
break;
+ case 2:
+ xlt_crd (src, xlt, crd);
+ if (crd.type()) break;
+
+ crd = *s;
+ set_as_del = 1;
+
case 1:
del_crd (src == &root && s->flags() & 0x800 ? &kern : src, del, crd, s->flags() >> 9 & 3, s->hotspot());
break;
};
if (d)
- *d-- = Xfer (crd, s->flags());
+ *d-- = Xfer (crd, s->flags() | set_as_del);
}
}