T191: Implement prototype for new retype
[barrelfish] / kernel / include / capabilities.h
1 /**
2  * \file
3  * \brief Kernel capability management.
4  */
5
6 /*
7  * Copyright (c) 2007-2009,2011, ETH Zurich.
8  * Copyright (c) 2015, Hewlett Packard Enterprise Development LP.
9  * All rights reserved.
10  *
11  * This file is distributed under the terms in the attached LICENSE file.
12  * If you do not find this file, copies can be found by writing to:
13  * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
14  */
15
16 #ifndef CAPABILITIES_H
17 #define CAPABILITIES_H
18
19 #include <barrelfish_kpi/capabilities.h>
20 #include <mdb/mdb.h>
21 #include <offsets.h>
22 #include <cap_predicates.h>
23 #include <paging_generic.h>
24
25 struct cte;
26
27 #define DELETE_LIST_SIZE (sizeof(uint64_t))
28 struct delete_list {
29     struct cte *next;
30     // make sure delete list is always the same size!
31     char padding[DELETE_LIST_SIZE - sizeof(struct cte*)];
32 };
33
34 #ifndef ROUND_UP
35 #define ROUND_UP(n, size)           ((((n) + (size) - 1)) & (~((size) - 1)))
36 #endif
37
38 STATIC_ASSERT((ROUND_UP(sizeof(struct capability), 8)
39                + ROUND_UP(sizeof(struct mdbnode), 8)
40                + sizeof(struct delete_list))
41                <= (1UL << OBJBITS_CTE),
42               "cap+mdbnode fit in cte");
43
44 STATIC_ASSERT(sizeof(enum objtype) == 1, "short enums work");
45
46 /**
47  * \brief A CTE (Capability Table Entry).
48  *
49  * A CTE is an entry in a CNode, which in turn is an entry in CSpace, the
50  * capability space. CSpace is a guarded tree structure. Refer to the seL4
51  * reference manual for further information about how CSpace is implemented.
52  */
53 struct cte {
54     struct capability   cap;            ///< The capability
55     char padding0[ROUND_UP(sizeof(struct capability), 8)- sizeof(struct capability)];
56     struct mdbnode      mdbnode;        ///< MDB "root" node for the cap
57     char padding1[ROUND_UP(sizeof(struct mdbnode), 8) - sizeof(struct mdbnode)];
58     struct delete_list  delete_node;    ///< State for in-progress delete cascades
59
60     /// Padding to fill the struct out to the size required by OBJBITS_CTE
61     char padding[(1UL << OBJBITS_CTE)
62                  - sizeof(struct delete_list)
63                  - ROUND_UP(sizeof(struct capability), 8)
64                  - ROUND_UP(sizeof(struct mdbnode), 8)];
65 };
66
67 STATIC_ASSERT_SIZEOF(struct cte, (1UL << OBJBITS_CTE));
68
69 static inline struct cte *caps_locate_slot(lpaddr_t cnode, cslot_t offset)
70 {
71     return (struct cte *)(local_phys_to_mem(cnode) +
72                           (1UL << OBJBITS_CTE) * offset);
73 }
74
75 static inline struct cte *cte_for_cap(struct capability *cap)
76 {
77     return (struct cte *) ((char *)cap - offsetof(struct cte, cap));
78 }
79
80 int sprint_cap(char *buf, size_t len, struct capability *cap);
81 void caps_trace(const char *func, int line, struct cte *cte, const char *msg);
82 errval_t caps_create_new(enum objtype type, lpaddr_t addr, size_t bits,
83                          size_t objbits, coreid_t owner, struct cte *caps);
84 errval_t caps_create_from_existing(struct capability *root, capaddr_t cnode_cptr,
85                                    int cnode_vbits, cslot_t dest_slot,
86                                    coreid_t owner, struct capability *src);
87 errval_t caps_copy_to_cnode(struct cte *dest_cnode_cte, cslot_t dest_slot,
88                             struct cte *src_cte, bool mint, uintptr_t param1,
89                             uintptr_t param2);
90 errval_t caps_copy_to_cte(struct cte *dest_cte, struct cte *src_cte, bool mint,
91                           uintptr_t param1, uintptr_t param2);
92 errval_t caps_copy_to_vnode(struct cte *dest_vnode_cte, cslot_t dest_slot,
93                             struct cte *src_cte, uintptr_t flags,
94                             uintptr_t offset, uintptr_t pte_count,
95                             struct cte *mapping_cte);
96 size_t do_unmap(lvaddr_t pt, cslot_t slot, size_t num_pages);
97 errval_t page_mappings_unmap(struct capability *pgtable, struct cte *mapping);
98 errval_t page_mappings_modify_flags(struct capability *mapping, size_t offset,
99                                     size_t pages, size_t mflags,
100                                     genvaddr_t va_hint);
101 errval_t paging_modify_flags(struct capability *frame, uintptr_t offset,
102                              uintptr_t pages, uintptr_t kpi_paging_flags);
103 void paging_dump_tables(struct dcb *dispatcher);
104
105 errval_t caps_retype(enum objtype type, size_t objbits,
106                      struct capability *dest_cnode,
107                      cslot_t dest_slot, struct cte *src_cte,
108                      bool from_monitor);
109 errval_t caps_retype2(enum objtype type, gensize_t objsize, size_t count,
110                       struct capability *dest_cnode, cslot_t dest_slot,
111                       struct cte *src_cte, gensize_t offset,
112                       bool from_monitor);
113 errval_t is_retypeable(struct cte *src_cte,
114                        enum objtype src_type,
115                        enum objtype dest_type,
116                        bool from_monitor);
117
118 errval_t caps_lookup_cap(struct capability *cnode_cap, capaddr_t cptr,
119                          uint8_t vbits, struct capability **ret,
120                          CapRights rights);
121 errval_t caps_lookup_slot(struct capability *cnode_cap, capaddr_t cptr,
122                           uint8_t vbits, struct cte **ret, CapRights rights);
123
124 /*
125  * Delete and revoke
126  */
127
128 errval_t caps_delete_last(struct cte *cte, struct cte *ret_ram_cap);
129 errval_t caps_delete_foreigns(struct cte *cte);
130 errval_t caps_mark_revoke(struct capability *base, struct cte *revoked);
131 errval_t caps_delete_step(struct cte *ret_next);
132 errval_t caps_clear_step(struct cte *ret_ram_cap);
133 errval_t caps_delete(struct cte *cte);
134 errval_t caps_revoke(struct cte *cte);
135
136 /*
137  * Cap tracing
138  */
139 #ifdef TRACE_PMEM_CAPS
140 STATIC_ASSERT(44 == ObjType_Num, "knowledge of all cap types");
141 STATIC_ASSERT(64 >= ObjType_Num, "cap types fit in uint64_t bitfield");
142 #define MAPPING_TYPES \
143     ((1ull<<ObjType_VNode_x86_64_pml4_Mapping) | \
144      (1ull<<ObjType_VNode_x86_64_pdpt_Mapping) | \
145      (1ull<<ObjType_VNode_x86_64_pdir_Mapping) | \
146      (1ull<<ObjType_VNode_x86_64_ptable_Mapping) | \
147      (1ull<<ObjType_VNode_x86_32_pdpt_Mapping) | \
148      (1ull<<ObjType_VNode_x86_32_pdir_Mapping) | \
149      (1ull<<ObjType_VNode_x86_32_ptable_Mapping) | \
150      (1ull<<ObjType_VNode_ARM_l1_Mapping) | \
151      (1ull<<ObjType_VNode_ARM_l2_Mapping) | \
152      (1ull<<ObjType_VNode_AARCH64_l1_Mapping) | \
153      (1ull<<ObjType_VNode_AARCH64_l2_Mapping) | \
154      (1ull<<ObjType_VNode_AARCH64_l3_Mapping) | \
155      (1ull<<ObjType_Frame_Mapping) | \
156      (1ull<<ObjType_DevFrame_Mapping))
157
158 #define ALL_PMEM_TYPES \
159     ((1ull<<ObjType_RAM) | \
160      (1ull<<ObjType_Frame) | \
161      (1ull<<ObjType_DevFrame) | \
162      (1ull<<ObjType_CNode) | \
163      (1ull<<ObjType_FCNode) | \
164      (1ull<<ObjType_VNode_x86_64_pml4) | \
165      (1ull<<ObjType_VNode_x86_64_pdpt) | \
166      (1ull<<ObjType_VNode_x86_64_pdir) | \
167      (1ull<<ObjType_VNode_x86_64_ptable) | \
168      (1ull<<ObjType_VNode_x86_32_pdpt) | \
169      (1ull<<ObjType_VNode_x86_32_pdir) | \
170      (1ull<<ObjType_VNode_x86_32_ptable) | \
171      (1ull<<ObjType_VNode_ARM_l1) | \
172      (1ull<<ObjType_VNode_ARM_l2) | \
173      (1ull<<ObjType_VNode_AARCH64_l1) | \
174      (1ull<<ObjType_VNode_AARCH64_l2) | \
175      (1ull<<ObjType_VNode_AARCH64_l3) | \
176      (1ull<<ObjType_PhysAddr) | \
177      (1ull<<ObjType_KernelControlBlock) | \
178      MAPPING_TYPES)
179
180 #define TRACE_TYPES_ENABLED_INITIAL 0x0
181 #define TRACE_PMEM_BEGIN_INITIAL    0x0
182 #define TRACE_PMEM_SIZE_INITIAL     (~(uint32_t)0)
183
184 extern uint64_t trace_types_enabled;
185 extern genpaddr_t TRACE_PMEM_BEGIN;
186 extern gensize_t TRACE_PMEM_SIZE;
187 void caps_trace_ctrl(uint64_t types, genpaddr_t start, gensize_t size);
188 static inline bool caps_should_trace(struct capability *cap)
189 {
190     if (!(trace_types_enabled & (1ull<<cap->type))) {
191         return false;
192     }
193     if (!(ALL_PMEM_TYPES & (1ull<<cap->type))) {
194         return true;
195     }
196     genpaddr_t begin = get_address(cap);
197     gensize_t size = get_size(cap);
198     genpaddr_t end = begin+size;
199     return (begin < TRACE_PMEM_BEGIN && end > TRACE_PMEM_BEGIN)
200         || (begin >= TRACE_PMEM_BEGIN && begin < (TRACE_PMEM_BEGIN+TRACE_PMEM_SIZE));
201 }
202 #define TRACE_CAP_MSGF(trace_cte, msgfmt, ...) do { \
203     struct cte *__tmp_cte = (trace_cte); \
204     if (__tmp_cte && caps_should_trace(&__tmp_cte->cap)) { \
205         char __tmp_msg_buf[256]; \
206         snprintf(__tmp_msg_buf, 256, msgfmt, __VA_ARGS__); \
207         caps_trace(__func__, __LINE__, __tmp_cte, (__tmp_msg_buf)); \
208     } \
209 } while (0)
210 #define TRACE_CAP_MSG(msg, trace_cte) do { \
211     struct cte *__tmp_cte = (trace_cte); \
212     if (__tmp_cte && caps_should_trace(&__tmp_cte->cap)) { \
213         caps_trace(__func__, __LINE__, __tmp_cte, (msg)); \
214     } \
215 } while (0)
216 #define TRACE_CAP(trace_cte) TRACE_CAP_MSG(NULL, trace_cte)
217 #else
218 #define TRACE_CAP_MSGF(trace_cte, msgfmt, ...) ((void)0)
219 #define TRACE_CAP_MSG(msg, trace_cte) ((void)0)
220 #define TRACE_CAP(trace_cte) ((void)0)
221 #endif
222
223 #endif