1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* winfixup.S: Handle cases where user stack pointer is found to be bogus. |
3 | * |
4 | * Copyright (C) 1997, 2006 David S. Miller (davem@davemloft.net) |
5 | */ |
6 | |
7 | #include <asm/asi.h> |
8 | #include <asm/head.h> |
9 | #include <asm/page.h> |
10 | #include <asm/ptrace.h> |
11 | #include <asm/processor.h> |
12 | #include <asm/spitfire.h> |
13 | #include <asm/thread_info.h> |
14 | |
15 | .text |
16 | |
17 | /* It used to be the case that these register window fault |
18 | * handlers could run via the save and restore instructions |
19 | * done by the trap entry and exit code. They now do the |
20 | * window spill/fill by hand, so that case no longer can occur. |
21 | */ |
22 | |
23 | .align 32 |
24 | fill_fixup: |
25 | TRAP_LOAD_THREAD_REG(%g6, %g1) |
26 | rdpr %tstate, %g1 |
27 | and %g1, TSTATE_CWP, %g1 |
28 | or %g4, FAULT_CODE_WINFIXUP, %g4 |
29 | stb %g4, [%g6 + TI_FAULT_CODE] |
30 | stx %g5, [%g6 + TI_FAULT_ADDR] |
31 | wrpr %g1, %cwp |
32 | ba,pt %xcc, etrap |
33 | rd %pc, %g7 |
34 | call do_sparc64_fault |
35 | add %sp, PTREGS_OFF, %o0 |
36 | ba,a,pt %xcc, rtrap |
37 | |
38 | /* Be very careful about usage of the trap globals here. |
39 | * You cannot touch %g5 as that has the fault information. |
40 | */ |
41 | spill_fixup: |
42 | spill_fixup_mna: |
43 | spill_fixup_dax: |
44 | TRAP_LOAD_THREAD_REG(%g6, %g1) |
45 | ldx [%g6 + TI_FLAGS], %g1 |
46 | andcc %sp, 0x1, %g0 |
47 | movne %icc, 0, %g1 |
48 | andcc %g1, _TIF_32BIT, %g0 |
49 | ldub [%g6 + TI_WSAVED], %g1 |
50 | sll %g1, 3, %g3 |
51 | add %g6, %g3, %g3 |
52 | stx %sp, [%g3 + TI_RWIN_SPTRS] |
53 | sll %g1, 7, %g3 |
54 | bne,pt %xcc, 1f |
55 | add %g6, %g3, %g3 |
56 | stx %l0, [%g3 + TI_REG_WINDOW + 0x00] |
57 | stx %l1, [%g3 + TI_REG_WINDOW + 0x08] |
58 | stx %l2, [%g3 + TI_REG_WINDOW + 0x10] |
59 | stx %l3, [%g3 + TI_REG_WINDOW + 0x18] |
60 | stx %l4, [%g3 + TI_REG_WINDOW + 0x20] |
61 | stx %l5, [%g3 + TI_REG_WINDOW + 0x28] |
62 | stx %l6, [%g3 + TI_REG_WINDOW + 0x30] |
63 | stx %l7, [%g3 + TI_REG_WINDOW + 0x38] |
64 | stx %i0, [%g3 + TI_REG_WINDOW + 0x40] |
65 | stx %i1, [%g3 + TI_REG_WINDOW + 0x48] |
66 | stx %i2, [%g3 + TI_REG_WINDOW + 0x50] |
67 | stx %i3, [%g3 + TI_REG_WINDOW + 0x58] |
68 | stx %i4, [%g3 + TI_REG_WINDOW + 0x60] |
69 | stx %i5, [%g3 + TI_REG_WINDOW + 0x68] |
70 | stx %i6, [%g3 + TI_REG_WINDOW + 0x70] |
71 | ba,pt %xcc, 2f |
72 | stx %i7, [%g3 + TI_REG_WINDOW + 0x78] |
73 | 1: stw %l0, [%g3 + TI_REG_WINDOW + 0x00] |
74 | stw %l1, [%g3 + TI_REG_WINDOW + 0x04] |
75 | stw %l2, [%g3 + TI_REG_WINDOW + 0x08] |
76 | stw %l3, [%g3 + TI_REG_WINDOW + 0x0c] |
77 | stw %l4, [%g3 + TI_REG_WINDOW + 0x10] |
78 | stw %l5, [%g3 + TI_REG_WINDOW + 0x14] |
79 | stw %l6, [%g3 + TI_REG_WINDOW + 0x18] |
80 | stw %l7, [%g3 + TI_REG_WINDOW + 0x1c] |
81 | stw %i0, [%g3 + TI_REG_WINDOW + 0x20] |
82 | stw %i1, [%g3 + TI_REG_WINDOW + 0x24] |
83 | stw %i2, [%g3 + TI_REG_WINDOW + 0x28] |
84 | stw %i3, [%g3 + TI_REG_WINDOW + 0x2c] |
85 | stw %i4, [%g3 + TI_REG_WINDOW + 0x30] |
86 | stw %i5, [%g3 + TI_REG_WINDOW + 0x34] |
87 | stw %i6, [%g3 + TI_REG_WINDOW + 0x38] |
88 | stw %i7, [%g3 + TI_REG_WINDOW + 0x3c] |
89 | 2: add %g1, 1, %g1 |
90 | stb %g1, [%g6 + TI_WSAVED] |
91 | rdpr %tstate, %g1 |
92 | andcc %g1, TSTATE_PRIV, %g0 |
93 | saved |
94 | be,pn %xcc, 1f |
95 | and %g1, TSTATE_CWP, %g1 |
96 | retry |
97 | 1: mov FAULT_CODE_WRITE | FAULT_CODE_DTLB | FAULT_CODE_WINFIXUP, %g4 |
98 | stb %g4, [%g6 + TI_FAULT_CODE] |
99 | stx %g5, [%g6 + TI_FAULT_ADDR] |
100 | wrpr %g1, %cwp |
101 | ba,pt %xcc, etrap |
102 | rd %pc, %g7 |
103 | call do_sparc64_fault |
104 | add %sp, PTREGS_OFF, %o0 |
105 | ba,a,pt %xcc, rtrap |
106 | |
107 | winfix_mna: |
108 | andn %g3, 0x7f, %g3 |
109 | add %g3, 0x78, %g3 |
110 | wrpr %g3, %tnpc |
111 | done |
112 | |
113 | fill_fixup_mna: |
114 | rdpr %tstate, %g1 |
115 | and %g1, TSTATE_CWP, %g1 |
116 | wrpr %g1, %cwp |
117 | ba,pt %xcc, etrap |
118 | rd %pc, %g7 |
119 | sethi %hi(tlb_type), %g1 |
120 | lduw [%g1 + %lo(tlb_type)], %g1 |
121 | cmp %g1, 3 |
122 | bne,pt %icc, 1f |
123 | add %sp, PTREGS_OFF, %o0 |
124 | mov %l4, %o2 |
125 | call sun4v_do_mna |
126 | mov %l5, %o1 |
127 | ba,a,pt %xcc, rtrap |
128 | 1: mov %l4, %o1 |
129 | mov %l5, %o2 |
130 | call mem_address_unaligned |
131 | nop |
132 | ba,a,pt %xcc, rtrap |
133 | |
134 | winfix_dax: |
135 | andn %g3, 0x7f, %g3 |
136 | add %g3, 0x74, %g3 |
137 | wrpr %g3, %tnpc |
138 | done |
139 | |
140 | fill_fixup_dax: |
141 | rdpr %tstate, %g1 |
142 | and %g1, TSTATE_CWP, %g1 |
143 | wrpr %g1, %cwp |
144 | ba,pt %xcc, etrap |
145 | rd %pc, %g7 |
146 | sethi %hi(tlb_type), %g1 |
147 | mov %l4, %o1 |
148 | lduw [%g1 + %lo(tlb_type)], %g1 |
149 | mov %l5, %o2 |
150 | cmp %g1, 3 |
151 | bne,pt %icc, 1f |
152 | add %sp, PTREGS_OFF, %o0 |
153 | call sun4v_data_access_exception |
154 | nop |
155 | ba,a,pt %xcc, rtrap |
156 | nop |
157 | 1: call spitfire_data_access_exception |
158 | nop |
159 | ba,a,pt %xcc, rtrap |
160 | nop |
161 | |