Flexpage: shared Mem
ba_f
ba_f at rbg.informatik.tu-darmstadt.de
Fri May 13 19:57:20 CEST 2016
Nope,
still the same ERR=9.
> I think this should look like this:
> l4_utcb_br()->br[0] = dataspace.cap() | L4_RCV_ITEM_SINGLE_CAP;
> l4_utcb_br()->bdr = 0;
I think the cap() function is C++ only so left this out.
Guess this ok since 'typedef l4_cap_idx_t l4re_ds_t;'
/* server.c */
l4re_ds_t dataspace = l4re_util_cap_alloc();
if (l4_is_invalid_cap( dataspace))
return 1;
l4_utcb_br()->br[0] = dataspace | L4_RCV_ITEM_SINGLE_CAP;
l4_utcb_br()->bdr = 0;
Greets,
ba_f
Am 2016-05-12 23:56, schrieb Adam Lackorzynski:
> Hi,
>
> On Thu May 12, 2016 at 16:09:47 +0200, ba_f wrote:
>> Am 2016-05-12 00:20, schrieb Adam Lackorzynski:
>> > Hi,
>> >
>> > > /* client.c */
>> > >
>> > > l4_fpage_t fpage = l4_obj_fpage( dataspace, 0, L4_CAP_FPAGE_RW );
>> > > l4_utcb_mr()->mr[0] = size;
>> > > l4_utcb_br()->br[0] = fpage.raw;
>> >
>> > That is more like a setup for a receive. Please have a look at some
>> > calls in l4sys, such as l4_scheduler_run_thread or l4_task_map which
>> > send caps to the callee. Note that the l4_map_obj_control+l4_obj_fpage
>> > pair(s) must be at the end of the MR-array. And do not forget proper
>> > values for the sending l4_msgtag.
>>
>>
>> This is what my trial(!) looks now:
>>
>> /* client.c */
>>
>> l4_utcb_mr()->mr[0] = size;
>> l4_utcb_mr()->mr[1] = l4_map_obj_control(dataspace, L4_ITEM_CONT);
>> l4_utcb_mr()->mr[2] = l4_obj_fpage( dataspace, 0, L4_CAP_FPAGE_RW
>> ).raw;
>
> Referring to the functions I pointed you to, this should look like
> this:
>
> l4_utcb_mr()->mr[0] = size;
> l4_utcb_mr()->mr[1] = l4_map_obj_control(0, 0);
> l4_utcb_mr()->mr[2] = l4_obj_fpage(dataspace, 0,
> L4_CAP_FPAGE_RWX).raw;
>
> ret = l4_ipc_call(server, l4_utcb(), l4_msgtag(your_proto, 1, 1, 0),
> L4_IPC_NEVER)
>
>> /* server.c */
>>
>> l4_utcb_br()->bdr = 0;
>> // l4_utcb_br()->br[0] = l4_map_obj_control(dataspace,
>> L4_RCV_ITEM_SINGLE_CAP);
>> l4_utcb_br()->br[0] = L4_ITEM_MAP;
>> l4_utcb_br()->br[1] = l4_obj_fpage(dataspace, 0,
>> L4_CAP_FPAGE_RW).raw;
>
> I think this should look like this:
> l4_utcb_br()->br[0] = dataspace.cap() | L4_RCV_ITEM_SINGLE_CAP;
> l4_utcb_br()->bdr = 0;
>
>> tag = l4_ipc_wait(l4_utcb(), &label, L4_IPC_NEVER);
>> while(1){
>> r = l4_ipc_error(tag, l4_utcb());
>> if ( r) {
>> fprintf(stderr, "IPC error: %x\n", r);
>> tag = l4_ipc_wait(l4_utcb(), &label, L4_IPC_NEVER);
>> continue;
>> }
>> ...
>> tag = l4_ipc_reply_and_wait(l4_utcb(), l4_msgtag(0, 1, 0, 0),
>> &label, L4_IPC_NEVER);
>>
>>
>> This gives me "IPC error: 9" when doing l4_ipc_reply_and_wait().
>> I don't receive a dataspace from client, neither.
>
> 9 is L4_IPC_REMSGCUT: Cut receive message, due to message buffer is too
> small.
>
> Which tells us that the receive side did not provide enough receive
> capacity (aka where to put the receiving cap).
>
>>
>> Actually, I would like to understand what's going on.
>> I know every thread has its UTCBs and an IPC_CALL just copies the MRs
>> from
>> caller to callee.
>
> Yes...
>
>> But, flexpages seem to be a special case.
>
> ... they are. The difference is described in the l4_msgtag, the second
> param describes the number of MRs to be transmitted as pure data, the
> third one describes how many items are there, such as flexpages.
>
>> I guess, the BRs are for receiving flexpages. And there must be some
>> kind of
>> parsing of the MRs since l4_map_obj_control+l4_obj_fpage pair(s) are
>> recognized.
>
> Both right.
>
>> And somehow the kernel must find the matching BRs.
>
> That's right. The bdr = 0 points the kernel to the br field index.
>
>> Where does all this stuff happen?
>
> In the kernel :) kern/thread-ipc.cpp is probably a good place to start
> exploring this, e.g. in transfer_msg_items()
>
>
>
> Adam
More information about the l4-hackers
mailing list