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.
This commit is contained in:
Bahadir Balban
2008-02-29 12:33:53 +00:00
parent 617d24b4f0
commit 55117c600b
10 changed files with 65 additions and 47 deletions

View File

@@ -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;

View File

@@ -8,8 +8,7 @@
#include <l4/generic/space.h>
.macro utcb_address rx
mov \rx, #L4_KIP_ADDRESS
add \rx, \rx, #UTCB_KIP_OFFSET
ldr \rx, =utcb
ldr \rx, [\rx]
.endm

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -13,34 +13,47 @@
*
* Copyright (C) 2008 Bahadir Balban
*/
#include <l4lib/types.h>
#include <l4/lib/list.h>
#include <vm_area.h>
#include <kmalloc/kmalloc.h>
#include <task.h>
#include <l4/api/kip.h>
#include <l4/api/errno.h>
#include <kmalloc/kmalloc.h>
#include <vm_area.h>
#include <string.h>
#include <file.h>
#include <task.h>
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;
}

View File

@@ -1,7 +1,7 @@
/*
* Page fault handling.
*
* Copyright (C) 2007 Bahadir Balban
* Copyright (C) 2007, 2008 Bahadir Balban
*/
#include <vm_area.h>
#include <task.h>

View File

@@ -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;
}

View File

@@ -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 <l4/config.h>
#include <l4/macros.h>
#include <l4/types.h>

View File

@@ -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);