Confusion about global and local names/ids of capability in the source code

Stefan Kalkowski stefan.kalkowski at ...1...
Fri Nov 9 13:00:03 CET 2012


Hi Jaeyong,

Am 09.11.2012 03:46, schrieb jaeyong yoo:
> Hello,
> 
> I was reading the codes about capabilities, and I found this, which is
> suspected as a conflict in my understanding.
> 
> 1)  In Cap_index class, we have an id, which is commented as global
> capability id:
> 
>     class Cap_index {
>         ...blah
>         uint16_t _id;      /* global capability id */
>         ...blah
>     };
> 
> 2) But in Native_capability class, there is something like this:
> 
>     class Native_capability {
>         ...blah
>         int   local_name() const { return _idx ? _idx->id() : 0;}
>         ...blah
>     };
> 
> here, the id of Cap_index (i.e., commented as global capability id) is
> returned as local_name.
> I think it is a conflict or do I miss something?
> Please enlighten me about this.

I have to go back a bit further to explain this.

In capability based systems, global names don't exist any more. Every
protection domain has its own names for objects. Therefore, the generic
interface of a "Native_capability" in Genode contains the "local_name()"
accessor.

But, most kernels don't implement capability mechanisms at all, or
insufficiently for our framework's needs. Although Fiasco.OC implements
a capability mechanism, it's missing an important feature:
Every protection domain has to manage its capability name space by
itself. When a thread wants to receive capabilities, it has to allocate
free slots in the capability space of its protection domain beforehand.
Before issuing a receive syscall, it prepares a message descriptor for
the kernel that contains the previously allocated capability slots. Now,
if the thread receives capabilities via IPC, they should end up in the
allocated slots. But, there is no manageable way to identify capability
duplicates received via IPC. Using the kernel primitives only, we cannot
detect, whether a received capability references an object that is
already referenced by a previously existent capability in the same
protection domain.

But, the facility to detect capability duplicates is crucial for us. For
example, capability slots are rapidly exhausted when using signals in
Genode. Have a look at issue #112 in our issue tracker:

  https://github.com/genodelabs/genode/issues/112

Even more important, in some cases where capabilities are used as
arguments in an RPC, they are used to retrieve objects on the server
side. An important example can be found in the parent interface. When a
child opens a session via its parent, the parent process at least will
store the session capability of the client together with information
about resources (e.g.: RAM) it had to delegate from the child to the
service provider. Now, if the child wants to close this session, it uses
the 'close' call of the parent interface providing the session
capability as an argument. The parent process takes that capability to
find the information about the delegated resources and reverses the
delegation. Thereby, the parent attaches its own context information to
the session capability and uses it on later calls to 'close'.

So, we had to implement the retrieval of capabilities by ourselves.
Thereby, Genode's capabilities on Fiasco.OC contain a globally valid ID
to uniquely identify capabilities received by IPC. That ID gets
allocated via the 'cap_session' interface in core. The ID is used to
retrieve capabilities, a protection domain already owns. Moreover, it is
also used as key to identify the concrete server object behind that
capability. This server object retrieval is part of the generic code
base and the 'local_name()' method thereby is used as the key.

So far, I hope the answer is more enlightening than confusing.

Regards
Stefan

-- 
Stefan Kalkowski
Genode Labs

http://www.genode-labs.com/ ยท http://genode.org/




More information about the users mailing list