From: Andrea Arcangeli <andrea@suse.de>

If more than one page was in the list the kernel was not flushing the tlb at
all.

Signed-off-by: Andrea Arcangeli <andrea@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/x86_64/mm/pageattr.c |   24 ++++++++++++++++--------
 1 files changed, 16 insertions(+), 8 deletions(-)

diff -puN arch/x86_64/mm/pageattr.c~pageattr-flush-tlb-fix arch/x86_64/mm/pageattr.c
--- 25/arch/x86_64/mm/pageattr.c~pageattr-flush-tlb-fix	2004-12-03 20:04:24.536342192 -0800
+++ 25-akpm/arch/x86_64/mm/pageattr.c	2004-12-03 20:04:24.540341584 -0800
@@ -61,7 +61,10 @@ static void flush_kernel_map(void *addre
 			asm volatile("clflush (%0)" :: "r" (address + i)); 
 	} else
 		asm volatile("wbinvd":::"memory"); 
-	__flush_tlb_one(address);
+	if (address)
+		__flush_tlb_one(address);
+	else
+		__flush_tlb_all();
 }
 
 
@@ -202,13 +205,18 @@ void global_flush_tlb(void)
 	down_read(&init_mm.mmap_sem);
 	df = xchg(&df_list, NULL);
 	up_read(&init_mm.mmap_sem);
-	flush_map((df && !df->next) ? df->address : 0);
-	for (; df; df = next_df) { 
-		next_df = df->next;
-		if (df->fpage) 
-			__free_page(df->fpage);
-		kfree(df);
-	} 
+	if (df) {
+		if (!df->next)
+			flush_map(df->address);
+		else
+			flush_map(0); /* flush everything */
+		for (; df; df = next_df) {
+			next_df = df->next;
+			if (df->fpage)
+				__free_page(df->fpage);
+			kfree(df);
+		}
+	}
 } 
 
 EXPORT_SYMBOL(change_page_attr);
_