===== kernel/fork.c 1.5 vs edited ===== --- 1.5/kernel/fork.c Sat Feb 10 20:54:34 2001 +++ edited/kernel/fork.c Thu Mar 8 13:50:44 2001 @@ -203,7 +203,9 @@ atomic_set(&mm->mm_count, 1); init_MUTEX(&mm->mmap_sem); mm->page_table_lock = SPIN_LOCK_UNLOCKED; + lock_kernel(); mm->pgd = pgd_alloc(); + unlock_kernel(); if (mm->pgd) return mm; free_mm(mm); @@ -234,7 +236,9 @@ inline void __mmdrop(struct mm_struct *mm) { if (mm == &init_mm) BUG(); + lock_kernel(); pgd_free(mm->pgd); + unlock_kernel(); destroy_context(mm); free_mm(mm); } ===== mm/vmalloc.c 1.3 vs edited ===== --- 1.3/mm/vmalloc.c Sat Feb 10 20:54:34 2001 +++ edited/mm/vmalloc.c Thu Mar 8 12:55:42 2001 @@ -146,6 +146,7 @@ lock_kernel(); do { pmd_t *pmd; + pgd_t olddir = *dir; pmd = pmd_alloc_kernel(dir, address); ret = -ENOMEM; @@ -155,6 +156,8 @@ ret = -ENOMEM; if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot)) break; + if (pgd_val(olddir) != pgd_val(*dir)) + set_pgdir(address, *dir); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; ===== include/asm-i386/pgalloc.h 1.1 vs edited ===== --- 1.1/include/asm-i386/pgalloc.h Sat Jan 6 10:26:31 2001 +++ edited/include/asm-i386/pgalloc.h Thu Mar 8 12:50:47 2001 @@ -152,6 +152,33 @@ extern int do_check_pgt_cache(int, int); +extern inline void set_pgdir(unsigned long address, pgd_t entry) +{ + struct task_struct * p; + pgd_t *pgd; +#ifdef CONFIG_SMP + int i; +#endif + + read_lock(&tasklist_lock); + for_each_task(p) { + if (!p->mm) + continue; + *pgd_offset(p->mm,address) = entry; + } + read_unlock(&tasklist_lock); +#ifndef CONFIG_SMP + for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) + pgd[address >> PGDIR_SHIFT] = entry; +#else + /* To pgd_alloc/pgd_free, one holds master kernel lock and so does our callee, so we can + modify pgd caches of other CPUs as well. -jj */ + for (i = 0; i < NR_CPUS; i++) + for (pgd = (pgd_t *)cpu_data[i].pgd_quick; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) + pgd[address >> PGDIR_SHIFT] = entry; +#endif +} + /* * TLB flushing: * ===== arch/i386/mm/ioremap.c 1.1 vs edited ===== --- 1.1/arch/i386/mm/ioremap.c Sat Jan 6 10:29:43 2001 +++ edited/arch/i386/mm/ioremap.c Thu Mar 8 12:50:47 2001 @@ -78,6 +78,7 @@ if (remap_area_pmd(pmd, address, end - address, phys_addr + address, flags)) return -ENOMEM; + set_pgdir(address, *dir); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end));