
From: Ingo Molnar <mingo@elte.hu>

SYSENTER creates a degenerate 'small' stackframe with an esp0 that is
missing the 5 entry words relative to the normal entry (int80 or irq) esp0
stackframe.  These 5 words are: xss, esp, eflags, xcs, eip.  The sysenter
code sets them up manually.

Now if an interrupt hits at this point, it will set up a 'same privilege
level' stackframe, which has eip/xcs/eflags, i.e.  no esp/xss.  If upon
irq-return we then examine the stack due to your patch, it will be an
incorrect stackframe -> kaboom.

The correct solution is to always let the sysenter path set up a full and
correct stackframe, before allowing preemption (see the attached patch). 
This was a nasty bug in the waiting.  (I have not made this conditional on
CONFIG_PREEMPT, to keep it simple and because the impact to irq latency is
small and predictable.  There's no runtime overhead.)

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/i386/kernel/entry.S |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletion(-)

diff -puN arch/i386/kernel/entry.S~sysenter-irq-atomicity-fix arch/i386/kernel/entry.S
--- 25/arch/i386/kernel/entry.S~sysenter-irq-atomicity-fix	2005-04-07 03:10:36.000000000 -0700
+++ 25-akpm/arch/i386/kernel/entry.S	2005-04-07 03:10:36.000000000 -0700
@@ -179,12 +179,17 @@ need_resched:
 ENTRY(sysenter_entry)
 	movl TSS_sysenter_esp0(%esp),%esp
 sysenter_past_esp:
-	sti
+	#
+	# irqs are disabled: set up an entry stackframe without
+	# allowing irqs to potentially preempt us with an
+	# incomplete entry frame!
+	#
 	pushl $(__USER_DS)
 	pushl %ebp
 	pushfl
 	pushl $(__USER_CS)
 	pushl $SYSENTER_RETURN
+	sti
 
 /*
  * Load the potential sixth argument from user stack.
_
