From b1b901c2029aa0fd8aa4ac5f04f31648ae2358b4 Mon Sep 17 00:00:00 2001
From: Russ Anderson <rja@sgi.com>
Date: Wed, 6 Apr 2005 00:07:00 -0700
Subject: [IA64] MCA recovery improvements

Jack Steiner uncovered some opportunities for improvement in
the MCA recovery code.

  1) Set bsp to save registers on the kernel stack.
  2) Disable interrupts while in the MCA recovery code.
  3) Change the way the user process is killed, to avoid
     a panic in schedule.

Testing shows that these changes make the recovery code much
more reliable with the 2.6.12 kernel.

Signed-off-by: Russ Anderson <rja@sgi.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
 arch/ia64/kernel/mca_drv.c     |  4 ++--
 arch/ia64/kernel/mca_drv_asm.S | 18 +++++++++++++++---
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index ab478172c3..abc0113a82 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -132,8 +132,7 @@ mca_handler_bh(unsigned long paddr)
 	spin_unlock(&mca_bh_lock);
 
 	/* This process is about to be killed itself */
-	force_sig(SIGKILL, current);
-	schedule();
+	do_exit(SIGKILL);
 }
 
 /**
@@ -439,6 +438,7 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_chec
 			psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
 			psr2->cpl = 0;
 			psr2->ri  = 0;
+			psr2->i  = 0;
 
 			return 1;
 		}
diff --git a/arch/ia64/kernel/mca_drv_asm.S b/arch/ia64/kernel/mca_drv_asm.S
index bcfa05acc5..2d7e021763 100644
--- a/arch/ia64/kernel/mca_drv_asm.S
+++ b/arch/ia64/kernel/mca_drv_asm.S
@@ -10,6 +10,7 @@
 
 #include <asm/asmmacro.h>
 #include <asm/processor.h>
+#include <asm/ptrace.h>
 
 GLOBAL_ENTRY(mca_handler_bhhook)
 	invala						// clear RSE ?
@@ -20,12 +21,21 @@ GLOBAL_ENTRY(mca_handler_bhhook)
 	;;						
 	alloc		r16=ar.pfs,0,2,1,0		// make a new frame
 	;;
+	mov		ar.rsc=0
+	;;
 	mov		r13=IA64_KR(CURRENT)		// current task pointer
 	;;
-	adds		r12=IA64_TASK_THREAD_KSP_OFFSET,r13
+	mov		r2=r13
+	;;
+	addl		r22=IA64_RBS_OFFSET,r2
+	;;
+	mov		ar.bspstore=r22
 	;;
-	ld8		r12=[r12]			// stack pointer
+	addl		sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2
 	;;
+	adds		r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+	;;
+	st1		[r2]=r0				// clear current->thread.on_ustack flag
 	mov		loc0=r16
 	movl		loc1=mca_handler_bh		// recovery C function
 	;;
@@ -34,7 +44,9 @@ GLOBAL_ENTRY(mca_handler_bhhook)
 	;;
 	mov		loc1=rp
 	;;
-	br.call.sptk.many    rp=b6			// not return ...
+	ssm		psr.i
+	;;
+	br.call.sptk.many    rp=b6			// does not return ...
 	;;
 	mov		ar.pfs=loc0
 	mov 		rp=loc1
-- 
cgit v1.2.2