diff options
author | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-06-27 02:05:08 +0000 |
---|---|---|
committer | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-06-27 02:05:08 +0000 |
commit | 8a6a74d2e0311629141438e64319fad5d657f5ac (patch) | |
tree | 3225f9a86374a4c4922e8bc126772d9f10ed5251 /arch/mips64 | |
parent | fef84721fc04db3ce781aacf1c6e247acc7ba04b (diff) |
Explain pgd/pmd allocation failure strategies. Create a global bad-pmd-table,
distinct from invalid-pmd-table for use during pmd allocation failure (so as
to differentiate pgd_bad and pgd_none). The bad page table must have invalid
pte entries to catch any user references to the range of virtual addresses
it covers.
Diffstat (limited to 'arch/mips64')
-rw-r--r-- | arch/mips64/kernel/head.S | 1 | ||||
-rw-r--r-- | arch/mips64/mm/init.c | 62 | ||||
-rw-r--r-- | arch/mips64/sgi-ip27/ip27-memory.c | 4 |
3 files changed, 20 insertions, 47 deletions
diff --git a/arch/mips64/kernel/head.S b/arch/mips64/kernel/head.S index f13bd9290..946bd98b3 100644 --- a/arch/mips64/kernel/head.S +++ b/arch/mips64/kernel/head.S @@ -171,4 +171,3 @@ NESTED(bootstrap, 16, sp) page invalid_pmd_table, 1 page empty_bad_page_table, 0 page empty_bad_pmd_table, 1 - page empty_bad_page diff --git a/arch/mips64/mm/init.c b/arch/mips64/mm/init.c index c6b301e14..c518f96b4 100644 --- a/arch/mips64/mm/init.c +++ b/arch/mips64/mm/init.c @@ -56,7 +56,7 @@ void __bad_pte(pmd_t *pmd) void __bad_pmd(pgd_t *pgd) { printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd)); - pgd_set(pgd, (pmd_t *) BAD_PAGETABLE); + pgd_set(pgd, empty_bad_pmd_table); } void pgd_init(unsigned long page) @@ -93,7 +93,7 @@ pgd_t *get_pgd_slow(void) return ret; } -void pmd_init(unsigned long addr) +void pmd_init(unsigned long addr, unsigned long pagetable) { unsigned long *p, *end; @@ -101,14 +101,14 @@ void pmd_init(unsigned long addr) end = p + PTRS_PER_PMD; while (p < end) { - p[0] = (unsigned long) invalid_pte_table; - p[1] = (unsigned long) invalid_pte_table; - p[2] = (unsigned long) invalid_pte_table; - p[3] = (unsigned long) invalid_pte_table; - p[4] = (unsigned long) invalid_pte_table; - p[5] = (unsigned long) invalid_pte_table; - p[6] = (unsigned long) invalid_pte_table; - p[7] = (unsigned long) invalid_pte_table; + p[0] = (unsigned long)pagetable; + p[1] = (unsigned long)pagetable; + p[2] = (unsigned long)pagetable; + p[3] = (unsigned long)pagetable; + p[4] = (unsigned long)pagetable; + p[5] = (unsigned long)pagetable; + p[6] = (unsigned long)pagetable; + p[7] = (unsigned long)pagetable; p += 8; } } @@ -120,7 +120,7 @@ pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset) pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 1); if (pgd_none(*pgd)) { if (pmd) { - pmd_init((unsigned long)pmd); + pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table); pgd_set(pgd, pmd); return pmd + offset; } @@ -246,21 +246,6 @@ unsigned long setup_zero_pages(void) return 1UL << order; } -extern inline void pte_init(unsigned long page) -{ - unsigned long *p, *end, bp; - - bp = pte_val(BAD_PAGE); - p = (unsigned long *) page; - end = p + (2 * PTRS_PER_PTE); - - while (p < end) { - p[0] = p[1] = p[2] = p[3] = - p[4] = p[5] = p[6] = p[7] = bp; - p += 8; - } -} - /* * BAD_PAGE is the page that is used for page faults when linux * is out-of-memory. Older versions of linux just did a @@ -276,32 +261,17 @@ extern inline void pte_init(unsigned long page) */ pmd_t * __bad_pmd_table(void) { - extern pmd_t invalid_pmd_table[PTRS_PER_PMD]; - unsigned long page; - - page = (unsigned long) invalid_pmd_table; - pmd_init(page); - - return (pmd_t *) page; + return empty_bad_pmd_table; } pte_t * __bad_pagetable(void) { - unsigned long page; - - page = (unsigned long) empty_bad_page_table; - pte_init(page); - - return (pte_t *) page; + return empty_bad_page_table; } pte_t __bad_page(void) { - extern char empty_bad_page[PAGE_SIZE]; - unsigned long page = (unsigned long) empty_bad_page; - - clear_page((void *)page); - return pte_mkdirty(mk_pte_phys(__pa(page), PAGE_SHARED)); + return __pte(0); } void show_mem(void) @@ -346,8 +316,10 @@ void __init paging_init(void) /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); - pmd_init((unsigned long)invalid_pmd_table); + pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE); + pmd_init((unsigned long)empty_bad_pmd_table, (unsigned long)empty_bad_page_table); + memset((void *)empty_bad_page_table, 0, sizeof(pte_t) * PTRS_PER_PTE); max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; low = max_low_pfn; diff --git a/arch/mips64/sgi-ip27/ip27-memory.c b/arch/mips64/sgi-ip27/ip27-memory.c index ddc01c1f1..afa900313 100644 --- a/arch/mips64/sgi-ip27/ip27-memory.c +++ b/arch/mips64/sgi-ip27/ip27-memory.c @@ -248,8 +248,10 @@ void __init paging_init(void) /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); - pmd_init((unsigned long)invalid_pmd_table); + pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE); + pmd_init((unsigned long)empty_bad_pmd_table, (unsigned long)empty_bad_page_table); + memset((void *)empty_bad_page_table, 0, sizeof(pte_t) * PTRS_PER_PTE); for (node = 0; node < numnodes; node++) { pfn_t start_pfn = slot_getbasepfn(node, 0); |