1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(GD_GPL) 9 */ 10 11#ifndef __ARCH_OBJECT_STRUCTURES_H 12#define __ARCH_OBJECT_STRUCTURES_H 13 14#include <assert.h> 15#include <config.h> 16#include <util.h> 17#include <api/types.h> 18#include <api/macros.h> 19#include <arch/types.h> 20#include <arch/object/structures_gen.h> 21#include <arch/machine/hardware.h> 22#include <arch/machine/registerset.h> 23#include <arch/api/constants.h> 24 25enum tcb_arch_cnode_index { 26#ifdef CONFIG_VTX 27 /* VSpace root for running any associated VCPU in */ 28 tcbArchEPTRoot = tcbCNodeEntries, 29 tcbArchCNodeEntries 30#else 31 tcbArchCNodeEntries = tcbCNodeEntries 32#endif 33}; 34 35typedef struct arch_tcb { 36 user_context_t tcbContext; 37#ifdef CONFIG_VTX 38 /* Pointer to associated VCPU. NULL if not associated. 39 * tcb->tcbVCPU->vcpuTCB == tcb. */ 40 struct vcpu *tcbVCPU; 41#endif /* CONFIG_VTX */ 42} arch_tcb_t; 43 44struct user_data { 45 word_t words[BIT(seL4_PageBits) / sizeof(word_t)]; 46}; 47 48typedef struct user_data user_data_t; 49 50struct user_data_device { 51 word_t words[BIT(seL4_PageBits) / sizeof(word_t)]; 52}; 53 54typedef struct user_data_device user_data_device_t; 55 56#define SEL_NULL GDT_NULL 57#define SEL_CS_0 (GDT_CS_0 << 3) 58#define SEL_DS_0 (GDT_DS_0 << 3) 59#define SEL_CS_3 ((GDT_CS_3 << 3) | 3) 60#define SEL_DS_3 ((GDT_DS_3 << 3) | 3) 61#define SEL_TSS (GDT_TSS << 3) 62#define SEL_TLS ((GDT_TLS << 3) | 3) 63#define SEL_IPCBUF ((GDT_IPCBUF << 3) | 3) 64 65#define IDT_ENTRIES 256 66 67#define VTD_RT_SIZE_BITS 12 68 69#define VTD_CTE_SIZE_BITS 3 70#define VTD_CTE_PTR(r) ((vtd_cte_t*)(r)) 71#define VTD_CT_BITS 9 72#define VTD_CT_SIZE_BITS (VTD_CT_BITS + VTD_CTE_SIZE_BITS) 73 74#define VTD_PTE_SIZE_BITS 3 75#define VTD_PTE_PTR(r) ((vtd_pte_t*)(r)) 76#define VTD_PT_INDEX_BITS 9 77 78compile_assert(vtd_pt_size_sane, VTD_PT_INDEX_BITS + VTD_PTE_SIZE_BITS == seL4_IOPageTableBits) 79 80#ifdef CONFIG_VTX 81 82#define EPT_PML4E_SIZE_BITS seL4_X86_EPTPML4EntryBits 83#define EPT_PML4_INDEX_BITS seL4_X86_EPTPML4IndexBits 84#define EPT_PDPTE_SIZE_BITS seL4_X86_EPTPDPTEntryBits 85#define EPT_PDPT_INDEX_BITS seL4_X86_EPTPDPTIndexBits 86#define EPT_PDE_SIZE_BITS seL4_X86_EPTPDEntryBits 87#define EPT_PD_INDEX_BITS seL4_X86_EPTPDIndexBits 88#define EPT_PTE_SIZE_BITS seL4_X86_EPTPTEntryBits 89#define EPT_PT_INDEX_BITS seL4_X86_EPTPTIndexBits 90 91#define EPT_PT_INDEX_OFFSET (seL4_PageBits) 92#define EPT_PD_INDEX_OFFSET (EPT_PT_INDEX_OFFSET + EPT_PT_INDEX_BITS) 93#define EPT_PDPT_INDEX_OFFSET (EPT_PD_INDEX_OFFSET + EPT_PD_INDEX_BITS) 94#define EPT_PML4_INDEX_OFFSET (EPT_PDPT_INDEX_OFFSET + EPT_PDPT_INDEX_BITS) 95 96#define GET_EPT_PML4_INDEX(x) ( (((uint64_t)(x)) >> (EPT_PML4_INDEX_OFFSET)) & MASK(EPT_PML4_INDEX_BITS)) 97#define GET_EPT_PDPT_INDEX(x) ( ((x) >> (EPT_PDPT_INDEX_OFFSET)) & MASK(EPT_PDPT_INDEX_BITS)) 98#define GET_EPT_PD_INDEX(x) ( ((x) >> (EPT_PD_INDEX_OFFSET)) & MASK(EPT_PD_INDEX_BITS)) 99#define GET_EPT_PT_INDEX(x) ( ((x) >> (EPT_PT_INDEX_OFFSET)) & MASK(EPT_PT_INDEX_BITS)) 100 101#define EPT_PML4E_PTR(r) ((ept_pml4e_t *)(r)) 102#define EPT_PML4E_PTR_PTR(r) ((ept_pml4e_t **)(r)) 103#define EPT_PML4E_REF(p) ((word_t)(p)) 104 105#define EPT_PML4_SIZE_BITS seL4_X86_EPTPML4Bits 106#define EPT_PML4_PTR(r) ((ept_pml4e_t *)(r)) 107#define EPT_PML4_REF(p) ((word_t)(p)) 108 109#define EPT_PDPTE_PTR(r) ((ept_pdpte_t *)(r)) 110#define EPT_PDPTE_PTR_PTR(r) ((ept_pdpte_t **)(r)) 111#define EPT_PDPTE_REF(p) ((word_t)(p)) 112 113#define EPT_PDPT_SIZE_BITS seL4_X86_EPTPDPTBits 114#define EPT_PDPT_PTR(r) ((ept_pdpte_t *)(r)) 115#define EPT_PDPT_REF(p) ((word_t)(p)) 116 117#define EPT_PDE_PTR(r) ((ept_pde_t *)(r)) 118#define EPT_PDE_PTR_PTR(r) ((ept_pde_t **)(r)) 119#define EPT_PDE_REF(p) ((word_t)(p)) 120 121#define EPT_PD_SIZE_BITS seL4_X86_EPTPDBits 122#define EPT_PD_PTR(r) ((ept_pde_t *)(r)) 123#define EPT_PD_REF(p) ((word_t)(p)) 124 125#define EPT_PTE_PTR(r) ((ept_pte_t *)(r)) 126#define EPT_PTE_REF(p) ((word_t)(p)) 127 128#define EPT_PT_SIZE_BITS seL4_X86_EPTPTBits 129#define EPT_PT_PTR(r) ((ept_pte_t *)(r)) 130#define EPT_PT_REF(p) ((word_t)(p)) 131 132#define VCPU_PTR(r) ((vcpu_t *)(r)) 133#define VCPU_REF(p) ((word_t)(p)) 134 135#endif /* CONFIG_VTX */ 136 137struct rdmsr_safe_result { 138 uint64_t value; 139 bool_t success; 140}; 141 142typedef struct rdmsr_safe_result rdmsr_safe_result_t; 143 144/* helper structure for filling descriptor registers */ 145typedef struct gdt_idt_ptr { 146 uint16_t limit; 147 word_t base; 148} __attribute__((packed)) gdt_idt_ptr_t; 149 150enum vm_rights { 151 VMKernelOnly = 1, 152 VMReadOnly = 2, 153 VMReadWrite = 3 154}; 155typedef word_t vm_rights_t; 156 157#include <mode/object/structures.h> 158 159static inline word_t CONST 160cap_get_archCapSizeBits(cap_t cap) 161{ 162 cap_tag_t ctag; 163 164 ctag = cap_get_capType(cap); 165 166 switch (ctag) { 167 case cap_frame_cap: 168 return pageBitsForSize(cap_frame_cap_get_capFSize(cap)); 169 170 case cap_page_table_cap: 171 return seL4_PageTableBits; 172 173 case cap_page_directory_cap: 174 return seL4_PageDirBits; 175 176 case cap_io_port_cap: 177 return 0; 178 179#ifdef CONFIG_IOMMU 180 case cap_io_space_cap: 181 return 0; 182 case cap_io_page_table_cap: 183 return seL4_IOPageTableBits; 184#endif 185 186 case cap_asid_control_cap: 187 return 0; 188 189 case cap_asid_pool_cap: 190 return seL4_ASIDPoolBits; 191 192#ifdef CONFIG_VTX 193 case cap_vcpu_cap: 194 return seL4_X86_VCPUBits; 195 196 case cap_ept_pml4_cap: 197 return seL4_X86_EPTPML4Bits; 198 case cap_ept_pdpt_cap: 199 return seL4_X86_EPTPDPTBits; 200 case cap_ept_pd_cap: 201 return seL4_X86_EPTPDBits; 202 case cap_ept_pt_cap: 203 return seL4_X86_EPTPTBits; 204#endif /* CONFIG_VTX */ 205 206 default: 207 return cap_get_modeCapSizeBits(cap); 208 } 209} 210 211static inline bool_t CONST 212cap_get_archCapIsPhysical(cap_t cap) 213{ 214 cap_tag_t ctag; 215 216 ctag = cap_get_capType(cap); 217 218 switch (ctag) { 219 220 case cap_frame_cap: 221 return true; 222 223 case cap_page_table_cap: 224 return true; 225 226 case cap_page_directory_cap: 227 return true; 228 229 case cap_io_port_cap: 230 return false; 231 232#ifdef CONFIG_IOMMU 233 case cap_io_space_cap: 234 return false; 235 236 case cap_io_page_table_cap: 237 return true; 238#endif 239 240 case cap_asid_control_cap: 241 return false; 242 243 case cap_asid_pool_cap: 244 return true; 245 246#ifdef CONFIG_VTX 247 case cap_ept_pt_cap: 248 return true; 249 250 case cap_ept_pd_cap: 251 return true; 252 253 case cap_ept_pdpt_cap: 254 return true; 255 256 case cap_ept_pml4_cap: 257 return true; 258#endif /* CONFIG_VTX */ 259 260 default: 261 return cap_get_modeCapIsPhysical(cap); 262 } 263} 264 265static inline void * CONST 266cap_get_archCapPtr(cap_t cap) 267{ 268 cap_tag_t ctag; 269 270 ctag = cap_get_capType(cap); 271 272 switch (ctag) { 273 274 case cap_frame_cap: 275 return (void *)(cap_frame_cap_get_capFBasePtr(cap)); 276 277 case cap_page_table_cap: 278 return PD_PTR(cap_page_table_cap_get_capPTBasePtr(cap)); 279 280 case cap_page_directory_cap: 281 return PT_PTR(cap_page_directory_cap_get_capPDBasePtr(cap)); 282 283 case cap_io_port_cap: 284 return NULL; 285 286#ifdef CONFIG_IOMMU 287 case cap_io_space_cap: 288 return NULL; 289 290 case cap_io_page_table_cap: 291 return (void *)(cap_io_page_table_cap_get_capIOPTBasePtr(cap)); 292#endif 293 294 case cap_asid_control_cap: 295 return NULL; 296 297 case cap_asid_pool_cap: 298 return ASID_POOL_PTR(cap_asid_pool_cap_get_capASIDPool(cap)); 299 300#ifdef CONFIG_VTX 301 case cap_ept_pt_cap: 302 return EPT_PT_PTR(cap_ept_pt_cap_get_capPTBasePtr(cap)); 303 304 case cap_ept_pd_cap: 305 return EPT_PD_PTR(cap_ept_pd_cap_get_capPDBasePtr(cap)); 306 307 case cap_ept_pdpt_cap: 308 return EPT_PDPT_PTR(cap_ept_pdpt_cap_get_capPDPTBasePtr(cap)); 309 310 case cap_ept_pml4_cap: 311 return EPT_PML4_PTR(cap_ept_pml4_cap_get_capPML4BasePtr(cap)); 312#endif /* CONFIG_VTX */ 313 314 default: 315 return cap_get_modeCapPtr(cap); 316 } 317} 318 319static inline bool_t CONST 320Arch_isCapRevocable(cap_t derivedCap, cap_t srcCap) 321{ 322 switch (cap_get_capType(derivedCap)) { 323 case cap_io_port_cap: 324 return cap_get_capType(srcCap) == cap_io_port_control_cap; 325 326 default: 327 return false; 328 } 329} 330 331#endif /* __ARCH_OBJECT_STRUCTURES_H */ 332