Capability mapping

Stefan Kalkowski stefan.kalkowski at ...1...
Mon Jan 7 10:10:42 CET 2013

Hi Daniel,

sorry for my late response.

On 01/04/2013 12:52 AM, Daniel Waddington wrote:
> Hi Stefan,
> Ahhh, I see. I always wondered about message registers vs. buffer
> registers in the UTCB ;-).  To close the loop do you happen to know
> where in the Fiasco.OC kernel this implicit capability mapping is performed?

without having validated that, I guess it's probably this trace:

Thread::do_ipc -> src/kern/thread-ipc.cpp:422
Thread::transfer_msg -> src/kern/thread-ipc.cpp:578
Thread::copy_utcb_to -> src/kern/thread-ipc.cpp:829
Thread::copy_utcb_to_utcb -> src/kern/thread-ipc.cpp:803
Thread::transfer_msg_items -> src/kern/thread-ipc.cpp:844
fpage_map -> src/kern/map_util.cpp:300

> Thanks for your enlightenment as always.

You're welcome.


> Daniel
> On 01/03/2013 01:44 AM, Stefan Kalkowski wrote:
>> Hi Daniel,
>> On 01/02/2013 08:58 PM, Daniel Waddington wrote:
>>> Hi Norman, a few more follow up questions in line..
>>> On 12/23/2012 11:04 AM, Norman Feske wrote:
>>>> I'd like to better understand the capability mapping support in Genode.
>>>> Is there a generalized mechanism (beyond RPC endpoint mapping) for a
>>>> parent to map capabilities (e.g., Dataspace) between two child processes?
>>>> capabilities are not limited to session interfaces but can refer to any
>>>> kind of object. For example, each dataspaces allocated from a RAM
>>>> session is referenced by a capability, or each PCI device returned by
>>>> the PCI session interface is represented as a capability, or a nitpicker
>>>> view created via a nitpicker session is one. These capabilities can be
>>>> delegated via arbitrary RPC calls. The parent does not play a special
>>>> role here.
>>> But "under the hood" does the Genode core perform the l4 map system
>>> call?  If so can you point me to the code in core?  I want to understand
>>> how Genode interacts with the Fiasco.OC kernel.
>> Core isn't involved in general to transfer a capability from one side to
>> the other. As you probably know: we use C++ streaming operators to put
>> arguments into IPC message buffers, or get them out of it. When using
>> Fiasco.OC, the streaming operators of 'Capability' objects are
>> overloaded. Have a look at:
>>   base-foc/include/base/ipc.h
>> The 'local_name()' of the capability is transferred as a regular value.
>> But the index in the capability name space of the corresponding task is
>> added explicitly to the message buffer as a special value. When
>> preparing the IPC syscall, we setup flex-pages for each capability that
>> has to be transferred. These flex-pages are part of the UTCB, and get
>> analyzed by the kernel after the IPC syscall was done. Look at:
>>   base-foc/src/base/ipc/
>> To sum it up, we do not use a 'l4_task_map' syscall to transfer
>> capabilities when they are exchanged via explicit messages.
>>>>> Can a process (e.g., client) map a capability into another capability? 
>>>>> I am wondering how the packet_stream interface establishes shared memory
>>>>> e.g., for channels.
>>>> Would you mind me throwing another sequence diagram in your direction?
>>>> ;-) The attached diagram illustrates the way shared memory gets
>>>> established in Genode.
>>>> First, the server allocates a dataspace from core's RAM service (or
>>>> another provider of dataspaces). At allocation time, the dataspace's
>>>> backing store gets reserved in core. The server receives a dataspace
>>>> capability in return of the alloc-RPC-call. This capability can then be
>>>> used to make the dataspace visible in the server's address space using
>>>> core's RM service. As the second step, the server delegates the
>>>> dataspace capability to the client as RPC payload (usually as a return
>>>> value of a RPC function). 
>>> So the capability identifier in the RPC payload does not have any
>>> special marshalling/unmarshalling it's just a value?
>>> In your example is 'delegate' just some arbitrary interface method?
>> I hope this is clarified via the explanations above?
>>>> After the delegation, both server and client
>>>> have a capability referring to the same physical dataspace. Now, the
>>>> client is able to also use core's RM session to make the same dataspace
>>>> visible in its local address space. But only the server is able to
>>>> destroy it (because it has both the dataspace capability and the RAM
>>>> session capability that was used to allocate the dataspace)
>>>> This procedure is performed by all users of the packet-stream interface,
>>>> for example the 'Nic::Session' interface. There are two possible uses of
>>>> the packet stream interface, which are the transmission of bulk data to
>>>> the server (represented by the packet_stream_tx RPC interface) and the
>>>> reception of bulk data from the server (represented by the
>>>> packet_stream_rx RPC interface). The 'Nic::Session' is bi-directional.
>>>> Hence, it aggregates two instances of the packet-stream interface.
>>>>> I guess I am looking for something equivalent to L4Re
>>>>> l4re_ns_query_to_srv
>>>>> <>
>>>>> and l4re_ns_query_to_srv
>>>>> <>
>>>>> APIs.
>>>> There is currently no generic way to publish capabilities at a central
>>>> registry and looking them up. Thanks to Genode's session mechanism, we
>>>> haven't had the need for such a feature yet. Generally speaking, such a
>>>> feature could be implemented as a service providing the registering and
>>>> lookup functionalities via a session interface. Parents could then
>>>> instantiate as many instances of this service as desired whereas each
>>>> instance would represent a separate namespace
>>>> Could you please briefly explain your intention behind this inquiry?
>>>> Maybe there is an solution to your problem that does not need a new
>>>> interface?
>>> I am trying to get my head around the Genode capability model which
>>> seems quite different from the L4Re capability model.  I think the
>>> essence of the Genode solution is to hide the mapping between Genode
>>> caps and OS-specific caps in Genode's core, and have this core process
>>> perform the mapping w.r.t. calling the kernel.
>>> Apologies if I am totally missing the point.
>> As already said: in general, the delegation of capabilities between
>> processes is done without the help of core. We simply use the kernel's
>> IPC mechanism for that. Nevertheless, there are some capabilities in a
>> process that are managed by core. These capabilities are somehow
>> special, e.g. the pager capability of a thread, or its task capability.
>> These capabilities are needed by a new born thread in order to be able
>> to do at least IPC calls to other ones. That's why these capabilities
>> are transferred by core via the 'l4_task_map' syscall just before a new
>> thread gets executed.
>> I hope this helps to clarify your questions. Happy new year ;-)
>> Stefan
>>> Daniel
>>> ------------------------------------------------------------------------------
>>> Master Java SE, Java EE, Eclipse, Spring, Hibernate, JavaScript, jQuery
>>> and much more. Keep your Java skills current with LearnJavaNow -
>>> 200+ hours of step-by-step video tutorials by Java experts.
>>> SALE $49.99 this month only -- learn more at:
>>> _______________________________________________
>>> Genode-main mailing list
>>> Genode-main at
> ------------------------------------------------------------------------------
> Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
> MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
> with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
> MVPs and experts. ON SALE this month only -- learn more at:
> _______________________________________________
> Genode-main mailing list
> Genode-main at

Stefan Kalkowski
Genode Labs ยท

More information about the users mailing list