Commit | Line | Data |
---|---|---|
b53e906d LFT |
1 | /* |
2 | * Copyright (C) 2013-2014 Altera Corporation | |
3 | * Copyright (C) 2011-2012 Tobias Klauser <tklauser@distanz.ch> | |
4 | * Copyright (C) 2004 Microtronix Datacom Ltd | |
5 | * Copyright (C) 1991, 1992 Linus Torvalds | |
6 | * | |
7 | * This file is subject to the terms and conditions of the GNU General Public | |
8 | * License. See the file COPYING in the main directory of this archive | |
9 | * for more details. | |
10 | */ | |
11 | ||
12 | #include <linux/signal.h> | |
13 | #include <linux/errno.h> | |
14 | #include <linux/ptrace.h> | |
15 | #include <linux/uaccess.h> | |
16 | #include <linux/unistd.h> | |
17 | #include <linux/personality.h> | |
18 | #include <linux/tracehook.h> | |
19 | ||
20 | #include <asm/ucontext.h> | |
21 | #include <asm/cacheflush.h> | |
22 | ||
23 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | |
24 | ||
25 | /* | |
26 | * Do a signal return; undo the signal stack. | |
27 | * | |
28 | * Keep the return code on the stack quadword aligned! | |
29 | * That makes the cache flush below easier. | |
30 | */ | |
31 | ||
32 | struct rt_sigframe { | |
33 | struct siginfo info; | |
34 | struct ucontext uc; | |
35 | }; | |
36 | ||
37 | static inline int rt_restore_ucontext(struct pt_regs *regs, | |
38 | struct switch_stack *sw, | |
39 | struct ucontext *uc, int *pr2) | |
40 | { | |
41 | int temp; | |
92d5dd8c | 42 | unsigned long *gregs = uc->uc_mcontext.gregs; |
b53e906d LFT |
43 | int err; |
44 | ||
45 | /* Always make any pending restarted system calls return -EINTR */ | |
7587d126 | 46 | current->restart_block.fn = do_no_restart_syscall; |
b53e906d LFT |
47 | |
48 | err = __get_user(temp, &uc->uc_mcontext.version); | |
49 | if (temp != MCONTEXT_VERSION) | |
50 | goto badframe; | |
51 | /* restore passed registers */ | |
52 | err |= __get_user(regs->r1, &gregs[0]); | |
53 | err |= __get_user(regs->r2, &gregs[1]); | |
54 | err |= __get_user(regs->r3, &gregs[2]); | |
55 | err |= __get_user(regs->r4, &gregs[3]); | |
56 | err |= __get_user(regs->r5, &gregs[4]); | |
57 | err |= __get_user(regs->r6, &gregs[5]); | |
58 | err |= __get_user(regs->r7, &gregs[6]); | |
59 | err |= __get_user(regs->r8, &gregs[7]); | |
60 | err |= __get_user(regs->r9, &gregs[8]); | |
61 | err |= __get_user(regs->r10, &gregs[9]); | |
62 | err |= __get_user(regs->r11, &gregs[10]); | |
63 | err |= __get_user(regs->r12, &gregs[11]); | |
64 | err |= __get_user(regs->r13, &gregs[12]); | |
65 | err |= __get_user(regs->r14, &gregs[13]); | |
66 | err |= __get_user(regs->r15, &gregs[14]); | |
67 | err |= __get_user(sw->r16, &gregs[15]); | |
68 | err |= __get_user(sw->r17, &gregs[16]); | |
69 | err |= __get_user(sw->r18, &gregs[17]); | |
70 | err |= __get_user(sw->r19, &gregs[18]); | |
71 | err |= __get_user(sw->r20, &gregs[19]); | |
72 | err |= __get_user(sw->r21, &gregs[20]); | |
73 | err |= __get_user(sw->r22, &gregs[21]); | |
74 | err |= __get_user(sw->r23, &gregs[22]); | |
75 | /* gregs[23] is handled below */ | |
76 | err |= __get_user(sw->fp, &gregs[24]); /* Verify, should this be | |
77 | settable */ | |
78 | err |= __get_user(sw->gp, &gregs[25]); /* Verify, should this be | |
79 | settable */ | |
80 | ||
81 | err |= __get_user(temp, &gregs[26]); /* Not really necessary no user | |
82 | settable bits */ | |
83 | err |= __get_user(regs->ea, &gregs[27]); | |
84 | ||
85 | err |= __get_user(regs->ra, &gregs[23]); | |
86 | err |= __get_user(regs->sp, &gregs[28]); | |
87 | ||
88 | regs->orig_r2 = -1; /* disable syscall checks */ | |
89 | ||
90 | err |= restore_altstack(&uc->uc_stack); | |
91 | if (err) | |
92 | goto badframe; | |
93 | ||
94 | *pr2 = regs->r2; | |
95 | return err; | |
96 | ||
97 | badframe: | |
98 | return 1; | |
99 | } | |
100 | ||
101 | asmlinkage int do_rt_sigreturn(struct switch_stack *sw) | |
102 | { | |
103 | struct pt_regs *regs = (struct pt_regs *)(sw + 1); | |
104 | /* Verify, can we follow the stack back */ | |
105 | struct rt_sigframe *frame = (struct rt_sigframe *) regs->sp; | |
106 | sigset_t set; | |
107 | int rval; | |
108 | ||
109 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | |
110 | goto badframe; | |
111 | ||
112 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | |
113 | goto badframe; | |
114 | ||
115 | set_current_blocked(&set); | |
116 | ||
117 | if (rt_restore_ucontext(regs, sw, &frame->uc, &rval)) | |
118 | goto badframe; | |
119 | ||
120 | return rval; | |
121 | ||
122 | badframe: | |
123 | force_sig(SIGSEGV, current); | |
124 | return 0; | |
125 | } | |
126 | ||
127 | static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) | |
128 | { | |
129 | struct switch_stack *sw = (struct switch_stack *)regs - 1; | |
92d5dd8c | 130 | unsigned long *gregs = uc->uc_mcontext.gregs; |
b53e906d LFT |
131 | int err = 0; |
132 | ||
133 | err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); | |
134 | err |= __put_user(regs->r1, &gregs[0]); | |
135 | err |= __put_user(regs->r2, &gregs[1]); | |
136 | err |= __put_user(regs->r3, &gregs[2]); | |
137 | err |= __put_user(regs->r4, &gregs[3]); | |
138 | err |= __put_user(regs->r5, &gregs[4]); | |
139 | err |= __put_user(regs->r6, &gregs[5]); | |
140 | err |= __put_user(regs->r7, &gregs[6]); | |
141 | err |= __put_user(regs->r8, &gregs[7]); | |
142 | err |= __put_user(regs->r9, &gregs[8]); | |
143 | err |= __put_user(regs->r10, &gregs[9]); | |
144 | err |= __put_user(regs->r11, &gregs[10]); | |
145 | err |= __put_user(regs->r12, &gregs[11]); | |
146 | err |= __put_user(regs->r13, &gregs[12]); | |
147 | err |= __put_user(regs->r14, &gregs[13]); | |
148 | err |= __put_user(regs->r15, &gregs[14]); | |
149 | err |= __put_user(sw->r16, &gregs[15]); | |
150 | err |= __put_user(sw->r17, &gregs[16]); | |
151 | err |= __put_user(sw->r18, &gregs[17]); | |
152 | err |= __put_user(sw->r19, &gregs[18]); | |
153 | err |= __put_user(sw->r20, &gregs[19]); | |
154 | err |= __put_user(sw->r21, &gregs[20]); | |
155 | err |= __put_user(sw->r22, &gregs[21]); | |
156 | err |= __put_user(sw->r23, &gregs[22]); | |
157 | err |= __put_user(regs->ra, &gregs[23]); | |
158 | err |= __put_user(sw->fp, &gregs[24]); | |
159 | err |= __put_user(sw->gp, &gregs[25]); | |
160 | err |= __put_user(regs->ea, &gregs[27]); | |
161 | err |= __put_user(regs->sp, &gregs[28]); | |
162 | return err; | |
163 | } | |
164 | ||
165 | static inline void *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, | |
166 | size_t frame_size) | |
167 | { | |
168 | unsigned long usp; | |
169 | ||
170 | /* Default to using normal stack. */ | |
171 | usp = regs->sp; | |
172 | ||
173 | /* This is the X/Open sanctioned signal stack switching. */ | |
174 | usp = sigsp(usp, ksig); | |
175 | ||
176 | /* Verify, is it 32 or 64 bit aligned */ | |
177 | return (void *)((usp - frame_size) & -8UL); | |
178 | } | |
179 | ||
180 | static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, | |
181 | struct pt_regs *regs) | |
182 | { | |
183 | struct rt_sigframe *frame; | |
184 | int err = 0; | |
185 | ||
186 | frame = get_sigframe(ksig, regs, sizeof(*frame)); | |
187 | ||
188 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) | |
189 | err |= copy_siginfo_to_user(&frame->info, &ksig->info); | |
190 | ||
191 | /* Create the ucontext. */ | |
192 | err |= __put_user(0, &frame->uc.uc_flags); | |
193 | err |= __put_user(0, &frame->uc.uc_link); | |
194 | err |= __save_altstack(&frame->uc.uc_stack, regs->sp); | |
195 | err |= rt_setup_ucontext(&frame->uc, regs); | |
196 | err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | |
197 | ||
198 | if (err) | |
199 | goto give_sigsegv; | |
200 | ||
201 | /* Set up to return from userspace; jump to fixed address sigreturn | |
202 | trampoline on kuser page. */ | |
d24c8163 | 203 | regs->ra = (unsigned long) (0x1044); |
b53e906d LFT |
204 | |
205 | /* Set up registers for signal handler */ | |
206 | regs->sp = (unsigned long) frame; | |
207 | regs->r4 = (unsigned long) ksig->sig; | |
208 | regs->r5 = (unsigned long) &frame->info; | |
209 | regs->r6 = (unsigned long) &frame->uc; | |
210 | regs->ea = (unsigned long) ksig->ka.sa.sa_handler; | |
211 | return 0; | |
212 | ||
213 | give_sigsegv: | |
214 | force_sigsegv(ksig->sig, current); | |
215 | return -EFAULT; | |
216 | } | |
217 | ||
218 | /* | |
219 | * OK, we're invoking a handler | |
220 | */ | |
221 | static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) | |
222 | { | |
223 | int ret; | |
224 | sigset_t *oldset = sigmask_to_save(); | |
225 | ||
226 | /* set up the stack frame */ | |
227 | ret = setup_rt_frame(ksig, oldset, regs); | |
228 | ||
229 | signal_setup_done(ret, ksig, 0); | |
230 | } | |
231 | ||
232 | static int do_signal(struct pt_regs *regs) | |
233 | { | |
234 | unsigned int retval = 0, continue_addr = 0, restart_addr = 0; | |
235 | int restart = 0; | |
236 | struct ksignal ksig; | |
237 | ||
238 | current->thread.kregs = regs; | |
239 | ||
240 | /* | |
241 | * If we were from a system call, check for system call restarting... | |
242 | */ | |
243 | if (regs->orig_r2 >= 0) { | |
244 | continue_addr = regs->ea; | |
245 | restart_addr = continue_addr - 4; | |
246 | retval = regs->r2; | |
247 | ||
248 | /* | |
249 | * Prepare for system call restart. We do this here so that a | |
250 | * debugger will see the already changed PC. | |
251 | */ | |
252 | switch (retval) { | |
253 | case ERESTART_RESTARTBLOCK: | |
254 | restart = -2; | |
255 | case ERESTARTNOHAND: | |
256 | case ERESTARTSYS: | |
257 | case ERESTARTNOINTR: | |
258 | restart++; | |
259 | regs->r2 = regs->orig_r2; | |
260 | regs->r7 = regs->orig_r7; | |
261 | regs->ea = restart_addr; | |
262 | break; | |
263 | } | |
264 | } | |
265 | ||
266 | if (get_signal(&ksig)) { | |
267 | /* handler */ | |
268 | if (unlikely(restart && regs->ea == restart_addr)) { | |
269 | if (retval == ERESTARTNOHAND || | |
270 | retval == ERESTART_RESTARTBLOCK || | |
271 | (retval == ERESTARTSYS | |
272 | && !(ksig.ka.sa.sa_flags & SA_RESTART))) { | |
273 | regs->r2 = EINTR; | |
274 | regs->r7 = 1; | |
275 | regs->ea = continue_addr; | |
276 | } | |
277 | } | |
278 | handle_signal(&ksig, regs); | |
279 | return 0; | |
280 | } | |
281 | ||
282 | /* | |
283 | * No handler present | |
284 | */ | |
285 | if (unlikely(restart) && regs->ea == restart_addr) { | |
286 | regs->ea = continue_addr; | |
287 | regs->r2 = __NR_restart_syscall; | |
288 | } | |
289 | ||
290 | /* | |
291 | * If there's no signal to deliver, we just put the saved sigmask back. | |
292 | */ | |
293 | restore_saved_sigmask(); | |
294 | ||
295 | return restart; | |
296 | } | |
297 | ||
298 | asmlinkage int do_notify_resume(struct pt_regs *regs) | |
299 | { | |
300 | /* | |
301 | * We want the common case to go fast, which is why we may in certain | |
302 | * cases get here from kernel mode. Just return without doing anything | |
303 | * if so. | |
304 | */ | |
305 | if (!user_mode(regs)) | |
306 | return 0; | |
307 | ||
308 | if (test_thread_flag(TIF_SIGPENDING)) { | |
309 | int restart = do_signal(regs); | |
310 | ||
311 | if (unlikely(restart)) { | |
312 | /* | |
313 | * Restart without handlers. | |
314 | * Deal with it without leaving | |
315 | * the kernel space. | |
316 | */ | |
317 | return restart; | |
318 | } | |
319 | } else if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) | |
320 | tracehook_notify_resume(regs); | |
321 | ||
322 | return 0; | |
323 | } |