From: Andrea Arcangeli If more than one page was in the list the kernel was not flushing the tlb at all. Signed-off-by: Andrea Arcangeli Signed-off-by: Andrew Morton --- 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); _