1/** 2 * \file 3 * \brief Code for managing VSpace of a new domain when it is spawned 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, 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, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <barrelfish/barrelfish.h> 16#include <spawndomain/spawndomain.h> 17#include "spawn.h" 18 19/** 20 * \brief Initialize the vspace for the domain being spawned 21 * 22 * \param vnode The pml4 cap for the new domain 23 * 24 * \bug architecture specific 25 */ 26errval_t spawn_vspace_init(struct spawninfo *si, struct capref vnode, 27 enum cpu_type cpu_type) 28{ 29 errval_t err; 30 struct pmap *pmap = NULL; 31 32 si->vspace = malloc(sizeof (struct vspace)); 33 if (si->vspace == NULL) { 34 err = LIB_ERR_MALLOC_FAIL; 35 goto error; 36 } 37 pmap = malloc(ARCH_DEFAULT_PMAP_SIZE); 38 if (!pmap) { 39 err = LIB_ERR_MALLOC_FAIL; 40 goto error; 41 } 42 43 err = pmap_init(pmap, si->vspace, vnode, &si->pagecn_slot_alloc.a); 44 if (err_is_fail(err)) { 45 err = err_push(err, LIB_ERR_PMAP_INIT); 46 goto error; 47 } 48 49 err = vspace_init(si->vspace, pmap); 50 if (err_is_fail(err)) { 51 err = err_push(err, LIB_ERR_VSPACE_INIT); 52 goto error; 53 } 54 55 return SYS_ERR_OK; 56 57 error: // XXX: proper cleanup 58 if (si->vspace) { 59 free(si->vspace); 60 } 61 if (pmap) { 62 free(pmap); 63 } 64 return err; 65} 66 67/** 68 * \brief Map one frame anywhere 69 */ 70errval_t spawn_vspace_map_one_frame(struct spawninfo *si, genvaddr_t *retaddr, 71 struct capref frame, size_t size) 72{ 73 errval_t err; 74 struct vregion *vregion = NULL; 75 struct memobj_one_frame *memobj = NULL; 76 77 vregion = malloc(sizeof(struct vregion)); 78 if (!vregion) { 79 err = LIB_ERR_MALLOC_FAIL; 80 goto error; 81 } 82 memobj = malloc(sizeof(struct memobj_one_frame)); 83 if (!memobj) { 84 err = LIB_ERR_MALLOC_FAIL; 85 goto error; 86 } 87 88 err = memobj_create_one_frame(memobj, size, 0); 89 if (err_is_fail(err)) { 90 err = err_push(err, LIB_ERR_MEMOBJ_CREATE_ANON); 91 goto error; 92 } 93 err = memobj->m.f.fill(&memobj->m, 0, frame, size); 94 if (err_is_fail(err)) { 95 err = err_push(err, LIB_ERR_MEMOBJ_FILL); 96 goto error; 97 } 98 err = vregion_map(vregion, si->vspace, &memobj->m, 0, size, 99 VREGION_FLAGS_READ_WRITE); 100 if (err_is_fail(err)) { 101 err = err_push(err, LIB_ERR_VSPACE_MAP); 102 goto error; 103 } 104 err = memobj->m.f.pagefault(&memobj->m, vregion, 0, 0); 105 if (err_is_fail(err)) { 106 err = err_push(err, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER); 107 goto error; 108 } 109 110 *retaddr = vregion_get_base_addr(vregion); 111 return SYS_ERR_OK; 112 113 error: // XXX: proper cleanup 114 if (vregion) { 115 free(vregion); 116 } 117 if (memobj) { 118 free(memobj); 119 } 120 return err; 121} 122 123/** 124 * \brief Map one frame at the given addr 125 */ 126errval_t spawn_vspace_map_fixed_one_frame(struct spawninfo *si, genvaddr_t addr, 127 struct capref frame, size_t size) 128{ 129 errval_t err; 130 struct vregion *vregion = NULL; 131 struct memobj_one_frame *memobj = NULL; 132 133 vregion = malloc(sizeof(struct vregion)); 134 if (!vregion) { 135 err = LIB_ERR_MALLOC_FAIL; 136 goto error; 137 } 138 memobj = malloc(sizeof(struct memobj_one_frame)); 139 if (!memobj) { 140 err = LIB_ERR_MALLOC_FAIL; 141 goto error; 142 } 143 144 err = memobj_create_one_frame(memobj, size, 0); 145 if (err_is_fail(err)) { 146 err = err_push(err, LIB_ERR_MEMOBJ_CREATE_ANON); 147 goto error; 148 } 149 err = memobj->m.f.fill(&memobj->m, 0, frame, size); 150 if (err_is_fail(err)) { 151 err = err_push(err, LIB_ERR_MEMOBJ_FILL); 152 goto error; 153 } 154 err = vregion_map_fixed(vregion, si->vspace, &memobj->m, 0, size, addr, 155 VREGION_FLAGS_READ_WRITE); 156 if (err_is_fail(err)) { 157 err = err_push(err, LIB_ERR_VSPACE_MAP); 158 goto error; 159 } 160 err = memobj->m.f.pagefault(&memobj->m, vregion, 0, 0); 161 if (err_is_fail(err)) { 162 err = err_push(err, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER); 163 goto error; 164 } 165 166 return SYS_ERR_OK; 167 168 error: // XXX: proper cleanup 169 if (vregion) { 170 free(vregion); 171 } 172 if (memobj) { 173 free(memobj); 174 } 175 return err; 176} 177 178/** 179 * \brief Return memobj and vregion for anonymous type mapping 180 */ 181errval_t spawn_vspace_map_anon_fixed_attr(struct spawninfo *si, genvaddr_t addr, 182 size_t size, struct vregion **vregion, 183 struct memobj **memobj, 184 vregion_flags_t flags) 185{ 186 errval_t err; 187 188 // Allocate space 189 *vregion = malloc(sizeof(struct vregion)); 190 if (!*vregion) { 191 err = LIB_ERR_MALLOC_FAIL; 192 goto error; 193 } 194 *memobj = malloc(sizeof(struct memobj_anon)); 195 if (!*memobj) { 196 err = LIB_ERR_MALLOC_FAIL; 197 goto error; 198 } 199 200 // Create the objects 201 err = memobj_create_anon((struct memobj_anon*)*memobj, size, 0); 202 if (err_is_fail(err)) { 203 err = err_push(err, LIB_ERR_MEMOBJ_CREATE_ANON); 204 goto error; 205 } 206 err = vregion_map_fixed(*vregion, si->vspace, *memobj, 0, size, addr, 207 flags); 208 if (err_is_fail(err)) { 209 // err = LIB_ERR_VSPACE_MAP; 210 goto error; 211 } 212 213 return SYS_ERR_OK; 214 215 error: // XXX: proper cleanup 216 if (*vregion) { 217 free(*vregion); 218 } 219 if (*memobj) { 220 free(*memobj); 221 } 222 return err; 223} 224