diff --git a/conts/libl4/include/l4lib/arch-arm/syscalls.h b/conts/libl4/include/l4lib/arch-arm/syscalls.h index 584da7a..de08dec 100644 --- a/conts/libl4/include/l4lib/arch-arm/syscalls.h +++ b/conts/libl4/include/l4lib/arch-arm/syscalls.h @@ -19,7 +19,6 @@ struct task_ids { l4id_t tid; l4id_t spid; l4id_t tgid; - l4id_t cid; }; static inline void * diff --git a/conts/posix/mm0/include/task.h b/conts/posix/mm0/include/task.h index e5f8f30..b5b8308 100644 --- a/conts/posix/mm0/include/task.h +++ b/conts/posix/mm0/include/task.h @@ -96,9 +96,9 @@ struct tcb { char name[16]; /* Task ids */ - int tid; - int spid; - int tgid; + l4id_t tid; + l4id_t spid; + l4id_t tgid; /* Related task ids */ unsigned int pagerid; /* Task's pager */ diff --git a/conts/posix/mm0/main.c b/conts/posix/mm0/main.c index d5514f7..5d98c55 100644 --- a/conts/posix/mm0/main.c +++ b/conts/posix/mm0/main.c @@ -195,7 +195,7 @@ void handle_requests(void) void main(void) { - printf("\n%s: Started with thread id %d\n", __TASKNAME__, self_tid()); + printf("\n%s: Started with thread id %x\n", __TASKNAME__, self_tid()); init(); diff --git a/conts/posix/mm0/mm/task.c b/conts/posix/mm0/mm/task.c index ada721c..b28200f 100644 --- a/conts/posix/mm0/mm/task.c +++ b/conts/posix/mm0/mm/task.c @@ -446,7 +446,7 @@ int task_copy_args_to_user(char *user_stack, { char **argv_start, **envp_start; - BUG_ON((unsigned long)user_stack & 7); + BUG_ON(!is_aligned(user_stack, 8)); /* Copy argc */ *((int *)user_stack) = args->argc; @@ -508,12 +508,18 @@ int task_map_stack(struct vm_file *f, struct exec_file_desc *efd, struct tcb *task, struct args_struct *args, struct args_struct *env) { - /* First set up task's stack markers */ - unsigned long stack_used = align_up(args->size + env->size + 8, 8); + unsigned long stack_used; unsigned long arg_pages = __pfn(page_align_up(stack_used)); char *args_on_stack; void *mapped; + /* + * Stack contains: args, environment, argc integer, + * 2 Null integers as terminators. + * + * It needs to be 8-byte aligned also. + */ + stack_used = align_up(args->size + env->size + sizeof(int) * 3 + 8, 8); task->stack_end = __pfn_to_addr(cont_mem_regions.task->end); task->stack_start = __pfn_to_addr(cont_mem_regions.task->end) - DEFAULT_STACK_SIZE; task->args_end = task->stack_end; diff --git a/conts/posix/test0/main.c b/conts/posix/test0/main.c index fdd97b9..51048ff 100644 --- a/conts/posix/test0/main.c +++ b/conts/posix/test0/main.c @@ -31,7 +31,7 @@ l4id_t pagerid; int main(int argc, char *argv[]) { - printf("\n%s: Started with thread id %d\n", __TASKNAME__, getpid()); + printf("\n%s: Started with thread id %x\n", __TASKNAME__, getpid()); parent_of_all = getpid(); diff --git a/conts/posix/test0/src/test_exec/test_exec.c b/conts/posix/test0/src/test_exec/test_exec.c index 41695a1..845c512 100644 --- a/conts/posix/test0/src/test_exec/test_exec.c +++ b/conts/posix/test0/src/test_exec/test_exec.c @@ -51,7 +51,7 @@ int main(int argc, char *argv[]) /* Compare two pid strings. We use strings because we dont have atoi() */ if (!strcmp(pidbuf, parent_of_all)) { printf("EXECVE TEST -- PASSED --\n"); - printf("\nThread (%d): Continues to sync with the pager...\n\n", getpid()); + printf("\nThread (%x): Continues to sync with the pager...\n\n", getpid()); while (1) wait_pager(pagerid); } diff --git a/include/l4/generic/container.h b/include/l4/generic/container.h index f9ac26d..816483e 100644 --- a/include/l4/generic/container.h +++ b/include/l4/generic/container.h @@ -107,6 +107,7 @@ int container_init_pagers(struct kernel_resources *kres, pgd_table_t *current_pgd); int init_containers(struct kernel_resources *kres); +struct container *container_find(struct kernel_resources *kres, l4id_t cid); #endif /* __CONTAINER_H__ */ diff --git a/include/l4/generic/resource.h b/include/l4/generic/resource.h index 8beef1d..6856dc3 100644 --- a/include/l4/generic/resource.h +++ b/include/l4/generic/resource.h @@ -32,6 +32,7 @@ struct boot_resources { struct container_head { int ncont; struct link list; + struct spinlock lock; }; static inline void @@ -39,6 +40,7 @@ container_head_init(struct container_head *chead) { chead->ncont = 0; link_init(&chead->list); + spin_lock_init(&chead->lock); } /* Hash table for all existing tasks */ diff --git a/include/l4/generic/tcb.h b/include/l4/generic/tcb.h index ab707d0..787ba09 100644 --- a/include/l4/generic/tcb.h +++ b/include/l4/generic/tcb.h @@ -41,6 +41,12 @@ enum task_state { #define TASK_CID_MASK 0xFF000000 #define TASK_ID_MASK 0x00FFFFFF +#define TASK_CID_SHIFT 24 + +static inline l4id_t tid_to_cid(l4id_t tid) +{ + return (tid & TASK_CID_MASK) >> TASK_CID_SHIFT; +} static inline int task_id_special(l4id_t id) { @@ -53,7 +59,6 @@ struct task_ids { l4id_t tid; l4id_t spid; l4id_t tgid; - l4id_t cid; }; struct container; @@ -166,7 +171,7 @@ void tcb_add(struct ktcb *tcb); void tcb_remove(struct ktcb *tcb); void tcb_init(struct ktcb *tcb); -struct ktcb *tcb_alloc_init(void); +struct ktcb *tcb_alloc_init(l4id_t cid); void tcb_delete(struct ktcb *tcb); diff --git a/src/api/syscall.c b/src/api/syscall.c index 94fea02..1ff2769 100644 --- a/src/api/syscall.c +++ b/src/api/syscall.c @@ -48,7 +48,6 @@ int sys_getid(struct task_ids *ids) ids->tid = this->tid; ids->spid = this->space->spid; ids->tgid = this->tgid; - ids->cid = this->container->cid; return 0; } diff --git a/src/api/thread.c b/src/api/thread.c index 5034b4b..618a16d 100644 --- a/src/api/thread.c +++ b/src/api/thread.c @@ -346,7 +346,7 @@ int thread_create(struct task_ids *ids, unsigned int flags) } } - if (!(new = tcb_alloc_init())) + if (!(new = tcb_alloc_init(curcont->cid))) return -ENOMEM; /* Set up new thread space by using space id and flags */ diff --git a/src/generic/capability.c b/src/generic/capability.c index a8452f7..ff62991 100644 --- a/src/generic/capability.c +++ b/src/generic/capability.c @@ -451,10 +451,11 @@ struct capability *cap_match_thread(struct capability *cap, if (action_flags == THREAD_CREATE) { /* - * TODO: Add cid to task_ids arg. + * NOTE: Currently we only allow creation in + * current container. * - * Its a thread create and we have no knowledge of - * thread id, space id, or any other id. + * TODO: Add capability checking for space, + * as well. * * We _assume_ target is the largest group, * e.g. same container as current. We check @@ -462,7 +463,7 @@ struct capability *cap_match_thread(struct capability *cap, */ if (cap_rtype(cap) != CAP_RTYPE_CONTAINER) return 0; - if (cap->resid != current->container->cid) + if (cap->resid != curcont->cid) return 0; /* Resource type and id match, success */ return cap; diff --git a/src/generic/container.c b/src/generic/container.c index 3a447f8..8f248ad 100644 --- a/src/generic/container.c +++ b/src/generic/container.c @@ -47,8 +47,25 @@ struct container *container_create(void) void kres_insert_container(struct container *c, struct kernel_resources *kres) { + spin_lock(&kres->containers.lock); list_insert(&c->list, &kres->containers.list); kres->containers.ncont++; + spin_unlock(&kres->containers.lock); +} + +struct container *container_find(struct kernel_resources *kres, l4id_t cid) +{ + struct container *c; + + spin_lock(&kres->containers.lock); + list_foreach_struct(c, &kres->containers.list, list) { + if (c->cid == cid) { + spin_unlock(&kres->containers.lock); + return c; + } + } + spin_unlock(&kres->containers.lock); + return 0; } /* @@ -86,8 +103,11 @@ int init_pager(struct pager *pager, */ cap_list_move(¤t->cap_list, &pager->cap_list); + /* Setup dummy container pointer so that curcont works */ + current->container = cont; + /* New ktcb allocation is needed */ - task = tcb_alloc_init(); + task = tcb_alloc_init(cont->cid); /* If first, manually allocate/initalize space */ if (first) { @@ -117,11 +137,7 @@ int init_pager(struct pager *pager, task->tgid = task->tid; task->container = cont; - /* - * Setup dummy container pointer so that curcont works, - * and add the address space to container space list - */ - current->container = cont; + /* Add the address space to container space list */ address_space_add(task->space); /* Initialize uninitialized capability fields while on dummy */ diff --git a/src/generic/resource.c b/src/generic/resource.c index 4ec4318..705cf78 100644 --- a/src/generic/resource.c +++ b/src/generic/resource.c @@ -402,8 +402,6 @@ void init_kernel_resources(struct kernel_resources *kres) memcap_unmap(&kres->physmem_free, kernel_area->start, kernel_area->end); - /* Initialize zombie pager list */ - init_ktcb_list(&kres->zombie_list); /* TODO: * Add all virtual memory areas used by the kernel @@ -529,7 +527,8 @@ void setup_kernel_resources(struct boot_resources *bootres, * See how many containers we have. Assign next * unused container id for kernel resources */ - kres->cid = id_get(&kres->container_ids, bootres->nconts + 1); + //kres->cid = id_get(&kres->container_ids, bootres->nconts + 1); + kres->cid = id_get(&kres->container_ids, 0); /* First initialize the list of non-memory capabilities */ cap = boot_capability_create(); diff --git a/src/generic/tcb.c b/src/generic/tcb.c index 47dcab4..dce4b47 100644 --- a/src/generic/tcb.c +++ b/src/generic/tcb.c @@ -43,7 +43,7 @@ void tcb_init(struct ktcb *new) waitqueue_head_init(&new->wqh_pager); } -struct ktcb *tcb_alloc_init(void) +struct ktcb *tcb_alloc_init(l4id_t cid) { struct ktcb *tcb; struct task_ids ids; @@ -52,6 +52,7 @@ struct ktcb *tcb_alloc_init(void) return 0; ids.tid = id_new(&kernel_resources.ktcb_ids); + ids.tid |= TASK_CID_MASK & (cid << TASK_CID_SHIFT); ids.tgid = L4_NILTHREAD; ids.spid = L4_NILTHREAD; @@ -92,6 +93,9 @@ void tcb_delete(struct ktcb *tcb) mutex_unlock(&curcont->space_list.lock); } + /* Clear container id part */ + tcb->tid &= ~TASK_CID_MASK; + /* Deallocate tcb ids */ id_del(&kernel_resources.ktcb_ids, tcb->tid); @@ -114,22 +118,44 @@ struct ktcb *tcb_find_by_space(l4id_t spid) return 0; } -struct ktcb *tcb_find(l4id_t tid) +struct ktcb *container_find_tcb(struct container *c, l4id_t tid) { struct ktcb *task; + spin_lock(&c->ktcb_list.list_lock); + list_foreach_struct(task, &c->ktcb_list.list, task_list) { + if (task->tid == tid) { + spin_unlock(&c->ktcb_list.list_lock); + return task; + } + } + spin_unlock(&c->ktcb_list.list_lock); + return 0; +} + +/* + * Threads are the only resource where inter-container searches are + * allowed. This is because on other containers, only threads can be + * targeted for operations. E.g. ipc, sharing memory. Currently you + * can't reach a space, a mutex, or any other resouce on another + * container. + */ +struct ktcb *tcb_find(l4id_t tid) +{ + struct container *c; + if (current->tid == tid) return current; - spin_lock(&curcont->ktcb_list.list_lock); - list_foreach_struct(task, &curcont->ktcb_list.list, task_list) { - if (task->tid == tid) { - spin_unlock(&curcont->ktcb_list.list_lock); - return task; - } + if (tid_to_cid(tid) == curcont->cid) { + return container_find_tcb(curcont, tid); + } else { + if (!(c = container_find(&kernel_resources, + tid_to_cid(tid)))) + return 0; + else + return container_find_tcb(c, tid); } - spin_unlock(&curcont->ktcb_list.list_lock); - return 0; } void ktcb_list_add(struct ktcb *new, struct ktcb_list *ktcb_list)