3 * \brief Kernel capability management implementation.
7 * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, ETH Zurich.
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
18 #include <barrelfish_kpi/syscalls.h>
19 #include <barrelfish_kpi/paging_arch.h>
20 #include <barrelfish_kpi/lmp.h>
22 #include <capabilities.h>
23 #include <cap_predicates.h>
27 #include <paging_kernel_arch.h>
29 #include <mdb/mdb_tree.h>
30 #include <trace/trace.h>
31 #include <trace_definitions/trace_defs.h>
34 /// Sets the specified number of low-order bits to 1
35 #define MASK(bits) ((1UL << bits) - 1)
37 #ifdef TRACE_PMEM_CAPS
38 uint64_t trace_types_enabled = TRACE_TYPES_ENABLED_INITIAL;
39 genpaddr_t TRACE_PMEM_BEGIN = TRACE_PMEM_BEGIN_INITIAL;
40 gensize_t TRACE_PMEM_SIZE = TRACE_PMEM_SIZE_INITIAL;
42 void caps_trace_ctrl(uint64_t types, genpaddr_t start, gensize_t size)
45 trace_types_enabled = types;
46 TRACE_PMEM_BEGIN = start;
47 TRACE_PMEM_SIZE = size;
49 trace_types_enabled = false;
54 struct capability monitor_ep;
56 int sprint_cap(char *buf, size_t len, struct capability *cap)
59 case ObjType_PhysAddr:
60 return snprintf(buf, len,
61 "physical address range cap (0x%" PRIxGENPADDR ":%u)",
62 cap->u.physaddr.base, cap->u.physaddr.bits);
65 return snprintf(buf, len, "RAM cap (0x%" PRIxGENPADDR ":%u)",
66 cap->u.ram.base, cap->u.ram.bits);
69 int ret = snprintf(buf, len, "CNode cap "
70 "(bits %u, rights mask 0x%" PRIxCAPRIGHTS ")",
71 cap->u.cnode.bits, cap->u.cnode.rightsmask);
72 if (cap->u.cnode.guard_size != 0 && ret < len) {
73 ret += snprintf(&buf[ret], len - ret, " (guard 0x%" PRIxCADDR ":%u)",
74 cap->u.cnode.guard, cap->u.cnode.guard_size);
79 case ObjType_Dispatcher:
80 return snprintf(buf, len, "Dispatcher cap %p", cap->u.dispatcher.dcb);
83 return snprintf(buf, len, "Frame cap (0x%" PRIxGENPADDR ":%u)",
84 cap->u.frame.base, cap->u.frame.bits);
86 case ObjType_DevFrame:
87 return snprintf(buf, len, "Device Frame cap (0x%" PRIxGENPADDR ":%u)",
88 cap->u.frame.base, cap->u.devframe.bits);
90 case ObjType_VNode_ARM_l1:
91 return snprintf(buf, len, "ARM L1 table at 0x%" PRIxGENPADDR,
92 cap->u.vnode_arm_l1.base);
94 case ObjType_VNode_ARM_l2:
95 return snprintf(buf, len, "ARM L2 table at 0x%" PRIxGENPADDR,
96 cap->u.vnode_arm_l2.base);
98 case ObjType_VNode_x86_32_ptable:
99 return snprintf(buf, len, "x86_32 Page table at 0x%" PRIxGENPADDR,
100 cap->u.vnode_x86_32_ptable.base);
102 case ObjType_VNode_x86_32_pdir:
103 return snprintf(buf, len, "x86_32 Page directory at 0x%" PRIxGENPADDR,
104 cap->u.vnode_x86_32_pdir.base);
106 case ObjType_VNode_x86_32_pdpt:
107 return snprintf(buf, len, "x86_32 PDPT at 0x%" PRIxGENPADDR,
108 cap->u.vnode_x86_32_pdpt.base);
110 case ObjType_VNode_x86_64_ptable:
111 return snprintf(buf, len, "x86_64 Page table at 0x%" PRIxGENPADDR,
112 cap->u.vnode_x86_64_ptable.base);
114 case ObjType_VNode_x86_64_pdir:
115 return snprintf(buf, len, "x86_64 Page directory at 0x%" PRIxGENPADDR,
116 cap->u.vnode_x86_64_pdir.base);
118 case ObjType_VNode_x86_64_pdpt:
119 return snprintf(buf, len, "x86_64 PDPT at 0x%" PRIxGENPADDR,
120 cap->u.vnode_x86_64_pdpt.base);
122 case ObjType_VNode_x86_64_pml4:
123 return snprintf(buf, len, "x86_64 PML4 at 0x%" PRIxGENPADDR,
124 cap->u.vnode_x86_64_pml4.base);
126 case ObjType_IRQTable:
127 return snprintf(buf, len, "IRQTable cap");
129 case ObjType_EndPoint:
130 return snprintf(buf, len, "EndPoint cap (disp %p offset 0x%" PRIxLVADDR ")",
131 cap->u.endpoint.listener, cap->u.endpoint.epoffset);
134 return snprintf(buf, len, "IO cap (0x%hx-0x%hx)",
135 cap->u.io.start, cap->u.io.end);
138 return snprintf(buf, len, "Kernel cap");
141 return snprintf(buf, len, "ID capability (coreid 0x%" PRIxCOREID
142 " core_local_id 0x%" PRIx32 ")", cap->u.id.coreid,
143 cap->u.id.core_local_id);
145 case ObjType_PerfMon:
146 return snprintf(buf, len, "PerfMon cap");
149 return snprintf(buf, len, "Null capability (empty slot)");
152 return snprintf(buf, len, "UNKNOWN TYPE! (%d)", cap->type);
156 void caps_trace(const char *func, int line, struct cte *cte, const char *msg)
159 sprint_cap(cap_buf, 512, &cte->cap);
163 dispatcher_handle_t handle = dcb_current->disp;
164 struct dispatcher_shared_generic *disp =
165 get_dispatcher_shared_generic(handle);
166 snprintf(disp_buf, 64, "from %.*s", DISP_NAME_LEN, disp->name);
169 strcpy(disp_buf, "no disp");
172 printk(LOG_WARN, "%s: %s:%d: %s %p %s"
173 " (owner:%" PRIuCOREID ", rc:%d/ra:%d/rd:%d)\n",
174 disp_buf, func, line, (msg ? : ""), cte, cap_buf, cte->mdbnode.owner,
175 cte->mdbnode.remote_copies, cte->mdbnode.remote_ancs,
176 cte->mdbnode.remote_descs);
180 * ID capability core_local_id counter.
182 static uint32_t id_cap_counter = 1;
185 * Sets #dest equal to #src
187 * #dest cannot be in use.
189 static errval_t set_cap(struct capability *dest, struct capability *src)
191 /* Parameter checking */
193 assert(dest != NULL);
195 // Reserved object bits must always be greater/equal to actual object size
196 assert((1UL << OBJBITS_CTE) >= sizeof(struct cte));
198 // Cannot overwrite an already existing cap
199 if (dest->type != ObjType_Null) {
200 return SYS_ERR_SLOT_IN_USE;
203 memcpy(dest, src, sizeof(struct capability));
208 * \brief Determine how many objects can be created in a specified region.
210 * This function computes the number of objects that can be created by a call
213 * \param type Type of objects to create.
214 * \param bits Size of memory area as 2^bits.
215 * \param objbits For variable-sized objects, size multiplier as 2^bits.
217 * \return Number of objects to be created, or zero on error
220 // If you create more capability types you need to deal with them
221 // in the table below.
222 STATIC_ASSERT(27 == ObjType_Num, "Knowledge of all cap types");
224 static size_t caps_numobjs(enum objtype type, uint8_t bits, uint8_t objbits)
227 case ObjType_PhysAddr:
230 case ObjType_DevFrame:
231 if (objbits > bits) {
234 return 1UL << (bits - objbits);
238 if (bits < OBJBITS_CTE || objbits > bits - OBJBITS_CTE) {
241 return 1UL << (bits - OBJBITS_CTE - objbits);
244 case ObjType_VNode_x86_64_pml4:
245 case ObjType_VNode_x86_64_pdpt:
246 case ObjType_VNode_x86_64_pdir:
247 case ObjType_VNode_x86_64_ptable:
248 case ObjType_VNode_x86_32_pdpt:
249 case ObjType_VNode_x86_32_pdir:
250 case ObjType_VNode_x86_32_ptable:
251 case ObjType_VNode_ARM_l1:
252 case ObjType_VNode_ARM_l2:
254 size_t objbits_vnode = vnode_objbits(type);
255 if (bits < objbits_vnode) {
258 return 1UL << (bits - objbits_vnode);
262 case ObjType_Dispatcher:
263 if (bits < OBJBITS_DISPATCHER) {
266 return 1UL << (bits - OBJBITS_DISPATCHER);
269 case ObjType_KernelControlBlock:
270 if (bits < OBJBITS_KCB) {
273 return 1UL << (bits - OBJBITS_KCB);
277 case ObjType_IRQTable:
279 case ObjType_EndPoint:
281 case ObjType_Notify_RCK:
282 case ObjType_Notify_IPI:
283 case ObjType_PerfMon:
288 panic("invalid type");
294 * \brief Initialize the objects for which local caps are about to be created.
296 * For the meaning of the parameters, see the 'caps_create' function.
298 STATIC_ASSERT(ObjType_Num == 27, "Knowledge of all cap types");
300 static errval_t caps_init_objects(enum objtype type, lpaddr_t lpaddr, uint8_t
301 bits, uint8_t objbits, size_t numobjs)
303 // Virtual address of the memory the kernel object resides in
304 // XXX: A better of doing this,
305 // this is creating caps that the kernel cannot address.
306 // It assumes that the cap is not of the type which will have to zeroed out.
308 if(lpaddr < PADDR_SPACE_LIMIT) {
309 lvaddr = local_phys_to_mem(lpaddr);
317 trace_event(TRACE_SUBSYS_KERNEL, TRACE_EVENT_KERNEL_BZERO, 1);
318 // XXX: SCC hack, while we don't have a devframe allocator
319 if(lpaddr + ((lpaddr_t)1 << bits) < PADDR_SPACE_LIMIT) {
320 memset((void*)lvaddr, 0, (lvaddr_t)1 << bits);
322 printk(LOG_WARN, "Allocating RAM at 0x%" PRIxLPADDR
323 " uninitialized\n", lpaddr);
325 trace_event(TRACE_SUBSYS_KERNEL, TRACE_EVENT_KERNEL_BZERO, 0);
329 case ObjType_VNode_ARM_l1:
330 case ObjType_VNode_ARM_l2:
331 case ObjType_VNode_x86_32_ptable:
332 case ObjType_VNode_x86_32_pdir:
333 case ObjType_VNode_x86_32_pdpt:
334 case ObjType_VNode_x86_64_ptable:
335 case ObjType_VNode_x86_64_pdir:
336 case ObjType_VNode_x86_64_pdpt:
337 case ObjType_VNode_x86_64_pml4:
338 case ObjType_Dispatcher:
339 case ObjType_KernelControlBlock:
340 TRACE(KERNEL, BZERO, 1);
341 memset((void*)lvaddr, 0, 1UL << bits);
342 TRACE(KERNEL, BZERO, 0);
354 * \brief Create capabilities to kernel objects.
356 * This function creates kernel objects of 'type' into the memory
357 * area, based at 'addr' and of size 2^'bits', so they completely fill the
358 * area. For each created kernel object, a capability is created to it and
359 * put consecutively into the array of CTEs pointed to by 'caps'. The array
360 * needs to have the appropriate size to hold all created caps. Some kernel
361 * objects can have a variable size. In that case, 'objbits' should be non-zero
362 * and give the a size multiplier as 2^'objbits'.
364 * \param type Type of objects to create.
365 * \param addr Base address in the local address space.
366 * \param bits Size of memory area as 2^bits.
367 * \param objbits For variable-sized objects, size multiplier as 2^bits.
368 * \param numobjs Number of objects to be created, from caps_numobjs()
369 * \param dest_caps Pointer to array of CTEs to hold created caps.
373 // If you create more capability types you need to deal with them
374 // in the table below.
375 STATIC_ASSERT(27 == ObjType_Num, "Knowledge of all cap types");
377 static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, uint8_t bits,
378 uint8_t objbits, size_t numobjs, coreid_t owner,
379 struct cte *dest_caps)
383 /* Parameter checking */
384 assert(dest_caps != NULL);
385 assert(type != ObjType_Null);
386 assert(type < ObjType_Num);
389 genpaddr_t genpaddr = local_phys_to_gen_phys(lpaddr);
391 // Virtual address of the memory the kernel object resides in
392 // XXX: A better of doing this,
393 // this is creating caps that the kernel cannot address.
394 // It assumes that the cap is not of the type which will have to zeroed out.
396 if(lpaddr < PADDR_SPACE_LIMIT) {
397 lvaddr = local_phys_to_mem(lpaddr);
402 /* Initialize the created capability */
403 struct capability src_cap;
404 memset(&src_cap, 0, sizeof(struct capability));
406 // XXX: Handle rights!
407 src_cap.rights = CAPRIGHTS_ALLRIGHTS;
409 if (owner == my_core_id) {
410 // If we're creating new local objects, they need to be initialized
411 err = caps_init_objects(type, lpaddr, bits, objbits, numobjs);
412 if (err_is_fail(err)) {
420 /* Set the type specific fields and insert into #dest_caps */
423 TRACE(KERNEL, BZERO, 1);
424 // XXX: SCC hack, while we don't have a devframe allocator
425 if(lpaddr + ((lpaddr_t)1 << bits) < PADDR_SPACE_LIMIT) {
426 memset((void*)lvaddr, 0, (lvaddr_t)1 << bits);
428 printk(LOG_WARN, "Allocating RAM at 0x%" PRIxLPADDR
429 " uninitialized\n", lpaddr);
431 TRACE(KERNEL, BZERO, 0);
432 for(dest_i = 0; dest_i < numobjs; dest_i++) {
433 // Initialize type specific fields
434 src_cap.u.frame.base = genpaddr + dest_i * ((genpaddr_t)1 << objbits);
435 src_cap.u.frame.bits = objbits;
436 // Insert the capabilities
437 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
438 if (err_is_fail(err)) {
444 case ObjType_PhysAddr:
445 for(dest_i = 0; dest_i < numobjs; dest_i++) {
446 // Initialize type specific fields
447 src_cap.u.physaddr.base = genpaddr + dest_i * ((genpaddr_t)1 << objbits);
448 src_cap.u.physaddr.bits = objbits;
449 // Insert the capabilities
450 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
451 if (err_is_fail(err)) {
458 for(dest_i = 0; dest_i < numobjs; dest_i++) {
459 // Initialize type specific fields
460 src_cap.u.ram.base = genpaddr + dest_i * ((genpaddr_t)1 << objbits);
461 src_cap.u.ram.bits = objbits;
462 // Insert the capabilities
463 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
464 if (err_is_fail(err)) {
470 case ObjType_DevFrame:
471 for(dest_i = 0; dest_i < numobjs; dest_i++) {
472 // Initialize type specific fields
473 src_cap.u.devframe.base = genpaddr + dest_i * ((genpaddr_t)1 << objbits);
474 src_cap.u.devframe.bits = objbits;
475 // Insert the capabilities
476 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
477 if (err_is_fail(err)) {
484 assert((1UL << OBJBITS_CTE) >= sizeof(struct cte));
485 TRACE(KERNEL, BZERO, 1);
486 memset((void*)lvaddr, 0, 1UL << bits);
487 TRACE(KERNEL, BZERO, 0);
489 for(dest_i = 0; dest_i < numobjs; dest_i++) {
490 // Initialize type specific fields
491 src_cap.u.cnode.cnode =
492 lpaddr + dest_i * ((lpaddr_t)1 << (objbits + OBJBITS_CTE));
493 src_cap.u.cnode.bits = objbits;
494 src_cap.u.cnode.guard = 0;
495 src_cap.u.cnode.guard_size = 0;
496 // XXX: Handle rights!
497 src_cap.u.cnode.rightsmask = CAPRIGHTS_ALLRIGHTS;
498 // Insert the capability
499 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
500 if (err_is_fail(err)) {
506 case ObjType_VNode_ARM_l1:
508 size_t objbits_vnode = vnode_objbits(type);
510 TRACE(KERNEL, BZERO, 1);
511 memset((void*)lvaddr, 0, 1UL << bits);
512 TRACE(KERNEL, BZERO, 0);
514 for(dest_i = 0; dest_i < numobjs; dest_i++) {
515 // Initialize type specific fields
516 src_cap.u.vnode_arm_l1.base =
517 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
520 // Insert kernel/mem mappings into new table.
522 gen_phys_to_local_phys(
523 local_phys_to_mem(src_cap.u.vnode_arm_l1.base)
529 // Insert the capability
530 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
531 if (err_is_fail(err)) {
539 case ObjType_VNode_ARM_l2:
541 size_t objbits_vnode = vnode_objbits(type);
543 TRACE(KERNEL, BZERO, 1);
544 memset((void*)lvaddr, 0, 1UL << bits);
545 TRACE(KERNEL, BZERO, 0);
547 for(dest_i = 0; dest_i < numobjs; dest_i++) {
548 // Initialize type specific fields
549 src_cap.u.vnode_arm_l2.base =
550 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
552 // Insert the capability
553 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
554 if (err_is_fail(err)) {
561 case ObjType_VNode_x86_32_ptable:
563 size_t objbits_vnode = vnode_objbits(type);
565 TRACE(KERNEL, BZERO, 1);
566 memset((void*)lvaddr, 0, 1UL << bits);
567 TRACE(KERNEL, BZERO, 0);
569 for(dest_i = 0; dest_i < numobjs; dest_i++) {
570 // Initialize type specific fields
571 src_cap.u.vnode_x86_32_ptable.base =
572 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
574 // Insert the capability
575 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
576 if (err_is_fail(err)) {
583 case ObjType_VNode_x86_32_pdir:
585 size_t objbits_vnode = vnode_objbits(type);
587 TRACE(KERNEL, BZERO, 1);
588 memset((void*)lvaddr, 0, 1UL << bits);
589 TRACE(KERNEL, BZERO, 0);
591 for(dest_i = 0; dest_i < numobjs; dest_i++) {
592 // Initialize type specific fields
593 src_cap.u.vnode_x86_32_pdir.base =
594 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
596 #if defined(__i386__) && !defined(CONFIG_PAE)
597 // Make it a good PDE by inserting kernel/mem VSpaces
598 lpaddr = gen_phys_to_local_phys(src_cap.u.vnode_x86_32_pdir.base);
599 paging_x86_32_make_good_pdir(lpaddr);
602 // Insert the capability
603 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
604 if (err_is_fail(err)) {
611 case ObjType_VNode_x86_32_pdpt:
613 size_t objbits_vnode = vnode_objbits(type);
615 TRACE(KERNEL, BZERO, 1);
616 memset((void*)lvaddr, 0, 1UL << bits);
617 TRACE(KERNEL, BZERO, 0);
619 for(dest_i = 0; dest_i < numobjs; dest_i++) {
620 // Initialize type specific fields
621 src_cap.u.vnode_x86_32_pdir.base =
622 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
624 #if defined(__i386__) && defined(CONFIG_PAE)
625 // Make it a good PDPTE by inserting kernel/mem VSpaces
627 gen_phys_to_local_phys(src_cap.u.vnode_x86_32_pdpt.base);
628 paging_x86_32_make_good_pdpte(var);
631 // Insert the capability
632 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
633 if (err_is_fail(err)) {
640 case ObjType_VNode_x86_64_ptable:
642 size_t objbits_vnode = vnode_objbits(type);
644 TRACE(KERNEL, BZERO, 1);
645 memset((void*)lvaddr, 0, 1UL << bits);
646 TRACE(KERNEL, BZERO, 0);
648 for(dest_i = 0; dest_i < numobjs; dest_i++) {
649 // Initialize type specific fields
650 src_cap.u.vnode_x86_64_ptable.base =
651 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
653 // Insert the capability
654 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
655 if (err_is_fail(err)) {
662 case ObjType_VNode_x86_64_pdir:
664 size_t objbits_vnode = vnode_objbits(type);
666 TRACE(KERNEL, BZERO, 1);
667 memset((void*)lvaddr, 0, 1UL << bits);
668 TRACE(KERNEL, BZERO, 0);
670 for(dest_i = 0; dest_i < numobjs; dest_i++) {
671 // Initialize type specific fields
672 src_cap.u.vnode_x86_64_pdir.base =
673 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
675 // Insert the capability
676 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
677 if (err_is_fail(err)) {
684 case ObjType_VNode_x86_64_pdpt:
686 size_t objbits_vnode = vnode_objbits(type);
688 TRACE(KERNEL, BZERO, 1);
689 memset((void*)lvaddr, 0, 1UL << bits);
690 TRACE(KERNEL, BZERO, 0);
692 for(dest_i = 0; dest_i < numobjs; dest_i++) {
693 // Initialize type specific fields
694 src_cap.u.vnode_x86_64_pdpt.base =
695 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
697 // Insert the capability
698 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
699 if (err_is_fail(err)) {
706 case ObjType_VNode_x86_64_pml4:
708 size_t objbits_vnode = vnode_objbits(type);
710 TRACE(KERNEL, BZERO, 1);
711 memset((void*)lvaddr, 0, 1UL << bits);
712 TRACE(KERNEL, BZERO, 0);
714 for(dest_i = 0; dest_i < numobjs; dest_i++) {
715 // Initialize type specific fields
716 src_cap.u.vnode_x86_64_pml4.base =
717 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
719 #if defined(__x86_64__) || defined(__k1om__)
720 // Make it a good PML4 by inserting kernel/mem VSpaces
721 lpaddr_t var = gen_phys_to_local_phys(src_cap.u.vnode_x86_64_pml4.base);
722 paging_x86_64_make_good_pml4(var);
725 // Insert the capability
726 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
727 if (err_is_fail(err)) {
735 case ObjType_Dispatcher:
736 assert((1UL << OBJBITS_DISPATCHER) >= sizeof(struct dcb));
737 TRACE(KERNEL, BZERO, 1);
738 memset((void*)lvaddr, 0, 1UL << bits);
739 TRACE(KERNEL, BZERO, 0);
741 for(dest_i = 0; dest_i < numobjs; dest_i++) {
742 // Initialize type specific fields
743 src_cap.u.dispatcher.dcb = (struct dcb *)
744 (lvaddr + dest_i * (1UL << OBJBITS_DISPATCHER));
745 // Insert the capability
746 err = set_cap(&dest_caps[dest_i].cap, &src_cap);
747 if (err_is_fail(err)) {
754 // ID type does not refer to a kernel object
757 assert(objbits == 0);
758 assert(numobjs == 1);
760 // Prevent wrap around
761 if (id_cap_counter >= UINT32_MAX) {
762 return SYS_ERR_ID_SPACE_EXHAUSTED;
765 // Generate a new ID, core_local_id monotonically increases
766 src_cap.u.id.coreid = my_core_id;
767 src_cap.u.id.core_local_id = id_cap_counter++;
769 // Insert the capability
770 err = set_cap(&dest_caps->cap, &src_cap);
774 src_cap.u.io.start = 0;
775 src_cap.u.io.end = 65535;
780 case ObjType_IRQTable:
781 case ObjType_EndPoint:
782 case ObjType_Notify_RCK:
783 case ObjType_Notify_IPI:
784 case ObjType_PerfMon:
785 // These types do not refer to a kernel object
788 assert(objbits == 0);
789 assert(numobjs == 1);
791 // Insert the capability
792 err = set_cap(&dest_caps->cap, &src_cap);
793 if (err_is_ok(err)) {
798 case ObjType_KernelControlBlock:
799 assert((1UL << OBJBITS_KCB) >= sizeof(struct dcb));
801 for(size_t i = 0; i < numobjs; i++) {
802 // Initialize type specific fields
803 src_cap.u.kernelcontrolblock.kcb = (struct kcb *)
804 (lvaddr + i * (1UL << OBJBITS_DISPATCHER));
805 // Insert the capability
806 err = set_cap(&dest_caps[i].cap, &src_cap);
807 if (err_is_fail(err)) {
814 panic("Unhandled capability type or capability of this type cannot"
818 if (err_is_fail(err)) {
819 // Revert the partially initialized caps to zero
820 for (size_t i = 0; i < dest_i; i++) {
821 memset(&dest_caps[i], 0, sizeof(dest_caps[i]));
826 // Set the owner for all the new caps
827 for (size_t i = 0; i < dest_i; i++) {
828 dest_caps[i].mdbnode.owner = owner;
836 * Look up a capability.
838 * Starting from #cnode_cap, recursively lookup the capability at #cptr
843 errval_t caps_lookup_slot(struct capability *cnode_cap, capaddr_t cptr,
844 uint8_t vbits, struct cte **ret, CapRights rights)
846 TRACE(KERNEL, CAP_LOOKUP_SLOT, 0);
847 /* parameter checking */
848 assert(cnode_cap != NULL);
850 /* Can only resolve CNode type */
851 if (cnode_cap->type != ObjType_CNode) {
852 debug(SUBSYS_CAPS, "caps_lookup_slot: Cap to lookup not of type CNode\n"
853 "cnode_cap->type = %u\n", cnode_cap->type);
854 TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
855 return SYS_ERR_CNODE_TYPE;
858 /* Apply rights to this CNode */
859 if ((cnode_cap->rights & rights) != rights) {
860 debug(SUBSYS_CAPS, "caps_lookup_slot: Rights mismatch\n"
861 "Passed rights = %u, cnode_cap->rights = %u\n",
862 rights, cnode_cap->rights);
863 TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
864 return SYS_ERR_CNODE_RIGHTS;
867 /* Number of bits resolved by this cnode (guard and bits) */
868 uint8_t bits_resolved = cnode_cap->u.cnode.bits +
869 cnode_cap->u.cnode.guard_size;
870 // All CNodes must resolve at least one bit
871 assert(bits_resolved > 0);
872 // If lookup exceeded expected depth then table is malformed
873 if (bits_resolved > vbits) {
874 debug(SUBSYS_CAPS, "caps_lookup_slot: Lookup exceeded valid bits\n"
875 "Cnode bits = %u, guard size = %u, valid bits = %u, bits_resolved = %u\n",
876 cnode_cap->u.cnode.bits, cnode_cap->u.cnode.guard_size,
877 vbits, bits_resolved);
878 TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
879 return SYS_ERR_DEPTH_EXCEEDED;
882 /* Guard-check (bit-mask of guard in cptr must match guard in cnode cap) */
883 capaddr_t cptr_guard = (cptr >> (vbits - cnode_cap->u.cnode.guard_size))
884 & MASK(cnode_cap->u.cnode.guard_size);
885 if (cptr_guard != cnode_cap->u.cnode.guard) {
886 debug(SUBSYS_CAPS, "caps_lookup_slot: guard check failed\n"
887 "Computed guard = %"PRIuCADDR", "
888 "Cnode guard = %"PRIxCADDR", bits = %u\n",
889 cptr_guard, cnode_cap->u.cnode.guard,
890 cnode_cap->u.cnode.guard_size);
891 TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
892 return SYS_ERR_GUARD_MISMATCH;
895 /* Locate capability in this cnode */
896 // Offset into the cnode
897 size_t offset = (cptr >> (vbits - bits_resolved)) &
898 MASK(cnode_cap->u.cnode.bits);
899 // The capability at the offset
900 struct cte *next_slot = caps_locate_slot(cnode_cap->u.cnode.cnode, offset);
901 // Do not return NULL type capability
902 if (next_slot->cap.type == ObjType_Null) {
903 TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
904 return SYS_ERR_CAP_NOT_FOUND;
907 /* Number of bits left to resolve */
908 int bitsleft = vbits - bits_resolved;
909 // If all bits have been resolved, return the capability
912 TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
916 /* If next capability is not of type cnode, return it */
917 // XXX: Is this consistent?
918 if (next_slot->cap.type != ObjType_CNode) {
920 TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
924 /* Descend to next level */
925 return caps_lookup_slot(&next_slot->cap, cptr, bitsleft, ret, rights);
929 * Wrapper for caps_lookup_slot returning capability instead of cte.
931 errval_t caps_lookup_cap(struct capability *cnode_cap, capaddr_t cptr,
932 uint8_t vbits, struct capability **ret, CapRights rights)
934 TRACE(KERNEL, CAP_LOOKUP_CAP, 0);
936 errval_t err = caps_lookup_slot(cnode_cap, cptr, vbits, &ret_cte, rights);
937 if (err_is_fail(err)) {
940 *ret = &ret_cte->cap;
941 TRACE(KERNEL, CAP_LOOKUP_CAP, 1);
946 * \brief Create a capability from an existing capability metadata.
948 * Used when sending capabilities across cores. The metadata is sent across
949 * cores and the receiving monitor can create the new capability on its core.
951 * \bug Does not check that supplied owner matches existing copies of cap.
953 errval_t caps_create_from_existing(struct capability *root, capaddr_t cnode_cptr,
954 int cnode_vbits, cslot_t dest_slot, coreid_t owner,
955 struct capability *src)
957 TRACE(KERNEL, CAP_CREATE_FROM_EXISTING, 0);
959 struct capability *cnode;
960 err = caps_lookup_cap(root, cnode_cptr, cnode_vbits, &cnode,
961 CAPRIGHTS_READ_WRITE);
962 if (err_is_fail(err)) {
963 return err_push(err, SYS_ERR_SLOT_LOOKUP_FAIL);
965 if (cnode->type != ObjType_CNode) {
966 return SYS_ERR_CNODE_TYPE;
969 struct cte *dest = caps_locate_slot(cnode->u.cnode.cnode, dest_slot);
971 err = set_cap(&dest->cap, src);
972 if (err_is_fail(err)) {
976 dest->mdbnode.owner = owner;
978 err = mdb_insert(dest);
979 assert(err_is_ok(err));
981 struct cte *neighbour = NULL;
983 && (neighbour = mdb_predecessor(dest))
984 && !is_copy(&dest->cap, &neighbour->cap))
989 && (neighbour = mdb_successor(dest))
990 && !is_copy(&dest->cap, &neighbour->cap))
996 assert(!neighbour->mdbnode.in_delete);
997 assert(neighbour->mdbnode.owner == owner);
998 #define CP_ATTR(a) dest->mdbnode.a = neighbour->mdbnode.a
1000 CP_ATTR(remote_copies);
1001 CP_ATTR(remote_ancs);
1002 CP_ATTR(remote_descs);
1006 dest->mdbnode.locked = false;
1007 if (owner != my_core_id) {
1008 // For foreign caps it does not really matter if ancestors or
1009 // descendants exist
1010 dest->mdbnode.remote_copies = true;
1011 dest->mdbnode.remote_ancs = false;
1012 dest->mdbnode.remote_descs = false;
1015 // We just created a new copy of a owned capability from nothing.
1016 // This is either caused by a retype, or by sharing a capability
1017 // that does not care about locality.
1018 // XXX: This should probably be done more explicitly -MN
1019 if (distcap_needs_locality(dest->cap.type)) {
1020 // Retype, so have ancestors and no descendants
1021 dest->mdbnode.remote_copies = false;
1022 dest->mdbnode.remote_ancs = true;
1023 dest->mdbnode.remote_descs = false;
1026 dest->mdbnode.remote_copies = false;
1027 dest->mdbnode.remote_ancs = false;
1028 dest->mdbnode.remote_descs = false;
1033 TRACE_CAP_MSG("created", dest);
1035 TRACE(KERNEL, CAP_CREATE_FROM_EXISTING, 1);
1039 /// Create caps to new kernel objects.
1040 errval_t caps_create_new(enum objtype type, lpaddr_t addr, size_t bits,
1041 size_t objbits, coreid_t owner, struct cte *caps)
1043 TRACE(KERNEL, CAP_CREATE_NEW, 0);
1044 /* Parameter checking */
1045 assert(type != ObjType_EndPoint); // Cap of this type cannot be created
1047 size_t numobjs = caps_numobjs(type, bits, objbits);
1048 assert(numobjs > 0);
1050 /* Create the new capabilities */
1051 errval_t err = caps_create(type, addr, bits, objbits, numobjs, owner, caps);
1052 if (err_is_fail(err)) {
1056 // Handle the mapping database
1057 set_init_mapping(caps, numobjs);
1059 TRACE_CAP_MSG("created", &caps[0]);
1061 TRACE(KERNEL, CAP_CREATE_NEW, 1);
1067 errval_t caps_retype(enum objtype type, size_t objbits,
1068 struct capability *dest_cnode, cslot_t dest_slot,
1069 struct cte *src_cte, bool from_monitor)
1071 TRACE(KERNEL, CAP_RETYPE, 0);
1074 genpaddr_t base = 0;
1077 /* Parameter checking */
1078 assert(type != ObjType_Null);
1079 assert(type < ObjType_Num);
1081 struct capability *src_cap = &src_cte->cap;
1083 TRACE_CAP_MSG("retyping", src_cte);
1085 /* Check retypability */
1086 err = is_retypeable(src_cte, src_cap->type, type, from_monitor);
1087 if (err_is_fail(err)) {
1088 debug(SUBSYS_CAPS, "caps_retype: is_retypeable failed\n");
1092 /* Create Destination caps as per source and destination type */
1093 switch(src_cap->type) {
1094 case ObjType_PhysAddr:
1095 bits = src_cap->u.physaddr.bits;
1096 base = src_cap->u.physaddr.base;
1100 bits = src_cap->u.ram.bits;
1101 base = src_cap->u.ram.base;
1104 case ObjType_Dispatcher:
1109 bits = src_cap->u.frame.bits;
1110 base = src_cap->u.frame.base;
1113 case ObjType_DevFrame:
1114 bits = src_cap->u.devframe.bits;
1115 base = src_cap->u.devframe.base;
1119 panic("Unreachable case");
1122 /* determine number of objects to be created */
1123 numobjs = caps_numobjs(type, bits, objbits);
1126 debug(SUBSYS_CAPS, "caps_retype: numobjs == 0\n");
1127 return SYS_ERR_INVALID_SIZE_BITS;
1129 // debug(SUBSYS_CAPS, "caps_retype: numobjs == %d\n", (int)numobjs);
1131 /* check that destination slots all fit within target cnode */
1132 if (dest_slot + numobjs > (1UL << dest_cnode->u.cnode.bits)) {
1133 debug(SUBSYS_CAPS, "caps_retype: dest slots don't fit in cnode\n");
1134 return SYS_ERR_SLOTS_INVALID;
1137 /* check that destination slots are all empty */
1138 debug(SUBSYS_CAPS, "caps_retype: dest cnode is %#" PRIxLPADDR
1140 dest_cnode->u.cnode.cnode, (int)dest_slot);
1141 for (cslot_t i = 0; i < numobjs; i++) {
1142 if (caps_locate_slot(dest_cnode->u.cnode.cnode, dest_slot + i)->cap.type
1144 debug(SUBSYS_CAPS, "caps_retype: dest slot %d in use\n",
1145 (int)(dest_slot + i));
1146 return SYS_ERR_SLOTS_IN_USE;
1150 /* create new caps */
1151 struct cte *dest_cte =
1152 caps_locate_slot(dest_cnode->u.cnode.cnode, dest_slot);
1153 err = caps_create(type, base, bits, objbits, numobjs, my_core_id, dest_cte);
1154 if (err_is_fail(err)) {
1155 debug(SUBSYS_CAPS, "caps_retype: failed to create a dest cap\n");
1156 return err_push(err, SYS_ERR_RETYPE_CREATE);
1159 /* special initialisation for endpoint caps */
1160 if (type == ObjType_EndPoint) {
1161 assert(src_cap->type == ObjType_Dispatcher);
1162 assert(numobjs == 1);
1163 struct capability *dest_cap = &dest_cte->cap;
1164 dest_cap->u.endpoint.listener = src_cap->u.dispatcher.dcb;
1167 /* Handle mapping */
1168 for (size_t i = 0; i < numobjs; i++) {
1169 mdb_insert(&dest_cte[i]);
1172 #ifdef TRACE_PMEM_CAPS
1173 for (size_t i = 0; i < numobjs; i++) {
1174 TRACE_CAP_MSG("created", &dest_cte[i]);
1178 TRACE(KERNEL, CAP_RETYPE, 1);
1182 /// Check the validity of a retype operation
1183 errval_t is_retypeable(struct cte *src_cte, enum objtype src_type,
1184 enum objtype dest_type, bool from_monitor)
1186 if (!is_well_founded(src_type, dest_type)) {
1187 return SYS_ERR_INVALID_RETYPE;
1188 } else if (!is_revoked_first(src_cte, src_type)){
1189 printf("err_revoke_first: (%p, %d, %d)\n", src_cte, src_type, dest_type);
1190 return SYS_ERR_REVOKE_FIRST;
1191 } else if (dest_type == ObjType_EndPoint && src_cte->mdbnode.owner == my_core_id) {
1192 // XXX: because of the current "multi-retype" hack for endpoints, a
1193 // dispatcher->endpoint retype can happen irrespective of the existence
1194 // of descendents on any core.
1195 // Howevery, we only do this for locally owned caps as the owner should
1196 // be notified that the cap has remote descendants
1198 } else if (!from_monitor && (src_cte->mdbnode.owner != my_core_id
1199 || src_cte->mdbnode.remote_descs)) {
1200 return SYS_ERR_RETRY_THROUGH_MONITOR;
1206 /// Create copies to a slot within a cnode
1207 errval_t caps_copy_to_cnode(struct cte *dest_cnode_cte, cslot_t dest_slot,
1208 struct cte *src_cte, bool mint, uintptr_t param1,
1211 /* Parameter Checking */
1212 assert(dest_cnode_cte->cap.type == ObjType_CNode);
1214 struct cte *dest_cte;
1215 dest_cte = caps_locate_slot(dest_cnode_cte->cap.u.cnode.cnode, dest_slot);
1216 return caps_copy_to_cte(dest_cte, src_cte, mint, param1, param2);
1220 /// Create copies to a cte
1221 errval_t caps_copy_to_cte(struct cte *dest_cte, struct cte *src_cte, bool mint,
1222 uintptr_t param1, uintptr_t param2)
1225 /* Parameter checking */
1227 assert(dest_cte != NULL);
1228 assert(src_cte != NULL);
1230 struct capability *src_cap = &src_cte->cap;
1231 struct capability *dest_cap = &dest_cte->cap;
1232 // NULL caps cannot be copied/minted
1233 if (src_cap->type == ObjType_Null) {
1234 return SYS_ERR_CAP_NOT_FOUND;
1236 // Parameters should be 0 if not minting
1238 assert(param1 == 0);
1239 assert(param2 == 0);
1242 assert(!src_cte->mdbnode.in_delete);
1244 /* Insert #source_cap into #dest_cap */
1245 err = set_cap(dest_cap, src_cap);
1246 if (err_is_fail(err)) {
1250 /* Transfer MDB attributes that must be equal for all copies */
1251 #define CP_ATTR(at) dest_cte->mdbnode.at = src_cte->mdbnode.at
1254 CP_ATTR(remote_copies);
1255 CP_ATTR(remote_ancs);
1256 CP_ATTR(remote_descs);
1261 TRACE_CAP_MSG("copied to", dest_cte);
1262 // Handle mapping here only for non-mint operations
1263 // (mint can change eq fields which would make the early insertion
1264 // invalid in some cases)
1265 mdb_insert(dest_cte);
1269 TRACE_CAP_MSG("minting to", dest_cte);
1272 /* For minting, set the specified parameters */
1273 // Process source-specific parameters for minting
1274 // XXX: If failure, revert the insertion
1275 switch(src_cap->type) {
1277 if (param2 > CPTR_BITS) {
1278 return SYS_ERR_GUARD_SIZE_OVERFLOW;
1280 dest_cap->u.cnode.guard = param1;
1281 dest_cap->u.cnode.guard_size = param2;
1284 case ObjType_EndPoint:
1285 // XXX: FIXME: check that buffer offset lies wholly within the disp frame
1286 // can't easily enforce this here, because the dispatcher frame may not
1288 /* if (param1 < sizeof(struct dispatcher) ||
1289 dest_cap->u.endpoint.listener->disp == NULL ||
1290 param2 < IDC_RECV_LENGTH ||
1291 param1 + sizeof(struct idc_endpoint) + param2 * sizeof(uintptr_t) >
1292 (1UL << dest_cap->u.endpoint.listener->disp_cte.cap.u.frame.bits)) {
1293 return SYS_ERR_INVALID_EPBUF;
1295 if (param2 < LMP_RECV_HEADER_LENGTH) {
1296 return SYS_ERR_INVALID_EPLEN;
1298 dest_cap->u.endpoint.epoffset = param1;
1299 dest_cap->u.endpoint.epbuflen = param2;
1303 if(src_cap->u.io.start <= param1) {
1304 dest_cap->u.io.start = param1;
1306 if(src_cap->u.io.end >= param2) {
1307 dest_cap->u.io.end = param2;
1312 // Unhandled source type for mint
1313 return SYS_ERR_INVALID_SOURCE_TYPE;
1316 // Insert after doing minting operation
1317 mdb_insert(dest_cte);
1323 // If you create more capability types you need to deal with them
1324 // in the table below.
1325 STATIC_ASSERT(27 == ObjType_Num, "Knowledge of all cap types");
1329 caps_debug_print(struct cte *c)
1331 printk(LOG_NOTE, "%s\n", __FUNCTION__);
1332 switch (c->cap.type) {
1334 case ObjType_CNode: {
1335 struct CNode *cn = &(c->cap.u.cnode);
1336 for (cslot_t slot = 0; slot < 1UL << cn->bits; slot++) {
1338 errval_t err = caps_debug_print(
1339 (struct cte *) local_phys_to_mem(
1340 cn->cnode + slot * sizeof(*c)));
1341 if (err_is_fail(err)) {
1347 case ObjType_Frame: {
1351 // Unhandled source type for mint
1352 return SYS_ERR_INVALID_SOURCE_TYPE;