WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Fix floating-point corruption (a nasty race in fp task-s

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix floating-point corruption (a nasty race in fp task-switch
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sun, 30 Oct 2005 11:02:07 +0000
Delivery-date: Sun, 30 Oct 2005 10:59:44 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID b5903c9aeda56523b6676163e06b7db5cf4cd93d
# Parent  07aa5213d8119f9889f49cd79cc9a2a3ae787881
Fix floating-point corruption (a nasty race in fp task-switch
exception handling).
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 07aa5213d811 -r b5903c9aeda5 
linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Sun Oct 30 08:39:55 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Sun Oct 30 09:45:49 2005
@@ -653,7 +653,7 @@
 ENTRY(device_not_available)
        pushl $-1                       # mark this as an int
        SAVE_ALL
-       preempt_stop
+       #preempt_stop /* This is already an interrupt gate on Xen. */
        call math_state_restore
        jmp ret_from_exception
 
diff -r 07aa5213d811 -r b5903c9aeda5 
linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Sun Oct 30 08:39:55 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Sun Oct 30 09:45:49 2005
@@ -647,6 +647,12 @@
        do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
 }
 #endif
+
+static inline void conditional_sti(struct pt_regs *regs)
+{
+       if ((uint8_t)(regs->xcs >> 16) == 0)
+               local_irq_enable();
+}
 
 /*
  * Our handling of the processor debug registers is non-trivial.
@@ -680,11 +686,9 @@
        if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
                                        SIGTRAP) == NOTIFY_STOP)
                return;
-#if 0
+
        /* It's safe to allow irq's after DR6 has been saved */
-       if (regs->eflags & X86_EFLAGS_IF)
-               local_irq_enable();
-#endif
+       conditional_sti(regs);
 
        /* Mask out spurious debug traps due to lazy DR7 setting */
        if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
@@ -967,15 +971,18 @@
 #endif
 
 
-/* NB. All these are "trap gates" (i.e. events_mask isn't cleared). */
+/*
+ * NB. All these are "trap gates" (i.e. events_mask isn't cleared) except
+ * for those that specify <dpl>|4 in the second field.
+ */
 static trap_info_t trap_table[] = {
        {  0, 0, __KERNEL_CS, (unsigned long)divide_error               },
-       {  1, 0, __KERNEL_CS, (unsigned long)debug                      },
-       {  3, 3, __KERNEL_CS, (unsigned long)int3                       },
+       {  1, 0|4, __KERNEL_CS, (unsigned long)debug                    },
+       {  3, 3|4, __KERNEL_CS, (unsigned long)int3                     },
        {  4, 3, __KERNEL_CS, (unsigned long)overflow                   },
        {  5, 3, __KERNEL_CS, (unsigned long)bounds                     },
        {  6, 0, __KERNEL_CS, (unsigned long)invalid_op                 },
-       {  7, 0, __KERNEL_CS, (unsigned long)device_not_available       },
+       {  7, 0|4, __KERNEL_CS, (unsigned long)device_not_available     },
        {  9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
        { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS                },
        { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present        },
diff -r 07aa5213d811 -r b5903c9aeda5 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Sun Oct 30 08:39:55 2005
+++ b/xen/arch/x86/traps.c      Sun Oct 30 09:45:49 2005
@@ -1147,6 +1147,9 @@
 
 asmlinkage int math_state_restore(struct cpu_user_regs *regs)
 {
+    struct trap_bounce *tb;
+    trap_info_t *ti;
+
     /* Prevent recursion. */
     clts();
 
@@ -1154,10 +1157,15 @@
 
     if ( current->arch.guest_context.ctrlreg[0] & X86_CR0_TS )
     {
-        struct trap_bounce *tb = &current->arch.trap_bounce;
+        tb = &current->arch.trap_bounce;
+        ti = &current->arch.guest_context.trap_ctxt[TRAP_no_device];
+
         tb->flags = TBF_EXCEPTION;
-        tb->cs    = current->arch.guest_context.trap_ctxt[7].cs;
-        tb->eip   = current->arch.guest_context.trap_ctxt[7].address;
+        tb->cs    = ti->cs;
+        tb->eip   = ti->address;
+        if ( TI_GET_IF(ti) )
+            tb->flags |= TBF_INTERRUPT;
+
         current->arch.guest_context.ctrlreg[0] &= ~X86_CR0_TS;
     }
 
@@ -1169,6 +1177,7 @@
     unsigned long condition;
     struct vcpu *v = current;
     struct trap_bounce *tb = &v->arch.trap_bounce;
+    trap_info_t *ti;
 
     __asm__ __volatile__("mov %%db6,%0" : "=r" (condition));
 
@@ -1198,9 +1207,12 @@
     /* Save debug status register where guest OS can peek at it */
     v->arch.guest_context.debugreg[6] = condition;
 
+    ti = &v->arch.guest_context.trap_ctxt[TRAP_debug];
     tb->flags = TBF_EXCEPTION;
-    tb->cs    = v->arch.guest_context.trap_ctxt[TRAP_debug].cs;
-    tb->eip   = v->arch.guest_context.trap_ctxt[TRAP_debug].address;
+    tb->cs    = ti->cs;
+    tb->eip   = ti->address;
+    if ( TI_GET_IF(ti) )
+        tb->flags |= TBF_INTERRUPT;
 
  out:
     return EXCRET_not_a_fault;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Fix floating-point corruption (a nasty race in fp task-switch, Xen patchbot -unstable <=