-
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