Full utcb copying partially works now.

This commit is contained in:
Bahadir Balban
2009-05-19 11:26:45 +03:00
parent b950ec323d
commit 3bbbcdfefa
5 changed files with 49 additions and 5 deletions

View File

@@ -10,6 +10,7 @@
#include <l4/generic/space.h>
#include <l4/lib/idpool.h>
#include <l4/api/kip.h>
#include <l4/api/errno.h>
#include INC_ARCH(exception.h)
#include INC_SUBARCH(mm.h)
#include INC_GLUE(memory.h)
@@ -164,3 +165,41 @@ void task_update_utcb(struct ktcb *cur, struct ktcb *next)
kip.utcb = next->utcb_address;
}
/*
* Checks whether a task's utcb is currently accessible by the kernel
* It returns an error if its not paged in yet, and also maps a non-current
* task's utcb to current task with kernel-access privileges.
*/
int tcb_check_and_lazy_map_utcb(struct ktcb *task)
{
unsigned int phys;
int ret;
BUG_ON(!task->utcb_address);
if ((ret = check_access(task->utcb_address, UTCB_SIZE,
MAP_SVC_RW_FLAGS, 0)) < 0) {
/* Current task simply hasn't mapped its utcb */
if (task == current) {
return -EFAULT;
} else {
if (!(phys = virt_to_phys_by_pgd(task->utcb_address,
TASK_PGD(task)))) {
/* Task hasn't mapped its utcb */
return -EFAULT;
} else {
/*
* Task has utcb but it hasn't yet been mapped
* to current task with kernel access. Do it.
*/
add_mapping_pgd(phys, task->utcb_address,
page_align_up(UTCB_SIZE),
MAP_SVC_RW_FLAGS,
TASK_PGD(current));
}
}
}
return 0;
}