diff options
author | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-07-06 00:09:40 +0000 |
---|---|---|
committer | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-07-06 00:09:40 +0000 |
commit | 949c604d3d84d59df95445a4231aaaa00b06800a (patch) | |
tree | 188c6269d0136f3998358cf01919e37596402888 | |
parent | bae03c055d11da8172ac22e1f7f6104132138306 (diff) |
Vmalloc/vfree fixes: use swapper_pg_dir[0] for the vmalloc range
translations, use a kernel pmd table that points into the kptbl[].
This is to make the generic part of vmalloc()/vfree() find pgd/pmd/pte
that it expects.
-rw-r--r-- | arch/mips64/kernel/head.S | 1 | ||||
-rw-r--r-- | arch/mips64/kernel/setup.c | 10 | ||||
-rw-r--r-- | include/asm-mips64/pgalloc.h | 4 | ||||
-rw-r--r-- | include/asm-mips64/pgtable.h | 7 |
4 files changed, 18 insertions, 4 deletions
diff --git a/arch/mips64/kernel/head.S b/arch/mips64/kernel/head.S index 74d3c34ef..f87366d21 100644 --- a/arch/mips64/kernel/head.S +++ b/arch/mips64/kernel/head.S @@ -173,4 +173,5 @@ NESTED(bootstrap, 16, sp) page empty_bad_pmd_table, 1 page kptbl, KPTBL_PAGE_ORDER .globl ekptbl + page kpmdtbl, 0 ekptbl: diff --git a/arch/mips64/kernel/setup.c b/arch/mips64/kernel/setup.c index 93f7f8a78..691e88d20 100644 --- a/arch/mips64/kernel/setup.c +++ b/arch/mips64/kernel/setup.c @@ -154,8 +154,10 @@ void __init setup_arch(char **cmdline_p) unsigned long tmp; unsigned long *initrd_header; #endif + int i; + pmd_t *pmd = kpmdtbl; + pte_t *pte = kptbl; - memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER); cpu_probe(); load_mmu(); @@ -193,4 +195,10 @@ void __init setup_arch(char **cmdline_p) #endif paging_init(); + + memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER); + memset((void *)kpmdtbl, 0, PAGE_SIZE); + pgd_set(swapper_pg_dir, kpmdtbl); + for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE) + pmd_val(*pmd) = (unsigned long)pte; } diff --git a/include/asm-mips64/pgalloc.h b/include/asm-mips64/pgalloc.h index 8d091227a..d9a766097 100644 --- a/include/asm-mips64/pgalloc.h +++ b/include/asm-mips64/pgalloc.h @@ -192,9 +192,9 @@ extern inline pmd_t *pmd_alloc(pgd_t * pgd, unsigned long address) } extern pte_t kptbl[(PAGE_SIZE<<KPTBL_PAGE_ORDER)/sizeof(pte_t)]; +extern pmd_t kpmdtbl[PTRS_PER_PMD]; -#define MAGIC_PMD_VAL ((pmd_t *)0x1234) -#define pmd_alloc_kernel(d,a) MAGIC_PMD_VAL +#define pmd_alloc_kernel(d,a) (pmd_t *)kpmdtbl extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) { diff --git a/include/asm-mips64/pgtable.h b/include/asm-mips64/pgtable.h index e3f688c8a..6e6212a06 100644 --- a/include/asm-mips64/pgtable.h +++ b/include/asm-mips64/pgtable.h @@ -64,6 +64,11 @@ do { \ * that the failure is recognized later on. Linux does not seem to * handle these failures very well though. The empty_bad_page_table has * invalid pte entries in it, to force page faults. + * Vmalloc handling: vmalloc uses swapper_pg_dir[0] (returned by + * pgd_offset_k), which is initalized to point to kpmdtbl. kpmdtbl is + * the only single page pmd in the system. kpmdtbl entries point into + * kptbl[] array. We reserve 1<<KPTBL_PAGE_ORDER pages to hold the + * vmalloc range translations, which the fault handler looks at. */ #endif /* !defined (_LANGUAGE_ASSEMBLY) */ @@ -442,7 +447,7 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define page_pte(page) page_pte_prot(page, __pgprot(0)) /* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k(address) pgd_offset(&init_mm, address) +#define pgd_offset_k(address) pgd_offset(&init_mm, 0) #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) |