Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64/sparc64 Handle improperly aligned stack poi...
details: https://anonhg.NetBSD.org/src/rev/9801168147c4
branches: trunk
changeset: 532347:9801168147c4
user: eeh <eeh%NetBSD.org@localhost>
date: Wed Jun 05 18:11:18 2002 +0000
description:
Handle improperly aligned stack pointers more cleanly.
diffstat:
sys/arch/sparc64/sparc64/locore.s | 79 ++++++++++++++++++++++++++++++--------
1 files changed, 62 insertions(+), 17 deletions(-)
diffs (107 lines):
diff -r 0e6c7bb59d45 -r 9801168147c4 sys/arch/sparc64/sparc64/locore.s
--- a/sys/arch/sparc64/sparc64/locore.s Wed Jun 05 17:58:33 2002 +0000
+++ b/sys/arch/sparc64/sparc64/locore.s Wed Jun 05 18:11:18 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.s,v 1.155 2002/06/04 15:04:08 eeh Exp $ */
+/* $NetBSD: locore.s,v 1.156 2002/06/05 18:11:18 eeh Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath
@@ -3422,9 +3422,17 @@
/*
* We're here because we took an alignment fault in NUCLEUS context.
* This could be a kernel bug or it could be due to saving a user
- * window to an invalid stack pointer. If the latter is the case,
- * we should emulate the save by storing all the user register windows
- * to the PCB and returning.
+ * window to an invalid stack pointer.
+ *
+ * If the latter is the case, we could try to emulate unaligned accesses,
+ * but we really don't know where to store the registers since we can't
+ * determine if there's a stack bias. Or we could store all the regs
+ * into the PCB and punt, until the user program uses up all the CPU's
+ * register windows and we run out of places to store them. So for
+ * simplicity we'll just blow them away and enter the trap code which
+ * will generate a bus error. Debugging the problem will be a bit
+ * complicated since lots of register windows will be lost, but what
+ * can we do?
*/
checkalign:
rdpr %tl, %g2
@@ -3448,8 +3456,8 @@
!!
!! Double data fault -- bad stack?
!!
- wrpr %g2, %tl ! Restore trap level.
- sir ! Just issue a reset and don't try to recover.
+ wrpr %g2, %tl ! Restore trap level.
+ sir ! Just issue a reset and don't try to recover.
mov %fp, %l6 ! Save the frame pointer
set EINTSTACK+USPACE+CC64FSZ-STKB, %fp ! Set the frame pointer to the middle of the idle stack
add %fp, -CC64FSZ, %sp ! Create a stackframe
@@ -3459,17 +3467,54 @@
ba slowtrap ! all our register windows.
wrpr %g0, 0x101, %tt
#endif
-checkalignspill:
- wr %g0, ASI_DMMU, %asi ! We need to re-load trap info
- ldxa [SFSR] %asi, %g3 ! get sync fault status register
- stxa %g0, [SFSR] %asi ! Clear out fault now
- membar #Sync ! No real reason for this XXXX
- /*
- * Here we just jump to winfixspill and let it take care of
- * saving the windows.
- */
- ba,pt %icc, winfixspill ! Continue with the winfix
- orcc %g0, %g0, %g0 ! Make sure we compare to zero
+checkalignspill:
+ /*
+ * %g1 -- current tl
+ * %g2 -- original tl
+ * %g4 -- tstate
+ * %g7 -- tt
+ */
+
+ and %g4, CWP, %g5
+ wrpr %g5, %cwp ! Go back to the original register win
+
+ /*
+ * Remember:
+ *
+ * %otherwin = 0
+ * %cansave = NWINDOWS - 2 - %canrestore
+ */
+
+ rdpr %otherwin, %g6
+ rdpr %canrestore, %g3
+ rdpr %ver, %g5
+ sub %g3, %g6, %g3 ! Calculate %canrestore - %g7
+ and %g5, CWP, %g5 ! NWINDOWS-1
+ movrlz %g3, %g0, %g3 ! Clamp at zero
+ wrpr %g0, 0, %otherwin
+ wrpr %g3, 0, %canrestore ! This is the new canrestore
+ dec %g5 ! NWINDOWS-2
+ wrpr %g5, 0, %cleanwin ! Set cleanwin to max, since we're in-kernel
+ sub %g5, %g3, %g5 ! NWINDOWS-2-%canrestore
+#ifdef xTRAPTRACE
+ wrpr %g5, 0, %cleanwin ! Force cleanwindow faults
+#endif
+ wrpr %g5, 0, %cansave
+
+ wrpr %g0, T_ALIGN, %tt ! This was an alignment fault
+ /*
+ * Now we need to determine if this was a userland store or not.
+ * Userland stores occur in anything other than the kernel spill
+ * handlers (trap type 09x).
+ */
+ and %g7, 0xff0, %g5
+ cmp %g5, 0x90
+ bz,pn %icc, slowtrap
+ nop
+ bclr TSTATE_PRIV, %g4
+ wrpr %g4, 0, %tstate
+ ba,a,pt %icc, slowtrap
+ nop
/*
* slowtrap() builds a trap frame and calls trap().
Home |
Main Index |
Thread Index |
Old Index