/** * Common code for copying and minting except the mint flag and param passing */ struct sysret sys_copy_or_mint(struct capability *root, capaddr_t destcn_cptr, cslot_t dest_slot, capaddr_t source_cptr, int destcn_vbits, int source_vbits, uintptr_t param1, uintptr_t param2, bool mint) { errval_t err; if (!mint) { param1 = param2 = 0; } /* Lookup source cap */ struct cte *src_cap; err = caps_lookup_slot(root, source_cptr, source_vbits, &src_cap, CAPRIGHTS_READ); if (err_is_fail(err)) { return SYSRET(err_push(err, SYS_ERR_SOURCE_CAP_LOOKUP)); } /* Lookup destination cnode cap */ struct cte *dest_cnode_cap; err = caps_lookup_slot(root, destcn_cptr, destcn_vbits, &dest_cnode_cap, CAPRIGHTS_READ_WRITE); if (err_is_fail(err)) { return SYSRET(err_push(err, SYS_ERR_DEST_CNODE_LOOKUP)); } /* Perform copy */ if (dest_cnode_cap->cap.type == ObjType_CNode) { return SYSRET(caps_copy_to_cnode(dest_cnode_cap, dest_slot, src_cap, mint, param1, param2)); } else { return SYSRET(SYS_ERR_DEST_TYPE_INVALID); } }
struct sysret sys_monitor_copy_existing(struct capability *src, capaddr_t cnode_cptr, uint8_t cnode_vbits, cslot_t slot) { struct cte *copy = mdb_find_equal(src); if (!copy || copy->mdbnode.in_delete) { return SYSRET(SYS_ERR_CAP_NOT_FOUND); } struct cte *cnode; errval_t err = caps_lookup_slot(&dcb_current->cspace.cap, cnode_cptr, cnode_vbits, &cnode, CAPRIGHTS_READ_WRITE); if (err_is_fail(err)) { return SYSRET(err_push(err, SYS_ERR_SLOT_LOOKUP_FAIL)); } if (cnode->cap.type != ObjType_CNode) { return SYSRET(SYS_ERR_CNODE_TYPE); } return SYSRET(caps_copy_to_cnode(cnode, slot, copy, false, 0, 0)); }