mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 10:53:16 +01:00
Fixed error escalation in thread_create() and its function calls.
This commit is contained in:
@@ -265,23 +265,36 @@ int thread_setup_new_ids(struct task_ids *ids, unsigned int flags,
|
||||
*/
|
||||
int thread_create(struct task_ids *ids, unsigned int flags)
|
||||
{
|
||||
struct ktcb *task = 0, *new = (struct ktcb *)zalloc_page();
|
||||
struct ktcb *task = 0;
|
||||
struct ktcb *new = (struct ktcb *)zalloc_page();
|
||||
unsigned int create_flags = flags & THREAD_CREATE_MASK;
|
||||
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Determine space allocation */
|
||||
if (create_flags == THREAD_NEW_SPACE) {
|
||||
/* Allocate new pgd and copy all kernel areas */
|
||||
new->pgd = alloc_pgd();
|
||||
if (!(new->pgd = alloc_pgd())) {
|
||||
free_page(new);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
copy_pgd_kern_all(new->pgd);
|
||||
} else {
|
||||
/* Existing space will be used, find it from all tasks */
|
||||
list_for_each_entry(task, &global_task_list, task_list) {
|
||||
/* Space ids match, can use existing space */
|
||||
if (task->spid == ids->spid) {
|
||||
if (flags == THREAD_SAME_SPACE)
|
||||
if (flags == THREAD_SAME_SPACE) {
|
||||
new->pgd = task->pgd;
|
||||
else
|
||||
} else {
|
||||
new->pgd = copy_page_tables(task->pgd);
|
||||
if (IS_ERR(new->pgd)) {
|
||||
free_page(new);
|
||||
return (int)new->pgd;
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <l4/lib/string.h>
|
||||
#include <l4/generic/scheduler.h>
|
||||
#include <l4/generic/space.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include INC_SUBARCH(mm.h)
|
||||
#include INC_SUBARCH(mmu_ops.h)
|
||||
#include INC_GLUE(memory.h)
|
||||
@@ -428,7 +429,9 @@ pgd_table_t *copy_page_tables(pgd_table_t *from)
|
||||
pgd_table_t *pgd;
|
||||
|
||||
/* Allocate and copy pgd. This includes all kernel entries */
|
||||
pgd = alloc_pgd();
|
||||
if (!(pgd = alloc_pgd()))
|
||||
return PTR_ERR(-ENOMEM);
|
||||
|
||||
memcpy(pgd, from, sizeof(pgd_table_t));
|
||||
|
||||
/* Allocate and copy all pmds that will be exclusive to new task. */
|
||||
@@ -437,7 +440,8 @@ pgd_table_t *copy_page_tables(pgd_table_t *from)
|
||||
if (!is_kern_pgdi(i) &&
|
||||
((pgd->entry[i] & PGD_TYPE_MASK) == PGD_TYPE_COARSE)) {
|
||||
/* Allocate new pmd */
|
||||
pmd = alloc_pmd();
|
||||
if (!(pmd = alloc_pmd()))
|
||||
goto out_error;
|
||||
|
||||
/* Find original pmd */
|
||||
orig = (pmd_table_t *)
|
||||
@@ -454,6 +458,20 @@ pgd_table_t *copy_page_tables(pgd_table_t *from)
|
||||
}
|
||||
|
||||
return pgd;
|
||||
|
||||
out_error:
|
||||
/* Find all allocated pmds and free them */
|
||||
for (int i = 0; i < PGD_ENTRY_TOTAL; i++) {
|
||||
if ((pgd->entry[i] & PGD_TYPE_MASK) == PGD_TYPE_COARSE) {
|
||||
/* Clear coarse indicator from address */
|
||||
pgd->entry[i] &= ~PGD_TYPE_COARSE;
|
||||
/* Free pmd by converting to its virtual value first */
|
||||
free_pmd((void *)phys_to_virt(pgd->entry[i]));
|
||||
}
|
||||
}
|
||||
/* Free the pgd */
|
||||
free_pgd(pgd);
|
||||
return PTR_ERR(-ENOMEM);
|
||||
}
|
||||
|
||||
extern pmd_table_t *pmd_array;
|
||||
|
||||
@@ -181,7 +181,11 @@ int free_pgd(void *v)
|
||||
|
||||
void *zalloc_page(void)
|
||||
{
|
||||
void *p = alloc_page();
|
||||
void *p;
|
||||
|
||||
if (!(p = alloc_page()))
|
||||
return 0;
|
||||
|
||||
memset(p, 0, PAGE_SIZE);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ void main(void)
|
||||
|
||||
dirtest();
|
||||
|
||||
// exectest();
|
||||
exectest();
|
||||
|
||||
/* Check mmap/munmap */
|
||||
mmaptest();
|
||||
|
||||
Reference in New Issue
Block a user