From: Andrew Morton general protection fault: 0000 [1] PREEMPT SMP last sysfs file: CPU 1 Modules linked in: Pid: 0, comm: swapper Not tainted 2.6.19-rc3 #6 RIP: 0010:[] [] flush_kernel_map+0x24/0x50 RSP: 0018:ffff81017fc9bf78 EFLAGS: 00010093 RAX: 001f40ffc0000000 RBX: 001f40ffc0000000 RCX: 0000000000000040 RDX: 0000000000000000 RSI: 0000000000000002 RDI: 001f40ffc0000000 RBP: ffff81017fc9bf78 R08: ffff81017fc92010 R09: ffffffff80636040 R10: ffffffff80636040 R11: ffffffff80636040 R12: ffffffff80220d48 R13: 0000000000000001 R14: ffffffff805ec300 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff81017fc0ca20(0000) knlGS:0000000000000000 CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b CR2: 0000000000000000 CR3: 0000000000201000 CR4: 00000000000006e0 Process swapper (pid: 0, threadinfo ffff81017fc92000, task ffff81017fc69100) Stack: ffff81017fc9bfa8 ffffffff80217c06 ffffffff80636040 ffffffff802082f4 0000000000000001 0000000000000001 ffff81017fc93e30 ffffffff8020a4b6 ffff81017fc93e30 ffff81017fc93eb8 ffffffff80636040 ffffffff80636040 Call Trace: [] smp_call_function_interrupt+0x4b/0x6c [] mwait_idle+0x0/0x10 [] call_function_interrupt+0x66/0x70 [] mwait_idle_with_hints+0x4c/0x4e [] mwait_idle+0xe/0x10 [] cpu_idle+0x8d/0xc6 [] start_secondary+0x478/0x489 Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/x86_64/mm/pageattr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff -puN arch/x86_64/mm/pageattr.c~revert-x86_64-mm-cpa-clflush arch/x86_64/mm/pageattr.c --- a/arch/x86_64/mm/pageattr.c~revert-x86_64-mm-cpa-clflush +++ a/arch/x86_64/mm/pageattr.c @@ -64,9 +64,8 @@ static struct page *split_large_page(uns static void flush_kernel_map(void *address) { - /* When clflush is available always use it because it is - much cheaper than WBINVD */ - if (cpu_has_clflush) { + if (0 && address && cpu_has_clflush) { + /* is this worth it? */ int i; for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) asm volatile("clflush (%0)" :: "r" (address + i)); @@ -78,6 +77,7 @@ static void flush_kernel_map(void *addre __flush_tlb_all(); } + static inline void flush_map(unsigned long address) { on_each_cpu(flush_kernel_map, (void *)address, 1, 1); @@ -213,7 +213,7 @@ void global_flush_tlb(void) dpage = xchg(&deferred_pages, NULL); up_read(&init_mm.mmap_sem); - flush_map((unsigned long)page_address(dpage)); + flush_map((dpage && !dpage->lru.next) ? (unsigned long)page_address(dpage) : 0); while (dpage) { struct page *tmp = dpage; dpage = (struct page *)dpage->lru.next; _