]> git.neil.brown.name Git - history.git/commit
[PATCH] ldt-fix-2.5.32-A3
authorIngo Molnar <mingo@elte.hu>
Fri, 30 Aug 2002 08:45:53 +0000 (01:45 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Fri, 30 Aug 2002 08:45:53 +0000 (01:45 -0700)
commit89d637a87209aacf1bde6a8b33db034d5c29de7e
tree90f3fedcfa0bb0f181f3438deb6af8c053f7ff96
parente5d588fefc9151f6c17a63a19e9c05435559dbcf
[PATCH] ldt-fix-2.5.32-A3

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.]
arch/i386/kernel/ldt.c
include/asm-i386/desc.h
include/asm-i386/mmu.h
include/asm-i386/mmu_context.h