blob: d782af81509d2fe16ea5dd54d65ed7d14f8995ac [file] [log] [blame]
// 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 *cra; // c1
void *csp; // c2
void *cgp; // c3
void *ctp; // c4
void *ct0; // c5
void *ct1; // c6
void *ct2; // c7
void *cs0; // c8
void *cs1; // c9
void *ca0; // c10
void *ca1; // c11
void *ca2; // c12
void *ca3; // c13
void *ca4; // c14
void *ca5; // 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;
// Padding up to multiple of 16-bytes.
uint8_t padding[
#ifdef CONFIG_MSHWM
12
#else
4
#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);