/** * \file * \brief Arch-generic capability invocation wrappers specific to the monitors */ /* * Copyright (c) 2007, 2008, 2009, 2010, 2016, ETH Zurich. * All rights reserved. * * This file is distributed under the terms in the attached LICENSE file. * If you do not find this file, copies can be found by writing to: * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group. */ #include "invocations.h" #include // for memset() bool monitor_can_send_cap(struct capability *cap) { /* Cannot send caps of these types so send error */ return !((cap->type == ObjType_Null) || (cap->type == ObjType_EndPointLMP) || (cap->type == ObjType_Dispatcher) || (cap->type == ObjType_Kernel) || (cap->type == ObjType_IRQTable)); } /** * \brief Invoke the kernel cap to acquire the raw metadata of a cap. * * \param cap The cap to identify * \param out Struct to return the metadata */ errval_t monitor_cap_identify(struct capref cap, struct capability *out) { // If it's a NULL cap reference, return a fabricated Null cap if(capref_is_null(cap)) { goto nullcap; } uint8_t level = get_cap_level(cap); capaddr_t caddr = get_cap_addr(cap); errval_t err = invoke_monitor_identify_cap(caddr, level, out); if (err_no(err) == SYS_ERR_IDENTIFY_LOOKUP && err_no(err>>10) == SYS_ERR_CAP_NOT_FOUND) { // XXX: is it ok to return a fabricated null cap when doing cap // identify on an empty slot? -SG, 2013-07-31 goto nullcap; } return err; nullcap: memset(out, 0, sizeof(struct capability)); out->type = ObjType_Null; return SYS_ERR_OK; } /** * \brief Invoke the kernel cap to acquire the raw metadata of a cap that is * located off another domains root cnode * * \param croot The root cnode of the process to which this cap belongs * \param cap The caddr of the cap to identify * \param level CSpace level of the cap to identify * \param out Struct to return the metadata */ errval_t monitor_domains_cap_identify(struct capref croot, capaddr_t cap, int level, struct capability *out) { assert (out != NULL); uint8_t rootcap_level = get_cap_level(croot); capaddr_t rootcap_addr = get_cap_addr(croot); return invoke_monitor_identify_domains_cap(rootcap_addr, rootcap_level, cap, level, out); } /** * Let the kernel know that this capability has remote relations, and read the * resulting remote relation flags. */ errval_t monitor_domcap_remote_relations(struct capref croot, capaddr_t cptr, int level, uint8_t relations, uint8_t mask, uint8_t *ret_relations) { uint8_t rootcap_level = get_cap_level(croot); capaddr_t rootcap_addr = get_cap_addr(croot); return invoke_monitor_remote_relations(rootcap_addr, rootcap_level, cptr, level, relations, mask, ret_relations); } errval_t monitor_remote_relations(struct capref cap, uint8_t relations, uint8_t mask, uint8_t *ret_relations) { uint8_t level = get_cap_level(cap); capaddr_t cptr = get_cap_addr(cap); return monitor_domcap_remote_relations(cap_root, cptr, level, relations, mask, ret_relations); } /** * */ errval_t monitor_cap_has_relations(struct capref cap, uint8_t mask, uint8_t *res) { capaddr_t caddr = get_cap_addr(cap); uint8_t level = get_cap_level(cap); return invoke_monitor_cap_has_relations(caddr, level, mask, res); } /** * \brief Invoke the kernel cap to set the type of #cap to null */ errval_t monitor_nullify_cap(struct capref cap) { capaddr_t caddr = get_cap_addr(cap); uint8_t level = get_cap_level(cap); return invoke_monitor_nullify_cap(caddr, level); } /** * \brief Invoke the kernel cap to create a new cap. * * \param dest Location to place the new cap in. * \param cap Metadata of the cap to create * \param owner Core that currently owns the cap */ errval_t monitor_cap_create(struct capref dest, struct capability *cap, coreid_t owner) { capaddr_t caddr = get_cnode_addr(dest); uint8_t level = get_cnode_level(dest); size_t slot = dest.slot; return invoke_monitor_create_cap((uint64_t*)cap, caddr, level, slot, owner); } /** * \brief Retype a capability on behalf of another domains. Capabilities which * are remote (cross-core) must be retyped through the monitor to maintain * cross-core consistancy. */ errval_t monitor_retype_remote_cap(struct capref dest_start, struct capref src, gensize_t offset, enum objtype newtype, gensize_t objsize, gensize_t count) { // Address of destination cspace capaddr_t dcs_addr = get_croot_addr(dest_start); // Address of the cap to the destination CNode capaddr_t dcn_addr = get_cnode_addr(dest_start); // Depth/Level of destination cnode enum cnode_type dcn_level = get_cnode_level(dest_start); // Address of source cspace capaddr_t scp_root = get_croot_addr(src); // Address of source capability capaddr_t scp_addr = get_cap_addr(src); /*return invoke_monitor_remote_cap_retype(rootcap_addr, rootcap_level, src, offset, newtype, objsize, count, to, slot, level);*/ return invoke_monitor_remote_cap_retype(scp_root, scp_addr, offset, newtype, objsize, count, dcs_addr, dcn_addr,dest_start.slot ,dcn_level); } errval_t monitor_domcap_retype_remote_cap(struct domcapref dest_start, struct domcapref src, gensize_t offset, enum objtype newtype, gensize_t objsize, gensize_t count, capaddr_t slot) { return invoke_monitor_remote_cap_retype(get_croot_addr(src.croot), src.cptr, offset, newtype, objsize, count, get_croot_addr(dest_start.croot), dest_start.cptr ,slot ,dest_start.level); } errval_t monitor_create_caps(struct capref src_root, struct capref dest_root, enum objtype newtype, gensize_t objsize, size_t count, capaddr_t src, int src_level, size_t offset, capaddr_t dest_cn, int dest_level, cslot_t dest_slot) { capaddr_t src_root_cptr = get_cap_addr(src_root); capaddr_t dest_root_cptr = get_cap_addr(dest_root); return invoke_monitor_remote_cap_retype(src_root_cptr, src, offset, newtype, objsize, count, dest_root_cptr, dest_cn, dest_slot, dest_level); } errval_t monitor_copy_if_exists(struct capability* cap, struct capref dest) { capaddr_t croot = get_croot_addr(dest); capaddr_t caddr = get_cnode_addr(dest); uint8_t level = get_cnode_level(dest); size_t slot = dest.slot; return invoke_monitor_copy_existing((uint64_t*)cap, croot, caddr, level, slot); } /** * \brief Determine the current owner of a cap and its copies. */ errval_t monitor_get_cap_owner(struct capref croot, capaddr_t cptr, int level, coreid_t *ret_owner) { capaddr_t root_addr = get_cap_addr(croot); uint8_t root_level = get_cap_level(croot); return invoke_monitor_get_cap_owner(root_addr, root_level, cptr, level, ret_owner); } /** * \brief Change the owner of a cap and its copies. */ errval_t monitor_set_cap_owner(struct capref croot, capaddr_t cptr, int level, coreid_t owner) { capaddr_t root_addr = get_cap_addr(croot); uint8_t root_level = get_cap_level(croot); return invoke_monitor_set_cap_owner(root_addr, root_level, cptr, level, owner); } /** * \brief Lock the cap and its copies */ errval_t monitor_lock_cap(struct capref croot, capaddr_t cptr, int level) { capaddr_t root_addr = get_cap_addr(croot); uint8_t root_level = get_cap_level(croot); return invoke_monitor_lock_cap(root_addr, root_level, cptr, level); } /** * \brief Unlock the cap and its copies */ errval_t monitor_unlock_cap(struct capref croot, capaddr_t cptr, int level) { capaddr_t root_addr = get_cap_addr(croot); uint8_t root_level = get_cap_level(croot); return invoke_monitor_unlock_cap(root_addr, root_level, cptr, level); } errval_t monitor_has_descendants(struct capability *cap, bool *res) { return invoke_monitor_has_descendants((uint64_t*)cap, res); } errval_t monitor_is_retypeable(struct capability *cap, gensize_t offset, gensize_t objsize, size_t count) { return invoke_monitor_is_retypeable((uint64_t*)cap, offset, objsize, count); } errval_t monitor_delete_last(struct capref croot, capaddr_t cptr, int level, struct capref ret_cap) { capaddr_t root_addr = get_cap_addr(croot); uint8_t root_level = get_cap_level(croot); capaddr_t ret_cn = get_cnode_addr(ret_cap); uint8_t ret_cn_level = get_cnode_level(ret_cap); cslot_t ret_slot = ret_cap.slot; return invoke_monitor_delete_last(root_addr, root_level, cptr, level, ret_cn, ret_cn_level, ret_slot); } errval_t monitor_delete_foreigns(struct capref cap) { capaddr_t cptr = get_cap_addr(cap); uint8_t level = get_cap_level(cap); return invoke_monitor_delete_foreigns(cptr, level); } errval_t monitor_revoke_mark_target(struct capref croot, capaddr_t cptr, int level) { capaddr_t root_addr = get_cap_addr(croot); uint8_t root_level = get_cap_level(croot); return invoke_monitor_revoke_mark_target(root_addr, root_level, cptr, level); } errval_t monitor_revoke_mark_relations(struct capability *cap) { return invoke_monitor_revoke_mark_relations((uint64_t*)cap); } errval_t monitor_delete_step(struct capref ret_cap) { return invoke_monitor_delete_step(get_cnode_addr(ret_cap), get_cnode_level(ret_cap), ret_cap.slot); } errval_t monitor_clear_step(struct capref ret_cap) { return invoke_monitor_clear_step(get_cnode_addr(ret_cap), get_cnode_level(ret_cap), ret_cap.slot); }