diff -urN linux-bg1/arch/i386/mm/init.c linux/arch/i386/mm/init.c --- linux-bg1/arch/i386/mm/init.c Fri Aug 2 10:15:28 2002 +++ linux/arch/i386/mm/init.c Sun Aug 4 12:14:42 2002 @@ -126,7 +126,7 @@ unsigned long pfn; pgd_t *pgd; pmd_t *pmd; - pte_t *pte; + pte_t *pte, *pte_base; int pgd_ofs, pmd_ofs, pte_ofs; pgd_ofs = __pgd_offset(PAGE_OFFSET); @@ -141,10 +141,19 @@ set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE)); pfn += PTRS_PER_PTE; } else { - pte = one_page_table_init(pmd); + /* + * We cannot set the pmd until the page is full, since we are + * changing the pte under running code and a tlb miss will + * cause an oops. + */ + pte_base = pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) set_pte(pte, pfn_pte(pfn, PAGE_KERNEL)); + + set_pmd(pmd, __pmd(__pa(pte_base) | _KERNPG_TABLE)); + if (pte_base != pte_offset_kernel(pmd, 0)) + BUG(); } } }