Add foreign state init
This commit is contained in:
parent
c83edbb696
commit
fdf72890f1
@ -49,8 +49,9 @@ struct pt_t {
|
||||
size_t mapping_size;
|
||||
|
||||
// NOTE rueegges: points to an array with pointers for every potential next level page table
|
||||
// it is NULL for mapping a frame instead of a page table
|
||||
// entries are NULL if the corresponding mapping does not yet exist
|
||||
// the entries are NULL if the corresponding mapping does not yet exist
|
||||
// l0_pt children will initially be NULL and initialized in first mapping call
|
||||
// lower pt children arrays are immediately allocated.
|
||||
struct pt_t **children;
|
||||
};
|
||||
|
||||
@ -67,7 +68,7 @@ struct paging_state {
|
||||
struct slot_allocator *slot_alloc;
|
||||
|
||||
// NOTE rueegges: added to keep track of pt metadata
|
||||
struct pt_t *l0_pt;
|
||||
struct pt_t l0_pt;
|
||||
|
||||
// NOTE rueegges: added to allocate shadow page table metadata
|
||||
struct slab_allocator pt_slabs;
|
||||
@ -82,7 +83,7 @@ struct paging_state {
|
||||
struct capref free_l3_vnode;
|
||||
|
||||
// TODO rueegges: implement more precisely?
|
||||
struct pt_vaddr_reg_t *vaddr_head;
|
||||
struct pt_vaddr_reg_t vaddr_head;
|
||||
};
|
||||
|
||||
|
||||
|
||||
123
lib/aos/paging.c
123
lib/aos/paging.c
@ -30,10 +30,6 @@ static struct paging_state current;
|
||||
#define PT_PT_SLAB_INITIAL_SPACE SLAB_STATIC_SIZE(PT_PT_SLAB_MIN_SPACE, PT_META_MAX_SIZE)
|
||||
#define PT_CHILDREN_SLAB_INITIAL_SPACE SLAB_STATIC_SIZE(PT_CHILDREN_SLAB_MIN_SPACE, BASE_PAGE_SIZE)
|
||||
|
||||
|
||||
char pt_pt_slab_buf[PT_PT_SLAB_INITIAL_SPACE];
|
||||
char pt_children_slab_buf[PT_CHILDREN_SLAB_INITIAL_SPACE];
|
||||
|
||||
/**
|
||||
* \brief Helper function that allocates a slot and
|
||||
* creates a aarch64 page table capability for a certain level
|
||||
@ -73,8 +69,9 @@ __attribute__((unused)) static errval_t pt_alloc_l3(struct paging_state * st, st
|
||||
void pt_print_state(struct paging_state *st) {
|
||||
// iterates over all the page table entries and prints them
|
||||
debug_printf("L0\n");
|
||||
if(st->l0_pt.children == NULL) return;
|
||||
for(size_t i0 = 0; i0 < PTABLE_ENTRIES; ++i0) {
|
||||
struct pt_t *l1_pt = st->l0_pt->children[i0];
|
||||
struct pt_t *l1_pt = st->l0_pt.children[i0];
|
||||
if (l1_pt == NULL) continue;
|
||||
|
||||
debug_printf(" %lu -> L1\n", i0);
|
||||
@ -134,8 +131,7 @@ static errval_t pt_ensure_slabs(struct paging_state *st) {
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_SLOT_ALLOC);
|
||||
}
|
||||
// TODO rueegges: use fuctions for refill size
|
||||
err = slab_refill_no_pagefault(&st->pt_children_slabs, frame_cap, 10 * 4096);
|
||||
err = slab_refill_no_pagefault(&st->pt_children_slabs, frame_cap, LARGE_PAGE_SIZE);
|
||||
|
||||
st->refilling = 0;
|
||||
// debug_printf("DEBUG rueegges: pt_ensure_slabs - refilling pt_children_slabs DONE\n");
|
||||
@ -212,7 +208,7 @@ static errval_t pt_ensure(struct paging_state *st, struct pt_t *pt_parent, size_
|
||||
errval_t err;
|
||||
struct pt_t *res;
|
||||
|
||||
// debug_printf("DEBUG rueegges: pt_ensure l%u\n", pt_parent->level+1);
|
||||
// debug_printf("DEBUG rueegges: pt_ensure l%u\n", level);
|
||||
|
||||
// If this fails we got an l3 pt as the parent
|
||||
assert(pt_parent->children != NULL);
|
||||
@ -226,7 +222,7 @@ static errval_t pt_ensure(struct paging_state *st, struct pt_t *pt_parent, size_
|
||||
}
|
||||
|
||||
// check if the page table already exists
|
||||
res = (pt_parent->children)[pt_index];
|
||||
res = pt_parent->children[pt_index];
|
||||
if (res != NULL) {
|
||||
*pt_ret = res;
|
||||
return SYS_ERR_OK;
|
||||
@ -240,8 +236,8 @@ static errval_t pt_ensure(struct paging_state *st, struct pt_t *pt_parent, size_
|
||||
return err;
|
||||
}
|
||||
|
||||
// check if the page table already exists
|
||||
res = (pt_parent->children)[pt_index];
|
||||
// check again if the page table already exists
|
||||
res = pt_parent->children[pt_index];
|
||||
if (res != NULL) {
|
||||
*pt_ret = res;
|
||||
return SYS_ERR_OK;
|
||||
@ -276,7 +272,6 @@ static errval_t pt_ensure(struct paging_state *st, struct pt_t *pt_parent, size_
|
||||
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_children_slabs, pt_children);
|
||||
pt_save_allocation(st, pt_cap, level);
|
||||
@ -325,51 +320,25 @@ errval_t paging_init_state(struct paging_state *st, lvaddr_t start_vaddr,
|
||||
// TODO rueegges: is this how we should initialize the slab allocators?
|
||||
slab_init(&st->pt_slabs, PT_META_MAX_SIZE, NULL);
|
||||
slab_init(&st->pt_children_slabs, BASE_PAGE_SIZE, NULL);
|
||||
slab_grow(&st->pt_slabs, pt_pt_slab_buf, PT_PT_SLAB_INITIAL_SPACE);
|
||||
slab_grow(&st->pt_children_slabs, pt_children_slab_buf, PT_CHILDREN_SLAB_INITIAL_SPACE);
|
||||
|
||||
// initialize shadow page tables
|
||||
struct pt_t *l0_pt = slab_alloc(&st->pt_slabs);
|
||||
if(l0_pt == NULL) {
|
||||
debug_printf("Failed to alloc l0 meta\n");
|
||||
return LIB_ERR_SLAB_ALLOC_FAIL;
|
||||
}
|
||||
struct pt_t **l0_children = (struct pt_t **) slab_alloc(&st->pt_children_slabs);
|
||||
if(l0_children == NULL) {
|
||||
debug_printf("Failed to alloc l0 children\n");
|
||||
slab_free(&st->pt_slabs, l0_pt);
|
||||
return LIB_ERR_SLAB_ALLOC_FAIL;
|
||||
}
|
||||
// make sure all child pointers are initialized to NULL
|
||||
memset(l0_children, 0, st->pt_children_slabs.blocksize);
|
||||
|
||||
l0_pt->cap_pt = pdir;
|
||||
l0_pt->cap_mapping = NULL_CAP;
|
||||
l0_pt->children = l0_children;
|
||||
st->l0_pt.cap_pt = pdir;
|
||||
st->l0_pt.cap_mapping = NULL_CAP;
|
||||
st->l0_pt.children = NULL;
|
||||
|
||||
// initialize virtual address space
|
||||
struct pt_vaddr_reg_t *vaddr_reg = (struct pt_vaddr_reg_t *) slab_alloc(&st->pt_slabs);
|
||||
if (vaddr_reg == NULL) {
|
||||
debug_printf("Failed to alloc l0 children\n");
|
||||
slab_free(&st->pt_slabs, l0_pt);
|
||||
slab_free(&st->pt_children_slabs, l0_children);
|
||||
return LIB_ERR_SLAB_ALLOC_FAIL;
|
||||
}
|
||||
vaddr_reg->base = start_vaddr;
|
||||
vaddr_reg->size = VADDR_SIZE - start_vaddr;
|
||||
vaddr_reg->free = true;
|
||||
vaddr_reg->next = NULL;
|
||||
st->vaddr_head.base = start_vaddr;
|
||||
st->vaddr_head.size = VADDR_SIZE - start_vaddr;
|
||||
st->vaddr_head.free = true;
|
||||
st->vaddr_head.next = NULL;
|
||||
|
||||
st->slot_alloc = ca;
|
||||
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->vaddr_head = vaddr_reg;
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
@ -390,10 +359,21 @@ errval_t paging_init_state(struct paging_state *st, lvaddr_t start_vaddr,
|
||||
errval_t paging_init_state_foreign(struct paging_state *st, lvaddr_t start_vaddr,
|
||||
struct capref pdir, struct slot_allocator *ca)
|
||||
{
|
||||
errval_t err;
|
||||
// TODO (M2): Implement state struct initialization
|
||||
// TODO (M4): Implement page fault handler that installs frames when a page fault
|
||||
// occurs and keeps track of the virtual address space.
|
||||
return LIB_ERR_NOT_IMPLEMENTED;
|
||||
struct capref pt_cap;
|
||||
err = ca->alloc(ca, &pt_cap);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_SLOT_ALLOC);
|
||||
}
|
||||
err = cap_copy(pt_cap, pdir);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_CAP_COPY_FAIL);
|
||||
}
|
||||
|
||||
return paging_init_state(st, start_vaddr, pt_cap, ca);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -416,6 +396,11 @@ errval_t paging_init(void)
|
||||
err = paging_init_state(¤t, VADDR_OFFSET, cap_vroot, get_default_slot_allocator());
|
||||
if (err_is_fail(err)) return err;
|
||||
|
||||
static char pt_pt_slab_buf[PT_PT_SLAB_INITIAL_SPACE];
|
||||
static char pt_children_slab_buf[PT_CHILDREN_SLAB_INITIAL_SPACE];
|
||||
slab_grow(¤t.pt_slabs, pt_pt_slab_buf, PT_PT_SLAB_INITIAL_SPACE);
|
||||
slab_grow(¤t.pt_children_slabs, pt_children_slab_buf, PT_CHILDREN_SLAB_INITIAL_SPACE);
|
||||
|
||||
set_current_paging_state(¤t);
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
@ -535,7 +520,7 @@ errval_t paging_alloc(struct paging_state *st, void **buf, size_t bytes, size_t
|
||||
return err;
|
||||
}
|
||||
|
||||
struct pt_vaddr_reg_t *vaddr_reg = st->vaddr_head;
|
||||
struct pt_vaddr_reg_t *vaddr_reg = &st->vaddr_head;
|
||||
while(vaddr_reg != NULL) {
|
||||
// calculate the number of bytes to skip to achieve alignment
|
||||
size_t prefix_size = (alignment - (vaddr_reg->base & (alignment - 1))) % alignment;
|
||||
@ -633,10 +618,29 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
||||
assert(st != NULL);
|
||||
assert(st->slot_alloc != NULL);
|
||||
|
||||
// debug_printf("DEBUG rueegges: paging_map_fixed_attr(%p, 0x%lx, cap, %lu, %d)\n", st, vaddr, bytes, flags);
|
||||
|
||||
// make sure we have enough slot and slab space left
|
||||
err = pt_ensure_slabs(st);
|
||||
if(err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_SLAB_REFILL);
|
||||
}
|
||||
|
||||
// get the l0 page table and make sure late init is completed
|
||||
struct pt_t *l0_pt = &st->l0_pt;
|
||||
if (l0_pt->children == NULL) {
|
||||
l0_pt->children = (struct pt_t **) slab_alloc(&st->pt_children_slabs);
|
||||
if(l0_pt->children == NULL) {
|
||||
return LIB_ERR_SLAB_ALLOC_FAIL;
|
||||
}
|
||||
memset(l0_pt->children, 0, st->pt_children_slabs.blocksize);
|
||||
}
|
||||
assert(l0_pt->children != NULL);
|
||||
|
||||
// make sure the virtual address space is reserved for this mapping. For this we require either an allocated vaddr reg to
|
||||
// precisely exist as required or not at all, i.e. it is not overlapping multiple existing regions
|
||||
// TODO rueegges: not sure this is the best way to do this
|
||||
struct pt_vaddr_reg_t *vaddr_reg = st->vaddr_head;
|
||||
struct pt_vaddr_reg_t *vaddr_reg = &st->vaddr_head;
|
||||
for(;vaddr_reg != NULL; vaddr_reg = vaddr_reg->next) {
|
||||
// we have found the region it belongs to
|
||||
if(vaddr_reg->base <= vaddr && vaddr + bytes <= vaddr_reg->base + vaddr_reg->size) {
|
||||
@ -654,9 +658,6 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
||||
return LIB_ERR_PMAP_ADDR_NOT_FREE;
|
||||
}
|
||||
|
||||
|
||||
// debug_printf("DEBUG rueegges: paging_map_fixed_attr(%p, 0x%lx, cap, %lu, %d)\n", st, vaddr, bytes, flags);
|
||||
|
||||
// TODO rueegges: cleanup partially completed mapping?
|
||||
size_t mapping_size;
|
||||
for(lvaddr_t current_vaddr = vaddr; current_vaddr < vaddr + bytes; current_vaddr += mapping_size * BASE_PAGE_SIZE) {
|
||||
@ -665,15 +666,15 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
||||
capaddr_t l2_index = VMSAv8_64_L2_INDEX(current_vaddr);
|
||||
capaddr_t l3_index = VMSAv8_64_L3_INDEX(current_vaddr);
|
||||
|
||||
// get the size of the mapping
|
||||
mapping_size = MIN(PTABLE_ENTRIES - l3_index, (vaddr + bytes - current_vaddr) / BASE_PAGE_SIZE);
|
||||
|
||||
// Cannot map anything with l0_index = 0 since this part of the page table was created by the kernel for us
|
||||
assert(l0_index != 0);
|
||||
|
||||
// get the size of the mapping
|
||||
mapping_size = MIN(PTABLE_ENTRIES - l3_index, (vaddr + bytes - current_vaddr) / BASE_PAGE_SIZE);
|
||||
|
||||
// get l1 page table
|
||||
struct pt_t *l1_pt;
|
||||
err = pt_ensure(st, st->l0_pt, l0_index, 1, &l1_pt);
|
||||
err = pt_ensure(st, l0_pt, l0_index, 1, &l1_pt);
|
||||
if(err_is_fail(err)) {
|
||||
return err;
|
||||
}
|
||||
@ -695,27 +696,26 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
||||
}
|
||||
assert(l3_pt->children != NULL);
|
||||
|
||||
// debug_printf("DEBUG rueegges: paging_map_fixed_attr - allocate mapping meta\n");
|
||||
|
||||
// make sure we have enough slot and slab space left
|
||||
err = pt_ensure_slabs(st);
|
||||
if(err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_SLAB_REFILL);
|
||||
}
|
||||
|
||||
// debug_printf("DEBUG rueegges: paging_map_fixed_attr - allocate mapping meta\n");
|
||||
|
||||
// create structures for the new metadata
|
||||
struct pt_t *pt_entry = (struct pt_t *) slab_alloc(&st->pt_slabs);
|
||||
if (pt_entry == NULL) {
|
||||
DEBUG_ERR(err, "Failed to refill slabs before adding page mapping.");
|
||||
return LIB_ERR_SLAB_ALLOC_FAIL;
|
||||
}
|
||||
|
||||
// set to null to indicate it is a frame mapping and not a page table mapping
|
||||
pt_entry->children = NULL;
|
||||
pt_entry->mapping_size = mapping_size;
|
||||
// allocate the new mapping
|
||||
err = st->slot_alloc->alloc(st->slot_alloc, &pt_entry->cap_mapping);
|
||||
if (err_is_fail(err)) {
|
||||
slab_free(&st->pt_slabs, pt_entry);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -725,6 +725,11 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
||||
err = vnode_map(l3_pt->cap_pt, frame, l3_index, flags, current_vaddr - vaddr, mapping_size, pt_entry->cap_mapping);
|
||||
if (err_is_fail(err)) {
|
||||
debug_printf("Failed to map vnode at vaddr 0x%lx\n", current_vaddr);
|
||||
slab_free(&st->pt_slabs, pt_entry);
|
||||
errval_t err_err = st->slot_alloc->free(st->slot_alloc, pt_entry->cap_mapping);
|
||||
if (err_is_fail(err_err)) {
|
||||
DEBUG_ERR(err, "Failed to free slot during error handling");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@ -7,11 +7,11 @@
|
||||
// used to avoid conflicts between tests
|
||||
static lvaddr_t vaddr = 0x0000100000000000L;
|
||||
|
||||
static void test_paging_run(errval_t func(void), char *name) {
|
||||
static void test_paging_run(errval_t func(struct paging_state *paging_state), char *name, struct paging_state *paging_state) {
|
||||
errval_t err;
|
||||
|
||||
// debug_printf("TEST_PAGING %19s: start\n", name);
|
||||
err = func();
|
||||
err = func(paging_state);
|
||||
|
||||
if (err_is_ok(err)) {
|
||||
debug_printf("TEST_PAGING %23s: OK\n", name);
|
||||
@ -21,7 +21,7 @@ static void test_paging_run(errval_t func(void), char *name) {
|
||||
}
|
||||
}
|
||||
|
||||
static errval_t test_paging_full_l3(void) {
|
||||
static errval_t test_paging_full_l3(struct paging_state *paging_state) {
|
||||
errval_t err;
|
||||
|
||||
size_t mapping_size = BASE_PAGE_SIZE;
|
||||
@ -33,7 +33,7 @@ static errval_t test_paging_full_l3(void) {
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_FRAME_ALLOC);
|
||||
}
|
||||
err = paging_map_fixed_attr(get_current_paging_state(), vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
||||
err = paging_map_fixed_attr(paging_state, vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_PMAP_NOT_MAPPED);
|
||||
}
|
||||
@ -51,7 +51,7 @@ static errval_t test_paging_full_l3(void) {
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
static errval_t test_paging_full_l2(void) {
|
||||
static errval_t test_paging_full_l2(struct paging_state *paging_state) {
|
||||
errval_t err;
|
||||
|
||||
size_t mapping_size = BASE_PAGE_SIZE;
|
||||
@ -63,7 +63,7 @@ static errval_t test_paging_full_l2(void) {
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_FRAME_ALLOC);
|
||||
}
|
||||
err = paging_map_fixed_attr(get_current_paging_state(), vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
||||
err = paging_map_fixed_attr(paging_state, vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_PMAP_NOT_MAPPED);
|
||||
}
|
||||
@ -81,7 +81,7 @@ static errval_t test_paging_full_l2(void) {
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
static errval_t test_paging_big_regions(void) {
|
||||
static errval_t test_paging_big_regions(struct paging_state *paging_state) {
|
||||
errval_t err;
|
||||
|
||||
size_t mapping_size;
|
||||
@ -95,7 +95,7 @@ static errval_t test_paging_big_regions(void) {
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_FRAME_ALLOC);
|
||||
}
|
||||
err = paging_map_fixed_attr(get_current_paging_state(), vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
||||
err = paging_map_fixed_attr(paging_state, vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_PMAP_NOT_MAPPED);
|
||||
}
|
||||
@ -114,9 +114,9 @@ static errval_t test_paging_big_regions(void) {
|
||||
}
|
||||
|
||||
void do_test_paging(void) {
|
||||
test_paging_run(test_paging_full_l3, "test_paging_full_l3");
|
||||
test_paging_run(test_paging_full_l2, "test_paging_full_l2");
|
||||
test_paging_run(test_paging_big_regions, "test_paging_big_regions");
|
||||
test_paging_run(test_paging_full_l3, "test_paging_full_l3", get_current_paging_state());
|
||||
test_paging_run(test_paging_full_l2, "test_paging_full_l2", get_current_paging_state());
|
||||
test_paging_run(test_paging_big_regions, "test_paging_big_regions", get_current_paging_state());
|
||||
|
||||
// Test paging
|
||||
for (int i = 0; i < 40; i++) {
|
||||
@ -124,4 +124,42 @@ void do_test_paging(void) {
|
||||
char *data = alloc_frame(5176*4096, 16, NULL, NULL);
|
||||
memset(data, 33, 5176*4096);
|
||||
}
|
||||
|
||||
debug_printf("TEST: do foreign test\n");
|
||||
// Tet foreign init
|
||||
errval_t err;
|
||||
struct capref rootcn_cap;
|
||||
struct cnoderef rootcn;
|
||||
struct cnoderef pagecn;
|
||||
struct paging_state st;
|
||||
err = cnode_create_l1(&rootcn_cap, &rootcn);
|
||||
assert(err_is_ok(err));
|
||||
err = cnode_create_foreign_l2(rootcn_cap, ROOTCN_SLOT_PAGECN, &pagecn);
|
||||
assert(err_is_ok(err));
|
||||
struct capref l0 = {
|
||||
.cnode = pagecn,
|
||||
.slot = PAGECN_SLOT_VROOT,
|
||||
};
|
||||
err = vnode_create(l0, ObjType_VNode_AARCH64_l0);
|
||||
assert(err_is_ok(err));
|
||||
err = paging_init_state_foreign(&st, VADDR_OFFSET, l0, get_default_slot_allocator());
|
||||
assert(err_is_ok(err));
|
||||
|
||||
debug_printf("TEST: map foreign l3\n");
|
||||
size_t mapping_size = BASE_PAGE_SIZE;
|
||||
|
||||
// map all entries of a single l3 table
|
||||
for(size_t i = 0; i < VMSAv8_64_PTABLE_NUM_ENTRIES; ++i) {
|
||||
struct capref frame;
|
||||
err = frame_alloc(&frame, mapping_size, NULL);
|
||||
if (err_is_fail(err)) {
|
||||
USER_PANIC_ERR(err, "Failed frame alloc");
|
||||
}
|
||||
err = paging_map_fixed_attr(&st, vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
||||
if (err_is_fail(err)) {
|
||||
USER_PANIC_ERR(err, "Failed page mapping");
|
||||
}
|
||||
|
||||
vaddr += mapping_size;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user