--- /dev/null
+From 891348ca0f66206f1dc0e30d63757e3df1ae2d15 Mon Sep 17 00:00:00 2001
+From: Robin Holt <holt@sgi.com>
+Date: Thu, 20 Dec 2012 15:05:50 -0800
+Subject: SGI-XP: handle non-fatal traps
+
+From: Robin Holt <holt@sgi.com>
+
+commit 891348ca0f66206f1dc0e30d63757e3df1ae2d15 upstream.
+
+We found a user code which was raising a divide-by-zero trap. That trap
+would lead to XPC connections between system-partitions being torn down
+due to the die_chain notifier callouts it received.
+
+This also revealed a different issue where multiple callers into
+xpc_die_deactivate() would all attempt to do the disconnect in parallel
+which would sometimes lock up but often overwhelm the console on very
+large machines as each would print at least one line of output at the
+end of the deactivate.
+
+I reviewed all the users of the die_chain notifier and changed the code
+to ignore the notifier callouts for reasons which will not actually lead
+to a system to continue on to call die().
+
+[akpm@linux-foundation.org: fix ia64]
+Signed-off-by: Robin Holt <holt@sgi.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/sgi-xp/xpc_main.c | 34 ++++++++++++++++++++++++++++++++--
+ 1 file changed, 32 insertions(+), 2 deletions(-)
+
+--- a/drivers/misc/sgi-xp/xpc_main.c
++++ b/drivers/misc/sgi-xp/xpc_main.c
+@@ -53,6 +53,10 @@
+ #include <linux/kthread.h>
+ #include "xpc.h"
+
++#ifdef CONFIG_X86_64
++#include <asm/traps.h>
++#endif
++
+ /* define two XPC debug device structures to be used with dev_dbg() et al */
+
+ struct device_driver xpc_dbg_name = {
+@@ -1079,6 +1083,9 @@ xpc_system_reboot(struct notifier_block
+ return NOTIFY_DONE;
+ }
+
++/* Used to only allow one cpu to complete disconnect */
++static unsigned int xpc_die_disconnecting;
++
+ /*
+ * Notify other partitions to deactivate from us by first disengaging from all
+ * references to our memory.
+@@ -1092,6 +1099,9 @@ xpc_die_deactivate(void)
+ long keep_waiting;
+ long wait_to_print;
+
++ if (cmpxchg(&xpc_die_disconnecting, 0, 1))
++ return;
++
+ /* keep xpc_hb_checker thread from doing anything (just in case) */
+ xpc_exiting = 1;
+
+@@ -1159,7 +1169,7 @@ xpc_die_deactivate(void)
+ * about the lack of a heartbeat.
+ */
+ static int
+-xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
++xpc_system_die(struct notifier_block *nb, unsigned long event, void *_die_args)
+ {
+ #ifdef CONFIG_IA64 /* !!! temporary kludge */
+ switch (event) {
+@@ -1191,7 +1201,27 @@ xpc_system_die(struct notifier_block *nb
+ break;
+ }
+ #else
+- xpc_die_deactivate();
++ struct die_args *die_args = _die_args;
++
++ switch (event) {
++ case DIE_TRAP:
++ if (die_args->trapnr == X86_TRAP_DF)
++ xpc_die_deactivate();
++
++ if (((die_args->trapnr == X86_TRAP_MF) ||
++ (die_args->trapnr == X86_TRAP_XF)) &&
++ !user_mode_vm(die_args->regs))
++ xpc_die_deactivate();
++
++ break;
++ case DIE_INT3:
++ case DIE_DEBUG:
++ break;
++ case DIE_OOPS:
++ case DIE_GPF:
++ default:
++ xpc_die_deactivate();
++ }
+ #endif
+
+ return NOTIFY_DONE;
--- /dev/null
+From holt@sgi.com Thu Jan 24 12:43:57 2013
+From: Kees Cook <keescook@chromium.org>
+Date: Thu, 24 Jan 2013 14:14:20 -0600
+Subject: x86: Use enum instead of literals for trap values [PARTIAL]
+To: Greg KH <gregkh@linuxfoundation.org>
+Message-ID: <20130124201420.GI3438@sgi.com>
+Content-Disposition: inline
+
+From: Kees Cook <keescook@chromium.org>
+
+[Based on commit c94082656dac74257f63e91f78d5d458ac781fa5 upstream, only
+taking the traps.h portion.]
+
+The traps are referred to by their numbers and it can be difficult to
+understand them while reading the code without context. This patch adds
+enumeration of the trap numbers and replaces the numbers with the correct
+enum for x86.
+
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: http://lkml.kernel.org/r/20120310000710.GA32667@www.outflux.net
+Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Robin Holt <holt@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/traps.h | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/arch/x86/include/asm/traps.h
++++ b/arch/x86/include/asm/traps.h
+@@ -1,6 +1,7 @@
+ #ifndef _ASM_X86_TRAPS_H
+ #define _ASM_X86_TRAPS_H
+
++#include <linux/kprobes.h>
+ #include <asm/debugreg.h>
+ #include <asm/siginfo.h> /* TRAP_TRACE, ... */
+
+@@ -87,4 +88,29 @@ asmlinkage void smp_thermal_interrupt(vo
+ asmlinkage void mce_threshold_interrupt(void);
+ #endif
+
++/* Interrupts/Exceptions */
++enum {
++ X86_TRAP_DE = 0, /* 0, Divide-by-zero */
++ X86_TRAP_DB, /* 1, Debug */
++ X86_TRAP_NMI, /* 2, Non-maskable Interrupt */
++ X86_TRAP_BP, /* 3, Breakpoint */
++ X86_TRAP_OF, /* 4, Overflow */
++ X86_TRAP_BR, /* 5, Bound Range Exceeded */
++ X86_TRAP_UD, /* 6, Invalid Opcode */
++ X86_TRAP_NM, /* 7, Device Not Available */
++ X86_TRAP_DF, /* 8, Double Fault */
++ X86_TRAP_OLD_MF, /* 9, Coprocessor Segment Overrun */
++ X86_TRAP_TS, /* 10, Invalid TSS */
++ X86_TRAP_NP, /* 11, Segment Not Present */
++ X86_TRAP_SS, /* 12, Stack Segment Fault */
++ X86_TRAP_GP, /* 13, General Protection Fault */
++ X86_TRAP_PF, /* 14, Page Fault */
++ X86_TRAP_SPURIOUS, /* 15, Spurious Interrupt */
++ X86_TRAP_MF, /* 16, x87 Floating-Point Exception */
++ X86_TRAP_AC, /* 17, Alignment Check */
++ X86_TRAP_MC, /* 18, Machine Check */
++ X86_TRAP_XF, /* 19, SIMD Floating-Point Exception */
++ X86_TRAP_IRET = 32, /* 32, IRET Exception */
++};
++
+ #endif /* _ASM_X86_TRAPS_H */