1/* 2 * Copyright (c) 2018, ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <barrelfish/barrelfish.h> 11#include <numa.h> 12 13#include "intel_vtd.h" 14 15errval_t vtd_root_table_create(struct vtd_root_table *rt, struct vtd *vtd) 16{ 17 errval_t err; 18 19 INTEL_VTD_DEBUG_RTABLE("creating root table\n"); 20 21 assert(capref_is_null(rt->rtcap)); 22 assert(capref_is_null(rt->mappingcncap)); 23 24 /* allocate slots for capability and */ 25 26 err = slot_alloc_root(&rt->mappingcncap); 27 if (err_is_fail(err)) { 28 return err_push(err, LIB_ERR_SLOT_ALLOC); 29 } 30 31 err = slot_alloc(&rt->rtcap); 32 if (err_is_fail(err)) { 33 err = err_push(err, LIB_ERR_SLOT_ALLOC); 34 goto err_out_1; 35 } 36 37 struct capref ramcap; 38 err = numa_ram_alloc_on_node(&ramcap, BASE_PAGE_SIZE, vtd->proximity_domain, 39 NULL); 40 if (err_is_fail(err)) { 41 err = err_push(err, LIB_ERR_RAM_ALLOC); 42 goto err_out_2; 43 } 44 45 struct capref ramcap2; 46 err = numa_ram_alloc_on_node(&ramcap2, (1UL << (L2_CNODE_BITS + OBJBITS_CTE)), 47 vtd->proximity_domain, NULL); 48 if (err_is_fail(err)) { 49 err = err_push(err, LIB_ERR_RAM_ALLOC); 50 goto err_out_3; 51 } 52 53 err = cap_retype(rt->rtcap, ramcap, 0, ObjType_VNode_VTd_root_table, 54 vnode_objsize(ObjType_VNode_VTd_root_table), 1); 55 if (err_is_fail(err)) { 56 err = err_push(err, LIB_ERR_CAP_RETYPE); 57 goto err_out_4; 58 } 59 60 err = cnode_create_from_mem(rt->mappingcncap, ramcap2, ObjType_L2CNode, 61 &rt->mappigncn, L2_CNODE_SLOTS); 62 if (err_is_fail(err)) { 63 err = err_push(err, LIB_ERR_CNODE_CREATE_FROM_MEM); 64 goto err_out_5; 65 } 66 67 /* clean up */ 68 69 err = cap_destroy(ramcap); 70 if (err_is_fail(err)) { 71 err = err_push(err, LIB_ERR_CAP_DESTROY); 72 DEBUG_ERR(err, "ignoring destorying of ramcap\n"); 73 } 74 75 err = cap_destroy(ramcap2); 76 if (err_is_fail(err)) { 77 err = err_push(err, LIB_ERR_CAP_DESTROY); 78 DEBUG_ERR(err, "ignoring destorying of ramcap\n"); 79 } 80 81 rt->vtd = vtd; 82 83 return SYS_ERR_OK; 84 85 err_out_5: 86 cap_destroy(rt->rtcap); 87 err_out_4: 88 cap_destroy(ramcap2); 89 err_out_3: 90 cap_destroy(ramcap); 91 err_out_2: 92 slot_free(rt->rtcap); 93 err_out_1: 94 slot_free(rt->mappingcncap); 95 return err; 96} 97 98 99errval_t vtd_root_table_destroy(struct vtd_root_table *rt) 100{ 101 INTEL_VTD_DEBUG_RTABLE("destroying root table\n"); 102 103 errval_t err; 104 105 /* delete the cnode cap */ 106 if (!capref_is_null(rt->rtcap)) { 107 err = cap_destroy(rt->rtcap); 108 assert(err_is_ok(err)); 109 } 110 111 if (!capref_is_null(rt->mappingcncap)) { 112 err = cap_destroy(rt->mappingcncap); 113 assert(err_is_ok(err)); 114 } 115 116 memset(rt, 0, sizeof(*rt)); 117 118 return SYS_ERR_OK; 119} 120 121 122struct vtd_ctxt_table *vtd_root_table_get_context_table(struct vtd_root_table *rt, 123 uint8_t idx) 124{ 125 return rt->ctxt_tables[idx]; 126} 127 128