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

[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
...@@ -100,12 +100,37 @@ void mem_init(void) ...@@ -100,12 +100,37 @@ void mem_init(void)
#endif #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, static void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base) pgd_t *pgd_base)
{ {
pgd_t *pgd; pgd_t *pgd;
pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte;
int i, j; int i, j;
unsigned long vaddr; unsigned long vaddr;
...@@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end, ...@@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
pgd = pgd_base + i; pgd = pgd_base + i;
for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, 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++) { for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
if (pmd_none(*pmd)) { one_page_table_init(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();
}
vaddr += PMD_SIZE; vaddr += PMD_SIZE;
} }
j = 0; j = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment