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