diff -Naru linux-2.6.0/include/linux/vmalloc.h linux-vmsync/include/linux/vmalloc.h
--- linux-2.6.0/include/linux/vmalloc.h	2003-10-26 03:44:53.000000000 +0900
+++ linux-vmsync/include/linux/vmalloc.h	2003-12-18 14:21:53.000000000 +0900
@@ -30,7 +30,7 @@
 extern void *vmap(struct page **pages, unsigned int count,
 			unsigned long flags, pgprot_t prot);
 extern void vunmap(void *addr);
- 
+extern int vmsync(void *addr);
 /*
  *	Lowlevel-APIs (not for driver use!)
  */
diff -Naru linux-2.6.0/mm/vmalloc.c linux-vmsync/mm/vmalloc.c
--- linux-2.6.0/mm/vmalloc.c	2003-10-26 03:43:51.000000000 +0900
+++ linux-vmsync/mm/vmalloc.c	2003-12-24 12:29:36.675193520 +0900
@@ -541,3 +541,100 @@
 	read_unlock(&vmlist_lock);
 	return buf - buf_start;
 }
+
+
+#ifdef CONFIG_MMU
+static inline void copy_pgd_one(pgd_t *pgd, pgd_t *pgd_k,
+			       unsigned long address,
+			       unsigned long size)
+{
+	unsigned long end;
+	pmd_t *pmd = pmd_offset(pgd, address);
+	pmd_t *pmd_k = pmd_offset(pgd_k, address);
+
+	if (pmd == pmd_k) return; /* needless to copy */
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+
+	do {
+		if (unlikely(!pmd_present(*pmd_k))) {
+			BUG();
+		}else
+			set_pmd(pmd, *pmd_k);
+		address = ( address + PMD_SIZE ) & PMD_MASK;
+		pmd++; pmd_k++;
+	} while (address < end);
+
+	return ;
+}
+  
+/**
+ *	vmsync  -  synchronize all pmd entries corresponding specified vm area.
+ *
+ *	@addr: synchronize address
+ *
+ *	This prevent page-fault exception on specified vm area.
+ **/
+int vmsync(void *addr)
+{
+	pgd_t *pgd, *pgd_k;
+	struct vm_struct *area;
+	struct mm_struct *mm;
+	unsigned long v_address;
+	unsigned long end;
+
+	/* get vm area */
+	read_lock(&vmlist_lock);
+	for (area = vmlist ; (area) ;area = area->next) {
+		 if (area->addr == addr)
+			 goto found;
+	}
+	read_unlock(&vmlist_lock);
+	return -EINVAL;
+found:
+	read_unlock(&vmlist_lock);
+	v_address = (unsigned long)(area->addr);
+	end = v_address + (area->nr_pages << PAGE_SHIFT);
+
+	/*
+	 * Synchronize this task's top level page-table
+	 * with the 'reference' page table.
+	 */
+	spin_lock(&mmlist_lock);
+	spin_lock(&init_mm.page_table_lock);
+	list_for_each_entry(mm, &init_mm.mmlist, mmlist) {
+		int index;
+		unsigned long address;
+		if(mm == &init_mm) continue;
+
+		address = v_address;
+		index = pgd_index(address);
+		pgd = mm->pgd + index;
+		pgd_k = init_mm.pgd + index;
+		
+		spin_lock(&mm->page_table_lock);
+		do {
+			if (unlikely(!pgd_present(*pgd_k)))
+				BUG();
+			copy_pgd_one(pgd, pgd_k, address, end - address);
+			address = (address + PGDIR_SIZE) & PGDIR_MASK;
+			pgd++; pgd_k++;
+		} while (address < end);
+		spin_unlock(&mm->page_table_lock);
+	}
+	spin_unlock(&init_mm.page_table_lock);
+	spin_unlock(&mmlist_lock);
+	flush_tlb_kernel_range((unsigned long)(area->addr),
+			       (unsigned long)(area->addr)+area->size);
+	return 0;
+}
+#else
+int vmsync(void *addr)
+{
+	return 0;
+}
+#endif
+EXPORT_SYMBOL(vmsync);
