1/** 2 * \file 3 * \brief Arch-generic capability invocation wrappers specific to the monitors 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich. 8 * All rights reserved. 9 * 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. 13 */ 14 15#include "monitor.h" 16 17bool monitor_can_send_cap(struct capability *cap) 18{ 19 /* Cannot send caps of these types so send error */ 20 return !((cap->type == ObjType_Null) || (cap->type == ObjType_EndPoint) 21 || (cap->type == ObjType_Dispatcher) || (cap->type == ObjType_Kernel) 22 || (cap->type == ObjType_IRQTable)); 23} 24 25/** 26 * \brief Invoke the kernel cap to acquire the raw metadata of a cap. 27 * 28 * \param cap The cap to identify 29 * \param out Struct to return the metadata 30 */ 31errval_t monitor_cap_identify(struct capref cap, struct capability *out) 32{ 33 // If it's a NULL cap reference, return a fabricated Null cap 34 if(capref_is_null(cap)) { 35 goto nullcap; 36 } 37 38 uint8_t level = get_cap_level(cap); 39 capaddr_t caddr = get_cap_addr(cap); 40 errval_t err = invoke_monitor_identify_cap(caddr, level, out); 41 if (err_no(err) == SYS_ERR_IDENTIFY_LOOKUP && 42 err_no(err>>10) == SYS_ERR_CAP_NOT_FOUND) 43 { 44 // XXX: is it ok to return a fabricated null cap when doing cap 45 // identify on an empty slot? -SG, 2013-07-31 46 goto nullcap; 47 } 48 return err; 49 50nullcap: 51 memset(out, 0, sizeof(struct capability)); 52 out->type = ObjType_Null; 53 return SYS_ERR_OK; 54} 55 56 57/** 58 * \brief Invoke the kernel cap to acquire the raw metadata of a cap that is 59 * located off another domains root cnode 60 * 61 * \param croot The root cnode of the process to which this cap belongs 62 * \param cap The caddr of the cap to identify 63 * \param level CSpace level of the cap to identify 64 * \param out Struct to return the metadata 65 */ 66errval_t monitor_domains_cap_identify(struct capref croot, capaddr_t cap, 67 int level, struct capability *out) 68{ 69 assert (out != NULL); 70 71 uint8_t rootcap_level = get_cap_level(croot); 72 capaddr_t rootcap_addr = get_cap_addr(croot); 73 74 return invoke_monitor_identify_domains_cap(rootcap_addr, rootcap_level, 75 cap, level, out); 76} 77 78/** 79 * Let the kernel know that this capability has remote relations, and read the 80 * resulting remote relation flags. 81 */ 82errval_t monitor_domcap_remote_relations(struct capref croot, capaddr_t cptr, 83 int level, uint8_t relations, 84 uint8_t mask, uint8_t *ret_relations) 85{ 86 uint8_t rootcap_level = get_cap_level(croot); 87 capaddr_t rootcap_addr = get_cap_addr(croot); 88 89 return invoke_monitor_remote_relations(rootcap_addr, rootcap_level, 90 cptr, level, relations, mask, 91 ret_relations); 92} 93 94errval_t monitor_remote_relations(struct capref cap, uint8_t relations, 95 uint8_t mask, uint8_t *ret_relations) 96{ 97 uint8_t level = get_cap_level(cap); 98 capaddr_t cptr = get_cap_addr(cap); 99 return monitor_domcap_remote_relations(cap_root, cptr, level, relations, 100 mask, ret_relations); 101} 102 103/** 104 * 105 */ 106 107errval_t monitor_cap_has_relations(struct capref cap, uint8_t mask, 108 uint8_t *res) 109{ 110 capaddr_t caddr = get_cap_addr(cap); 111 uint8_t level = get_cap_level(cap); 112 return invoke_monitor_cap_has_relations(caddr, level, mask, res); 113} 114 115/** 116 * \brief Invoke the kernel cap to set the type of #cap to null 117 */ 118errval_t monitor_nullify_cap(struct capref cap) 119{ 120 capaddr_t caddr = get_cap_addr(cap); 121 uint8_t level = get_cap_level(cap); 122 return invoke_monitor_nullify_cap(caddr, level); 123} 124 125/** 126 * \brief Invoke the kernel cap to create a new cap. 127 * 128 * \param dest Location to place the new cap in. 129 * \param cap Metadata of the cap to create 130 * \param owner Core that currently owns the cap 131 */ 132errval_t monitor_cap_create(struct capref dest, struct capability *cap, 133 coreid_t owner) 134{ 135 capaddr_t caddr = get_cnode_addr(dest); 136 uint8_t level = get_cnode_level(dest); 137 size_t slot = dest.slot; 138 139 return invoke_monitor_create_cap((uint64_t*)cap, caddr, level, slot, owner); 140} 141 142/** 143 * \brief Retype a capability on behalf of another domains. Capabilities which 144 * are remote (cross-core) must be retyped through the monitor to maintain 145 * cross-core consistancy. 146 */ 147errval_t monitor_retype_remote_cap(struct capref croot, capaddr_t src, gensize_t offset, 148 enum objtype newtype, gensize_t objsize, 149 gensize_t count, capaddr_t to, capaddr_t slot, int level) 150{ 151 uint8_t rootcap_level = get_cap_level(croot); 152 capaddr_t rootcap_addr = get_cap_addr(croot); 153 154 return invoke_monitor_remote_cap_retype(rootcap_addr, rootcap_level, src, offset, 155 newtype, objsize, count, to, slot, level); 156} 157 158errval_t monitor_create_caps(struct capref src_root, struct capref dest_root, 159 enum objtype newtype, gensize_t objsize, 160 size_t count, capaddr_t src, 161 int src_level, size_t offset, capaddr_t dest_cn, 162 int dest_level, cslot_t dest_slot) 163{ 164 capaddr_t src_root_cptr = get_cap_addr(src_root); 165 capaddr_t dest_root_cptr = get_cap_addr(dest_root); 166 167 return invoke_monitor_remote_cap_retype(src_root_cptr, src, offset, 168 newtype, objsize, count, 169 dest_root_cptr, dest_cn, 170 dest_slot, dest_level); 171} 172 173errval_t monitor_copy_if_exists(struct capability* cap, struct capref dest) 174{ 175 capaddr_t croot = get_croot_addr(dest); 176 capaddr_t caddr = get_cnode_addr(dest); 177 uint8_t level = get_cnode_level(dest); 178 size_t slot = dest.slot; 179 180 return invoke_monitor_copy_existing((uint64_t*)cap, croot, caddr, level, slot); 181} 182 183/** 184 * \brief Determine the current owner of a cap and its copies. 185 */ 186errval_t monitor_get_cap_owner(struct capref croot, capaddr_t cptr, int level, coreid_t *ret_owner) 187{ 188 capaddr_t root_addr = get_cap_addr(croot); 189 uint8_t root_level = get_cap_level(croot); 190 191 return invoke_monitor_get_cap_owner(root_addr, root_level, cptr, level, ret_owner); 192} 193 194/** 195 * \brief Change the owner of a cap and its copies. 196 */ 197errval_t monitor_set_cap_owner(struct capref croot, capaddr_t cptr, int level, coreid_t owner) 198{ 199 capaddr_t root_addr = get_cap_addr(croot); 200 uint8_t root_level = get_cap_level(croot); 201 202 return invoke_monitor_set_cap_owner(root_addr, root_level, cptr, level, owner); 203} 204 205/** 206 * \brief Lock the cap and its copies 207 */ 208errval_t monitor_lock_cap(struct capref croot, capaddr_t cptr, int level) 209{ 210 capaddr_t root_addr = get_cap_addr(croot); 211 uint8_t root_level = get_cap_level(croot); 212 213 return invoke_monitor_lock_cap(root_addr, root_level, cptr, level); 214} 215 216/** 217 * \brief Unlock the cap and its copies 218 */ 219errval_t monitor_unlock_cap(struct capref croot, capaddr_t cptr, int level) 220{ 221 capaddr_t root_addr = get_cap_addr(croot); 222 uint8_t root_level = get_cap_level(croot); 223 224 return invoke_monitor_unlock_cap(root_addr, root_level, cptr, level); 225} 226 227errval_t monitor_has_descendants(struct capability *cap, bool *res) 228{ 229 return invoke_monitor_has_descendants((uint64_t*)cap, res); 230} 231 232errval_t monitor_is_retypeable(struct capability *cap, gensize_t offset, 233 gensize_t objsize, size_t count) 234{ 235 return invoke_monitor_is_retypeable((uint64_t*)cap, offset, objsize, count); 236} 237 238errval_t monitor_delete_last(struct capref croot, capaddr_t cptr, int level, struct capref ret_cap) 239{ 240 capaddr_t root_addr = get_cap_addr(croot); 241 uint8_t root_level = get_cap_level(croot); 242 capaddr_t ret_cn = get_cnode_addr(ret_cap); 243 uint8_t ret_cn_level = get_cnode_level(ret_cap); 244 cslot_t ret_slot = ret_cap.slot; 245 return invoke_monitor_delete_last(root_addr, root_level, cptr, level, 246 ret_cn, ret_cn_level, ret_slot); 247} 248 249errval_t monitor_delete_foreigns(struct capref cap) 250{ 251 capaddr_t cptr = get_cap_addr(cap); 252 uint8_t level = get_cap_level(cap); 253 return invoke_monitor_delete_foreigns(cptr, level); 254} 255 256errval_t monitor_revoke_mark_target(struct capref croot, capaddr_t cptr, 257 int level) 258{ 259 capaddr_t root_addr = get_cap_addr(croot); 260 uint8_t root_level = get_cap_level(croot); 261 return invoke_monitor_revoke_mark_target(root_addr, root_level, cptr, level); 262} 263 264errval_t monitor_revoke_mark_relations(struct capability *cap) 265{ 266 return invoke_monitor_revoke_mark_relations((uint64_t*)cap); 267} 268 269errval_t monitor_delete_step(struct capref ret_cap) 270{ 271 return invoke_monitor_delete_step(get_cnode_addr(ret_cap), 272 get_cnode_level(ret_cap), 273 ret_cap.slot); 274} 275 276errval_t monitor_clear_step(struct capref ret_cap) 277{ 278 return invoke_monitor_clear_step(get_cnode_addr(ret_cap), 279 get_cnode_level(ret_cap), 280 ret_cap.slot); 281} 282