Skip to content
  • Ingo Molnar's avatar
    x86: fix global_flush_tlb() bug · 9a24d04a
    Ingo Molnar authored
    While we were reviewing pageattr_32/64.c for unification,
    Thomas Gleixner noticed the following serious SMP bug in
    global_flush_tlb():
    
    	down_read(&init_mm.mmap_sem);
    	list_replace_init(&deferred_pages, &l);
    	up_read(&init_mm.mmap_sem);
    
    this is SMP-unsafe because list_replace_init() done on two CPUs in
    parallel can corrupt the list.
    
    This bug has been introduced about a year ago in the 64-bit tree:
    
           commit ea7322de
    
    
           Author: Andi Kleen <ak@suse.de>
           Date:   Thu Dec 7 02:14:05 2006 +0100
    
           [PATCH] x86-64: Speed and clean up cache flushing in change_page_attr
    
                    down_read(&init_mm.mmap_sem);
            -       dpage = xchg(&deferred_pages, NULL);
            +       list_replace_init(&deferred_pages, &l);
                    up_read(&init_mm.mmap_sem);
    
    the xchg() based version was SMP-safe, but list_replace_init() is not.
    So this "cleanup" introduced a nasty bug.
    
    why this bug never become prominent is a mystery - it can probably be
    explained with the (still) relative obscurity of the x86_64 architecture.
    
    the safe fix for now is to write-lock init_mm.mmap_sem.
    
    Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    9a24d04a