aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/sparc64/include/param.h6
-rw-r--r--sys/sparc64/include/trap.h1
-rw-r--r--sys/sparc64/sparc64/exception.S120
-rw-r--r--sys/sparc64/sparc64/exception.s120
-rw-r--r--sys/sparc64/sparc64/machdep.c2
-rw-r--r--sys/sparc64/sparc64/trap.c4
6 files changed, 244 insertions, 9 deletions
diff --git a/sys/sparc64/include/param.h b/sys/sparc64/include/param.h
index 60fd0bd2aa63..d93616625906 100644
--- a/sys/sparc64/include/param.h
+++ b/sys/sparc64/include/param.h
@@ -121,8 +121,10 @@
#define MAXPHYS (128 * 1024) /* max raw I/O transfer size */
#define MAXDUMPPGS (DFLTPHYS/PAGE_SIZE)
-#define KSTACK_PAGES 4 /* pages of kernel stack (with pcb) */
-#define UAREA_PAGES 1 /* pages of user area */
+#define KSTACK_PAGES 4 /* pages of kernel stack (with pcb) */
+#define UAREA_PAGES 1 /* pages of user area */
+
+#define PANIC_STACK_PAGES 1
#define KSTACK_GUARD /* compile in kstack guard page */
#define KSTACK_GUARD_PAGES 1
diff --git a/sys/sparc64/include/trap.h b/sys/sparc64/include/trap.h
index a730bb112483..0826d7c96022 100644
--- a/sys/sparc64/include/trap.h
+++ b/sys/sparc64/include/trap.h
@@ -83,6 +83,7 @@
#define T_SYSCALL 48
#define T_RSTRWP_PHYS 49
#define T_RSTRWP_VIRT 50
+#define T_KSTACK_FAULT 51
#define T_KERNEL 64
diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S
index 6648f1dd9ab8..cb2d272e3ad3 100644
--- a/sys/sparc64/sparc64/exception.S
+++ b/sys/sparc64/sparc64/exception.S
@@ -144,6 +144,88 @@
#define ERRATUM50(reg) mov reg, reg
+#define KSTACK_SLOP 1024
+
+#define KSTACK_CHECK \
+ dec 16, ASP_REG ; \
+ stx %g1, [ASP_REG + 0] ; \
+ stx %g2, [ASP_REG + 8] ; \
+ add %sp, SPOFF, %g1 ; \
+ andcc %g1, (1 << PTR_SHIFT) - 1, %g0 ; \
+ bnz,a %xcc, tl1_kstack_fault ; \
+ inc 16, ASP_REG ; \
+ ldx [PCPU(CURTHREAD)], %g2 ; \
+ ldx [%g2 + TD_KSTACK], %g2 ; \
+ add %g2, KSTACK_SLOP, %g2 ; \
+ subcc %g1, %g2, %g1 ; \
+ ble,a %xcc, tl1_kstack_fault ; \
+ inc 16, ASP_REG ; \
+ set KSTACK_PAGES * PAGE_SIZE, %g2 ; \
+ cmp %g1, %g2 ; \
+ bgt,a %xcc, tl1_kstack_fault ; \
+ inc 16, ASP_REG ; \
+ ldx [ASP_REG + 8], %g2 ; \
+ ldx [ASP_REG + 0], %g1 ; \
+ inc 16, ASP_REG
+
+ENTRY(tl1_kstack_fault)
+ rdpr %tl, %g1
+ cmp %g1, 3
+ beq %xcc, 1f
+ nop
+ blt %xcc, 2f
+ nop
+ sir
+
+1:
+#if KTR_COMPILE & KTR_TRAP
+ CATR(KTR_TRAP, "tl1_kstack_fault: tl=%#lx tpc=%#lx tnpc=%#lx"
+ , %g1, %g2, %g3, 7, 8, 9)
+ rdpr %tl, %g2
+ stx %g2, [%g1 + KTR_PARM1]
+ rdpr %tpc, %g2
+ stx %g2, [%g1 + KTR_PARM1]
+ rdpr %tnpc, %g2
+ stx %g2, [%g1 + KTR_PARM1]
+9:
+#endif
+ wrpr %g0, 2, %tl
+
+2:
+#if KTR_COMPILE & KTR_TRAP
+ CATR(KTR_TRAP,
+ "tl1_kstack_fault: sp=%#lx ks=%#lx cr=%#lx cs=%#lx ow=%#lx ws=%#lx"
+ , %g1, %g2, %g3, 7, 8, 9)
+ add %sp, SPOFF, %g2
+ stx %g2, [%g1 + KTR_PARM1]
+ ldx [PCPU(CURTHREAD)], %g2
+ ldx [%g2 + TD_KSTACK], %g2
+ stx %g2, [%g1 + KTR_PARM2]
+ rdpr %canrestore, %g2
+ stx %g2, [%g1 + KTR_PARM3]
+ rdpr %cansave, %g2
+ stx %g2, [%g1 + KTR_PARM4]
+ rdpr %otherwin, %g2
+ stx %g2, [%g1 + KTR_PARM5]
+ rdpr %wstate, %g2
+ stx %g2, [%g1 + KTR_PARM6]
+9:
+#endif
+
+ wrpr %g0, 0, %canrestore
+ wrpr %g0, 6, %cansave
+ wrpr %g0, 0, %otherwin
+ wrpr %g0, WSTATE_KERNEL, %wstate
+
+ SET(panic_stack + PANIC_STACK_PAGES * PAGE_SIZE, %g2, %g1)
+ sub %g1, SPOFF + CCFSZ, %sp
+ clr %fp
+
+ rdpr %pil, %o1
+ b %xcc, tl1_trap
+ mov T_KSTACK_FAULT | T_KERNEL, %o0
+END(tl1_kstack_fault)
+
/*
* Magic to resume from a spill or fill trap. If we get an alignment or an
* mmu fault during a spill or a fill, this macro will detect the fault and
@@ -247,7 +329,8 @@
* Game over if the window operation fails.
*/
#define RSF_FATAL(type) \
- sir type ; \
+ b %xcc, rsf_fatal ; \
+ mov type, %g2 ; \
.align 16
/*
@@ -269,6 +352,21 @@
nop ; \
.align 16
+ENTRY(rsf_fatal)
+#if KTR_COMPILE & KTR_TRAP
+ CATR(KTR_TRAP, "rsf_fatal: bad window trap tt=%#lx type=%#lx"
+ , %g1, %g3, %g4, 7, 8, 9)
+ rdpr %tt, %g3
+ stx %g3, [%g1 + KTR_PARM1]
+ stx %g2, [%g1 + KTR_PARM2]
+9:
+#endif
+
+ KSTACK_CHECK
+
+ sir
+END(rsf_fatal)
+
.comm intrnames, NIV * 8
.comm eintrnames, 0
@@ -1290,6 +1388,23 @@ END(intr_enqueue)
*/
2: wrpr %g0, PSTATE_ALT, %pstate
+ b,a %xcc, tl1_dmmu_miss_trap
+ nop
+ .align 128
+ .endm
+
+ENTRY(tl1_dmmu_miss_trap)
+#if KTR_COMPILE & KTR_TRAP
+ CATR(KTR_TRAP, "tl1_dmmu_miss_trap: tar=%#lx"
+ , %g1, %g2, %g3, 7, 8, 9)
+ mov AA_DMMU_TAR, %g2
+ ldxa [%g2] ASI_DMMU, %g2
+ stx %g2, [%g1 + KTR_PARM1]
+9:
+#endif
+
+ KSTACK_CHECK
+
wr %g0, ASI_DMMU, %asi
ldxa [%g0 + AA_DMMU_TAR] %asi, %g3
@@ -1298,8 +1413,7 @@ END(intr_enqueue)
mov %g3, %o3
b %xcc, tl1_trap
mov T_DATA_MISS | T_KERNEL, %o0
- .align 128
- .endm
+END(tl1_dmmu_miss_trap)
ENTRY(tl1_dmmu_miss_user)
/*
diff --git a/sys/sparc64/sparc64/exception.s b/sys/sparc64/sparc64/exception.s
index 6648f1dd9ab8..cb2d272e3ad3 100644
--- a/sys/sparc64/sparc64/exception.s
+++ b/sys/sparc64/sparc64/exception.s
@@ -144,6 +144,88 @@
#define ERRATUM50(reg) mov reg, reg
+#define KSTACK_SLOP 1024
+
+#define KSTACK_CHECK \
+ dec 16, ASP_REG ; \
+ stx %g1, [ASP_REG + 0] ; \
+ stx %g2, [ASP_REG + 8] ; \
+ add %sp, SPOFF, %g1 ; \
+ andcc %g1, (1 << PTR_SHIFT) - 1, %g0 ; \
+ bnz,a %xcc, tl1_kstack_fault ; \
+ inc 16, ASP_REG ; \
+ ldx [PCPU(CURTHREAD)], %g2 ; \
+ ldx [%g2 + TD_KSTACK], %g2 ; \
+ add %g2, KSTACK_SLOP, %g2 ; \
+ subcc %g1, %g2, %g1 ; \
+ ble,a %xcc, tl1_kstack_fault ; \
+ inc 16, ASP_REG ; \
+ set KSTACK_PAGES * PAGE_SIZE, %g2 ; \
+ cmp %g1, %g2 ; \
+ bgt,a %xcc, tl1_kstack_fault ; \
+ inc 16, ASP_REG ; \
+ ldx [ASP_REG + 8], %g2 ; \
+ ldx [ASP_REG + 0], %g1 ; \
+ inc 16, ASP_REG
+
+ENTRY(tl1_kstack_fault)
+ rdpr %tl, %g1
+ cmp %g1, 3
+ beq %xcc, 1f
+ nop
+ blt %xcc, 2f
+ nop
+ sir
+
+1:
+#if KTR_COMPILE & KTR_TRAP
+ CATR(KTR_TRAP, "tl1_kstack_fault: tl=%#lx tpc=%#lx tnpc=%#lx"
+ , %g1, %g2, %g3, 7, 8, 9)
+ rdpr %tl, %g2
+ stx %g2, [%g1 + KTR_PARM1]
+ rdpr %tpc, %g2
+ stx %g2, [%g1 + KTR_PARM1]
+ rdpr %tnpc, %g2
+ stx %g2, [%g1 + KTR_PARM1]
+9:
+#endif
+ wrpr %g0, 2, %tl
+
+2:
+#if KTR_COMPILE & KTR_TRAP
+ CATR(KTR_TRAP,
+ "tl1_kstack_fault: sp=%#lx ks=%#lx cr=%#lx cs=%#lx ow=%#lx ws=%#lx"
+ , %g1, %g2, %g3, 7, 8, 9)
+ add %sp, SPOFF, %g2
+ stx %g2, [%g1 + KTR_PARM1]
+ ldx [PCPU(CURTHREAD)], %g2
+ ldx [%g2 + TD_KSTACK], %g2
+ stx %g2, [%g1 + KTR_PARM2]
+ rdpr %canrestore, %g2
+ stx %g2, [%g1 + KTR_PARM3]
+ rdpr %cansave, %g2
+ stx %g2, [%g1 + KTR_PARM4]
+ rdpr %otherwin, %g2
+ stx %g2, [%g1 + KTR_PARM5]
+ rdpr %wstate, %g2
+ stx %g2, [%g1 + KTR_PARM6]
+9:
+#endif
+
+ wrpr %g0, 0, %canrestore
+ wrpr %g0, 6, %cansave
+ wrpr %g0, 0, %otherwin
+ wrpr %g0, WSTATE_KERNEL, %wstate
+
+ SET(panic_stack + PANIC_STACK_PAGES * PAGE_SIZE, %g2, %g1)
+ sub %g1, SPOFF + CCFSZ, %sp
+ clr %fp
+
+ rdpr %pil, %o1
+ b %xcc, tl1_trap
+ mov T_KSTACK_FAULT | T_KERNEL, %o0
+END(tl1_kstack_fault)
+
/*
* Magic to resume from a spill or fill trap. If we get an alignment or an
* mmu fault during a spill or a fill, this macro will detect the fault and
@@ -247,7 +329,8 @@
* Game over if the window operation fails.
*/
#define RSF_FATAL(type) \
- sir type ; \
+ b %xcc, rsf_fatal ; \
+ mov type, %g2 ; \
.align 16
/*
@@ -269,6 +352,21 @@
nop ; \
.align 16
+ENTRY(rsf_fatal)
+#if KTR_COMPILE & KTR_TRAP
+ CATR(KTR_TRAP, "rsf_fatal: bad window trap tt=%#lx type=%#lx"
+ , %g1, %g3, %g4, 7, 8, 9)
+ rdpr %tt, %g3
+ stx %g3, [%g1 + KTR_PARM1]
+ stx %g2, [%g1 + KTR_PARM2]
+9:
+#endif
+
+ KSTACK_CHECK
+
+ sir
+END(rsf_fatal)
+
.comm intrnames, NIV * 8
.comm eintrnames, 0
@@ -1290,6 +1388,23 @@ END(intr_enqueue)
*/
2: wrpr %g0, PSTATE_ALT, %pstate
+ b,a %xcc, tl1_dmmu_miss_trap
+ nop
+ .align 128
+ .endm
+
+ENTRY(tl1_dmmu_miss_trap)
+#if KTR_COMPILE & KTR_TRAP
+ CATR(KTR_TRAP, "tl1_dmmu_miss_trap: tar=%#lx"
+ , %g1, %g2, %g3, 7, 8, 9)
+ mov AA_DMMU_TAR, %g2
+ ldxa [%g2] ASI_DMMU, %g2
+ stx %g2, [%g1 + KTR_PARM1]
+9:
+#endif
+
+ KSTACK_CHECK
+
wr %g0, ASI_DMMU, %asi
ldxa [%g0 + AA_DMMU_TAR] %asi, %g3
@@ -1298,8 +1413,7 @@ END(intr_enqueue)
mov %g3, %o3
b %xcc, tl1_trap
mov T_DATA_MISS | T_KERNEL, %o0
- .align 128
- .endm
+END(tl1_dmmu_miss_trap)
ENTRY(tl1_dmmu_miss_user)
/*
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 1f7584e7b1ad..daed40057965 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -131,6 +131,8 @@ static struct trapframe frame0;
struct user *proc0uarea;
vm_offset_t proc0kstack;
+char panic_stack[PANIC_STACK_PAGES * PAGE_SIZE];
+
struct kva_md_info kmi;
u_long ofw_vec;
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index 1d9780d2795c..f52ac58b39df 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -139,6 +139,7 @@ const char *trap_msg[] = {
"syscall",
"restore physical watchpoint",
"restore virtual watchpoint",
+ "kernel stack fault",
};
void
@@ -294,6 +295,7 @@ if ((type & ~T_KERNEL) != T_BREAKPOINT)
*/
#ifdef DDB
case T_BREAKPOINT | T_KERNEL:
+ case T_KSTACK_FAULT | T_KERNEL:
if (kdb_trap(tf) != 0)
goto out;
break;
@@ -338,7 +340,7 @@ if ((type & ~T_KERNEL) != T_BREAKPOINT)
tf->tf_tstate &= ~TSTATE_IE;
wrpr(pstate, rdpr(pstate), PSTATE_IE);
PCPU_SET(wp_insn, *((u_int *)tf->tf_tnpc));
- *((u_int *)tf->tf_tnpc) = 0x91d03003; /* ta %xcc, 2 */
+ *((u_int *)tf->tf_tnpc) = 0x91d03003; /* ta %xcc, 3 */
flush(tf->tf_tnpc);
PCPU_SET(wp_va, watch_virt_get(&mask));
PCPU_SET(wp_mask, mask);