1/* 2 * Copyright (c) 2015, 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, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <stdio.h> 11#include "nestedpaging.h" 12 13extern errval_t vspace_add_vregion(struct vspace *vspace, struct vregion *region); 14errval_t install_user_managed_pdpt(genvaddr_t *base, void **ptable) 15{ 16 errval_t err; 17 assert(base); 18 assert(ptable); 19 printf("Installing our own page tables\n"); 20 struct pmap *p = get_current_pmap(); 21 struct memobj m; 22 // full pml4 entry 23 m.size = 512ULL * 1024 * 1024 * 1024; 24 genvaddr_t base_; 25 err = p->f.determine_addr(p, &m, m.size, &base_); 26 if (err_is_fail(err)) { 27 return err; 28 } 29 printf("base: %"PRIxGENVADDR"\n", base_); 30 31 struct vregion ours; 32 ours.base = base_; 33 ours.size = m.size; 34 vspace_add_vregion(get_current_vspace(), &ours); 35 36 *base = base_; 37 38 struct capref pdpt_ram, pdpt_cap; 39 err = ram_alloc(&pdpt_ram, BASE_PAGE_BITS); 40 if (err_is_fail(err)) { 41 return err; 42 } 43 err = slot_alloc(&pdpt_cap); 44 if (err_is_fail(err)) { 45 return err; 46 } 47 err = cap_retype(pdpt_cap, pdpt_ram, 0, ObjType_VNode_x86_64_pdpt, BASE_PAGE_SIZE, 1); 48 if (err_is_fail(err)) { 49 return err; 50 } 51 err = cap_destroy(pdpt_ram); 52 if (err_is_fail(err)) { 53 return err; 54 } 55 struct capref pml4 = (struct capref) { 56 .cnode = cnode_page, 57 .slot = 0 58 }; 59 size_t pml4e = X86_64_PML4_BASE(base_); 60 printf("our pml4e is: %zu\n", pml4e); 61 struct capref mapping; 62 err = slot_alloc(&mapping); 63 assert(err_is_ok(err)); 64 65 err = vnode_map(pml4, pdpt_cap, pml4e, PTABLE_ACCESS_DEFAULT, 0, 1, mapping); 66 if (err_is_fail(err)) { 67 return err; 68 } 69 struct capref pdpt_map; 70 err = slot_alloc(&pdpt_map); 71 if (err_is_fail(err)) { 72 return err; 73 } 74 err = cap_copy(pdpt_map, pdpt_cap); 75 if (err_is_fail(err)) { 76 return err; 77 } 78 79 void *ptable_ = NULL; 80 err = vspace_map_one_frame_attr(&ptable_, BASE_PAGE_SIZE, pdpt_map, 81 VREGION_FLAGS_READ_WRITE, NULL, NULL); 82 if (err_is_fail(err)) { 83 return err; 84 } 85 printf("pdpt mapped at %p\n", ptable_); 86 87 *ptable = ptable_; 88 89 return SYS_ERR_OK; 90} 91