diff -Naru linux-2.6.6/include/linux/vmalloc.h linux-vmsync/include/linux/vmalloc.h
--- linux-2.6.6/include/linux/vmalloc.h	2004-04-16 14:11:04.000000000 +0900
+++ linux-vmsync/include/linux/vmalloc.h	2004-05-11 11:15:13.011265672 +0900
@@ -30,6 +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!)
@@ -39,6 +40,7 @@
 extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
 			struct page ***pages);
 extern void unmap_vm_area(struct vm_struct *area);
+extern struct vm_struct *find_vm_area(void *addr);
 
 /*
  *	Internals.  Dont't use..
diff -Naru linux-2.6.6/mm/vmalloc.c linux-vmsync/mm/vmalloc.c
--- linux-2.6.6/mm/vmalloc.c	2004-02-20 16:03:48.000000000 +0900
+++ linux-vmsync/mm/vmalloc.c	2004-05-11 11:15:13.012265520 +0900
@@ -542,3 +542,108 @@
 	read_unlock(&vmlist_lock);
 	return buf - buf_start;
 }
+
+
+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 ;
+}
+
+struct vm_struct *find_vm_area(void *addr)
+{
+	struct vm_struct *area;
+	/* get vm area */
+	read_lock(&vmlist_lock);
+	for (area = vmlist ; (area) ;area = area->next) {
+		 if ((unsigned long)area->addr <= (unsigned long)addr && 
+		     (unsigned long)addr <= (unsigned long)area->addr + area->size ) {
+			break;
+		}
+	}
+	read_unlock(&vmlist_lock);
+	return area;
+}
+  
+/**
+ *	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->size;
+
+	/*
+	 * 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();
+	return 0;
+}
+
+EXPORT_SYMBOL(vmsync);
