void init_early_pagination (void) { unsigned i; u32 *pd0; u32 *pt0; u32 page_it; pd0 = (u32*)PDBOOT_ADDR; for (i = 0; i < PD_SIZE; i++) pd0[i] = P_NULL; pd0[0] = PTBOOT_ADDR | P_PRESENT | P_WRITABLE; pt0 = (u32*)PTBOOT_ADDR; page_it = 0; for (i = 0; i < PT_SIZE; i++) { pt0[i] = page_it | P_PRESENT | P_WRITABLE; page_it += PAGE_SIZE; } SET_PAGE_DIR(PDBOOT_ADDR); set_cr0(get_cr0() | CR0_PG | CR0_WP); }
int new_page_tables(struct task_struct * tsk) { pgd_t * page_dir, * new_pg; if (!(new_pg = pgd_alloc())) return -ENOMEM; page_dir = pgd_offset(&init_mm, 0); flush_cache_mm(tsk->mm); memcpy(new_pg + USER_PTRS_PER_PGD, page_dir + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof (pgd_t)); flush_tlb_mm(tsk->mm); SET_PAGE_DIR(tsk, new_pg); tsk->mm->pgd = new_pg; return 0; }
static inline void __exit_mm(struct task_struct * tsk) { struct mm_struct * mm = tsk->mm; /* Set us up to use the kernel mm state */ if (mm != &init_mm) { flush_cache_mm(mm); flush_tlb_mm(mm); destroy_context(mm); tsk->mm = &init_mm; tsk->swappable = 0; SET_PAGE_DIR(tsk, swapper_pg_dir); mm_release(); mmput(mm); } }
static inline void __exit_mm(struct task_struct * tsk) { struct mm_struct * mm = tsk->mm; /* Set us up to use the kernel mm state */ if (mm != &init_mm) { flush_cache_mm(mm); flush_tlb_mm(mm); tsk->mm = &init_mm; tsk->swappable = 0; SET_PAGE_DIR(tsk, swapper_pg_dir); /* free the old state - not used any more */ if (!--mm->count) { exit_mmap(mm); free_page_tables(mm); kfree(mm); } } }