aos/usr/init/distops/invocations.c
Daniel Schwyn 6d444bf552 Main handout
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>
2022-03-03 14:57:51 +01:00

298 lines
10 KiB
C

/**
* \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 <string.h> // 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);
}