struct sysret sys_monitor_remote_relations(capaddr_t root_addr, uint8_t root_bits, capaddr_t cptr, uint8_t bits, uint8_t relations, uint8_t mask) { 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); } #ifdef TRACE_PMEM_CAPS if (caps_should_trace(&cte->cap)) { char buf[512]; static const char chars[] = "~~01"; #define MK01(b) ((int)((b)!=0)) #define BITC(BIT) (chars[(2*MK01(mask & BIT)+MK01(relations & BIT))]) snprintf(buf, 512, "set remote: c %c, a %c, d %c", BITC(RRELS_COPY_BIT), BITC(RRELS_ANCS_BIT), BITC(RRELS_DESC_BIT)); #undef BITC #undef MK01 TRACE_CAP_MSG(buf, cte); } #endif if (mask) { mdb_set_relations(cte, relations, mask); } relations = 0; if (cte->mdbnode.remote_copies) { relations |= RRELS_COPY_BIT; } if (cte->mdbnode.remote_ancs) { relations |= RRELS_ANCS_BIT; } if (cte->mdbnode.remote_descs) { relations |= RRELS_DESC_BIT; } return (struct sysret){ .error = SYS_ERR_OK, .value = relations }; }
/** * \brief Cleanup a cap copy but not the object represented by the cap */ static errval_t cleanup_copy(struct cte *cte) { errval_t err; TRACE_CAP_MSG("cleaning up copy", cte); struct capability *cap = &cte->cap; if (type_is_vnode(cap->type) || cap->type == ObjType_Frame || cap->type == ObjType_DevFrame) { unmap_capability(cte); } if (distcap_is_foreign(cte)) { TRACE_CAP_MSG("cleaning up non-owned copy", cte); if (cte->mdbnode.remote_copies || cte->mdbnode.remote_descs) { struct cte *ancestor = mdb_find_ancestor(cte); if (ancestor) { mdb_set_relations(ancestor, RRELS_DESC_BIT, RRELS_DESC_BIT); } } } err = mdb_remove(cte); if (err_is_fail(err)) { return err; } TRACE_CAP_MSG("cleaned up copy", cte); assert(!mdb_reachable(cte)); memset(cte, 0, sizeof(*cte)); return SYS_ERR_OK; }