mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user