| // Copyright Microsoft and CHERIoT Contributors. | |
| // SPDX-License-Identifier: MIT | |
| #pragma once | |
| #include <cdefs.h> | |
| #include <cheri.hh> | |
| #include <stddef.h> | |
| #include <stdint.h> | |
| struct TrustedStackFrame | |
| { | |
| /// caller's stack | |
| void *csp; | |
| /** | |
| * The callee's export table. This is stored here so that we can find the | |
| * compartment's error handler, if we need to invoke the error handler | |
| * during this call. | |
| */ | |
| void *calleeExportTable; | |
| /** | |
| * Value indicating the number of times that this compartment invocation | |
| * has faulted. This is incremented whenever we hit a fault in the | |
| * compartment and then again once it returns. This means that the low bit | |
| * indicates whether we're currently processing a fault. A double fault | |
| * will forcibly unwind the stack. | |
| */ | |
| uint16_t errorHandlerCount; | |
| }; | |
| template<size_t NFrames> | |
| struct TrustedStackGeneric | |
| { | |
| void *mepcc; | |
| void *c1; | |
| void *csp; | |
| void *cgp; | |
| void *c4; | |
| void *c5; | |
| void *c6; | |
| void *c7; | |
| void *c8; | |
| void *c9; | |
| void *c10; | |
| void *c11; | |
| void *c12; | |
| void *c13; | |
| void *c14; | |
| void *c15; | |
| void *hazardPointers; | |
| size_t mstatus; | |
| size_t mcause; | |
| #ifdef CONFIG_MSHWM | |
| uint32_t mshwm; | |
| uint32_t mshwmb; | |
| #endif | |
| uint16_t frameoffset; | |
| /** | |
| * The ID of the current thread. Never modified during execution. | |
| */ | |
| uint16_t threadID; | |
| /** | |
| * Flag indicating whether this thread is in the process of a forced | |
| * unwind. If so, this is one, otherwise it is zero. | |
| */ | |
| uint8_t inForcedUnwind; | |
| // Padding up to multiple of 16-bytes. | |
| uint8_t padding[ | |
| #ifdef CONFIG_MSHWM | |
| 11 | |
| #else | |
| 3 | |
| #endif | |
| ]; | |
| /** | |
| * The trusted stack. There is always one frame, describing the entry | |
| * point. If this is popped then we have run off the stack and the thread | |
| * will exit. | |
| */ | |
| TrustedStackFrame frames[NFrames + 1]; | |
| }; | |
| using TrustedStack = TrustedStackGeneric<0>; | |
| #include "trusted-stack-assembly.h" | |
| static_assert( | |
| CheckSize<COMPARTMENT_STACK_PERMISSIONS, | |
| CHERI::PermissionSet{CHERI::Permission::Load, | |
| CHERI::Permission::Store, | |
| CHERI::Permission::LoadStoreCapability, | |
| CHERI::Permission::LoadMutable, | |
| CHERI::Permission::StoreLocal, | |
| CHERI::Permission::LoadGlobal} | |
| .as_raw()>::value); |