Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12f49643 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds
Browse files

[PATCH] uml: fixrange_init 3-level page table support



From: Al Viro - add three-level page table support to fixrange_init.

Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Cc: <viro@parcelfarce.linux.theplanet.co.uk>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 7b9014c1
Loading
Loading
Loading
Loading
+31 −9
Original line number Diff line number Diff line
@@ -100,12 +100,37 @@ void mem_init(void)
#endif
}

/*
 * Create a page table and place a pointer to it in a middle page
 * directory entry.
 */
static void __init one_page_table_init(pmd_t *pmd)
{
	if (pmd_none(*pmd)) {
		pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
		set_pmd(pmd, __pmd(_KERNPG_TABLE +
					   (unsigned long) __pa(pte)));
		if (pte != pte_offset_kernel(pmd, 0))
			BUG();
	}
}

static void __init one_md_table_init(pud_t *pud)
{
#ifdef CONFIG_3_LEVEL_PGTABLES
	pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
	set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table)));
	if (pmd_table != pmd_offset(pud, 0))
		BUG();
#endif
}

static void __init fixrange_init(unsigned long start, unsigned long end, 
				 pgd_t *pgd_base)
{
	pgd_t *pgd;
	pud_t *pud;
	pmd_t *pmd;
	pte_t *pte;
	int i, j;
	unsigned long vaddr;

@@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
	pgd = pgd_base + i;

	for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
		pmd = (pmd_t *)pgd;
		pud = pud_offset(pgd, vaddr);
		if (pud_none(*pud))
			one_md_table_init(pud);
		pmd = pmd_offset(pud, vaddr);
		for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
			if (pmd_none(*pmd)) {
				pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
				set_pmd(pmd, __pmd(_KERNPG_TABLE + 
						   (unsigned long) __pa(pte)));
				if (pte != pte_offset_kernel(pmd, 0))
					BUG();
			}
			one_page_table_init(pmd);
			vaddr += PMD_SIZE;
		}
		j = 0;