Fixed leaking of allocated stuff in paging (but not partially completed mapping)
This commit is contained in:
parent
347f3a1155
commit
07a861ea61
@ -40,8 +40,6 @@ typedef int paging_flags_t;
|
|||||||
|
|
||||||
// NOTE rueegges: page table metadata used to create child mappings and unmap
|
// NOTE rueegges: page table metadata used to create child mappings and unmap
|
||||||
struct pt_t {
|
struct pt_t {
|
||||||
// the level of the page table. since we abuse this struct also to track l3 entries we set it to 4 there.
|
|
||||||
size_t level;
|
|
||||||
// capref that holds this page table
|
// capref that holds this page table
|
||||||
struct capref cap_pt;
|
struct capref cap_pt;
|
||||||
// capref that maps this page table in the higher level page table
|
// capref that maps this page table in the higher level page table
|
||||||
@ -67,7 +65,9 @@ struct paging_state {
|
|||||||
// NOTE rueegges: remember if we are refilling so we can skip the checks
|
// NOTE rueegges: remember if we are refilling so we can skip the checks
|
||||||
uint8_t refilling;
|
uint8_t refilling;
|
||||||
|
|
||||||
// TODO rueegges: use to track an allocated slot in failure conditions
|
// NOTE rueegges: use to track an already allocated page table in failure conditions
|
||||||
|
struct capref free_l1_vnode;
|
||||||
|
struct capref free_l2_vnode;
|
||||||
struct capref free_l3_vnode;
|
struct capref free_l3_vnode;
|
||||||
|
|
||||||
// TODO rueegges: implement more precisely?
|
// TODO rueegges: implement more precisely?
|
||||||
|
|||||||
230
lib/aos/paging.c
230
lib/aos/paging.c
@ -29,7 +29,6 @@ static struct paging_state current;
|
|||||||
#define PT_PT_SLAB_INITIAL_SPACE SLAB_STATIC_SIZE(PT_PT_SLAB_MIN_SPACE, sizeof(struct pt_t))
|
#define PT_PT_SLAB_INITIAL_SPACE SLAB_STATIC_SIZE(PT_PT_SLAB_MIN_SPACE, sizeof(struct pt_t))
|
||||||
#define PT_CHILDREN_SLAB_INITIAL_SPACE SLAB_STATIC_SIZE(PT_CHILDREN_SLAB_MIN_SPACE, BASE_PAGE_SIZE)
|
#define PT_CHILDREN_SLAB_INITIAL_SPACE SLAB_STATIC_SIZE(PT_CHILDREN_SLAB_MIN_SPACE, BASE_PAGE_SIZE)
|
||||||
|
|
||||||
// NOTE rueegges: temporary (?) solution for initial slab space
|
|
||||||
char pt_pt_slab_buf[PT_PT_SLAB_INITIAL_SPACE];
|
char pt_pt_slab_buf[PT_PT_SLAB_INITIAL_SPACE];
|
||||||
char pt_children_slab_buf[PT_CHILDREN_SLAB_INITIAL_SPACE];
|
char pt_children_slab_buf[PT_CHILDREN_SLAB_INITIAL_SPACE];
|
||||||
|
|
||||||
@ -102,20 +101,20 @@ void pt_print_state(struct paging_state *st) {
|
|||||||
// - this slab
|
// - this slab
|
||||||
// - child slab
|
// - child slab
|
||||||
// - mm slab
|
// - mm slab
|
||||||
static errval_t pt_ensure_slots_and_slabs(struct paging_state *st) {
|
static errval_t pt_ensure_slabs(struct paging_state *st) {
|
||||||
errval_t err;
|
errval_t err;
|
||||||
|
|
||||||
// ensure there is enough space to refill the page tables at any time
|
// ensure there is enough space to refill the page tables at any time
|
||||||
if(slab_freecount(&st->pt_slabs) <= PT_PT_SLAB_MIN_SPACE && !st->refilling) {
|
if(slab_freecount(&st->pt_slabs) <= PT_PT_SLAB_MIN_SPACE && !st->refilling) {
|
||||||
// ASSESSMENT M1: show refilling
|
// ASSESSMENT M1: show refilling
|
||||||
// debug_printf("DEBUG rueegges: pt_ensure_slots_and_slabs - refilling pt_slab\n");
|
// debug_printf("DEBUG rueegges: pt_ensure_slabs - refilling pt_slab\n");
|
||||||
|
|
||||||
st->refilling = 1;
|
st->refilling = 1;
|
||||||
|
|
||||||
err = slab_default_refill(&st->pt_slabs);
|
err = slab_default_refill(&st->pt_slabs);
|
||||||
|
|
||||||
st->refilling = 0;
|
st->refilling = 0;
|
||||||
// debug_printf("DEBUG rueegges: pt_ensure_slots_and_slabs - refilling pt_slab DONE\n");
|
// debug_printf("DEBUG rueegges: pt_ensure_slabs - refilling pt_slab DONE\n");
|
||||||
|
|
||||||
if(err_is_fail(err)) {
|
if(err_is_fail(err)) {
|
||||||
return err_push(err, LIB_ERR_SLAB_REFILL);
|
return err_push(err, LIB_ERR_SLAB_REFILL);
|
||||||
@ -124,7 +123,7 @@ static errval_t pt_ensure_slots_and_slabs(struct paging_state *st) {
|
|||||||
|
|
||||||
if(slab_freecount(&st->pt_children_slabs) <= PT_CHILDREN_SLAB_MIN_SPACE && !st->refilling) {
|
if(slab_freecount(&st->pt_children_slabs) <= PT_CHILDREN_SLAB_MIN_SPACE && !st->refilling) {
|
||||||
// ASSESSMENT M1: show refilling
|
// ASSESSMENT M1: show refilling
|
||||||
// debug_printf("DEBUG rueegges: pt_ensure_slots_and_slabs - refilling pt_children_slabs\n");
|
// debug_printf("DEBUG rueegges: pt_ensure_slabs - refilling pt_children_slabs\n");
|
||||||
|
|
||||||
st->refilling = 1;
|
st->refilling = 1;
|
||||||
|
|
||||||
@ -137,7 +136,7 @@ static errval_t pt_ensure_slots_and_slabs(struct paging_state *st) {
|
|||||||
err = slab_refill_no_pagefault(&st->pt_children_slabs, frame_cap, 10 * 4096);
|
err = slab_refill_no_pagefault(&st->pt_children_slabs, frame_cap, 10 * 4096);
|
||||||
|
|
||||||
st->refilling = 0;
|
st->refilling = 0;
|
||||||
// debug_printf("DEBUG rueegges: pt_ensure_slots_and_slabs - refilling pt_children_slabs DONE\n");
|
// debug_printf("DEBUG rueegges: pt_ensure_slabs - refilling pt_children_slabs DONE\n");
|
||||||
|
|
||||||
if(err_is_fail(err)) {
|
if(err_is_fail(err)) {
|
||||||
return err_push(err, LIB_ERR_SLAB_REFILL);
|
return err_push(err, LIB_ERR_SLAB_REFILL);
|
||||||
@ -147,53 +146,83 @@ static errval_t pt_ensure_slots_and_slabs(struct paging_state *st) {
|
|||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE rueegges: ensures that a page table exists at the specified index in the parent page table and return it
|
static errval_t pt_alloc_level(struct paging_state *st, struct capref *pt_cap, uint8_t level) {
|
||||||
static errval_t pt_ensure(struct paging_state *st, struct pt_t *pt_parent, size_t pt_index, struct pt_t **pt_ret){
|
|
||||||
// debug_printf("DEBUG rueegges: pt_ensure l%u\n", pt_parent->level+1);
|
|
||||||
|
|
||||||
errval_t err;
|
errval_t err;
|
||||||
|
|
||||||
// If this fails we got an l3 pt as the parent
|
switch(level){
|
||||||
assert(pt_parent->children != NULL);
|
|
||||||
assert(pt_parent->level < 3);
|
|
||||||
|
|
||||||
// MUST DO before check if table already exists since it might create it
|
|
||||||
// make sure slot and slab refilling is performed in time
|
|
||||||
err = pt_ensure_slots_and_slabs(st);
|
|
||||||
if(err_is_fail(err)) {
|
|
||||||
DEBUG_ERR(err, "Could not restock slots and slabs");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the page table already exists
|
|
||||||
struct pt_t *res = (pt_parent->children)[pt_index];
|
|
||||||
if (res != NULL) {
|
|
||||||
*pt_ret = res;
|
|
||||||
return SYS_ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the page table
|
|
||||||
struct capref pt_cap;
|
|
||||||
switch(pt_parent->level){
|
|
||||||
case 0:
|
|
||||||
err = pt_alloc_l1(st, &pt_cap);
|
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
err = pt_alloc_l2(st, &pt_cap);
|
if(!capref_is_null(st->free_l1_vnode)){
|
||||||
|
*pt_cap = st->free_l1_vnode;
|
||||||
|
st->free_l1_vnode = NULL_CAP;
|
||||||
|
err = SYS_ERR_OK;
|
||||||
|
} else {
|
||||||
|
err = pt_alloc_l1(st, pt_cap);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
err = pt_alloc_l3(st, &pt_cap);
|
if(!capref_is_null(st->free_l2_vnode)){
|
||||||
|
*pt_cap = st->free_l2_vnode;
|
||||||
|
st->free_l2_vnode = NULL_CAP;
|
||||||
|
err = SYS_ERR_OK;
|
||||||
|
} else {
|
||||||
|
err = pt_alloc_l2(st, pt_cap);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(!capref_is_null(st->free_l3_vnode)){
|
||||||
|
*pt_cap = st->free_l3_vnode;
|
||||||
|
st->free_l3_vnode = NULL_CAP;
|
||||||
|
err = SYS_ERR_OK;
|
||||||
|
} else {
|
||||||
|
err = pt_alloc_l3(st, pt_cap);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err = ERR_INVALID_ARGS;
|
err = ERR_INVALID_ARGS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (err_is_fail(err)) {
|
|
||||||
DEBUG_ERR(err, "Failed pt_alloc l%u", pt_parent->level + 1);
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pt_save_allocation(struct paging_state *st, struct capref cap, uint8_t level) {
|
||||||
|
switch(level){
|
||||||
|
case 1:
|
||||||
|
assert(capref_is_null(st->free_l1_vnode));
|
||||||
|
st->free_l1_vnode = cap;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
assert(capref_is_null(st->free_l2_vnode));
|
||||||
|
st->free_l2_vnode = cap;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
assert(capref_is_null(st->free_l3_vnode));
|
||||||
|
st->free_l3_vnode = cap;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE rueegges: ensures that a page table exists at the specified index in the parent page table and return it
|
||||||
|
static errval_t pt_ensure(struct paging_state *st, struct pt_t *pt_parent, size_t pt_index, uint8_t level, struct pt_t **pt_ret){
|
||||||
|
errval_t err;
|
||||||
|
struct pt_t *res;
|
||||||
|
|
||||||
|
// debug_printf("DEBUG rueegges: pt_ensure l%u\n", pt_parent->level+1);
|
||||||
|
|
||||||
|
// If this fails we got an l3 pt as the parent
|
||||||
|
assert(pt_parent->children != NULL);
|
||||||
|
assert(level > 0 && level <= 3);
|
||||||
|
|
||||||
|
// MUST DO before check if table already exists since it might create it
|
||||||
|
// make sure slot and slab refilling is performed in time
|
||||||
|
err = pt_ensure_slabs(st);
|
||||||
|
if(err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO rueegges: store the allocated pt
|
|
||||||
// check if the page table already exists
|
// check if the page table already exists
|
||||||
res = (pt_parent->children)[pt_index];
|
res = (pt_parent->children)[pt_index];
|
||||||
if (res != NULL) {
|
if (res != NULL) {
|
||||||
@ -201,77 +230,61 @@ static errval_t pt_ensure(struct paging_state *st, struct pt_t *pt_parent, size_
|
|||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// debug_printf("DEBUG rueegges: allocated pt l%u\n", pt_parent->level+1);
|
// create the page table
|
||||||
|
struct capref pt_cap;
|
||||||
// create new mapping
|
err = pt_alloc_level(st, &pt_cap, level);
|
||||||
struct capref pt_mapping;
|
if (err_is_fail(err)) {
|
||||||
err = st->slot_alloc->alloc(st->slot_alloc, &pt_mapping);
|
DEBUG_ERR(err, "Failed pt_alloc l%u", level);
|
||||||
if (err_is_fail(err))
|
|
||||||
{
|
|
||||||
// NOTE rueegges: cannot free the pt allocated above since we do not have the ram cap
|
|
||||||
|
|
||||||
DEBUG_ERR(err, "Failed slot alloc for new pt mapping");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
err = vnode_map(pt_parent->cap_pt, pt_cap, pt_index, 0, 0, 1, pt_mapping);
|
|
||||||
if (err_is_fail(err))
|
|
||||||
{
|
|
||||||
// free the already allocated capref
|
|
||||||
errval_t err_err = st->slot_alloc->free(st->slot_alloc, pt_mapping);
|
|
||||||
if (err_is_fail(err_err)) {
|
|
||||||
DEBUG_ERR(err_err, "Failed to free capability slot during error handling");
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE rueegges: cannot free the pt allocated above since we do not have the ram cap
|
// check if the page table already exists
|
||||||
|
res = (pt_parent->children)[pt_index];
|
||||||
DEBUG_ERR(err, "Failed vnode_map for pt l%u", pt_parent->level + 1);
|
if (res != NULL) {
|
||||||
return err_push(err, LIB_ERR_VNODE_MAP);
|
*pt_ret = res;
|
||||||
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// debug_printf("DEBUG rueegges: inserted mapping for pt l%u\n", pt_parent->level+1);
|
|
||||||
|
|
||||||
// allocate shadow page table space
|
// allocate shadow page table space
|
||||||
struct pt_t *pt_meta = (struct pt_t *) slab_alloc(&st->pt_slabs);
|
struct pt_t *pt_meta = (struct pt_t *) slab_alloc(&st->pt_slabs);
|
||||||
if(pt_meta == NULL) {
|
if(pt_meta == NULL) {
|
||||||
err = vnode_unmap(pt_cap, pt_mapping);
|
pt_save_allocation(st, pt_cap, level);
|
||||||
if (err_is_fail(err)) {
|
|
||||||
DEBUG_ERR(err, "Failed to unmap pt during error handling");
|
|
||||||
}
|
|
||||||
|
|
||||||
err = st->slot_alloc->free(st->slot_alloc, pt_mapping);
|
|
||||||
if (err_is_fail(err)) {
|
|
||||||
DEBUG_ERR(err, "Failed to free capability slot during error handling");
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE rueegges: cannot free the pt allocated above since we do not have the ram cap
|
|
||||||
|
|
||||||
return LIB_ERR_SLAB_ALLOC_FAIL;
|
return LIB_ERR_SLAB_ALLOC_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pt_t **pt_children = (struct pt_t **) slab_alloc(&st->pt_children_slabs);
|
struct pt_t **pt_children = (struct pt_t **) slab_alloc(&st->pt_children_slabs);
|
||||||
if(pt_children == NULL) {
|
if(pt_children == NULL) {
|
||||||
err = vnode_unmap(pt_cap, pt_mapping);
|
slab_free(&st->pt_slabs, pt_meta);
|
||||||
if (err_is_fail(err)) {
|
pt_save_allocation(st, pt_cap, level);
|
||||||
DEBUG_ERR(err, "Failed to unmap pt during error handling");
|
return LIB_ERR_SLAB_ALLOC_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = st->slot_alloc->free(st->slot_alloc, pt_mapping);
|
// create new mapping
|
||||||
if (err_is_fail(err)) {
|
struct capref pt_mapping;
|
||||||
DEBUG_ERR(err, "Failed to free capability slot during error handling");
|
err = st->slot_alloc->alloc(st->slot_alloc, &pt_mapping);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
slab_free(&st->pt_slabs, pt_meta);
|
||||||
|
slab_free(&st->pt_children_slabs, pt_children);
|
||||||
|
pt_save_allocation(st, pt_cap, level);
|
||||||
|
return err_push(err, LIB_ERR_SLOT_ALLOC);
|
||||||
|
}
|
||||||
|
err = vnode_map(pt_parent->cap_pt, pt_cap, pt_index, 0, 0, 1, pt_mapping);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
errval_t err_err = st->slot_alloc->free(st->slot_alloc, pt_mapping);
|
||||||
|
if (err_is_fail(err_err)) {
|
||||||
|
DEBUG_ERR(err_err, "Failed to free capability slot during error handling");
|
||||||
}
|
}
|
||||||
|
|
||||||
slab_free(&st->pt_slabs, pt_meta);
|
slab_free(&st->pt_slabs, pt_meta);
|
||||||
|
slab_free(&st->pt_children_slabs, pt_children);
|
||||||
// NOTE rueegges: cannot free the pt allocated above since we do not have the ram cap
|
pt_save_allocation(st, pt_cap, level);
|
||||||
|
DEBUG_ERR(err, "Failed vnode_map for pt l%u", level);
|
||||||
return LIB_ERR_SLAB_ALLOC_FAIL;
|
return err_push(err, LIB_ERR_VNODE_MAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save metadata
|
||||||
// make sure all child pointers are initialized to NULL
|
// make sure all child pointers are initialized to NULL
|
||||||
memset(pt_children, 0, st->pt_children_slabs.blocksize);
|
memset(pt_children, 0, st->pt_children_slabs.blocksize);
|
||||||
|
|
||||||
// debug_printf("DEBUG rueegges: completed shadow allocation for pt l%u\n", pt_parent->level+1);
|
|
||||||
|
|
||||||
pt_meta->level = pt_parent->level + 1;
|
|
||||||
pt_meta->cap_pt = pt_cap;
|
pt_meta->cap_pt = pt_cap;
|
||||||
pt_meta->cap_mapping = pt_mapping;
|
pt_meta->cap_mapping = pt_mapping;
|
||||||
pt_meta->children = pt_children;
|
pt_meta->children = pt_children;
|
||||||
@ -306,9 +319,6 @@ errval_t paging_init_state(struct paging_state *st, lvaddr_t start_vaddr,
|
|||||||
|
|
||||||
assert(ca != NULL);
|
assert(ca != NULL);
|
||||||
|
|
||||||
st->slot_alloc = ca;
|
|
||||||
st->refilling = 0;
|
|
||||||
|
|
||||||
// initialize slab allocators
|
// initialize slab allocators
|
||||||
// TODO rueegges: is this how we should initialize the slab allocators?
|
// TODO rueegges: is this how we should initialize the slab allocators?
|
||||||
slab_init(&st->pt_slabs, sizeof(struct pt_t), NULL);
|
slab_init(&st->pt_slabs, sizeof(struct pt_t), NULL);
|
||||||
@ -331,11 +341,18 @@ errval_t paging_init_state(struct paging_state *st, lvaddr_t start_vaddr,
|
|||||||
// make sure all child pointers are initialized to NULL
|
// make sure all child pointers are initialized to NULL
|
||||||
memset(l0_children, 0, st->pt_children_slabs.blocksize);
|
memset(l0_children, 0, st->pt_children_slabs.blocksize);
|
||||||
|
|
||||||
l0_pt->level = 0;
|
|
||||||
l0_pt->cap_pt = pdir;
|
l0_pt->cap_pt = pdir;
|
||||||
|
l0_pt->cap_mapping = NULL_CAP;
|
||||||
l0_pt->children = l0_children;
|
l0_pt->children = l0_children;
|
||||||
|
|
||||||
|
st->slot_alloc = ca;
|
||||||
st->l0_pt = l0_pt;
|
st->l0_pt = l0_pt;
|
||||||
|
st->refilling = 0;
|
||||||
|
|
||||||
|
st->free_l1_vnode = NULL_CAP;
|
||||||
|
st->free_l2_vnode = NULL_CAP;
|
||||||
|
st->free_l3_vnode = NULL_CAP;
|
||||||
|
|
||||||
st->next_vaddr = start_vaddr;
|
st->next_vaddr = start_vaddr;
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
@ -488,15 +505,13 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
|||||||
lvaddr_t end_vaddr = vaddr + bytes;
|
lvaddr_t end_vaddr = vaddr + bytes;
|
||||||
assert(VADDR_OFFSET <= vaddr && vaddr < end_vaddr &&
|
assert(VADDR_OFFSET <= vaddr && vaddr < end_vaddr &&
|
||||||
end_vaddr <= VADDR_OFFSET + PTABLE_ENTRIES * PTABLE_ENTRIES *PTABLE_ENTRIES * PTABLE_ENTRIES * BASE_PAGE_SIZE);
|
end_vaddr <= VADDR_OFFSET + PTABLE_ENTRIES * PTABLE_ENTRIES *PTABLE_ENTRIES * PTABLE_ENTRIES * BASE_PAGE_SIZE);
|
||||||
|
|
||||||
// consistentcy checks
|
|
||||||
assert(st != NULL);
|
assert(st != NULL);
|
||||||
assert(st->slot_alloc != NULL);
|
assert(st->slot_alloc != NULL);
|
||||||
assert(st->l0_pt->level == 0);
|
|
||||||
|
|
||||||
// debug_printf("DEBUG rueegges: paging_map_fixed_attr(%p, 0x%lx, cap, %lu, %d)\n", st, vaddr, bytes, flags);
|
// debug_printf("DEBUG rueegges: paging_map_fixed_attr(%p, 0x%lx, cap, %lu, %d)\n", st, vaddr, bytes, flags);
|
||||||
|
|
||||||
// simple fix for now
|
// TODO rueegges: nicefy simple fix for mapping over multiple l3?
|
||||||
|
// TODO rueegges: cleanup partially completed mapping?
|
||||||
for(lvaddr_t current_vaddr = vaddr; current_vaddr < vaddr + bytes; current_vaddr += BASE_PAGE_SIZE) {
|
for(lvaddr_t current_vaddr = vaddr; current_vaddr < vaddr + bytes; current_vaddr += BASE_PAGE_SIZE) {
|
||||||
capaddr_t l0_index = VMSAv8_64_L0_INDEX(current_vaddr);
|
capaddr_t l0_index = VMSAv8_64_L0_INDEX(current_vaddr);
|
||||||
capaddr_t l1_index = VMSAv8_64_L1_INDEX(current_vaddr);
|
capaddr_t l1_index = VMSAv8_64_L1_INDEX(current_vaddr);
|
||||||
@ -508,36 +523,32 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
|||||||
|
|
||||||
// get l1 page table
|
// get l1 page table
|
||||||
struct pt_t *l1_pt;
|
struct pt_t *l1_pt;
|
||||||
err = pt_ensure(st, st->l0_pt, l0_index, &l1_pt);
|
err = pt_ensure(st, st->l0_pt, l0_index, 1, &l1_pt);
|
||||||
if(err_is_fail(err)) {
|
if(err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
assert(l1_pt->level == 1);
|
|
||||||
assert(l1_pt->children != NULL);
|
assert(l1_pt->children != NULL);
|
||||||
|
|
||||||
// get l2 page table
|
// get l2 page table
|
||||||
struct pt_t *l2_pt;
|
struct pt_t *l2_pt;
|
||||||
err = pt_ensure(st, l1_pt, l1_index, &l2_pt);
|
err = pt_ensure(st, l1_pt, l1_index, 2, &l2_pt);
|
||||||
if(err_is_fail(err)) {
|
if(err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
assert(l2_pt->level == 2);
|
|
||||||
assert(l2_pt->children != NULL);
|
assert(l2_pt->children != NULL);
|
||||||
|
|
||||||
// get l3 page table
|
// get l3 page table
|
||||||
struct pt_t *l3_pt;
|
struct pt_t *l3_pt;
|
||||||
err = pt_ensure(st, l2_pt, l2_index, &l3_pt);
|
err = pt_ensure(st, l2_pt, l2_index, 3, &l3_pt);
|
||||||
if(err_is_fail(err)) {
|
if(err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
assert(l3_pt->level == 3);
|
|
||||||
assert(l3_pt->children != NULL);
|
assert(l3_pt->children != NULL);
|
||||||
|
|
||||||
// make sure we have enough slot and slab space left
|
// make sure we have enough slot and slab space left
|
||||||
err = pt_ensure_slots_and_slabs(st);
|
err = pt_ensure_slabs(st);
|
||||||
if(err_is_fail(err)) {
|
if(err_is_fail(err)) {
|
||||||
DEBUG_ERR(err, "Could not ensure presence of sufficient slabs and slots");
|
return err_push(err, LIB_ERR_SLAB_REFILL);
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// debug_printf("DEBUG rueegges: paging_map_fixed_attr - allocate mapping meta\n");
|
// debug_printf("DEBUG rueegges: paging_map_fixed_attr - allocate mapping meta\n");
|
||||||
@ -550,9 +561,6 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
|||||||
|
|
||||||
// set to null to indicate it is a frame mapping and not a page table mapping
|
// set to null to indicate it is a frame mapping and not a page table mapping
|
||||||
pt_entry->children = NULL;
|
pt_entry->children = NULL;
|
||||||
// NOTE rueegges: we set this to 4 to indicate its an entry not a map to another
|
|
||||||
// table even though for superpages the level would be 3
|
|
||||||
pt_entry->level = 4;
|
|
||||||
// allocate the new mapping
|
// allocate the new mapping
|
||||||
err = st->slot_alloc->alloc(st->slot_alloc, &pt_entry->cap_mapping);
|
err = st->slot_alloc->alloc(st->slot_alloc, &pt_entry->cap_mapping);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user