summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-06-27 02:05:08 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-06-27 02:05:08 +0000
commit8a6a74d2e0311629141438e64319fad5d657f5ac (patch)
tree3225f9a86374a4c4922e8bc126772d9f10ed5251 /arch
parentfef84721fc04db3ce781aacf1c6e247acc7ba04b (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')
-rw-r--r--arch/mips64/kernel/head.S1
-rw-r--r--arch/mips64/mm/init.c62
-rw-r--r--arch/mips64/sgi-ip27/ip27-memory.c4
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);