diff --git a/include/l4/arch/arm/v5/mm.h b/include/l4/arch/arm/v5/mm.h index 6943ff9..a244ea4 100644 --- a/include/l4/arch/arm/v5/mm.h +++ b/include/l4/arch/arm/v5/mm.h @@ -123,6 +123,7 @@ typedef struct pmd_table { #define DABT_EXT_NON_LFETCH_SECT 0x8 #define DABT_EXT_NON_LFETCH_PAGE 0xA +#define TASK_PGD(x) (x)->space->pgd /* Kernel's data about the fault */ typedef struct fault_kdata { diff --git a/include/l4/generic/space.h b/include/l4/generic/space.h index cca33bb..9f72a0b 100644 --- a/include/l4/generic/space.h +++ b/include/l4/generic/space.h @@ -19,6 +19,17 @@ #define MAP_IO_DEFAULT_FLAGS MAP_SVC_IO_FLAGS #if defined (__KERNEL__) + +#include +#include INC_SUBARCH(mm.h) + +/* A simple page table with a reference count */ +struct address_space { + struct list_head list; + pgd_table_t *pgd; + int ktcb_refs; +}; + int check_access(unsigned long vaddr, unsigned long size, unsigned int flags); #endif diff --git a/include/l4/generic/tcb.h b/include/l4/generic/tcb.h index 51992a9..b6fa3ee 100644 --- a/include/l4/generic/tcb.h +++ b/include/l4/generic/tcb.h @@ -10,6 +10,7 @@ #include #include #include +#include #include INC_GLUE(memory.h) #include INC_GLUE(syscall.h) #include INC_GLUE(message.h) @@ -39,12 +40,6 @@ struct task_ids { l4id_t tgid; }; -/* A simple page table with a reference count */ -struct address_space { - struct pgd_table_t *pgd; - int ktcb_refs; -}; - struct ktcb { /* User context */ task_context_t context; diff --git a/src/api/space.c b/src/api/space.c index ca074b4..27f2456 100644 --- a/src/api/space.c +++ b/src/api/space.c @@ -36,7 +36,7 @@ int sys_map(syscall_context_t *regs) return -EINVAL; found: - add_mapping_pgd(phys, virt, npages << PAGE_BITS, flags, target->pgd); + add_mapping_pgd(phys, virt, npages << PAGE_BITS, flags, TASK_PGD(target)); return 0; } @@ -60,7 +60,7 @@ int sys_unmap(syscall_context_t *regs) return -ESRCH; for (int i = 0; i < npages; i++) { - ret = remove_mapping_pgd(virtual + i * PAGE_SIZE, target->pgd); + ret = remove_mapping_pgd(virtual + i * PAGE_SIZE, TASK_PGD(target)); if (ret) retval = ret; } diff --git a/src/api/thread.c b/src/api/thread.c index 283f62e..2bc7120 100644 --- a/src/api/thread.c +++ b/src/api/thread.c @@ -55,7 +55,7 @@ int arch_clear_thread(struct ktcb *task) task->context.spsr = ARM_MODE_USR; /* Clear the page tables */ - remove_mapping_pgd_all_user(task->pgd); + remove_mapping_pgd_all_user(TASK_PGD(task)); return 0; } @@ -256,12 +256,6 @@ int thread_setup_new_ids(struct task_ids *ids, unsigned int flags, return 0; } -#define KTCB_CREATE_PAGE_TABLES (1 << 0) -/* Allocates a ktcb and page tables depending on flags */ -struct ktcb *ktcb_create(unsigned int flags) -{ - -} /* * Creates a thread, with a new thread id, and depending on the flags, * either creates a new space, uses the same space as another thread, @@ -282,23 +276,23 @@ int thread_create(struct task_ids *ids, unsigned int flags) /* Determine space allocation */ if (create_flags == THREAD_NEW_SPACE) { /* Allocate new pgd and copy all kernel areas */ - if (!(new->pgd = alloc_pgd())) { + if (!(TASK_PGD(new) = alloc_pgd())) { free_page(new); return -ENOMEM; } - copy_pgd_kern_all(new->pgd); + copy_pgd_kern_all(TASK_PGD(new)); } 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) { - new->pgd = task->pgd; + TASK_PGD(new) = TASK_PGD(task); } else { - new->pgd = copy_page_tables(task->pgd); - if (IS_ERR(new->pgd)) { - err = (int)new->pgd; + TASK_PGD(new) = copy_page_tables(TASK_PGD(task)); + if (IS_ERR(TASK_PGD(new))) { + err = (int)TASK_PGD(new); free_page(new); return err; } diff --git a/src/arch/arm/v5/mm.c b/src/arch/arm/v5/mm.c index ac9122f..0bb5b48 100644 --- a/src/arch/arm/v5/mm.c +++ b/src/arch/arm/v5/mm.c @@ -29,7 +29,7 @@ */ void remove_section_mapping(unsigned long vaddr) { - pgd_table_t *pgd = current->pgd; + pgd_table_t *pgd = TASK_PGD(current); pgd_t pgd_i = PGD_INDEX(vaddr); if (!((pgd->entry[pgd_i] & PGD_TYPE_MASK) & PGD_TYPE_SECTION)) @@ -174,7 +174,7 @@ pte_t virt_to_pte_from_pgd(unsigned long virtual, pgd_table_t *pgd) /* Convert a virtual address to a pte if it exists in the page tables. */ pte_t virt_to_pte(unsigned long virtual) { - return virt_to_pte_from_pgd(virtual, current->pgd); + return virt_to_pte_from_pgd(virtual, TASK_PGD(current)); } void attach_pmd(pgd_table_t *pgd, pmd_table_t *pmd, unsigned int vaddr) @@ -238,7 +238,7 @@ void add_mapping_pgd(unsigned int paddr, unsigned int vaddr, void add_mapping(unsigned int paddr, unsigned int vaddr, unsigned int size, unsigned int flags) { - add_mapping_pgd(paddr, vaddr, size, flags, current->pgd); + add_mapping_pgd(paddr, vaddr, size, flags, TASK_PGD(current)); } /* @@ -271,7 +271,7 @@ int check_mapping_pgd(unsigned long vaddr, unsigned long size, int check_mapping(unsigned long vaddr, unsigned long size, unsigned int flags) { - return check_mapping_pgd(vaddr, size, flags, current->pgd); + return check_mapping_pgd(vaddr, size, flags, TASK_PGD(current)); } /* FIXME: Empty PMDs should be returned here !!! */ @@ -416,7 +416,7 @@ int remove_mapping_pgd(unsigned long vaddr, pgd_table_t *pgd) int remove_mapping(unsigned long vaddr) { - return remove_mapping_pgd(vaddr, current->pgd); + return remove_mapping_pgd(vaddr, TASK_PGD(current)); } /* @@ -503,7 +503,7 @@ void relocate_page_tables(void) memcpy((void *)pt_new, _start_kspace, pt_area_size); /* Update the only reference to current pgd table */ - current->pgd = (pgd_table_t *)pt_new; + TASK_PGD(current) = (pgd_table_t *)pt_new; /* * Since pmd's are also moved, update the pmd references in pgd by @@ -512,9 +512,9 @@ void relocate_page_tables(void) */ for (int i = 0; i < PGD_ENTRY_TOTAL; i++) /* If there's a coarse 2nd level entry */ - if ((current->pgd->entry[i] & PGD_TYPE_MASK) + if ((TASK_PGD(current)->entry[i] & PGD_TYPE_MASK) == PGD_TYPE_COARSE) - current->pgd->entry[i] -= reloc_offset; + TASK_PGD(current)->entry[i] -= reloc_offset; /* Update the pmd array pointer. */ pmd_array = (pmd_table_t *)((unsigned long)_start_pmd - reloc_offset); @@ -523,7 +523,7 @@ void relocate_page_tables(void) arm_clean_invalidate_cache(); arm_drain_writebuffer(); arm_invalidate_tlb(); - arm_set_ttb(virt_to_phys(current->pgd)); + arm_set_ttb(virt_to_phys(TASK_PGD(current))); arm_invalidate_tlb(); /* Unmap the old page table area */ @@ -535,7 +535,7 @@ void relocate_page_tables(void) __pt_end = pt_new + pt_area_size; printk("Initial page table area relocated from phys 0x%x to 0x%x\n", - virt_to_phys(&kspace), virt_to_phys(current->pgd)); + virt_to_phys(&kspace), virt_to_phys(TASK_PGD(current))); } /* @@ -552,7 +552,7 @@ void remap_as_pages(void *vstart, void *vend) unsigned long paddr = pstart; pgd_t pgd_i = PGD_INDEX(vstart); pmd_t pmd_i = PMD_INDEX(vstart); - pgd_table_t *pgd = (pgd_table_t *)current->pgd; + pgd_table_t *pgd = (pgd_table_t *)TASK_PGD(current); pmd_table_t *pmd = alloc_pmd(); u32 pmd_phys = virt_to_phys(pmd); int numpages = __pfn(page_align_up(pend) - pstart); diff --git a/src/generic/physmem.c b/src/generic/physmem.c index 44790f9..22cf65d 100644 --- a/src/generic/physmem.c +++ b/src/generic/physmem.c @@ -76,7 +76,7 @@ void physmem_init() /* Map initial pgd area as used */ start = (unsigned long)__pt_start; end = (unsigned long)__pt_end; - set_page_map(virt_to_phys(current->pgd), __pfn(end - start), 1); + set_page_map(virt_to_phys(TASK_PGD(current)), __pfn(end - start), 1); physmem.start = PHYS_MEM_START; physmem.end = PHYS_MEM_END; diff --git a/src/generic/scheduler.c b/src/generic/scheduler.c index 64d1db5..332bd47 100644 --- a/src/generic/scheduler.c +++ b/src/generic/scheduler.c @@ -256,7 +256,7 @@ static inline void context_switch(struct ktcb *next) // printk("(%d) to (%d)\n", cur->tid, next->tid); /* Flush caches and everything */ - arch_hardware_flush(next->pgd); + arch_hardware_flush(TASK_PGD(next)); /* Update utcb region for next task */ task_update_utcb(cur, next); diff --git a/src/glue/arm/init.c b/src/glue/arm/init.c index 64e53a0..0c2e849 100644 --- a/src/glue/arm/init.c +++ b/src/glue/arm/init.c @@ -33,6 +33,8 @@ void init_locks(void) { } +struct address_space pager_space; + /* Maps the early memory regions needed to bootstrap the system */ void init_kernel_mappings(void) { @@ -60,7 +62,8 @@ void init_kernel_mappings(void) * Setup a dummy current ktcb over the bootstack, so that generic * mapping functions can use this as the pgd source. */ - current->pgd = &kspace; + current->space = &pager_space; + TASK_PGD(current) = &kspace; } void print_sections(void) @@ -245,7 +248,7 @@ void switch_to_user(struct ktcb *task) { arm_clean_invalidate_cache(); arm_invalidate_tlb(); - arm_set_ttb(virt_to_phys(task->pgd)); + arm_set_ttb(virt_to_phys(TASK_PGD(task))); arm_invalidate_tlb(); jump(task); } @@ -297,12 +300,7 @@ void init_pager(char *name, struct task_ids *ids) /* Pager gets first UTCB area available by default */ task->utcb_address = UTCB_AREA_START; - if (!task->pgd) { - BUG(); /* Inittask won't come here */ - task->pgd = alloc_pgd(); - /* Tasks with no pgd copy from the inittask's pgd. */ - memcpy(task->pgd, current->pgd, sizeof(pgd_table_t)); - } + BUG_ON(!TASK_PGD(task)); /* * This task's userspace mapping. This should allocate a new pmd, if not @@ -310,7 +308,7 @@ void init_pager(char *name, struct task_ids *ids) */ add_mapping_pgd(taskimg->phys_start, INITTASK_AREA_START, task_pages * PAGE_SIZE, MAP_USR_DEFAULT_FLAGS, - task->pgd); + TASK_PGD(task)); printk("Mapping %d pages from 0x%x to 0x%x for %s\n", task_pages, taskimg->phys_start, INITTASK_AREA_START, name); @@ -359,9 +357,11 @@ void start_kernel(void) /* Initialise section mappings for the kernel area */ init_kernel_mappings(); + printascii("\nStarting virtual memory...\n"); /* Enable virtual memory and jump to virtual addresses */ start_vm(); + printascii("\nStarted virtual memory...\n"); /* PMD tables initialised */ init_pmd_tables(); diff --git a/src/glue/arm/memory.c b/src/glue/arm/memory.c index 4fbcdd3..c0b506f 100644 --- a/src/glue/arm/memory.c +++ b/src/glue/arm/memory.c @@ -117,7 +117,7 @@ void copy_pgd_kern_by_vrange(pgd_table_t *to, pgd_table_t *from, /* Copies all standard bits that a user process should have in its pgd */ void copy_pgd_kern_all(pgd_table_t *to) { - pgd_table_t *from = current->pgd; + pgd_table_t *from = TASK_PGD(current); copy_pgd_kern_by_vrange(to, from, KERNEL_AREA_START, KERNEL_AREA_END); copy_pgd_kern_by_vrange(to, from, IO_AREA_START, IO_AREA_END);