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