• Ingo Molnar's avatar
    [PATCH] ldt-fix-2.5.32-A3 · 89d637a8
    Ingo Molnar authored
    this is an updated version of the LDT fixes. It fixes the following kinds
    of problems:
    
     - fix a possible gcc optimization causing a race causing the loading of a
       corrupt LDT descriptor upon context switch. [this fix got simplified
       over previous versions.]
    
     - remove an unconditional OOM printk, and there's no need to set ->size
       in the OOM path.
    
     - fix preemption bugs, load_LDT()/clear_LDT() was not preemption-safe,
       when it was used outside of spinlocks.
    
    the context-switch race is the following. 'LDT modification' is the
    following operation: the seg->ldt pointer is modified, then seg->size is
    modified. In theory gcc is free to reschedule the two modifications, and
    first modify ->size, then ->ldt. Thus if this modification is not
    synchronized with context-switches, another thread might see a temporary
    state of the new ->size [which was increased], but still the old pointer.
    Ie.:
    
    	CPU0				CPU1
    
    	pc->size = newsize;
    					load_LDT(); // (oldptr, newsize)
    	pc->ldt = newptr;
    
    the corrupt LDT is loaded until the SMP cross-call is sent, leaving the
    window open for many usecs.
    
    the fix is to put a wmb() after ->ldt modifications. [this is also in
    preparation of not-write-ordered SMP x86 designs.]
    89d637a8
ldt.c 4.94 KB