1/** 2 * \file 3 * \brief Capability invocations specific to the monitors 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, 2010, 2012, 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, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#ifndef MONITOR_INVOCATIONS_ARCH_H 16#define MONITOR_INVOCATIONS_ARCH_H 17 18#include <barrelfish/syscall_arch.h> 19#include <barrelfish/caddr.h> 20#include <barrelfish/invocations_arch.h> 21#include <barrelfish_kpi/cpu.h> 22#include <barrelfish_kpi/syscall_overflows_arch.h> 23#include <barrelfish_kpi/syscalls.h> 24 25static inline errval_t 26invoke_monitor_remote_relations(capaddr_t root_cap, int root_bits, 27 capaddr_t cap, int bits, 28 uint8_t relations, uint8_t mask, 29 uint8_t *ret_remote_relations) 30{ 31 struct sysret r = cap_invoke6(cap_kernel, KernelCmd_Remote_relations, 32 root_cap, root_bits, cap, bits, 33 ((uint16_t)relations) | (((uint16_t)mask)<<8)); 34 if (err_is_ok(r.error) && ret_remote_relations) { 35 *ret_remote_relations = r.value; 36 } 37 return r.error; 38} 39 40static inline errval_t 41invoke_monitor_cap_has_relations(capaddr_t caddr, uint8_t bits, uint8_t mask, 42 uint8_t *res) 43{ 44 assert(res); 45 struct sysret ret = cap_invoke4(cap_kernel, KernelCmd_Cap_has_relations, 46 caddr, bits, mask); 47 if (err_is_ok(ret.error)) { 48 *res = ret.value; 49 } 50 return ret.error; 51} 52 53static inline errval_t 54invoke_monitor_identify_cap(capaddr_t cap, int bits, struct capability *out) 55{ 56 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 57 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 58 59 return syscall5((invoke_bits << 16) | (KernelCmd_Identify_cap << 8) 60 | SYSCALL_INVOKE, invoke_cptr, cap, bits, 61 (uintptr_t)out).error; 62} 63 64static inline errval_t 65invoke_monitor_identify_domains_cap(capaddr_t root_cap, int root_bits, 66 capaddr_t cap, int bits, 67 struct capability *out) 68{ 69 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 70 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 71 72 return syscall7((invoke_bits << 16) | (KernelCmd_Identify_domains_cap << 8) 73 | SYSCALL_INVOKE, invoke_cptr, root_cap, root_bits, 74 cap, bits, (uintptr_t)out).error; 75} 76 77static inline errval_t 78invoke_monitor_nullify_cap(capaddr_t cap, int bits) 79{ 80 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 81 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 82 83 return syscall4((invoke_bits << 16) | (KernelCmd_Nullify_cap << 8) 84 | SYSCALL_INVOKE, invoke_cptr, cap, bits).error; 85} 86 87static inline errval_t 88invoke_monitor_create_cap(uint64_t *raw, capaddr_t caddr, int bits, 89 capaddr_t slot, coreid_t owner) 90{ 91 assert(sizeof(struct capability) <= 3*sizeof(uint64_t)); 92 93 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 94 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 95 96 return syscall7((invoke_bits << 16) | (KernelCmd_Create_cap << 8) 97 | SYSCALL_INVOKE, invoke_cptr, caddr, bits, slot, owner, 98 (uintptr_t)raw).error; 99} 100 101static inline errval_t 102invoke_monitor_register(struct capref ep) 103{ 104 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 105 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 106 107 return syscall3((invoke_bits << 16) | (KernelCmd_Register << 8) 108 | SYSCALL_INVOKE, invoke_cptr, get_cap_addr(ep)).error; 109} 110 111/** 112 * \brief Set up tracing in the kernel 113 * 114 */ 115static inline errval_t 116invoke_trace_setup(struct capref cap) 117{ 118 USER_PANIC("NYI"); 119 return LIB_ERR_NOT_IMPLEMENTED; 120#if 0 121 struct idc_send_msg msg; 122 idc_msg_init(&msg); 123 idc_msg_encode_word(&msg, KernelCmd_Setup_trace); 124 idc_msg_encode_word(&msg, get_cap_addr(cap)); 125 return cap_invoke(cap_kernel, &msg); 126#endif 127} 128 129static inline errval_t 130invoke_domain_id(struct capref cap, domainid_t domain_id) 131{ 132 USER_PANIC("NYI"); 133 return LIB_ERR_NOT_IMPLEMENTED; 134#if 0 135 struct idc_send_msg msg; 136 idc_msg_init(&msg); 137 idc_msg_encode_word(&msg, KernelCmd_Domain_Id); 138 idc_msg_encode_word(&msg, get_cap_addr(cap)); 139 idc_msg_encode_word(&msg, domain_id); 140 return cap_invoke(cap_kernel, &msg); 141#endif 142} 143 144static inline errval_t 145invoke_monitor_ipi_register(struct capref ep, int chanid) 146{ 147 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 148 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 149 150 return syscall4((invoke_bits << 16) | (KernelCmd_IPI_Register << 8) 151 | SYSCALL_INVOKE, invoke_cptr, 152 get_cap_addr(ep), 153 chanid).error; 154} 155 156static inline errval_t 157invoke_monitor_ipi_delete(int chanid) 158{ 159 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 160 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 161 162 return syscall3((invoke_bits << 16) | (KernelCmd_IPI_Delete << 8) 163 | SYSCALL_INVOKE, invoke_cptr, 164 chanid).error; 165} 166 167static inline errval_t 168invoke_monitor_get_arch_id(uintptr_t *arch_id) 169{ 170 assert(arch_id != NULL); 171 172 struct sysret sysret = cap_invoke1(cap_kernel, KernelCmd_Get_arch_id); 173 if (sysret.error == SYS_ERR_OK) { 174 *arch_id = sysret.value; 175 } 176 return sysret.error; 177} 178 179static inline errval_t invoke_monitor_sync_timer(uint64_t synctime) 180{ 181 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 182 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 183 184 return syscall4((invoke_bits << 16) | (KernelCmd_Sync_timer << 8) 185 | SYSCALL_INVOKE, invoke_cptr, synctime >> 32, 186 synctime & 0xffffffff).error; 187} 188 189static inline errval_t 190invoke_monitor_add_kcb(uintptr_t kcb_base) 191{ 192 assert(kcb_base); 193 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 194 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 195 196 return syscall3((invoke_bits << 16) | (KernelCmd_Add_kcb << 8) | SYSCALL_INVOKE, 197 invoke_cptr, 198 kcb_base).error; 199} 200 201static inline errval_t 202invoke_monitor_remove_kcb(uintptr_t kcb_base) 203{ 204 assert(kcb_base); 205 206 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 207 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 208 209 return syscall3((invoke_bits << 16) | (KernelCmd_Remove_kcb << 8) | SYSCALL_INVOKE, 210 invoke_cptr, 211 kcb_base).error; 212} 213 214static inline errval_t 215invoke_monitor_suspend_kcb_scheduler(bool suspend) 216{ 217 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 218 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 219 220 return syscall3((invoke_bits << 16) | (KernelCmd_Suspend_kcb_sched << 8) | SYSCALL_INVOKE, 221 invoke_cptr, 222 suspend).error; 223} 224 225static inline errval_t 226invoke_monitor_remote_cap_retype(capaddr_t rootcap_addr, uint8_t rootcap_vbits, 227 capaddr_t src, enum objtype newtype, 228 int objbits, capaddr_t to, capaddr_t slot, 229 int bits) 230{ 231 uint8_t invoke_bits = get_cap_valid_bits(cap_kernel); 232 capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits); 233 234 assert(newtype <= ObjType_Num); 235 assert(objbits <= 0xff); 236 assert(bits <= 0xff); 237 238 struct remote_retype_syscall_overflow rootcap_struct = { 239 .rootcap_addr = rootcap_addr, 240 .rootcap_vbits = rootcap_vbits, 241 }; 242 243 // arguments 2-5 must match the deserialisation in 244 // kernel/arch/x86_32/handle_retype_common. 245 return syscall7((invoke_bits << 16) | (KernelCmd_Retype << 8) | SYSCALL_INVOKE, 246 invoke_cptr, (uintptr_t)&rootcap_struct, src, 247 (newtype << 16) | (objbits << 8) | bits, to, slot).error; 248} 249 250static inline errval_t 251invoke_monitor_copy_existing(uint64_t *raw, capaddr_t cn_addr, int cn_bits, cslot_t slot) 252{ 253 // XXX: this is assumed in client code of this function! 254 assert(sizeof(struct capability) <= 3*sizeof(uint64_t)); 255 256 return cap_invoke5(cap_kernel, KernelCmd_Copy_existing, 257 cn_addr, cn_bits, slot, (uintptr_t)raw).error; 258} 259 260static inline errval_t 261invoke_monitor_get_cap_owner(capaddr_t root, int rbits, capaddr_t cap, int cbits, coreid_t *ret_owner) 262{ 263 struct sysret sysret = cap_invoke5(cap_kernel, KernelCmd_Get_cap_owner, 264 root, rbits, cap, cbits); 265 if (err_is_ok(sysret.error)) { 266 *ret_owner = sysret.value; 267 } 268 return sysret.error; 269} 270 271static inline errval_t 272invoke_monitor_set_cap_owner(capaddr_t root, int rbits, capaddr_t cap, int cbits, coreid_t owner) 273{ 274 return cap_invoke6(cap_kernel, KernelCmd_Set_cap_owner, root, rbits, cap, cbits, owner).error; 275} 276 277static inline errval_t 278invoke_monitor_lock_cap(capaddr_t root, int rbits, capaddr_t cap, int cbits) 279{ 280 return cap_invoke5(cap_kernel, KernelCmd_Lock_cap, root, rbits, cap, cbits).error; 281} 282 283static inline errval_t 284invoke_monitor_unlock_cap(capaddr_t root, int rbits, capaddr_t cap, int cbits) 285{ 286 return cap_invoke5(cap_kernel, KernelCmd_Unlock_cap, root, rbits, cap, cbits).error; 287} 288 289static inline errval_t 290invoke_monitor_delete_last(capaddr_t root, int rbits, capaddr_t cap, int cbits, 291 capaddr_t retcn, int retcnbits, cslot_t retslot) 292{ 293 assert(rbits <= 0xff); 294 assert(cbits <= 0xff); 295 assert(retcnbits <= 0xff); 296 297 return cap_invoke6(cap_kernel, KernelCmd_Delete_last, root, cap, 298 retcn, retslot, ((cbits<<16)|(rbits<<8)|retcnbits)).error; 299} 300 301static inline errval_t 302invoke_monitor_delete_foreigns(capaddr_t cap, int bits) 303{ 304 return cap_invoke3(cap_kernel, KernelCmd_Delete_foreigns, cap, bits).error; 305} 306 307static inline errval_t 308invoke_monitor_revoke_mark_target(capaddr_t root, int rbits, 309 capaddr_t cap, int cbits) 310{ 311 return cap_invoke5(cap_kernel, KernelCmd_Revoke_mark_target, 312 root, rbits, cap, cbits).error; 313} 314 315static inline errval_t 316invoke_monitor_revoke_mark_relations(uint64_t *raw_base) 317{ 318 // XXX: this is assumed in client code of this function! 319 assert(sizeof(struct capability) <= 3*sizeof(uint64_t)); 320 return cap_invoke2(cap_kernel, KernelCmd_Revoke_mark_relations, 321 (uintptr_t)raw_base).error; 322} 323 324static inline errval_t 325invoke_monitor_delete_step(capaddr_t retcn, int retcnbits, cslot_t retslot) 326{ 327 return cap_invoke4(cap_kernel, KernelCmd_Delete_step, 328 retcn, retcnbits, retslot).error; 329} 330 331static inline errval_t 332invoke_monitor_clear_step(capaddr_t retcn, int retcnbits, cslot_t retslot) 333{ 334 return cap_invoke4(cap_kernel, KernelCmd_Clear_step, 335 retcn, retcnbits, retslot).error; 336} 337 338static inline errval_t 339invoke_monitor_has_descendants(uint64_t *raw, bool *res) 340{ 341 // XXX: this is assumed in client code of this function! 342 assert(sizeof(struct capability) <= 3*sizeof(uint64_t)); 343 344 struct sysret sysret; 345 sysret = cap_invoke2(cap_kernel, KernelCmd_Has_descendants, 346 (uintptr_t)raw); 347 if (err_is_ok(sysret.error)) { 348 *res = sysret.value; 349 } 350 return sysret.error; 351} 352 353#endif 354