summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/2.6.20/20965_linux-2.6-xen-sleazy-fpu-i386.patch')
-rw-r--r--trunk/2.6.20/20965_linux-2.6-xen-sleazy-fpu-i386.patch96
1 files changed, 96 insertions, 0 deletions
diff --git a/trunk/2.6.20/20965_linux-2.6-xen-sleazy-fpu-i386.patch b/trunk/2.6.20/20965_linux-2.6-xen-sleazy-fpu-i386.patch
new file mode 100644
index 0000000..0145385
--- /dev/null
+++ b/trunk/2.6.20/20965_linux-2.6-xen-sleazy-fpu-i386.patch
@@ -0,0 +1,96 @@
+# HG changeset patch
+# User "Eduardo Habkost <ehabkost@redhat.com>"
+# Date 1190313016 10800
+# Node ID 8792a16b6dd531cad0ed28d9bef86e3e597ea8db
+# Parent 35983eae211a531bd50bcd177a9da77d48631e2c
+Fix sleazy-fpu under Xen
+
+- Make it reset fpu_counter when needed (like __unlazy_fpu() does)
+- Make it call clts() before restoring the fpu state during task switch
+ (clts() will still not be called during the device_not_available trap,
+ because it is not needed under Xen)
+
+diff -r 35983eae211a -r 8792a16b6dd5 arch/i386/kernel/entry-xen.S
+--- a/arch/i386/kernel/entry-xen.S Wed Aug 08 16:15:30 2007 -0300
++++ b/arch/i386/kernel/entry-xen.S Thu Sep 20 15:30:16 2007 -0300
+@@ -950,7 +950,9 @@ device_available_emulate:
+ device_available_emulate:
+ #endif
+ preempt_stop(CLBR_ANY)
+- call math_state_restore
++ # 'clts' is done by Xen during virtual trap, so we can call
++ # __math_state_restore instead of math_state_restore
++ call __math_state_restore
+ jmp ret_from_exception
+ CFI_ENDPROC
+
+diff -r 35983eae211a -r 8792a16b6dd5 arch/i386/kernel/process-xen.c
+--- a/arch/i386/kernel/process-xen.c Wed Aug 08 16:15:30 2007 -0300
++++ b/arch/i386/kernel/process-xen.c Thu Sep 20 15:30:16 2007 -0300
+@@ -597,7 +597,9 @@ struct task_struct fastcall * __switch_t
+ mcl->op = __HYPERVISOR_fpu_taskswitch;
+ mcl->args[0] = 1;
+ mcl++;
+- }
++ } else
++ prev_p->fpu_counter = 0;
++
+ #if 0 /* lazy fpu sanity check */
+ else BUG_ON(!(read_cr0() & 8));
+ #endif
+diff -r 35983eae211a -r 8792a16b6dd5 arch/i386/kernel/traps-xen.c
+--- a/arch/i386/kernel/traps-xen.c Wed Aug 08 16:15:30 2007 -0300
++++ b/arch/i386/kernel/traps-xen.c Thu Sep 20 15:30:16 2007 -0300
+@@ -1012,17 +1012,22 @@ fastcall unsigned long patch_espfix_desc
+ * Must be called with kernel preemption disabled (in this case,
+ * local interrupts are disabled at the call-site in entry.S).
+ */
+-asmlinkage void math_state_restore(void)
++asmlinkage void __math_state_restore(void)
+ {
+ struct thread_info *thread = current_thread_info();
+ struct task_struct *tsk = thread->task;
+
+- /* NB. 'clts' is done for us by Xen during virtual trap. */
+ if (!tsk_used_math(tsk))
+ init_fpu(tsk);
+ restore_fpu(tsk);
+ thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */
+ tsk->fpu_counter++;
++}
++
++asmlinkage void math_state_restore(void)
++{
++ clts(); /* Allow maths ops (or we recurse) */
++ __math_state_restore();
+ }
+
+ #ifndef CONFIG_MATH_EMULATION
+diff -r 35983eae211a -r 8792a16b6dd5 arch/i386/kernel/traps.c
+--- a/arch/i386/kernel/traps.c Wed Aug 08 16:15:30 2007 -0300
++++ b/arch/i386/kernel/traps.c Thu Sep 20 15:30:16 2007 -0300
+@@ -1041,17 +1041,22 @@ fastcall unsigned long patch_espfix_desc
+ * Must be called with kernel preemption disabled (in this case,
+ * local interrupts are disabled at the call-site in entry.S).
+ */
+-asmlinkage void math_state_restore(void)
++asmlinkage void __math_state_restore(void)
+ {
+ struct thread_info *thread = current_thread_info();
+ struct task_struct *tsk = thread->task;
+
+- clts(); /* Allow maths ops (or we recurse) */
+ if (!tsk_used_math(tsk))
+ init_fpu(tsk);
+ restore_fpu(tsk);
+ thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */
+ tsk->fpu_counter++;
++}
++
++asmlinkage void math_state_restore(void)
++{
++ clts(); /* Allow maths ops (or we recurse) */
++ __math_state_restore();
+ }
+
+ #ifndef CONFIG_MATH_EMULATION