mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Task initally exec'ing with success. Some errors need to be investigated.
- Directory creation, file read/write is OK. - Cannot reuse old task's fds. They are not recycled for some reason. - Problems with fork/clone/exit. They fail for a reason.
This commit is contained in:
@@ -59,16 +59,6 @@ int sys_unmap(syscall_context_t *regs)
|
||||
else if (!(target = find_task(tid)))
|
||||
return -ESRCH;
|
||||
|
||||
/*
|
||||
* These special values mean unmap all the mappings
|
||||
* from task space except the kernel mappings
|
||||
*/
|
||||
if (virtual == UNMAP_ALL_SPACE &&
|
||||
npages == UNMAP_ALL_SPACE) {
|
||||
remove_mapping_pgd_all_user(target->pgd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < npages; i++) {
|
||||
ret = remove_mapping_pgd(virtual + i * PAGE_SIZE, target->pgd);
|
||||
if (ret)
|
||||
|
||||
@@ -87,7 +87,7 @@ void do_exchange_registers(struct ktcb *task, struct exregs_data *exregs)
|
||||
* the register context of a thread. The thread's registers can be
|
||||
* set only when the thread is in user mode. A newly created thread
|
||||
* that is the copy of another thread (forked or cloned) will also
|
||||
* be given its user mode context on the first chance to execute so
|
||||
* be given its user mode context on the first chance to execute so
|
||||
* such threads can also be modified by this call before execution.
|
||||
*
|
||||
* A thread executing in the kernel cannot be modified since this
|
||||
@@ -119,6 +119,9 @@ int sys_exchange_registers(syscall_context_t *regs)
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if 0
|
||||
A suspended thread implies it cannot do any harm
|
||||
even if it is in kernel mode.
|
||||
/*
|
||||
* The thread must be in user mode for its context
|
||||
* to be modified.
|
||||
@@ -127,6 +130,7 @@ int sys_exchange_registers(syscall_context_t *regs)
|
||||
err = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Copy registers */
|
||||
do_exchange_registers(task, exregs);
|
||||
|
||||
@@ -49,6 +49,47 @@ int thread_suspend(struct task_ids *ids)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int arch_clear_thread(struct ktcb *task)
|
||||
{
|
||||
memset(&task->context, 0, sizeof(task->context));
|
||||
task->context.spsr = ARM_MODE_USR;
|
||||
|
||||
/* Clear the page tables */
|
||||
remove_mapping_pgd_all_user(task->pgd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int thread_recycle(struct task_ids *ids)
|
||||
{
|
||||
struct ktcb *task;
|
||||
int ret;
|
||||
|
||||
if (!(task = find_task(ids->tid)))
|
||||
return -ESRCH;
|
||||
|
||||
if ((ret = thread_suspend(ids)) < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If there are any sleepers on any of the task's
|
||||
* waitqueues, we need to wake those tasks up.
|
||||
*/
|
||||
wake_up_all(&task->wqh_send, 0);
|
||||
wake_up_all(&task->wqh_recv, 0);
|
||||
|
||||
/*
|
||||
* The thread cannot have a pager waiting for it
|
||||
* since we ought to be the pager.
|
||||
*/
|
||||
BUG_ON(task->wqh_pager.sleepers > 0);
|
||||
|
||||
/* Clear the task's tcb */
|
||||
arch_clear_thread(task);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int thread_destroy(struct task_ids *ids)
|
||||
{
|
||||
struct ktcb *task;
|
||||
@@ -292,6 +333,10 @@ int sys_thread_control(syscall_context_t *regs)
|
||||
break;
|
||||
case THREAD_DESTROY:
|
||||
ret = thread_destroy(ids);
|
||||
break;
|
||||
case THREAD_RECYCLE:
|
||||
ret = thread_recycle(ids);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user