1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#pragma once
14
15/* Thread-local storage functionality for CAmkES. */
16
17#include <sel4camkes/gen_config.h>
18
19#include <assert.h>
20#include <sel4/sel4.h>
21#include <stdalign.h>
22#include <stdbool.h>
23#include <stdint.h>
24#include <utils/util.h>
25
26/* Extend this struct as required. */
27typedef struct camkes_tls_t {
28    seL4_CPtr tcb_cap;
29    seL4_CPtr sc_cap;
30    unsigned thread_index;
31
32    /* Cap to our own CNode. May be 0 if we don't have a cap to it. */
33    seL4_CPtr cnode_cap;
34
35    /* Members used for lazy saving of reply caps. See the API below for how to
36     * interact with these members.
37     */
38    seL4_CPtr reply_cap_slot;
39    bool reply_cap_in_tcb;
40    seL4_Error reply_cap_save_error;
41
42} camkes_tls_t;
43extern __thread camkes_tls_t camkes_tls;
44
45static inline camkes_tls_t *camkes_get_tls(void)
46{
47    return &camkes_tls;
48}
49
50#ifndef CONFIG_KERNEL_MCS
51/** Lazy reply cap save and restore functionality. **/
52
53/**
54 * Declare that there is a reply cap currently in your TCB.
55 *
56 *  @param shadow_slot - An empty CSlot to use as the target for saving the
57 *    pending reply cap in future if need be.
58 *  @return 0 on success, non-zero on failure.
59 *
60 * This should be called as soon as possible after receiving a reply cap in
61 * order to be safe guarded against further code overwriting the reply cap. The
62 * caller needs to pass a slot into which to save this pending reply cap if
63 * such a thing needs to be done in the future. Note that we do not support
64 * having more than one pending reply cap (saved or otherwise) at once.
65 */
66int camkes_declare_reply_cap(seL4_CPtr shadow_slot);
67
68/**
69 * Save any pending reply cap from accidental deletion.
70 *
71 * This should be called unconditionally by code that is about to perform an
72 * operation that may overwrite a pending reply cap. Note that this function is
73 * deliberately designed with no return value indicating success or failure
74 * because the caller has no way of responding to this. The reason is that they
75 * likely were not the one responsible for declaring the reply cap and they do
76 * not know what the consequences of its loss are. This function is idempotent.
77 */
78void camkes_protect_reply_cap(void);
79
80/**
81 * Discard information related to the current reply cap.
82 *
83 *  @return seL4_NoError on success, or a syscall error value indicating that
84 *    the prior save of this reply cap failed.
85 *
86 * Calls to this function should be paired with calls to
87 * `camkes_protect_reply_cap`. However, the two calls are likely performed in
88 * unrelated code. Code that needs to conditionally call this function should
89 * examine the value of `camkes_get_tls()->reply_cap_in_tcb` to determine
90 * whether the reply cap is still in their TCB and this function does not need
91 * to be invoked.
92 */
93seL4_Error camkes_unprotect_reply_cap(void);
94#endif
95