示例#1
0
static pte_t * __init kernel_page_table(void)
{
	pte_t *ptablep;

	ptablep = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);

	clear_page(ptablep);
	__flush_page_to_ram(ptablep);
	flush_tlb_kernel_page(ptablep);
	nocache_page(ptablep);

	return ptablep;
}
示例#2
0
static pmd_t * __init kernel_ptr_table(void)
{
	if (!last_pgtable) {
		unsigned long pmd, last;
		int i;

		/* Find the last ptr table that was used in head.S and
		 * reuse the remaining space in that page for further
		 * ptr tables.
		 */
		last = (unsigned long)kernel_pg_dir;
		for (i = 0; i < PTRS_PER_PGD; i++) {
			if (!pgd_present(kernel_pg_dir[i]))
				continue;
			pmd = __pgd_page(kernel_pg_dir[i]);
			if (pmd > last)
				last = pmd;
		}

		last_pgtable = (pmd_t *)last;
#ifdef DEBUG
		printk("kernel_ptr_init: %p\n", last_pgtable);
#endif
	}

	last_pgtable += PTRS_PER_PMD;
	if (((unsigned long)last_pgtable & ~PAGE_MASK) == 0) {
		last_pgtable = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);

		clear_page(last_pgtable);
		__flush_page_to_ram(last_pgtable);
		flush_tlb_kernel_page(last_pgtable);
		nocache_page(last_pgtable);
	}

	return last_pgtable;
}
pmd_t *get_pointer_table (void)
{
	pmd_t *pmdp = NULL;
	unsigned long flags;
	struct ptable_desc *dp = ptable_list.next;
	int i;

	/*
	 * For a pointer table for a user process address space, a
	 * table is taken from a page allocated for the purpose.  Each
	 * page can hold 8 pointer tables.  The page is remapped in
	 * virtual address space to be noncacheable.
	 */
	if (PD_NONEFREE (dp)) {

		if (!(dp = kmalloc (sizeof(struct ptable_desc),GFP_KERNEL))) {
			return 0;
		}

		if (!(dp->page = __get_free_page (GFP_KERNEL))) {
			kfree (dp);
			return 0;
		}

		nocache_page (dp->page);

		dp->alloced = 0;
		/* put at head of list */
		save_flags(flags);
		cli();
		dp->next = ptable_list.next;
		dp->prev = ptable_list.next->prev;
		ptable_list.next->prev = dp;
		ptable_list.next = dp;
		restore_flags(flags);
	}

	for (i = 0; i < 8; i++)
		if (PD_TABLEFREE (dp, i)) {
			PD_MARKUSED (dp, i);
			pmdp = (pmd_t *)(dp->page + PTABLE_SIZE*i);
			break;
		}

	if (PD_NONEFREE (dp)) {
		/* move to end of list */
		save_flags(flags);
		cli();
		dp->prev->next = dp->next;
		dp->next->prev = dp->prev;

		dp->next = ptable_list.next->prev;
		dp->prev = ptable_list.prev;
		ptable_list.prev->next = dp;
		ptable_list.prev = dp;
		restore_flags(flags);
	}

	memset (pmdp, 0, PTABLE_SIZE);

	return pmdp;
}