1 /**
2  * \file
3  * \brief Common factory related definitions.
4  * \ingroup l4_api
5  */
6 /*
7  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
8  *               Alexander Warg <warg@os.inf.tu-dresden.de>,
9  *               Björn Döbel <doebel@os.inf.tu-dresden.de>,
10  *               Torsten Frenzel <frenzel@os.inf.tu-dresden.de>,
11  *               Henning Schild <hschild@os.inf.tu-dresden.de>
12  *     economic rights: Technische Universität Dresden (Germany)
13  *
14  * This file is part of TUD:OS and distributed under the terms of the
15  * GNU General Public License 2.
16  * Please see the COPYING-GPL-2 file for details.
17  *
18  * As a special exception, you may use this file as part of a free software
19  * library without restriction.  Specifically, if other files instantiate
20  * templates or use macros or inline functions from this file, or you compile
21  * this file and link it with other files to produce an executable, this
22  * file does not by itself cause the resulting executable to be covered by
23  * the GNU General Public License.  This exception does not however
24  * invalidate any other reasons why the executable file might be covered by
25  * the GNU General Public License.
26  */
27 #pragma once
28 
29 #include <l4/sys/compiler.h>
30 #include <l4/sys/types.h>
31 #include <l4/sys/utcb.h>
32 
33 /**
34  * \defgroup l4_factory_api Factory
35  * \ingroup  l4_kernel_object_api
36  *
37  * C factory interface to create kernel objects.
38  *
39  * A factory is used to create all kinds of kernel objects:
40  * - \ref l4_task_api
41  * - \ref l4_thread_api
42  * - \ref l4_factory_api
43  * - \ref l4_kernel_object_gate_api
44  * - \ref l4_irq_api
45  * - \ref l4_vm_api
46  *
47  * To create a new kernel object the caller has to specify the factory to use
48  * for creation. The caller has to allocate a capability slot where the kernel
49  * stores the new object's capability.
50  *
51  * The factory is equipped with a limit that limits the amount of kernel
52  * memory available for that factory.
53  *
54  * \note The limit does not give any guarantee for the amount of available
55  *       kernel memory.
56  *
57  * \includefile{l4/sys/factory.h}
58  *
59  * For the C++ interface refer to L4::Factory.
60  */
61 
62 /**
63  * \defgroup l4_vm_api Virtual Machines
64  * \ingroup l4_kernel_object_api
65  * \brief Virtual Machine API
66  */
67 
68 /**
69  * \ingroup l4_factory_api
70  * \copybrief L4::Factory::create_task
71  * \param      factory     Capability selector for factory to use for creation.
72  * \param[out] target_cap  The kernel stores the new task's capability into
73  *                         this slot.
74  * \param      utcb_area   Flexpage that describes an area of kernel-user
75  *                         memory that can be used for UTCBs and vCPU
76  *                         state-save-areas of the new task.
77  *
78  * \return Syscall return tag.
79  *
80  * \note The size of the UTCB area specifies indirectly the number
81  *       of UTCBs available for this task. Refer to L4::Task::add_ku_mem
82  *       / l4_task_add_ku_mem() for adding more of this type of memory.
83  *
84  * \see \ref l4_task_api
85  */
86 L4_INLINE l4_msgtag_t
87 l4_factory_create_task(l4_cap_idx_t factory,
88                        l4_cap_idx_t target_cap, l4_fpage_t utcb_area) L4_NOTHROW;
89 
90 /**
91  * \ingroup l4_factory_api
92  * \copybrief L4::Factory::create_task
93  * \param factory  Capability selector for factory to use for creation.
94  * \copydetails L4::Factory::create_task
95  */
96 L4_INLINE l4_msgtag_t
97 l4_factory_create_task_u(l4_cap_idx_t factory, l4_cap_idx_t target_cap,
98                          l4_fpage_t utcb_area, l4_utcb_t *utcb) L4_NOTHROW;
99 
100 /**
101  * \ingroup l4_factory_api
102  * \copybrief L4::Factory::create_thread
103  * \param      factory     Capability selector for factory to use for creation.
104  * \param[out] target_cap  The kernel stores the new thread's capability into
105  *                         this slot.
106  *
107  * \return Syscall return tag
108  *
109  * \see \ref l4_thread_api
110  */
111 L4_INLINE l4_msgtag_t
112 l4_factory_create_thread(l4_cap_idx_t factory,
113                          l4_cap_idx_t target_cap) L4_NOTHROW;
114 
115 /**
116  * \ingroup l4_factory_api
117  * \copybrief L4::Factory::create_thread
118  * \param factory  Capability selector for factory to use for creation.
119  * \copydetails  L4::Factory::create_thread
120  */
121 L4_INLINE l4_msgtag_t
122 l4_factory_create_thread_u(l4_cap_idx_t factory,
123                            l4_cap_idx_t target_cap, l4_utcb_t *utcb) L4_NOTHROW;
124 
125 /**
126  * \ingroup l4_factory_api
127  * \copybrief L4::Factory::create_factory
128  * \param      factory     Capability selector for factory to use for creation.
129  * \param[out] target_cap  The kernel stores the new factory's capability into
130  *                         this slot.
131  * \param      limit       Limit for the new factory in bytes.
132  *
133  * \return Syscall return tag
134  *
135  * \note The limit of the new factory is subtracted from the available amount
136  *       of the factory used for creation.
137  */
138 L4_INLINE l4_msgtag_t
139 l4_factory_create_factory(l4_cap_idx_t factory, l4_cap_idx_t target_cap,
140                           unsigned long limit) L4_NOTHROW;
141 
142 /**
143  * \ingroup l4_factory_api
144  * \copybrief L4::Factory::create_factory
145  * \param factory  Capability selector for factory to use for creation.
146  * \copydetails L4::Factory::create_factory
147  */
148 L4_INLINE l4_msgtag_t
149 l4_factory_create_factory_u(l4_cap_idx_t factory, l4_cap_idx_t target_cap,
150                             unsigned long limit, l4_utcb_t *utcb) L4_NOTHROW;
151 
152 /**
153  * \ingroup l4_factory_api
154  * \copybrief L4::Factory::create_gate
155  * \param      factory     Capability selector for factory to use for creation.
156  * \param[out] target_cap  The kernel stores the new IPC gate's capability into
157  *                         this slot.
158  * \param      thread_cap  Optional capability selector of the thread to
159  *                         bind the gate to. Use #L4_INVALID_CAP to create
160  *                         an unbound IPC gate.
161  * \param      label       Optional label of the gate (is used if
162  *                         `thread_cap` is valid).
163  *
164  * \return Syscall return tag containing one of the following return codes.
165  *
166  * \retval L4_EOK      No error occurred.
167  * \retval -L4_ENOMEM  Out-of-memory during allocation of the Ipc_gate object.
168  * \retval -L4_ENOENT  `thread_cap` is void or points to something that is not
169  *                     a thread.
170  * \retval -L4_EPERM   No #L4_CAP_FPAGE_S rights on `thread_cap`.
171  *
172  * An unbound IPC gate can be bound to a thread using #l4_ipc_gate_bind_thread.
173  *
174  * \see  l4_kernel_object_gate_api
175  */
176 L4_INLINE l4_msgtag_t
177 l4_factory_create_gate(l4_cap_idx_t factory,
178                        l4_cap_idx_t target_cap,
179                        l4_cap_idx_t thread_cap, l4_umword_t label) L4_NOTHROW;
180 
181 /**
182  * \ingroup l4_factory_api
183  * \copybrief L4::Factory::create_gate
184  * \param factory  Capability selector for factory to use for creation.
185  * \copydetails  L4::Factory::create_gate
186  */
187 L4_INLINE l4_msgtag_t
188 l4_factory_create_gate_u(l4_cap_idx_t factory,
189                          l4_cap_idx_t target_cap,
190                          l4_cap_idx_t thread_cap, l4_umword_t label,
191                          l4_utcb_t *utcb) L4_NOTHROW;
192 
193 /**
194  * \ingroup l4_factory_api
195  * Create a new IRQ sender.
196  *
197  * \param      factory     Factory to use for creation.
198  * \param[out] target_cap  The kernel stores the new IRQ's capability into this
199  *                         slot.
200  *
201  * \return Syscall return tag
202  *
203  * \see \ref l4_irq_api
204  */
205 L4_INLINE l4_msgtag_t
206 l4_factory_create_irq(l4_cap_idx_t factory,
207                       l4_cap_idx_t target_cap) L4_NOTHROW;
208 
209 /**
210  * \ingroup l4_factory_api
211  * \copybrief L4::Factory::create_irq
212  * \param factory  Factory to use for creation.
213  * \copydetails L4::Factory::create_irq
214  */
215 L4_INLINE l4_msgtag_t
216 l4_factory_create_irq_u(l4_cap_idx_t factory,
217                         l4_cap_idx_t target_cap, l4_utcb_t *utcb) L4_NOTHROW;
218 
219 /**
220  * \ingroup l4_factory_api
221  * \copybrief L4::Factory::create_vm
222  * \param      factory     Capability selector for factory to use for creation.
223  * \param[out] target_cap  The kernel stores the new VM's capability into this
224  *                         slot.
225  *
226  * \return Syscall return tag
227  *
228  * \see \ref l4_vm_api
229  */
230 L4_INLINE l4_msgtag_t
231 l4_factory_create_vm(l4_cap_idx_t factory,
232                      l4_cap_idx_t target_cap) L4_NOTHROW;
233 
234 /**
235  * \ingroup l4_factory_api
236  * \copybrief L4::Factory::create_vm
237  * \param factory  Capability selector for factory to use for creation.
238  * \copydetails L4::Factory::create_vm
239  */
240 L4_INLINE l4_msgtag_t
241 l4_factory_create_vm_u(l4_cap_idx_t factory,
242                        l4_cap_idx_t target_cap, l4_utcb_t *utcb) L4_NOTHROW;
243 
244 L4_INLINE l4_msgtag_t
245 l4_factory_create_start_u(long obj, l4_cap_idx_t target,
246                           l4_utcb_t *utcb) L4_NOTHROW;
247 
248 L4_INLINE int
249 l4_factory_create_add_fpage_u(l4_fpage_t d, l4_msgtag_t *tag,
250                               l4_utcb_t *utcb) L4_NOTHROW;
251 
252 L4_INLINE int
253 l4_factory_create_add_int_u(l4_mword_t d, l4_msgtag_t *tag,
254                             l4_utcb_t *utcb) L4_NOTHROW;
255 
256 L4_INLINE int
257 l4_factory_create_add_uint_u(l4_umword_t d, l4_msgtag_t *tag,
258                             l4_utcb_t *utcb) L4_NOTHROW;
259 
260 L4_INLINE int
261 l4_factory_create_add_str_u(char const *s, l4_msgtag_t *tag,
262                             l4_utcb_t *utcb) L4_NOTHROW;
263 
264 L4_INLINE int
265 l4_factory_create_add_lstr_u(char const *s, unsigned len, l4_msgtag_t *tag,
266                              l4_utcb_t *utcb) L4_NOTHROW;
267 
268 L4_INLINE int
269 l4_factory_create_add_nil_u(l4_msgtag_t *tag, l4_utcb_t *utcb) L4_NOTHROW;
270 
271 L4_INLINE l4_msgtag_t
272 l4_factory_create_commit_u(l4_cap_idx_t factory, l4_msgtag_t tag,
273                            l4_utcb_t *utcb) L4_NOTHROW;
274 
275 L4_INLINE l4_msgtag_t
276 l4_factory_create_u(l4_cap_idx_t factory, long obj, l4_cap_idx_t target,
277                     l4_utcb_t *utcb) L4_NOTHROW;
278 
279 
280 L4_INLINE l4_msgtag_t
281 l4_factory_create(l4_cap_idx_t factory, long obj,
282                   l4_cap_idx_t target) L4_NOTHROW;
283 
284 /* IMPLEMENTATION -----------------------------------------------------------*/
285 
286 #include <l4/sys/ipc.h>
287 
288 L4_INLINE l4_msgtag_t
l4_factory_create_task_u(l4_cap_idx_t factory,l4_cap_idx_t target_cap,l4_fpage_t utcb_area,l4_utcb_t * u)289 l4_factory_create_task_u(l4_cap_idx_t factory,
290                          l4_cap_idx_t target_cap, l4_fpage_t utcb_area,
291                          l4_utcb_t *u) L4_NOTHROW
292 {
293   l4_msgtag_t t;
294   t = l4_factory_create_start_u(L4_PROTO_TASK, target_cap, u);
295   l4_factory_create_add_fpage_u(utcb_area, &t, u);
296   return l4_factory_create_commit_u(factory, t, u);
297 }
298 
299 L4_INLINE l4_msgtag_t
l4_factory_create_thread_u(l4_cap_idx_t factory,l4_cap_idx_t target_cap,l4_utcb_t * u)300 l4_factory_create_thread_u(l4_cap_idx_t factory,
301                            l4_cap_idx_t target_cap, l4_utcb_t *u) L4_NOTHROW
302 {
303   return l4_factory_create_u(factory, L4_PROTO_THREAD, target_cap, u);
304 }
305 
306 L4_INLINE l4_msgtag_t
l4_factory_create_factory_u(l4_cap_idx_t factory,l4_cap_idx_t target_cap,unsigned long limit,l4_utcb_t * u)307 l4_factory_create_factory_u(l4_cap_idx_t factory,
308                             l4_cap_idx_t target_cap, unsigned long limit,
309                             l4_utcb_t *u) L4_NOTHROW
310 {
311   l4_msgtag_t t;
312   t = l4_factory_create_start_u(L4_PROTO_FACTORY, target_cap, u);
313   l4_factory_create_add_uint_u(limit, &t, u);
314   return l4_factory_create_commit_u(factory, t, u);
315 }
316 
317 L4_INLINE l4_msgtag_t
l4_factory_create_gate_u(l4_cap_idx_t factory,l4_cap_idx_t target_cap,l4_cap_idx_t thread_cap,l4_umword_t label,l4_utcb_t * u)318 l4_factory_create_gate_u(l4_cap_idx_t factory,
319                          l4_cap_idx_t target_cap,
320                          l4_cap_idx_t thread_cap, l4_umword_t label,
321                          l4_utcb_t *u) L4_NOTHROW
322 {
323   l4_msgtag_t t;
324   l4_msg_regs_t *v;
325   int items = 0;
326   t = l4_factory_create_start_u(0, target_cap, u);
327   l4_factory_create_add_uint_u(label, &t, u);
328   v = l4_utcb_mr_u(u);
329   if (!(thread_cap & L4_INVALID_CAP_BIT))
330     {
331       items = 1;
332       v->mr[3] = l4_map_obj_control(0,0);
333       v->mr[4] = l4_obj_fpage(thread_cap, 0, L4_CAP_FPAGE_RWS).raw;
334     }
335   t = l4_msgtag(l4_msgtag_label(t), l4_msgtag_words(t), items, l4_msgtag_flags(t));
336   return l4_factory_create_commit_u(factory, t, u);
337 }
338 
339 L4_INLINE l4_msgtag_t
l4_factory_create_irq_u(l4_cap_idx_t factory,l4_cap_idx_t target_cap,l4_utcb_t * u)340 l4_factory_create_irq_u(l4_cap_idx_t factory,
341                         l4_cap_idx_t target_cap, l4_utcb_t *u) L4_NOTHROW
342 {
343   return l4_factory_create_u(factory, L4_PROTO_IRQ_SENDER, target_cap, u);
344 }
345 
346 L4_INLINE l4_msgtag_t
l4_factory_create_vm_u(l4_cap_idx_t factory,l4_cap_idx_t target_cap,l4_utcb_t * u)347 l4_factory_create_vm_u(l4_cap_idx_t factory,
348                        l4_cap_idx_t target_cap,
349                        l4_utcb_t *u) L4_NOTHROW
350 {
351   return l4_factory_create_u(factory, L4_PROTO_VM, target_cap, u);
352 }
353 
354 
355 
356 
357 
358 L4_INLINE l4_msgtag_t
l4_factory_create_task(l4_cap_idx_t factory,l4_cap_idx_t target_cap,l4_fpage_t utcb_area)359 l4_factory_create_task(l4_cap_idx_t factory,
360                        l4_cap_idx_t target_cap, l4_fpage_t utcb_area) L4_NOTHROW
361 {
362   return l4_factory_create_task_u(factory, target_cap, utcb_area, l4_utcb());
363 }
364 
365 L4_INLINE l4_msgtag_t
l4_factory_create_thread(l4_cap_idx_t factory,l4_cap_idx_t target_cap)366 l4_factory_create_thread(l4_cap_idx_t factory,
367                          l4_cap_idx_t target_cap) L4_NOTHROW
368 {
369   return l4_factory_create_thread_u(factory, target_cap, l4_utcb());
370 }
371 
372 L4_INLINE l4_msgtag_t
l4_factory_create_factory(l4_cap_idx_t factory,l4_cap_idx_t target_cap,unsigned long limit)373 l4_factory_create_factory(l4_cap_idx_t factory,
374                           l4_cap_idx_t target_cap, unsigned long limit) L4_NOTHROW
375 
376 {
377   return l4_factory_create_factory_u(factory, target_cap, limit, l4_utcb());
378 }
379 
380 L4_INLINE l4_msgtag_t
l4_factory_create_gate(l4_cap_idx_t factory,l4_cap_idx_t target_cap,l4_cap_idx_t thread_cap,l4_umword_t label)381 l4_factory_create_gate(l4_cap_idx_t factory,
382                        l4_cap_idx_t target_cap,
383                        l4_cap_idx_t thread_cap, l4_umword_t label) L4_NOTHROW
384 {
385   return l4_factory_create_gate_u(factory, target_cap, thread_cap, label, l4_utcb());
386 }
387 
388 L4_INLINE l4_msgtag_t
l4_factory_create_irq(l4_cap_idx_t factory,l4_cap_idx_t target_cap)389 l4_factory_create_irq(l4_cap_idx_t factory,
390                       l4_cap_idx_t target_cap) L4_NOTHROW
391 {
392   return l4_factory_create_irq_u(factory, target_cap, l4_utcb());
393 }
394 
395 L4_INLINE l4_msgtag_t
l4_factory_create_vm(l4_cap_idx_t factory,l4_cap_idx_t target_cap)396 l4_factory_create_vm(l4_cap_idx_t factory,
397                      l4_cap_idx_t target_cap) L4_NOTHROW
398 {
399   return l4_factory_create_vm_u(factory, target_cap, l4_utcb());
400 }
401 
402 L4_INLINE l4_msgtag_t
l4_factory_create_start_u(long obj,l4_cap_idx_t target_cap,l4_utcb_t * u)403 l4_factory_create_start_u(long obj, l4_cap_idx_t target_cap,
404                           l4_utcb_t *u) L4_NOTHROW
405 {
406   l4_msg_regs_t *v = l4_utcb_mr_u(u);
407   l4_buf_regs_t *b = l4_utcb_br_u(u);
408   v->mr[0] = obj;
409   b->bdr = 0;
410   b->br[0] = target_cap | L4_RCV_ITEM_SINGLE_CAP;
411   return l4_msgtag(L4_PROTO_FACTORY, 1, 0, 0);
412 }
413 
414 L4_INLINE int
l4_factory_create_add_fpage_u(l4_fpage_t d,l4_msgtag_t * tag,l4_utcb_t * u)415 l4_factory_create_add_fpage_u(l4_fpage_t d, l4_msgtag_t *tag,
416                               l4_utcb_t *u) L4_NOTHROW
417 {
418   l4_msg_regs_t *v = l4_utcb_mr_u(u);
419   int w = l4_msgtag_words(*tag);
420   if (w + 2 > L4_UTCB_GENERIC_DATA_SIZE)
421     return 0;
422   v->mr[w] = L4_VARG_TYPE_FPAGE | (sizeof(l4_fpage_t) << 16);
423   v->mr[w + 1] = d.raw;
424   w += 2;
425   tag->raw = (tag->raw & ~0x3fUL) | (w & 0x3f);
426   return 1;
427 }
428 
429 L4_INLINE int
l4_factory_create_add_int_u(l4_mword_t d,l4_msgtag_t * tag,l4_utcb_t * u)430 l4_factory_create_add_int_u(l4_mword_t d, l4_msgtag_t *tag,
431                             l4_utcb_t *u) L4_NOTHROW
432 {
433   l4_msg_regs_t *v = l4_utcb_mr_u(u);
434   int w = l4_msgtag_words(*tag);
435   if (w + 2 > L4_UTCB_GENERIC_DATA_SIZE)
436     return 0;
437   v->mr[w] = L4_VARG_TYPE_MWORD | (sizeof(l4_mword_t) << 16);
438   v->mr[w + 1] = d;
439   w += 2;
440   tag->raw = (tag->raw & ~0x3fUL) | (w & 0x3f);
441   return 1;
442 }
443 
444 L4_INLINE int
l4_factory_create_add_uint_u(l4_umword_t d,l4_msgtag_t * tag,l4_utcb_t * u)445 l4_factory_create_add_uint_u(l4_umword_t d, l4_msgtag_t *tag,
446                              l4_utcb_t *u) L4_NOTHROW
447 {
448   l4_msg_regs_t *v = l4_utcb_mr_u(u);
449   int w = l4_msgtag_words(*tag);
450   if (w + 2 > L4_UTCB_GENERIC_DATA_SIZE)
451     return 0;
452   v->mr[w] = L4_VARG_TYPE_UMWORD | (sizeof(l4_umword_t) << 16);
453   v->mr[w + 1] = d;
454   w += 2;
455   tag->raw = (tag->raw & ~0x3fUL) | (w & 0x3f);
456   return 1;
457 }
458 
459 L4_INLINE int
l4_factory_create_add_str_u(char const * s,l4_msgtag_t * tag,l4_utcb_t * u)460 l4_factory_create_add_str_u(char const *s, l4_msgtag_t *tag,
461                             l4_utcb_t *u) L4_NOTHROW
462 {
463   return l4_factory_create_add_lstr_u(s, __builtin_strlen(s) + 1, tag, u);
464 }
465 
466 L4_INLINE int
l4_factory_create_add_lstr_u(char const * s,unsigned len,l4_msgtag_t * tag,l4_utcb_t * u)467 l4_factory_create_add_lstr_u(char const *s, unsigned len, l4_msgtag_t *tag,
468                              l4_utcb_t *u) L4_NOTHROW
469 {
470 
471   l4_msg_regs_t *v = l4_utcb_mr_u(u);
472   unsigned w = l4_msgtag_words(*tag);
473   char *c;
474   unsigned i;
475 
476   if (w + 1 + l4_bytes_to_mwords(len) > L4_UTCB_GENERIC_DATA_SIZE)
477     return 0;
478 
479   v->mr[w] = L4_VARG_TYPE_STRING | (len << 16);
480   c = (char*)&v->mr[w + 1];
481   for (i = 0; i < len; ++i)
482     *c++ = *s++;
483 
484   w = w + 1 + l4_bytes_to_mwords(len);
485 
486   tag->raw = (tag->raw & ~0x3fUL) | (w & 0x3f);
487   return 1;
488 }
489 
490 L4_INLINE int
l4_factory_create_add_nil_u(l4_msgtag_t * tag,l4_utcb_t * utcb)491 l4_factory_create_add_nil_u(l4_msgtag_t *tag, l4_utcb_t *utcb) L4_NOTHROW
492 {
493   l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
494   int w = l4_msgtag_words(*tag);
495   v->mr[w] = L4_VARG_TYPE_NIL;
496   ++w;
497   tag->raw = (tag->raw & ~0x3fUL) | (w & 0x3f);
498   return 1;
499 }
500 
501 
502 L4_INLINE l4_msgtag_t
l4_factory_create_commit_u(l4_cap_idx_t factory,l4_msgtag_t tag,l4_utcb_t * u)503 l4_factory_create_commit_u(l4_cap_idx_t factory, l4_msgtag_t tag,
504                            l4_utcb_t *u) L4_NOTHROW
505 {
506   return l4_ipc_call(factory, u, tag, L4_IPC_NEVER);
507 }
508 
509 L4_INLINE l4_msgtag_t
l4_factory_create_u(l4_cap_idx_t factory,long obj,l4_cap_idx_t target,l4_utcb_t * utcb)510 l4_factory_create_u(l4_cap_idx_t factory, long obj, l4_cap_idx_t target,
511                     l4_utcb_t *utcb) L4_NOTHROW
512 {
513   l4_msgtag_t t = l4_factory_create_start_u(obj, target, utcb);
514   return l4_factory_create_commit_u(factory, t, utcb);
515 }
516 
517 
518 L4_INLINE l4_msgtag_t
l4_factory_create(l4_cap_idx_t factory,long obj,l4_cap_idx_t target)519 l4_factory_create(l4_cap_idx_t factory, long obj,
520                   l4_cap_idx_t target) L4_NOTHROW
521 {
522   return l4_factory_create_u(factory, obj, target, l4_utcb());
523 }
524