// TODO: XXX: multiple mappings? static inline errval_t find_next_ptable(struct cte *mapping_cte, struct cte **next) { assert(mapping_cte); struct Frame_Mapping *mapping = &mapping_cte->cap.u.frame_mapping; /* errval_t err; err = mdb_find_cap_for_address( local_phys_to_gen_phys(mapping->pte), next); if (err_no(err) == CAPS_ERR_CAP_NOT_FOUND || err_no(err) == SYS_ERR_CAP_NOT_FOUND) { debug(SUBSYS_PAGING, "could not find cap associated " "with 0x%"PRIxLPADDR"\n", mapping->pte); return SYS_ERR_VNODE_NOT_INSTALLED; } if (err_is_fail(err)) { debug(SUBSYS_PAGING, "error in compile_vaddr:" " mdb_find_range: 0x%"PRIxERRV"\n", err); return err; } */ if (!mapping->ptable || mapping->ptable->cap.type == ObjType_Null) { return SYS_ERR_VNODE_NOT_INSTALLED; } *next = mapping->ptable; if (!type_is_vnode((*next)->cap.type)) { struct cte *tmp = mdb_predecessor(*next); // check if there's a copy of *next that is a vnode, and return that // copy, if found. while(is_copy(&tmp->cap, &(*next)->cap)) { if (type_is_vnode(tmp->cap.type)) { *next = tmp; return SYS_ERR_OK; } tmp = mdb_predecessor(tmp); } tmp = mdb_successor(*next); while(is_copy(&tmp->cap, &(*next)->cap)) { if (type_is_vnode(tmp->cap.type)) { *next = tmp; return SYS_ERR_OK; } tmp = mdb_successor(tmp); } debug(SUBSYS_CAPS, "found cap not a VNode\n"); // no copy was vnode return SYS_ERR_VNODE_LOOKUP_NEXT; } return SYS_ERR_OK; }
static void sys_lock_cap_common(struct cte *cte, bool lock) { struct cte *pred = cte; do { pred->mdbnode.locked = lock; pred = mdb_predecessor(pred); } while (is_copy(&pred->cap, &cte->cap)); struct cte *succ = cte; do { succ->mdbnode.locked = lock; succ = mdb_successor(succ); } while (is_copy(&succ->cap, &cte->cap)); }
struct sysret sys_get_cap_owner(capaddr_t root_addr, uint8_t root_bits, capaddr_t cptr, uint8_t bits) { errval_t err; struct cte *cte; err = sys_double_lookup(root_addr, root_bits, cptr, bits, &cte); if (err_is_fail(err)) { printf("%s: error in double_lookup: %"PRIuERRV"\n", __FUNCTION__, err); return SYSRET(err); } return (struct sysret) { .error = SYS_ERR_OK, .value = cte->mdbnode.owner }; } struct sysret sys_set_cap_owner(capaddr_t root_addr, uint8_t root_bits, capaddr_t cptr, uint8_t bits, coreid_t owner) { errval_t err; struct cte *cte; err = sys_double_lookup(root_addr, root_bits, cptr, bits, &cte); if (err_is_fail(err)) { printf("%s: error in double_lookup: %"PRIuERRV"\n", __FUNCTION__, err); return SYSRET(err); } cte->mdbnode.owner = owner; TRACE_CAP(cte); struct cte *pred = cte; do { pred->mdbnode.owner = owner; pred = mdb_predecessor(pred); } while (is_copy(&pred->cap, &cte->cap)); struct cte *succ = cte; do { succ->mdbnode.owner = owner; succ = mdb_successor(succ); } while (is_copy(&succ->cap, &cte->cap)); return SYSRET(SYS_ERR_OK); }