From 55117c600b496204004321da2c5e1e5264f6952c Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Fri, 29 Feb 2008 12:33:53 +0000 Subject: [PATCH] Back to the same fs0 bug point as before, but environment, disjoint utcb addresses and passing of utcb address information via the environment are implemented. --- src/arch/arm/exception.c | 10 +++---- tasks/libl4/src/arm/syscalls.S | 3 +-- tasks/libl4/src/init.c | 4 +-- tasks/mm0/include/env.h | 2 +- tasks/mm0/include/task.h | 4 --- tasks/mm0/src/env.c | 48 +++++++++++++++++++++++++--------- tasks/mm0/src/fault.c | 2 +- tasks/mm0/src/init.c | 2 +- tasks/mm0/src/stack.c | 7 ++++- tasks/mm0/src/task.c | 30 +++++++++------------ 10 files changed, 65 insertions(+), 47 deletions(-) diff --git a/src/arch/arm/exception.c b/src/arch/arm/exception.c index 9e92534..ce9aba1 100644 --- a/src/arch/arm/exception.c +++ b/src/arch/arm/exception.c @@ -82,22 +82,22 @@ int check_aborts(u32 faulted_pc, u32 fsr, u32 far) int ret = 0; if (is_prefetch_abort(fsr)) { - dprintk("Prefetch abort @ ", faulted_pc); +// dprintk("Prefetch abort @ ", faulted_pc); return 0; } switch (fsr & ARM_FSR_MASK) { /* Aborts that are expected on page faults: */ case DABT_PERM_PAGE: - dprintk("Page permission fault @ ", far); +// dprintk("Page permission fault @ ", far); ret = 0; break; case DABT_XLATE_PAGE: - dprintk("Page translation fault @ ", far); +// dprintk("Page translation fault @ ", far); ret = 0; break; case DABT_XLATE_SECT: - dprintk("Section translation fault @ ", far); +// dprintk("Section translation fault @ ", far); ret = 0; break; @@ -166,7 +166,7 @@ int check_aborts(u32 faulted_pc, u32 fsr, u32 far) void data_abort_handler(u32 faulted_pc, u32 fsr, u32 far) { set_abort_type(fsr, ARM_DABT); - dprintk("Data abort @ PC: ", faulted_pc); +// dprintk("Data abort @ PC: ", faulted_pc); if (check_aborts(faulted_pc, fsr, far) < 0) { printascii("This abort can't be handled by any pager.\n"); goto error; diff --git a/tasks/libl4/src/arm/syscalls.S b/tasks/libl4/src/arm/syscalls.S index df390d8..911e649 100644 --- a/tasks/libl4/src/arm/syscalls.S +++ b/tasks/libl4/src/arm/syscalls.S @@ -8,8 +8,7 @@ #include .macro utcb_address rx - mov \rx, #L4_KIP_ADDRESS - add \rx, \rx, #UTCB_KIP_OFFSET + ldr \rx, =utcb ldr \rx, [\rx] .endm diff --git a/tasks/libl4/src/init.c b/tasks/libl4/src/init.c index 61ae4d5..8c20967 100644 --- a/tasks/libl4/src/init.c +++ b/tasks/libl4/src/init.c @@ -47,10 +47,10 @@ void __l4_init(void) /* Initialise utcb only if we're not the pager */ if (self_tid() != PAGER_TID) { - utcb = *(struct utcb **)(USER_AREA_END - 8); + /* FIXME: C library should give the environ pointer for this */ + utcb = *(struct utcb **)(USER_AREA_END - PAGE_SIZE); printf("UTCB Read from userspace as: 0x%x\n", (unsigned long)utcb); } - } diff --git a/tasks/mm0/include/env.h b/tasks/mm0/include/env.h index 9926d74..f6553c1 100644 --- a/tasks/mm0/include/env.h +++ b/tasks/mm0/include/env.h @@ -1,6 +1,6 @@ #ifndef __MM0_ENV__ #define __MM0_ENV__ -int task_prepare_env_file(struct tcb *t); +int task_prepare_environment(struct tcb *t); #endif diff --git a/tasks/mm0/include/task.h b/tasks/mm0/include/task.h index e6e8883..dce59d7 100644 --- a/tasks/mm0/include/task.h +++ b/tasks/mm0/include/task.h @@ -63,10 +63,6 @@ struct tcb { /* UTCB address */ unsigned long utcb_address; - /* Temporary storage for environment data */ - void *env_data; - unsigned long env_size; - /* Per-task environment file */ struct vm_file *env_file; diff --git a/tasks/mm0/src/env.c b/tasks/mm0/src/env.c index 03a3e70..94bd199 100644 --- a/tasks/mm0/src/env.c +++ b/tasks/mm0/src/env.c @@ -13,34 +13,47 @@ * * Copyright (C) 2008 Bahadir Balban */ +#include #include -#include -#include -#include #include #include +#include +#include #include #include +#include + +struct envdata { + struct list_head list; + void *env_data; + int env_size; + int id; +}; +LIST_HEAD(env_list); /* Copies environment data into provided page. */ int task_env_pager_read_page(struct vm_file *f, unsigned long f_off_pfn, void *dest_page) { - struct tcb *t = find_task(f->vnum); + struct envdata *env; - if (!t) { - printf("%s: No such task tid: %d, to copy environment for.\n", - __TASKNAME__, f->vnum); - return -EINVAL; - } + list_for_each_entry(env, &env_list, list) + if (env->id == f->vnum) + goto copyenv; + printf("%s: No such env id: %d, to copy environment for.\n", + __TASKNAME__, f->vnum); + return -EINVAL; + +copyenv: if (f_off_pfn != 0) { printf("%s: Environments currently have a single page.\n"); return -EINVAL; } memset(dest_page, 0, PAGE_SIZE); - memcpy(dest_page, t->env_data, t->env_size); + BUG_ON(env->env_size > PAGE_SIZE); + memcpy(dest_page, env->env_data, env->env_size); return 0; } @@ -53,13 +66,14 @@ struct vm_pager task_env_pager = { }, }; - /* * For a task that is about to execute, this dynamically - * generates its environment file. + * generates its environment file, and environment data. */ -int task_prepare_env_file(struct tcb *t) +int task_prepare_environment(struct tcb *t) { + struct envdata *env; + /* Allocate a new vmfile for this task's environment */ if (IS_ERR(t->env_file = vmfile_alloc_init())) return (int)t->env_file; @@ -75,6 +89,14 @@ int task_prepare_env_file(struct tcb *t) t->env_file->pager = &task_env_pager; list_add(&t->env_file->list, &vm_file_list); + /* Allocate, initialise and add per-task env data */ + BUG_ON(!(env = kzalloc(sizeof(struct envdata)))); + INIT_LIST_HEAD(&env->list); + env->env_data = &t->utcb_address; + env->env_size = sizeof(t->utcb_address); + env->id = t->tid; + list_add(&env->list, &env_list); + return 0; } diff --git a/tasks/mm0/src/fault.c b/tasks/mm0/src/fault.c index dfeae5a..6816a11 100644 --- a/tasks/mm0/src/fault.c +++ b/tasks/mm0/src/fault.c @@ -1,7 +1,7 @@ /* * Page fault handling. * - * Copyright (C) 2007 Bahadir Balban + * Copyright (C) 2007, 2008 Bahadir Balban */ #include #include diff --git a/tasks/mm0/src/init.c b/tasks/mm0/src/init.c index a97ef49..0516b69 100644 --- a/tasks/mm0/src/init.c +++ b/tasks/mm0/src/init.c @@ -34,7 +34,7 @@ void init_utcb(void) utcb_page = alloc_page(1); l4_map(utcb_page, utcb_virt, 1, MAP_USR_RW_FLAGS, self_tid()); - /* Also initialise the utcb reference that is used in l4lib. */ + /* Also initialise the utcb reference that is inside l4lib. */ utcb = utcb_virt; } diff --git a/tasks/mm0/src/stack.c b/tasks/mm0/src/stack.c index a83f02c..05e2e82 100644 --- a/tasks/mm0/src/stack.c +++ b/tasks/mm0/src/stack.c @@ -1,4 +1,9 @@ - +/* + * TODO: This is to be used when moving mm0's temporary + * stack to a proper place. It's unused for now. + * + * Copyright (C) 2007, 2008 Bahadir Balban + */ #include #include #include diff --git a/tasks/mm0/src/task.c b/tasks/mm0/src/task.c index 8271c82..1487224 100644 --- a/tasks/mm0/src/task.c +++ b/tasks/mm0/src/task.c @@ -107,14 +107,24 @@ int start_boot_tasks(struct initdata *initdata, struct tcb_head *tcbs) ids.spid = -1; } - /* Create vm file and tcb */ - file = vmfile_alloc_init(); + printf("Creating new thread.\n"); + /* Create the thread structures and address space */ + if ((err = l4_thread_control(THREAD_CREATE, &ids)) < 0) { + printf("l4_thread_control failed with %d.\n", err); + goto error; + } + + /* Create a task and use returned space and thread ids. */ + printf("New task with id: %d, space id: %d\n", ids.tid, ids.spid); task = create_init_tcb(tcbs); + task->tid = ids.tid; + task->spid = ids.spid; /* * For boot files, we use the physical address of the memory * file as its mock-up inode. */ + file = vmfile_alloc_init(); file->vnum = img->phys_start; file->length = img->phys_end - img->phys_start; file->pager = &boot_file_pager; @@ -132,12 +142,10 @@ int start_boot_tasks(struct initdata *initdata, struct tcb_head *tcbs) * when faulted, simply copies the task env data to the * allocated page. */ - if (task_prepare_env_file(task) < 0) { + if (task_prepare_environment(task) < 0) { printf("Could not create environment file.\n"); goto error; } - task->env_data = &task->utcb_address; - task->env_size = sizeof(task->utcb_address); /* * Task stack starts right after the environment, @@ -187,18 +195,6 @@ int start_boot_tasks(struct initdata *initdata, struct tcb_head *tcbs) goto error; } - printf("Creating new thread.\n"); - /* Create the thread structures and address space */ - if ((err = l4_thread_control(THREAD_CREATE, &ids)) < 0) { - printf("l4_thread_control failed with %d.\n", err); - goto error; - } - - /* Use returned space and thread ids. */ - printf("New task with id: %d, space id: %d\n", ids.tid, ids.spid); - task->tid = ids.tid; - task->spid = ids.spid; - /* Set up the task's thread details, (pc, sp, pager etc.) */ if ((err = l4_exchange_registers(pc, sp, self_tid(), task->tid) < 0)) { printf("l4_exchange_registers failed with %d.\n", err);