summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2002-02-23 18:55:21 +0000
committerjake <jake@FreeBSD.org>2002-02-23 18:55:21 +0000
commit3ed9f58376b0b0def37c9ab340dfc39dc4b186ab (patch)
tree4b7e05c8291d32289a72008a04f2f6f69c3112f2
parentfc548e14d2eaded91c0c28560fd89922d4defee6 (diff)
downloadFreeBSD-src-3ed9f58376b0b0def37c9ab340dfc39dc4b186ab.zip
FreeBSD-src-3ed9f58376b0b0def37c9ab340dfc39dc4b186ab.tar.gz
1. Setup the user stack pointer before returning to a user trap handler.
If we don't do this here there's a 1 instruction race where an interrupt could come in and crash the user process due to having no stack. 2. Pass %fsr to the user trap handler in %l4. Since %fsr can only be loaded from or stored to memory, we need to do some contortions and temporarily save it to the alternate global stack. 3. Reload the pcb and pcpu registers for traps in kernel mode, for sanity. Submitted by: tmm (1, 2)
-rw-r--r--sys/sparc64/sparc64/exception.S32
-rw-r--r--sys/sparc64/sparc64/exception.s32
2 files changed, 64 insertions, 0 deletions
diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S
index 92319ce..1694250 100644
--- a/sys/sparc64/sparc64/exception.S
+++ b/sys/sparc64/sparc64/exception.S
@@ -2035,6 +2035,22 @@ ENTRY(tl0_trap)
rdpr %cwp, %l6
wrpr %l6, %l7, %tstate
+ sub %fp, CCFSZ, %sp
+
+ /*
+ * Need to store %fsr to pass it to the user trap handler. Otherwise,
+ * the ftt field might be zeoed out in a store in another trap or
+ * interrupt. Use the temporary stack for that.
+ */
+ rd %fprs, %l3
+ or %l3, FPRS_FEF, %l4
+ wr %l4, 0, %fprs
+ dec 8, ASP_REG
+ stx %fsr, [ASP_REG]
+ ldx [ASP_REG], %l4
+ inc 8, ASP_REG
+ wr %l3, 0, %fprs
+
mov %l0, %l5
mov %l1, %l6
mov %l2, %l7
@@ -2468,12 +2484,20 @@ ENTRY(tl1_trap)
stx %i6, [%sp + SPOFF + CCFSZ + TF_O6]
stx %i7, [%sp + SPOFF + CCFSZ + TF_O7]
+ mov PCB_REG, %l4
+ mov PCPU_REG, %l5
+ wrpr %g0, PSTATE_NORMAL, %pstate
+
stx %g1, [%sp + SPOFF + CCFSZ + TF_G1]
stx %g2, [%sp + SPOFF + CCFSZ + TF_G2]
stx %g3, [%sp + SPOFF + CCFSZ + TF_G3]
stx %g4, [%sp + SPOFF + CCFSZ + TF_G4]
stx %g5, [%sp + SPOFF + CCFSZ + TF_G5]
+ mov %l4, PCB_REG
+ mov %l5, PCPU_REG
+ wrpr %g0, PSTATE_KERNEL, %pstate
+
call trap
add %sp, CCFSZ + SPOFF, %o0
@@ -2562,12 +2586,20 @@ ENTRY(tl1_intr)
stx %i6, [%sp + SPOFF + CCFSZ + TF_O6]
stx %i7, [%sp + SPOFF + CCFSZ + TF_O7]
+ mov PCB_REG, %l4
+ mov PCPU_REG, %l5
+ wrpr %g0, PSTATE_NORMAL, %pstate
+
stx %g1, [%sp + SPOFF + CCFSZ + TF_G1]
stx %g2, [%sp + SPOFF + CCFSZ + TF_G2]
stx %g3, [%sp + SPOFF + CCFSZ + TF_G3]
stx %g4, [%sp + SPOFF + CCFSZ + TF_G4]
stx %g5, [%sp + SPOFF + CCFSZ + TF_G5]
+ mov %l4, PCB_REG
+ mov %l5, PCPU_REG
+ wrpr %g0, PSTATE_KERNEL, %pstate
+
call critical_enter
nop
diff --git a/sys/sparc64/sparc64/exception.s b/sys/sparc64/sparc64/exception.s
index 92319ce..1694250 100644
--- a/sys/sparc64/sparc64/exception.s
+++ b/sys/sparc64/sparc64/exception.s
@@ -2035,6 +2035,22 @@ ENTRY(tl0_trap)
rdpr %cwp, %l6
wrpr %l6, %l7, %tstate
+ sub %fp, CCFSZ, %sp
+
+ /*
+ * Need to store %fsr to pass it to the user trap handler. Otherwise,
+ * the ftt field might be zeoed out in a store in another trap or
+ * interrupt. Use the temporary stack for that.
+ */
+ rd %fprs, %l3
+ or %l3, FPRS_FEF, %l4
+ wr %l4, 0, %fprs
+ dec 8, ASP_REG
+ stx %fsr, [ASP_REG]
+ ldx [ASP_REG], %l4
+ inc 8, ASP_REG
+ wr %l3, 0, %fprs
+
mov %l0, %l5
mov %l1, %l6
mov %l2, %l7
@@ -2468,12 +2484,20 @@ ENTRY(tl1_trap)
stx %i6, [%sp + SPOFF + CCFSZ + TF_O6]
stx %i7, [%sp + SPOFF + CCFSZ + TF_O7]
+ mov PCB_REG, %l4
+ mov PCPU_REG, %l5
+ wrpr %g0, PSTATE_NORMAL, %pstate
+
stx %g1, [%sp + SPOFF + CCFSZ + TF_G1]
stx %g2, [%sp + SPOFF + CCFSZ + TF_G2]
stx %g3, [%sp + SPOFF + CCFSZ + TF_G3]
stx %g4, [%sp + SPOFF + CCFSZ + TF_G4]
stx %g5, [%sp + SPOFF + CCFSZ + TF_G5]
+ mov %l4, PCB_REG
+ mov %l5, PCPU_REG
+ wrpr %g0, PSTATE_KERNEL, %pstate
+
call trap
add %sp, CCFSZ + SPOFF, %o0
@@ -2562,12 +2586,20 @@ ENTRY(tl1_intr)
stx %i6, [%sp + SPOFF + CCFSZ + TF_O6]
stx %i7, [%sp + SPOFF + CCFSZ + TF_O7]
+ mov PCB_REG, %l4
+ mov PCPU_REG, %l5
+ wrpr %g0, PSTATE_NORMAL, %pstate
+
stx %g1, [%sp + SPOFF + CCFSZ + TF_G1]
stx %g2, [%sp + SPOFF + CCFSZ + TF_G2]
stx %g3, [%sp + SPOFF + CCFSZ + TF_G3]
stx %g4, [%sp + SPOFF + CCFSZ + TF_G4]
stx %g5, [%sp + SPOFF + CCFSZ + TF_G5]
+ mov %l4, PCB_REG
+ mov %l5, PCPU_REG
+ wrpr %g0, PSTATE_KERNEL, %pstate
+
call critical_enter
nop
OpenPOWER on IntegriCloud