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