ported userspace tasks to new VMA implementation (untested!)

This commit is contained in:
Steffen Vogel 2013-11-20 13:19:58 +01:00
parent 707d7132c8
commit 71f55f0a89

View file

@ -196,7 +196,6 @@ static void wakeup_blocked_tasks(int result)
/** @brief A procedure to be called by /** @brief A procedure to be called by
* procedures which are called by exiting tasks. */ * procedures which are called by exiting tasks. */
static void NORETURN do_exit(int arg) { static void NORETURN do_exit(int arg) {
vma_t* tmp;
task_t* curr_task = per_core(current_task); task_t* curr_task = per_core(current_task);
uint32_t flags, core_id, fd, status; uint32_t flags, core_id, fd, status;
@ -230,18 +229,7 @@ static void NORETURN do_exit(int arg) {
wakeup_blocked_tasks(arg); wakeup_blocked_tasks(arg);
//vma_dump(curr_task); drop_vma_list(); // kfree virtual memory areas and the vma_list
spinlock_lock(&curr_task->vma_lock);
// remove memory regions
while((tmp = curr_task->vma_list) != NULL) {
kfree((void*) tmp->start, tmp->end - tmp->start + 1);
curr_task->vma_list = tmp->next;
kfree((void*) tmp, sizeof(vma_t));
}
spinlock_unlock(&curr_task->vma_lock);
drop_page_map(); // delete page directory and its page tables drop_page_map(); // delete page directory and its page tables
#if 0 #if 0
@ -262,9 +250,7 @@ static void NORETURN do_exit(int arg) {
reschedule(); reschedule();
kprintf("Kernel panic: scheduler on core %d found no valid task\n", CORE_ID); kprintf("Kernel panic: scheduler on core %d found no valid task\n", CORE_ID);
while(1) { while(1) HALT;
HALT;
}
} }
/** @brief A procedure to be called by kernel tasks */ /** @brief A procedure to be called by kernel tasks */
@ -330,7 +316,7 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uin
ret = create_page_map(task_table+i, 0); ret = create_page_map(task_table+i, 0);
if (ret < 0) { if (ret < 0) {
ret = -ENOMEM; ret = -ENOMEM;
goto create_task_out; goto out;
} }
task_table[i].id = i; task_table[i].id = i;
@ -376,7 +362,7 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uin
} }
} }
create_task_out: out:
spinlock_irqsave_unlock(&table_lock); spinlock_irqsave_unlock(&table_lock);
return ret; return ret;
@ -387,11 +373,7 @@ int sys_fork(void)
int ret = -ENOMEM; int ret = -ENOMEM;
unsigned int i, core_id, fd_i; unsigned int i, core_id, fd_i;
task_t* parent_task = per_core(current_task); task_t* parent_task = per_core(current_task);
vma_t** child;
vma_t* parent;
vma_t* tmp;
spinlock_lock(&parent_task->vma_lock);
spinlock_irqsave_lock(&table_lock); spinlock_irqsave_lock(&table_lock);
core_id = CORE_ID; core_id = CORE_ID;
@ -403,34 +385,19 @@ int sys_fork(void)
ret = create_page_map(task_table+i, 1); ret = create_page_map(task_table+i, 1);
if (ret < 0) { if (ret < 0) {
ret = -ENOMEM; ret = -ENOMEM;
goto create_task_out; goto out;
} }
ret = copy_vma_list(child_task);
if (BUILTIN_EXPECT(!ret, 0)) {
ret = -ENOMEM;
goto out;
}
task_table[i].id = i; task_table[i].id = i;
task_table[i].last_stack_pointer = NULL; task_table[i].last_stack_pointer = NULL;
task_table[i].stack = create_stack(); task_table[i].stack = create_stack();
spinlock_init(&task_table[i].vma_lock);
// copy VMA list
child = &task_table[i].vma_list;
parent = parent_task->vma_list;
tmp = NULL;
while(parent) {
*child = (vma_t*) kmalloc(sizeof(vma_t));
if (BUILTIN_EXPECT(!child, 0))
break;
(*child)->start = parent->start;
(*child)->end = parent->end;
(*child)->type = parent->type;
(*child)->prev = tmp;
(*child)->next = NULL;
parent = parent->next;
tmp = *child;
child = &((*child)->next);
} }
@ -487,9 +454,8 @@ int sys_fork(void)
} }
} }
create_task_out: out:
spinlock_irqsave_unlock(&table_lock); spinlock_irqsave_unlock(&table_lock);
spinlock_unlock(&parent_task->vma_lock);
return ret; return ret;
} }
@ -679,7 +645,7 @@ static int load_task(load_args_t* largs)
flags |= VMA_WRITE; flags |= VMA_WRITE;
if (prog_header.flags & PF_X) if (prog_header.flags & PF_X)
flags |= VMA_EXECUTE; flags |= VMA_EXECUTE;
vma_add(curr_task, prog_header.virt_addr, prog_header.virt_addr+npages*PAGE_SIZE-1, flags); vma_add(prog_header.virt_addr, prog_header.virt_addr+npages*PAGE_SIZE-1, flags);
if (!(prog_header.flags & PF_W)) if (!(prog_header.flags & PF_W))
change_page_permissions(prog_header.virt_addr, prog_header.virt_addr+npages*PAGE_SIZE-1, flags); change_page_permissions(prog_header.virt_addr, prog_header.virt_addr+npages*PAGE_SIZE-1, flags);
@ -708,7 +674,7 @@ static int load_task(load_args_t* largs)
flags |= VMA_WRITE; flags |= VMA_WRITE;
if (prog_header.flags & PF_X) if (prog_header.flags & PF_X)
flags |= VMA_EXECUTE; flags |= VMA_EXECUTE;
vma_add(curr_task, stack, stack+npages*PAGE_SIZE-1, flags); vma_add(stack, stack+npages*PAGE_SIZE-1, flags);
break; break;
} }
} }
@ -871,13 +837,11 @@ int create_user_task_on_core(tid_t* id, const char* fname, char** argv, uint32_t
int sys_execve(const char* fname, char** argv, char** env) int sys_execve(const char* fname, char** argv, char** env)
{ {
vfs_node_t* node; vfs_node_t* node;
vma_t* tmp;
size_t i, buffer_size = 0; size_t i, buffer_size = 0;
load_args_t* load_args = NULL; load_args_t* load_args = NULL;
char *dest, *src; char *dest, *src;
int ret, argc = 0; int ret, argc = 0;
int envc = 0; int envc = 0;
task_t* curr_task = per_core(current_task);
node = findnode_fs((char*) fname); node = findnode_fs((char*) fname);
if (!node || !(node->type == FS_FILE)) if (!node || !(node->type == FS_FILE))
@ -920,16 +884,8 @@ int sys_execve(const char* fname, char** argv, char** env)
while ((*dest++ = *src++) != 0); while ((*dest++ = *src++) != 0);
} }
spinlock_lock(&curr_task->vma_lock);
// remove old program // remove old program
while((tmp = curr_task->vma_list) != NULL) { drop_vma_list();
kfree((void*) tmp->start, tmp->end - tmp->start + 1);
curr_task->vma_list = tmp->next;
kfree((void*) tmp, sizeof(vma_t));
}
spinlock_unlock(&curr_task->vma_lock);
/* /*
* we use a trap gate to enter the kernel * we use a trap gate to enter the kernel