diff options
| -rw-r--r-- | sys/sparc64/include/param.h | 6 | ||||
| -rw-r--r-- | sys/sparc64/include/trap.h | 1 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/exception.S | 120 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/exception.s | 120 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/machdep.c | 2 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/trap.c | 4 |
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); |
