Merge branch 'extra/pass-paging-state' into 'main'
Extra/pass paging state See merge request rueegges/aos!1
This commit is contained in:
commit
24cfb539fa
@ -600,6 +600,7 @@ errors spawn SPAWN_ERR_ {
|
||||
failure COPY_VNODE "Failure copying top-level VNode from existing domain",
|
||||
failure CREATE_DISPATCHER "Failure creating DCB",
|
||||
failure CREATE_DISPATCHER_FRAME "Failure creating dispatcher frame",
|
||||
failure CREATE_VSPACE_BUF_FRAME "Failure creating vspace buf frame",
|
||||
failure CREATE_SELFEP "Failure creating endpoint to self",
|
||||
failure CREATE_ARGSPG "Failure creating page for arguments",
|
||||
failure CREATE_FDSPG "Failure creating page for file descriptors",
|
||||
@ -613,6 +614,8 @@ errors spawn SPAWN_ERR_ {
|
||||
// setup_vspace
|
||||
failure MAP_DISPATCHER_TO_NEW "Failure mapping dispatcher frame to new domain",
|
||||
failure MAP_DISPATCHER_TO_SELF "Failure mapping dispatcher frame to parent",
|
||||
failure MAP_VSPACE_BUF_TO_NEW "Failure mapping vspace buffer frame to new domain",
|
||||
failure MAP_VSPACE_BUF_TO_SELF "Failure mapping vspace buffer frame to parent",
|
||||
failure MAP_ARGSPG_TO_NEW "Failure mapping arguments page to new domain",
|
||||
failure MAP_ARGSPG_TO_SELF "Failure mapping arguments page to parent",
|
||||
failure MAP_FDSPG_TO_NEW "Failure mapping file descriptors page to new domain",
|
||||
@ -626,6 +629,7 @@ errors spawn SPAWN_ERR_ {
|
||||
failure UNMAP_MODULE "Failed unmapping module",
|
||||
failure CREATE_SEGCN "Failed to create segment CNode",
|
||||
failure CREATE_SMALLCN "Failed to create small RAM caps CNode",
|
||||
failure SERIALISE_VSPACE_TOO_LARGE "Failure serializing vspace, using too many capabilities",
|
||||
|
||||
// setup env
|
||||
failure ARGSPG_OVERFLOW "Overflow in arguments page: too many arguments or environment variables",
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <aos/slab.h>
|
||||
#include <barrelfish_kpi/paging_arch.h>
|
||||
#include <aos/paging_types.h>
|
||||
#include <barrelfish_kpi/domain_params.h>
|
||||
|
||||
struct paging_state;
|
||||
|
||||
@ -32,6 +33,7 @@ errval_t paging_init_state_foreign(struct paging_state *st, lvaddr_t start_vaddr
|
||||
struct capref pdir, struct slot_allocator * ca);
|
||||
/// initialize self-paging module
|
||||
errval_t paging_init(void);
|
||||
errval_t paging_init_params(struct spawn_domain_params *params);
|
||||
|
||||
errval_t paging_init_onthread(struct thread *t);
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#define VREGION_FLAGS_MPB 0x10 // Message passing buffer
|
||||
#define VREGION_FLAGS_GUARD 0x20 // Guard page
|
||||
#define VREGION_FLAGS_MASK 0x2f // Mask of all individual VREGION_FLAGS
|
||||
#define PT_CHILD_ARRAY_SIZE (PTABLE_ENTRIES * sizeof(void *)) // size of array holding references to page table children
|
||||
|
||||
#define VREGION_FLAGS_READ_WRITE \
|
||||
(VREGION_FLAGS_READ | VREGION_FLAGS_WRITE)
|
||||
|
||||
@ -110,7 +110,8 @@
|
||||
#define TASKCN_SLOT_PROC_MNG 18 ///< Cap for the process manager
|
||||
#define TASKCN_SLOT_DOMAINID 19 ///< Domain ID cap
|
||||
#define TASKCN_SLOT_DEVMAN 20 ///< DeviceID manager capability
|
||||
#define TASKCN_SLOTS_USER 21 ///< First free slot in taskcn for user
|
||||
#define TASKCN_SLOT_VSPACE 21 ///< Vspace frame slot
|
||||
#define TASKCN_SLOTS_USER 22 ///< First free slot in taskcn for user
|
||||
|
||||
/* Page CNode */
|
||||
#define PAGECN_SLOT_VROOT 0 ///< First slot of page cnode is root page table
|
||||
|
||||
@ -50,6 +50,7 @@ struct spawninfo {
|
||||
struct capref cspace_cap_rootcn; // < Contains a capability for the root (L1) CNode.
|
||||
struct capref cspace_cap_dispframe; // < A capability to the dispatcher frame, used to communicate between a process and the CPU driver.
|
||||
struct capref cspace_cap_argspage; // < A page containing a list of command line arguments.
|
||||
struct capref cspace_cap_vspace; // < The frame capability used to store the serialized vspace
|
||||
|
||||
struct capref vspace_cap_l0_pagetable;
|
||||
};
|
||||
|
||||
@ -153,6 +153,7 @@ size_t strftime(char * __restrict, size_t, const char * __restrict,
|
||||
const struct tm * __restrict);
|
||||
time_t time(time_t *);
|
||||
void time_wait_ms(unsigned long);
|
||||
long time_to_ms(struct timespec tt);
|
||||
#if __POSIX_VISIBLE >= 200112
|
||||
struct sigevent;
|
||||
int timer_create(clockid_t, struct sigevent *__restrict, timer_t *__restrict);
|
||||
|
||||
@ -128,7 +128,7 @@ errval_t barrelfish_init_onthread(struct spawn_domain_params *params)
|
||||
return err_push(err, LIB_ERR_RAM_ALLOC_SET);
|
||||
}
|
||||
|
||||
err = paging_init();
|
||||
err = paging_init_params(params);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_VSPACE_INIT);
|
||||
}
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#include <aos/paging.h>
|
||||
#include <aos/except.h>
|
||||
#include <aos/slab.h>
|
||||
#include <aos/slab.h>
|
||||
#include "threads_priv.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@ -29,7 +28,7 @@ static struct paging_state current;
|
||||
|
||||
#define PT_META_MAX_SIZE MAX(sizeof(struct pt_t), sizeof(struct pt_vaddr_reg_t))
|
||||
#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)
|
||||
#define PT_CHILDREN_SLAB_INITIAL_SPACE SLAB_STATIC_SIZE(PT_CHILDREN_SLAB_MIN_SPACE, PT_CHILD_ARRAY_SIZE)
|
||||
|
||||
/**
|
||||
* \brief Helper function that allocates a slot and
|
||||
@ -275,7 +274,7 @@ errval_t paging_init_state(struct paging_state *st, lvaddr_t start_vaddr,
|
||||
|
||||
// initialize slab allocators
|
||||
slab_init(&st->pt_slabs, PT_META_MAX_SIZE, NULL);
|
||||
slab_init(&st->pt_children_slabs, BASE_PAGE_SIZE, NULL);
|
||||
slab_init(&st->pt_children_slabs, PT_CHILD_ARRAY_SIZE, NULL);
|
||||
|
||||
// initialize shadow page tables
|
||||
st->l0_pt.cap_pt = pdir;
|
||||
@ -328,12 +327,7 @@ errval_t paging_init_state_foreign(struct paging_state *st, lvaddr_t start_vaddr
|
||||
return paging_init_state(st, start_vaddr, pt_cap, ca);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function initializes the paging for this domain
|
||||
*
|
||||
* Note: The function is called once before main.
|
||||
*/
|
||||
errval_t paging_init(void)
|
||||
errval_t paging_init_params(struct spawn_domain_params *params)
|
||||
{
|
||||
errval_t err;
|
||||
debug_printf("paging_init\n");
|
||||
@ -353,10 +347,28 @@ errval_t paging_init(void)
|
||||
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);
|
||||
|
||||
// if we got additional vspace info use it
|
||||
if(params != NULL && params->vspace_buf != NULL) {
|
||||
current.l0_pt = **(struct pt_t **)params->vspace_buf;
|
||||
current.vaddr_head = **(struct pt_vaddr_reg_t **)(params->vspace_buf + sizeof(struct pt_t *));
|
||||
debug_printf("Received initial paging state:\n");
|
||||
pt_print_state(¤t);
|
||||
}
|
||||
|
||||
set_current_paging_state(¤t);
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function initializes the paging for this domain
|
||||
*
|
||||
* Note: The function is called once before main.
|
||||
*/
|
||||
errval_t paging_init(void)
|
||||
{
|
||||
return paging_init_params(NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializes the paging functionality for the calling thread
|
||||
@ -565,7 +577,7 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
||||
assert(vaddr % BASE_PAGE_SIZE == 0);
|
||||
assert(bytes % BASE_PAGE_SIZE == 0);
|
||||
lvaddr_t end_vaddr = vaddr + bytes;
|
||||
assert(end_vaddr <= PTABLE_ENTRIES * PTABLE_ENTRIES *PTABLE_ENTRIES * PTABLE_ENTRIES * BASE_PAGE_SIZE);
|
||||
assert(end_vaddr <= PTABLE_ENTRIES * PTABLE_ENTRIES * PTABLE_ENTRIES * PTABLE_ENTRIES * BASE_PAGE_SIZE);
|
||||
assert(st != NULL);
|
||||
assert(st->slot_alloc != NULL);
|
||||
|
||||
@ -590,7 +602,6 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
||||
|
||||
// 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;
|
||||
for(;vaddr_reg != NULL; vaddr_reg = vaddr_reg->next) {
|
||||
// we have found the region it belongs to
|
||||
@ -611,7 +622,7 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
||||
return LIB_ERR_PMAP_ADDR_NOT_FREE;
|
||||
}
|
||||
|
||||
// TODO rueegges: cleanup partially completed mapping?
|
||||
// TODO: cleanup partially completed mapping?
|
||||
size_t mapping_size;
|
||||
for(lvaddr_t current_vaddr = vaddr; current_vaddr < end_vaddr; current_vaddr += mapping_size * BASE_PAGE_SIZE) {
|
||||
capaddr_t l0_index = VMSAv8_64_L0_INDEX(current_vaddr);
|
||||
@ -662,6 +673,7 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
||||
DEBUG_ERR(err, "Failed to refill slabs before adding page mapping.");
|
||||
return LIB_ERR_SLAB_ALLOC_FAIL;
|
||||
}
|
||||
pt_entry->cap_pt = NULL_CAP;
|
||||
pt_entry->children = NULL;
|
||||
pt_entry->mapping_size = mapping_size;
|
||||
// allocate the new mapping
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include <test_helper.h>
|
||||
#include <test_mm.h>
|
||||
#include <mm/mm.h>
|
||||
#include <time.h>
|
||||
|
||||
// ASSESSMENT M1: can be used to show the speed issues in mm_alloc
|
||||
#define TEST_MM_SMALL_COUNT 100
|
||||
@ -140,20 +141,33 @@ static errval_t test_mm_rand(struct mm *mm) {
|
||||
static errval_t test_mm_many(struct mm *mm) {
|
||||
errval_t err;
|
||||
|
||||
struct timespec tt;
|
||||
clock_gettime(CLOCK_REALTIME, &tt);
|
||||
long start_ms = time_to_ms(tt);
|
||||
for(int i = 0; i < TEST_MM_BIG_COUNT; ++i) {
|
||||
err = mm_alloc_aligned(mm, 1 << 10, 1 << 10, &caps_big[i]);
|
||||
if(err_is_fail(err)) {
|
||||
debug_printf("Iteration: %d\n", i);
|
||||
return err_push(err, MM_ERR_NEW_NODE);
|
||||
}
|
||||
if(!((i + 1) % 1000)) {
|
||||
clock_gettime(CLOCK_REALTIME, &tt);
|
||||
debug_printf("Mapped %d after %ld\n", i + 1, time_to_ms(tt) - start_ms);
|
||||
}
|
||||
}
|
||||
// free loads of small memory
|
||||
clock_gettime(CLOCK_REALTIME, &tt);
|
||||
start_ms = time_to_ms(tt);
|
||||
for(int i = 0; i < TEST_MM_BIG_COUNT; ++i) {
|
||||
err = mm_free(mm, caps_big[i]);
|
||||
if(err_is_fail(err)) {
|
||||
debug_printf("Iteration: %d\n", i);
|
||||
return err_push(err, MM_ERR_MM_FREE);
|
||||
}
|
||||
if(!((i + 1) % 1000)) {
|
||||
clock_gettime(CLOCK_REALTIME, &tt);
|
||||
debug_printf("Freed %d after %ld\n", i + 1, time_to_ms(tt) - start_ms);
|
||||
}
|
||||
}
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
@ -154,6 +154,11 @@ static errval_t test_paging_unmap(struct paging_state *paging_state) {
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_PMAP_NOT_MAPPED);
|
||||
}
|
||||
|
||||
// check that it is mapped
|
||||
*(uint8_t *) retaddr = 1;
|
||||
assert(*(uint8_t *)retaddr == 1);
|
||||
|
||||
err = paging_unmap(paging_state, retaddr);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_PMAP_UNMAP);
|
||||
@ -167,7 +172,7 @@ static errval_t test_paging_unmap(struct paging_state *paging_state) {
|
||||
return err_push(err, LIB_ERR_PMAP_NOT_MAPPED);
|
||||
}
|
||||
|
||||
*(uint8_t *) retaddr = 1;
|
||||
// check that it is mapped
|
||||
assert(*(uint8_t *)retaddr == 1);
|
||||
|
||||
return SYS_ERR_OK;
|
||||
|
||||
@ -51,6 +51,11 @@ time(time_t *t)
|
||||
return (retval);
|
||||
}
|
||||
|
||||
long
|
||||
time_to_ms(struct timespec tt) {
|
||||
return tt.tv_sec * 1000 + tt.tv_nsec / 1000 / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Wait for ms milliseconds before returning.
|
||||
*
|
||||
@ -64,10 +69,10 @@ time_wait_ms(unsigned long ms) {
|
||||
struct timespec tt;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &tt);
|
||||
long start = tt.tv_sec * 1000 + tt.tv_nsec / 1000 / 1000;
|
||||
long start = time_to_ms(tt);
|
||||
long now;
|
||||
do {
|
||||
clock_gettime(CLOCK_REALTIME, &tt);
|
||||
now = tt.tv_sec * 1000 + tt.tv_nsec / 1000 / 1000;
|
||||
now = time_to_ms(tt);
|
||||
} while(start + ms > now);
|
||||
}
|
||||
@ -119,6 +119,166 @@ static errval_t elf_allocate(
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
static size_t spawn_serialice_vspace_pt_size(struct pt_t *pt) {
|
||||
size_t sum = 0;
|
||||
|
||||
sum += sizeof(struct pt_t);
|
||||
|
||||
if(pt->children != NULL) {
|
||||
// children array
|
||||
sum += PT_CHILD_ARRAY_SIZE;
|
||||
|
||||
for(size_t i = 0; i < PTABLE_ENTRIES; ++i) {
|
||||
if(pt->children[i] != NULL) {
|
||||
sum += spawn_serialice_vspace_pt_size(pt->children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
// places pt as first thing in buf, then copies all else and increments curr_buf accordingly
|
||||
static errval_t spawn_serialize_pt(struct spawninfo *si, struct pt_t *pt, void *self_buf, void *child_buf, size_t *curr_offset, cslot_t *pagecn_slot) {
|
||||
errval_t err;
|
||||
|
||||
if (*pagecn_slot >= L2_CNODE_SLOTS - 2) {
|
||||
return SPAWN_ERR_SERIALISE_VSPACE_TOO_LARGE;
|
||||
}
|
||||
|
||||
// write pt to buffer
|
||||
struct pt_t *pt_child = (struct pt_t *) (self_buf + *curr_offset);
|
||||
memcpy(pt_child, pt, sizeof(struct pt_t));
|
||||
*curr_offset += sizeof(struct pt_t);
|
||||
|
||||
// copy capability references to child
|
||||
if(!capref_is_null(pt->cap_pt)) {
|
||||
pt_child->cap_pt.cnode = si->cspace_l2_cnode_pagecn;
|
||||
pt_child->cap_pt.slot = *pagecn_slot;
|
||||
*pagecn_slot = *pagecn_slot + 1;
|
||||
err = cap_copy(pt_child->cap_pt, pt->cap_pt);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_CAP_COPY_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
if(!capref_is_null(pt->cap_mapping)) {
|
||||
pt_child->cap_mapping.cnode = si->cspace_l2_cnode_pagecn;
|
||||
pt_child->cap_mapping.slot = *pagecn_slot;
|
||||
*pagecn_slot = *pagecn_slot + 1;
|
||||
err = cap_copy(pt_child->cap_mapping, pt->cap_mapping);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_CAP_COPY_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
if (pt->children == NULL) {
|
||||
assert(pt_child->children == NULL);
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
// serialize all children
|
||||
pt_child->children = (struct pt_t **)(child_buf + *curr_offset);
|
||||
struct pt_t ** children_self = (struct pt_t **)(self_buf + *curr_offset);
|
||||
*curr_offset += PT_CHILD_ARRAY_SIZE;
|
||||
for(size_t i = 0; i < PTABLE_ENTRIES; ++i) {
|
||||
if (pt->children[i] == NULL) {
|
||||
children_self[i] = NULL;
|
||||
} else {
|
||||
children_self[i] = (struct pt_t *)(child_buf + *curr_offset);
|
||||
err = spawn_serialize_pt(si, pt->children[i], self_buf, child_buf, curr_offset, pagecn_slot);
|
||||
if (err_is_fail(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
// serializes the vspace in a way that does not require deserialization
|
||||
// vspace_buf->|l0_pt*,vaddr_head*,data....|
|
||||
// so the child can just take the two pointers and store them into its current paging_state
|
||||
static errval_t spawn_serialize_vspace(struct spawninfo *si, struct paging_state *paging_state, struct spawn_domain_params *domain_params) {
|
||||
errval_t err;
|
||||
|
||||
// first calculate required vspace size
|
||||
size_t pt_space = spawn_serialice_vspace_pt_size(&paging_state->l0_pt);
|
||||
|
||||
size_t vaddr_space = 0;
|
||||
for(struct pt_vaddr_reg_t *cur_vaddr = &paging_state->vaddr_head; cur_vaddr != NULL; cur_vaddr = cur_vaddr->next) {
|
||||
vaddr_space += sizeof(struct pt_vaddr_reg_t);
|
||||
}
|
||||
|
||||
size_t pointer_space = 2 * sizeof(void *);
|
||||
|
||||
size_t total_space = pointer_space + pt_space + vaddr_space;
|
||||
size_t reserve_space =
|
||||
// additional structs for the vaddr allocation that is required
|
||||
2 * sizeof(struct pt_vaddr_reg_t) +
|
||||
// space for potential l1,l2,l3 page tables
|
||||
6 * (sizeof(struct pt_t) + PT_CHILD_ARRAY_SIZE) +
|
||||
// space for the page table entries when mapping up to 512 contiguous pages
|
||||
2 * sizeof(struct pt_t);
|
||||
total_space = ROUND_UP(total_space + reserve_space, BASE_PAGE_SIZE);
|
||||
// require this limit to restrict the ammount of additionally reserved space
|
||||
if(total_space > LARGE_PAGE_SIZE) {
|
||||
return SPAWN_ERR_SERIALISE_VSPACE_TOO_LARGE;
|
||||
}
|
||||
|
||||
// allocate memory to store the state
|
||||
void *vspace_buf_self;
|
||||
void *vspace_buf_child;
|
||||
err = frame_create(si->cspace_cap_vspace, total_space, NULL);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, SPAWN_ERR_CREATE_VSPACE_BUF_FRAME);
|
||||
}
|
||||
err = paging_map_frame_attr(
|
||||
get_current_paging_state(), &vspace_buf_self,
|
||||
total_space, si->cspace_cap_vspace, VREGION_FLAGS_READ_WRITE
|
||||
);
|
||||
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_MAP_VSPACE_BUF_TO_SELF);
|
||||
err = paging_map_frame_attr(
|
||||
paging_state, &vspace_buf_child,
|
||||
total_space, si->cspace_cap_vspace, VREGION_FLAGS_READ_WRITE
|
||||
);
|
||||
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_MAP_VSPACE_BUF_TO_NEW);
|
||||
|
||||
// first store all the page table structs
|
||||
cslot_t pagecn_slot = PAGECN_SLOT_VROOT + 1;
|
||||
size_t curr_offset = 2 * sizeof(void *);
|
||||
*(void **) vspace_buf_self = vspace_buf_child + curr_offset;
|
||||
err = spawn_serialize_pt(si, &paging_state->l0_pt, vspace_buf_self, vspace_buf_child, &curr_offset, &pagecn_slot);
|
||||
if(err_is_fail(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// then store all the vaddr region structs
|
||||
*(void **)(vspace_buf_self + sizeof(void *)) = vspace_buf_child + curr_offset;
|
||||
for(struct pt_vaddr_reg_t *cur_vaddr = &paging_state->vaddr_head; cur_vaddr != NULL; cur_vaddr = cur_vaddr->next) {
|
||||
struct pt_vaddr_reg_t *vaddr_child = (struct pt_vaddr_reg_t *)(vspace_buf_self + curr_offset);
|
||||
memcpy(vaddr_child, cur_vaddr, sizeof(struct pt_vaddr_reg_t));
|
||||
curr_offset += sizeof(struct pt_vaddr_reg_t);
|
||||
if(cur_vaddr->next != NULL) {
|
||||
vaddr_child->next = (struct pt_vaddr_reg_t *)(vspace_buf_child + curr_offset);
|
||||
}
|
||||
}
|
||||
|
||||
// unmap in self
|
||||
err = paging_unmap(get_current_paging_state(), vspace_buf_self);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_PMAP_UNMAP);
|
||||
}
|
||||
|
||||
assert(curr_offset <= total_space);
|
||||
|
||||
debug_printf("SPAWN: Passing vspace info at 0x%lx\n", vspace_buf_child);
|
||||
domain_params->vspace_buf = vspace_buf_child;
|
||||
domain_params->vspace_buf_len = total_space;
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* (M2): Implement this function.
|
||||
@ -205,6 +365,9 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
||||
si->cspace_cap_argspage.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_argspage.slot = TASKCN_SLOT_ARGSPAGE;
|
||||
|
||||
si->cspace_cap_vspace.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_vspace.slot = TASKCN_SLOT_VSPACE;
|
||||
|
||||
err = cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC0, &si->cspace_l2_cnode_slot_alloc_0);
|
||||
if (err_is_fail(err)) return err;
|
||||
err = cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC1, &si->cspace_l2_cnode_slot_alloc_1);
|
||||
@ -353,16 +516,19 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
||||
|
||||
// afeer: put the arguments into the argspage
|
||||
struct spawn_domain_params * domain_params = (struct spawn_domain_params *) arguments_page_in_self;
|
||||
domain_params->argc = argc;
|
||||
|
||||
err = spawn_serialize_vspace(si, &child_paging_state, domain_params);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, SPAWN_ERR_SERIALISE_VSPACE);
|
||||
}
|
||||
|
||||
// afeer: TODO: what do i put here? do we need to set these fields to some value?
|
||||
// domain_params->vspace_buf = NULL;
|
||||
// domain_params->vspace_buf_len = 0;
|
||||
// domain_params->tls_init_base = NULL;
|
||||
// domain_params->tls_init_len = 0;
|
||||
// domain_params->tls_total_len = 0;
|
||||
// domain_params->pagesize = BASE_PAGE_SIZE;
|
||||
|
||||
|
||||
domain_params->argc = argc;
|
||||
size_t offset = sizeof(struct spawn_domain_params);
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
// afeer: put the argument into page in self
|
||||
|
||||
Loading…
Reference in New Issue
Block a user