Native_capability as [out] parameters

Stefan Kalkowski stefan.kalkowski at ...1...
Tue Feb 19 11:15:30 CET 2013


Hi Daniel,

On 02/19/2013 01:38 AM, Daniel Waddington wrote:
> Hi Stefan,
> 
> In my test server side session function, if I use a core-created
> capability (via alloc_irq) it works.  If I try to do similar behavior
> locally, the capability appears to be valid (i.e., it exists in the jdb
> object table) but will not martial correctly - .valid() fails at the
> client side (note my server process has L4_BASE_FACTORY_CAP).
> 
> Can you enlighten me? I am clearly doing something wrong.
> 

I see. Well that's the reason I recommended to put such a service into
core to you ;-).
The point of the matter is: although your self constructed capabilities
have valid indices of the capability name space controlled by the
kernel, they have invalid IDs (alias "local_name"s). These IDs are
Genode specific, and have nothing to do with the kernel API. They are
used to find capabilities, a task already owns. Therefore, all
capabilities are stored in a task-local AVL tree. The IDs are used as
keys in the AVL tree. A capability without a proper ID (ID == 0) is
treated as an invalid capability. When you try to marshal a capability
into the message buffer, it is checked whether you try to transfer an
invalid capability or not. Without that check, the kernel would pollute
the debug messages with a lot of warnings about capability transfers
that failed. If it is an invalid one, no mapping gets established.
That's why no capability is transfered in your case.

I see two opportunities to solve that problem:
First, you implement a proper service in core, or use the existing ones
(e.g.: Cpu_session::alloc_irq). If you've to implement your own service
in core, or extend an existing one, you can use core's allocator for
capability IDs: "Platform::cap_id_alloc()".

If for some reason it is impassable for you to do this in core, you
might allocate a capability via core's cap_session service for every
capability you want to construct by hand. Thereby, you obtain an ID that
is not used otherwise. But be careful, this is the path of pain. Because
you have to get rid of the capability, allocated via core, in your
task-local AVL tree before getting your own capability into it. This
should be done via the smart pointer magic only. Don't remove a
capability from the tree by hand, when you still have references to it!
With other words, you have to get rid of all references to the
capability allocated via core, so that its destructor will do the
database removal for you. Later, when you want to free your capability
again, you'll have to re-construct the capability allocated via core. So
that you can go to core's cap_session service, and free it. Otherwise,
you'll have a capability leak in core.

Summing up, I hope I could convince you to implement variant number one ;-).

> 
> status_t Foo::Session_component::create(Genode::Native_capability&
> result_cap)
> {
> #if WORKS
>   Genode::Foc_cpu_session_client cpu(Genode::env()->cpu_session_cap());
>   result_cap = cpu.alloc_irq();
> #endif
> 
> #if DOES_NOT_WORK
>   Cap_index * i = Genode::cap_idx_alloc()->alloc_range(1);
> 
>   l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, i->kcap());
>   assert(!l4_error(res));
> 
>   Genode::Native_capability ncap(i);
>   result_cap = ncap;
> #endif
> }
> 
> 
> BTW, I'm currently using Native_capabilities to test.  But I also do not
> know how to convert from a Native_capability to a typed capability. ;-)
> Can you show me?

You can use the following method defined in
"base/include/base/capability.h" for it:

template <typename RPC_INTERFACE>
Capability<RPC_INTERFACE>
reinterpret_cap_cast(Untyped_capability const &untyped_cap);

Best regards
Stefan

> 
> Daniel
> 
> On 02/18/2013 01:15 AM, Stefan Kalkowski wrote:
>> Hi Daniel,
>>
>> On 02/14/2013 08:33 PM, Daniel Waddington wrote:
>>> Hi,
>>> Can I pass Native_capability types as [out] parameters using
>>> "Native_capability *" type - with the cross-process mapping happening? 
>>> Most of the examples use only use the return value to do [out]
>>> capabilities.  i.e. GENODE_RPC(Rpc_foo,int,foo,Genode::Native_capability
>>> *) doesn't seem to work, but there might be something else afoot.
>> actually it should work the way you've described it. I've tested it
>> right now by extending the hello example the same way, and the
>> capability was successfully transfered to the calling client as an argument.
>> By the way, why do you use Native_capability instead of Capability?
>> Although both should work, I would use the generic Capability class,
>> especially in an interface.
>>
>> Best regards
>> Stefan
>>
>>> Daniel
>>>
>>>
>>> ------------------------------------------------------------------------------
>>> Free Next-Gen Firewall Hardware Offer
>>> Buy your Sophos next-gen firewall before the end March 2013 
>>> and get the hardware for free! Learn more.
>>> http://p.sf.net/sfu/sophos-d2d-feb
>>>
>>>
>>>
>>> _______________________________________________
>>> Genode-main mailing list
>>> Genode-main at lists.sourceforge.net
>>> https://lists.sourceforge.net/lists/listinfo/genode-main
>>>
> 
> 
> 
> ------------------------------------------------------------------------------
> The Go Parallel Website, sponsored by Intel - in partnership with Geeknet, 
> is your hub for all things parallel software development, from weekly thought 
> leadership blogs to news, videos, case studies, tutorials, tech docs, 
> whitepapers, evaluation guides, and opinion stories. Check out the most 
> recent posts - join the conversation now. http://goparallel.sourceforge.net/
> 
> 
> 
> _______________________________________________
> Genode-main mailing list
> Genode-main at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/genode-main
> 

-- 
Stefan Kalkowski
Genode Labs

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




More information about the users mailing list