seL4/include/object/cnode.h
Matthew Brecknell b2ad98214d avoid passing extra_caps_t by value
The RISC-V calling convention specifies that when a C function takes an
argument by value, the binary function should take the argument by
reference, if the value is larger than 2 pointer words.

For binary verification, we avoid implementing this aspect of the RISC-V
calling convention, by eliminating all such function arguments for
functions which are not inlined.

In this commit, we remove `extra_caps_t` function arguments. This
primarily concerns invocation decode functions. Since `loookupExtraCaps`
already stores extra caps in a global `current_extra_caps`, this
essentially amounts to eliminating many redundant structure copy
operations.

On some execution paths involving IPC, the extra caps lookup may happen
twice: first in the invocation decode, and then for cap transfer in the
performance phase of the IPC operation. Because the two phases are
entirely distinct, there is no interference in the use of a common
global variable.

Even though we are primarily concerned with RISC-V, we remove
`extra_caps_t` arguments across all architectures.

Signed-off-by: Matthew Brecknell <Matthew.Brecknell@data61.csiro.au>
2021-03-19 11:29:51 +11:00

49 lines
1.7 KiB
C

/*
* Copyright 2014, General Dynamics C4 Systems
*
* SPDX-License-Identifier: GPL-2.0-only
*/
#pragma once
#include <types.h>
#include <api/failures.h>
#include <object/structures.h>
struct slot_range {
cte_t *cnode;
word_t offset;
word_t length;
};
typedef struct slot_range slot_range_t;
exception_t decodeCNodeInvocation(word_t invLabel, word_t length,
cap_t cap, word_t *buffer);
exception_t invokeCNodeRevoke(cte_t *destSlot);
exception_t invokeCNodeDelete(cte_t *destSlot);
exception_t invokeCNodeCancelBadgedSends(cap_t cap);
exception_t invokeCNodeInsert(cap_t cap, cte_t *srcSlot, cte_t *destSlot);
exception_t invokeCNodeMove(cap_t cap, cte_t *srcSlot, cte_t *destSlot);
exception_t invokeCNodeRotate(cap_t cap1, cap_t cap2, cte_t *slot1,
cte_t *slot2, cte_t *slot3);
void cteInsert(cap_t newCap, cte_t *srcSlot, cte_t *destSlot);
void cteMove(cap_t newCap, cte_t *srcSlot, cte_t *destSlot);
void capSwapForDelete(cte_t *slot1, cte_t *slot2);
void cteSwap(cap_t cap1, cte_t *slot1, cap_t cap2, cte_t *slot2);
exception_t cteRevoke(cte_t *slot);
exception_t cteDelete(cte_t *slot, bool_t exposed);
void cteDeleteOne(cte_t *slot);
void insertNewCap(cte_t *parent, cte_t *slot, cap_t cap);
bool_t PURE isMDBParentOf(cte_t *cte_a, cte_t *cte_b);
exception_t ensureNoChildren(cte_t *slot);
exception_t ensureEmptySlot(cte_t *slot);
bool_t PURE isFinalCapability(cte_t *cte);
bool_t PURE slotCapLongRunningDelete(cte_t *slot);
cte_t *getReceiveSlots(tcb_t *thread, word_t *buffer);
cap_transfer_t PURE loadCapTransfer(word_t *buffer);
#ifndef CONFIG_KERNEL_MCS
exception_t invokeCNodeSaveCaller(cte_t *destSlot);
void setupReplyMaster(tcb_t *thread);
#endif