Branch data Line data Source code
1 : : /*
2 : : * linux/arch/arm/kernel/signal.c
3 : : *
4 : : * Copyright (C) 1995-2009 Russell King
5 : : *
6 : : * This program is free software; you can redistribute it and/or modify
7 : : * it under the terms of the GNU General Public License version 2 as
8 : : * published by the Free Software Foundation.
9 : : */
10 : : #include <linux/errno.h>
11 : : #include <linux/random.h>
12 : : #include <linux/signal.h>
13 : : #include <linux/personality.h>
14 : : #include <linux/uaccess.h>
15 : : #include <linux/tracehook.h>
16 : : #include <linux/uprobes.h>
17 : :
18 : : #include <asm/elf.h>
19 : : #include <asm/cacheflush.h>
20 : : #include <asm/traps.h>
21 : : #include <asm/ucontext.h>
22 : : #include <asm/unistd.h>
23 : : #include <asm/vfp.h>
24 : :
25 : : extern const unsigned long sigreturn_codes[7];
26 : :
27 : : static unsigned long signal_return_offset;
28 : :
29 : : #ifdef CONFIG_CRUNCH
30 : : static int preserve_crunch_context(struct crunch_sigframe __user *frame)
31 : : {
32 : : char kbuf[sizeof(*frame) + 8];
33 : : struct crunch_sigframe *kframe;
34 : :
35 : : /* the crunch context must be 64 bit aligned */
36 : : kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7);
37 : : kframe->magic = CRUNCH_MAGIC;
38 : : kframe->size = CRUNCH_STORAGE_SIZE;
39 : : crunch_task_copy(current_thread_info(), &kframe->storage);
40 : : return __copy_to_user(frame, kframe, sizeof(*frame));
41 : : }
42 : :
43 : : static int restore_crunch_context(struct crunch_sigframe __user *frame)
44 : : {
45 : : char kbuf[sizeof(*frame) + 8];
46 : : struct crunch_sigframe *kframe;
47 : :
48 : : /* the crunch context must be 64 bit aligned */
49 : : kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7);
50 : : if (__copy_from_user(kframe, frame, sizeof(*frame)))
51 : : return -1;
52 : : if (kframe->magic != CRUNCH_MAGIC ||
53 : : kframe->size != CRUNCH_STORAGE_SIZE)
54 : : return -1;
55 : : crunch_task_restore(current_thread_info(), &kframe->storage);
56 : : return 0;
57 : : }
58 : : #endif
59 : :
60 : : #ifdef CONFIG_IWMMXT
61 : :
62 : : static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
63 : : {
64 : : char kbuf[sizeof(*frame) + 8];
65 : : struct iwmmxt_sigframe *kframe;
66 : :
67 : : /* the iWMMXt context must be 64 bit aligned */
68 : : kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
69 : : kframe->magic = IWMMXT_MAGIC;
70 : : kframe->size = IWMMXT_STORAGE_SIZE;
71 : : iwmmxt_task_copy(current_thread_info(), &kframe->storage);
72 : : return __copy_to_user(frame, kframe, sizeof(*frame));
73 : : }
74 : :
75 : : static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
76 : : {
77 : : char kbuf[sizeof(*frame) + 8];
78 : : struct iwmmxt_sigframe *kframe;
79 : :
80 : : /* the iWMMXt context must be 64 bit aligned */
81 : : kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
82 : : if (__copy_from_user(kframe, frame, sizeof(*frame)))
83 : : return -1;
84 : : if (kframe->magic != IWMMXT_MAGIC ||
85 : : kframe->size != IWMMXT_STORAGE_SIZE)
86 : : return -1;
87 : : iwmmxt_task_restore(current_thread_info(), &kframe->storage);
88 : : return 0;
89 : : }
90 : :
91 : : #endif
92 : :
93 : : #ifdef CONFIG_VFP
94 : :
95 : 0 : static int preserve_vfp_context(struct vfp_sigframe __user *frame)
96 : : {
97 : : const unsigned long magic = VFP_MAGIC;
98 : : const unsigned long size = VFP_STORAGE_SIZE;
99 : : int err = 0;
100 : :
101 : 1327595 : __put_user_error(magic, &frame->magic, err);
102 : 1327702 : __put_user_error(size, &frame->size, err);
103 : :
104 [ + + ]: 1327863 : if (err)
105 : : return -EFAULT;
106 : :
107 : 1327772 : return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc);
108 : : }
109 : :
110 : 0 : static int restore_vfp_context(struct vfp_sigframe __user *frame)
111 : : {
112 : : unsigned long magic;
113 : : unsigned long size;
114 : : int err = 0;
115 : :
116 : 1307495 : __get_user_error(magic, &frame->magic, err);
117 : 1307919 : __get_user_error(size, &frame->size, err);
118 : :
119 [ + + ]: 1307624 : if (err)
120 : : return -EFAULT;
121 [ + ]: 1307588 : if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
122 : : return -EINVAL;
123 : :
124 : 1307740 : return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc);
125 : : }
126 : :
127 : : #endif
128 : :
129 : : /*
130 : : * Do a signal return; undo the signal stack. These are aligned to 64-bit.
131 : : */
132 : : struct sigframe {
133 : : struct ucontext uc;
134 : : unsigned long retcode[2];
135 : : };
136 : :
137 : : struct rt_sigframe {
138 : : struct siginfo info;
139 : : struct sigframe sig;
140 : : };
141 : :
142 : 0 : static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
143 : : {
144 : : struct aux_sigframe __user *aux;
145 : : sigset_t set;
146 : : int err;
147 : :
148 : 1307877 : err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
149 [ + + ]: 1307313 : if (err == 0)
150 : 1307087 : set_current_blocked(&set);
151 : :
152 : 1308356 : __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
153 : 1308137 : __get_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err);
154 : 1308134 : __get_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err);
155 : 1308101 : __get_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err);
156 : 1308097 : __get_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err);
157 : 1308194 : __get_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err);
158 : 1307887 : __get_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err);
159 : 1308097 : __get_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err);
160 : 1307878 : __get_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err);
161 : 1307729 : __get_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err);
162 : 1307747 : __get_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err);
163 : 1307535 : __get_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err);
164 : 1307359 : __get_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err);
165 : 1307919 : __get_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err);
166 : 1307315 : __get_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err);
167 : 1307846 : __get_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err);
168 : 1307412 : __get_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err);
169 : :
170 : 1307917 : err |= !valid_user_regs(regs);
171 : :
172 : : aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
173 : : #ifdef CONFIG_CRUNCH
174 : : if (err == 0)
175 : : err |= restore_crunch_context(&aux->crunch);
176 : : #endif
177 : : #ifdef CONFIG_IWMMXT
178 : : if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
179 : : err |= restore_iwmmxt_context(&aux->iwmmxt);
180 : : #endif
181 : : #ifdef CONFIG_VFP
182 [ + ]: 1307917 : if (err == 0)
183 : 1307825 : err |= restore_vfp_context(&aux->vfp);
184 : : #endif
185 : :
186 : 0 : return err;
187 : : }
188 : :
189 : 0 : asmlinkage int sys_sigreturn(struct pt_regs *regs)
190 : : {
191 : : struct sigframe __user *frame;
192 : :
193 : : /* Always make any pending restarted system calls return -EINTR */
194 : 1304945 : current_thread_info()->restart_block.fn = do_no_restart_syscall;
195 : :
196 : : /*
197 : : * Since we stacked the signal on a 64-bit boundary,
198 : : * then 'sp' should be word aligned here. If it's
199 : : * not, then the user is trying to mess with us.
200 : : */
201 [ + ]: 1304945 : if (regs->ARM_sp & 7)
202 : : goto badframe;
203 : :
204 : 1305105 : frame = (struct sigframe __user *)regs->ARM_sp;
205 : :
206 [ + ]: 1305105 : if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
207 : : goto badframe;
208 : :
209 [ + ]: 1305193 : if (restore_sigframe(regs, frame))
210 : : goto badframe;
211 : :
212 : 1305221 : return regs->ARM_r0;
213 : :
214 : : badframe:
215 : 0 : force_sig(SIGSEGV, current);
216 : 0 : return 0;
217 : : }
218 : :
219 : 0 : asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
220 : : {
221 : : struct rt_sigframe __user *frame;
222 : :
223 : : /* Always make any pending restarted system calls return -EINTR */
224 : 2609 : current_thread_info()->restart_block.fn = do_no_restart_syscall;
225 : :
226 : : /*
227 : : * Since we stacked the signal on a 64-bit boundary,
228 : : * then 'sp' should be word aligned here. If it's
229 : : * not, then the user is trying to mess with us.
230 : : */
231 [ + - ]: 2609 : if (regs->ARM_sp & 7)
232 : : goto badframe;
233 : :
234 : 2609 : frame = (struct rt_sigframe __user *)regs->ARM_sp;
235 : :
236 [ + - ]: 2609 : if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
237 : : goto badframe;
238 : :
239 [ + - ]: 2609 : if (restore_sigframe(regs, &frame->sig))
240 : : goto badframe;
241 : :
242 [ + - ]: 2609 : if (restore_altstack(&frame->sig.uc.uc_stack))
243 : : goto badframe;
244 : :
245 : 2609 : return regs->ARM_r0;
246 : :
247 : : badframe:
248 : 0 : force_sig(SIGSEGV, current);
249 : 0 : return 0;
250 : : }
251 : :
252 : : static int
253 : 0 : setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
254 : : {
255 : : struct aux_sigframe __user *aux;
256 : : int err = 0;
257 : :
258 : 1328609 : __put_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
259 : 1327905 : __put_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err);
260 : 1327919 : __put_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err);
261 : 1327616 : __put_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err);
262 : 1328458 : __put_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err);
263 : 1328140 : __put_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err);
264 : 1328605 : __put_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err);
265 : 1327742 : __put_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err);
266 : 1327630 : __put_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err);
267 : 1328133 : __put_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err);
268 : 1328135 : __put_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err);
269 : 1327865 : __put_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err);
270 : 1327997 : __put_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err);
271 : 1328136 : __put_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err);
272 : 1328600 : __put_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err);
273 : 1327897 : __put_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err);
274 : 1328447 : __put_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err);
275 : :
276 : 1327304 : __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no, err);
277 : 1327950 : __put_user_error(current->thread.error_code, &sf->uc.uc_mcontext.error_code, err);
278 : 1327349 : __put_user_error(current->thread.address, &sf->uc.uc_mcontext.fault_address, err);
279 : 1328037 : __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);
280 : :
281 : 1327730 : err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
282 : :
283 : : aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
284 : : #ifdef CONFIG_CRUNCH
285 : : if (err == 0)
286 : : err |= preserve_crunch_context(&aux->crunch);
287 : : #endif
288 : : #ifdef CONFIG_IWMMXT
289 : : if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
290 : : err |= preserve_iwmmxt_context(&aux->iwmmxt);
291 : : #endif
292 : : #ifdef CONFIG_VFP
293 [ + + ]: 1328617 : if (err == 0)
294 : 1327600 : err |= preserve_vfp_context(&aux->vfp);
295 : : #endif
296 : 1328740 : __put_user_error(0, &aux->end_magic, err);
297 : :
298 : 1328188 : return err;
299 : : }
300 : :
301 : : static inline void __user *
302 : 1328454 : get_sigframe(struct ksignal *ksig, struct pt_regs *regs, int framesize)
303 : : {
304 : : unsigned long sp = sigsp(regs->ARM_sp, ksig);
305 : : void __user *frame;
306 : :
307 : : /*
308 : : * ATPCS B01 mandates 8-byte alignment
309 : : */
310 : 22977 : frame = (void __user *)((sp - framesize) & ~7);
311 : :
312 : : /*
313 : : * Check that we can actually write to the signal frame.
314 : : */
315 [ - + ][ # # ]: 1328454 : if (!access_ok(VERIFY_WRITE, frame, framesize))
316 : : frame = NULL;
317 : :
318 : : return frame;
319 : : }
320 : :
321 : : /*
322 : : * translate the signal
323 : : */
324 : : static inline int map_sig(int sig)
325 : : {
326 : : struct thread_info *thread = current_thread_info();
327 [ + ][ + + ]: 1327976 : if (sig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap)
[ + + ]
328 : 1326892 : sig = thread->exec_domain->signal_invmap[sig];
329 : : return sig;
330 : : }
331 : :
332 : : static int
333 : 0 : setup_return(struct pt_regs *regs, struct ksignal *ksig,
334 : : unsigned long __user *rc, void __user *frame)
335 : : {
336 : 1327976 : unsigned long handler = (unsigned long)ksig->ka.sa.sa_handler;
337 : : unsigned long retcode;
338 : : int thumb = 0;
339 : 1327976 : unsigned long cpsr = regs->ARM_cpsr & ~(PSR_f | PSR_E_BIT);
340 : :
341 : : cpsr |= PSR_ENDSTATE;
342 : :
343 : : /*
344 : : * Maybe we need to deliver a 32-bit signal to a 26-bit task.
345 : : */
346 [ - + ]: 1327976 : if (ksig->ka.sa.sa_flags & SA_THIRTYTWO)
347 : 0 : cpsr = (cpsr & ~MODE_MASK) | USR_MODE;
348 : :
349 : : #ifdef CONFIG_ARM_THUMB
350 [ + ]: 1327976 : if (elf_hwcap & HWCAP_THUMB) {
351 : : /*
352 : : * The LSB of the handler determines if we're going to
353 : : * be using THUMB or ARM mode for this signal handler.
354 : : */
355 : 1328191 : thumb = handler & 1;
356 : :
357 : : #if __LINUX_ARM_ARCH__ >= 7
358 : : /*
359 : : * Clear the If-Then Thumb-2 execution state
360 : : * ARM spec requires this to be all 000s in ARM mode
361 : : * Snapdragon S4/Krait misbehaves on a Thumb=>ARM
362 : : * signal transition without this.
363 : : */
364 : 1328191 : cpsr &= ~PSR_IT_MASK;
365 : : #endif
366 : :
367 [ + - ]: 1328191 : if (thumb) {
368 : 1328191 : cpsr |= PSR_T_BIT;
369 : : } else
370 : 0 : cpsr &= ~PSR_T_BIT;
371 : : }
372 : : #endif
373 : :
374 [ + + ]: 1327976 : if (ksig->ka.sa.sa_flags & SA_RESTORER) {
375 : 1327819 : retcode = (unsigned long)ksig->ka.sa.sa_restorer;
376 : : } else {
377 : 157 : unsigned int idx = thumb << 1;
378 : :
379 [ - + ]: 157 : if (ksig->ka.sa.sa_flags & SA_SIGINFO)
380 : 0 : idx += 3;
381 : :
382 : : /*
383 : : * Put the sigreturn code on the stack no matter which return
384 : : * mechanism we use in order to remain ABI compliant
385 : : */
386 [ + - + - ]: 314 : if (__put_user(sigreturn_codes[idx], rc) ||
387 : 157 : __put_user(sigreturn_codes[idx+1], rc+1))
388 : : return 1;
389 : :
390 : : #ifdef CONFIG_MMU
391 [ + - ]: 157 : if (cpsr & MODE32_BIT) {
392 : 157 : struct mm_struct *mm = current->mm;
393 : :
394 : : /*
395 : : * 32-bit code can use the signal return page
396 : : * except when the MPU has protected the vectors
397 : : * page from PL0
398 : : */
399 : 157 : retcode = mm->context.sigpage + signal_return_offset +
400 : 314 : (idx << 2) + thumb;
401 : : } else
402 : : #endif
403 : : {
404 : : /*
405 : : * Ensure that the instruction cache sees
406 : : * the return code written onto the stack.
407 : : */
408 : 0 : flush_icache_range((unsigned long)rc,
409 : : (unsigned long)(rc + 2));
410 : :
411 : 0 : retcode = ((unsigned long)rc) + thumb;
412 : : }
413 : : }
414 : :
415 : 2655952 : regs->ARM_r0 = map_sig(ksig->sig);
416 : 1327976 : regs->ARM_sp = (unsigned long)frame;
417 : 1327976 : regs->ARM_lr = retcode;
418 : 1327976 : regs->ARM_pc = handler;
419 : 1327976 : regs->ARM_cpsr = cpsr;
420 : :
421 : 1327976 : return 0;
422 : : }
423 : :
424 : : static int
425 : 0 : setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
426 : : {
427 : : struct sigframe __user *frame = get_sigframe(ksig, regs, sizeof(*frame));
428 : : int err = 0;
429 : :
430 [ # # ]: 0 : if (!frame)
431 : : return 1;
432 : :
433 : : /*
434 : : * Set uc.uc_flags to a value which sc.trap_no would never have.
435 : : */
436 : 1305616 : __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err);
437 : :
438 : 1304754 : err |= setup_sigframe(frame, regs, set);
439 [ + ]: 1304887 : if (err == 0)
440 : 1305508 : err = setup_return(regs, ksig, frame->retcode, frame);
441 : :
442 : 1305016 : return err;
443 : : }
444 : :
445 : : static int
446 : 0 : setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
447 : : {
448 : : struct rt_sigframe __user *frame = get_sigframe(ksig, regs, sizeof(*frame));
449 : : int err = 0;
450 : :
451 [ # # ]: 22977 : if (!frame)
452 : : return 1;
453 : :
454 : 22977 : err |= copy_siginfo_to_user(&frame->info, &ksig->info);
455 : :
456 : 22977 : __put_user_error(0, &frame->sig.uc.uc_flags, err);
457 : 22977 : __put_user_error(NULL, &frame->sig.uc.uc_link, err);
458 : :
459 : 22977 : err |= __save_altstack(&frame->sig.uc.uc_stack, regs->ARM_sp);
460 : 22977 : err |= setup_sigframe(&frame->sig, regs, set);
461 [ + - ]: 22977 : if (err == 0)
462 : 22977 : err = setup_return(regs, ksig, frame->sig.retcode, frame);
463 : :
464 [ + - ]: 22977 : if (err == 0) {
465 : : /*
466 : : * For realtime signals we must also set the second and third
467 : : * arguments for the signal handler.
468 : : * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
469 : : */
470 : 22977 : regs->ARM_r1 = (unsigned long)&frame->info;
471 : 22977 : regs->ARM_r2 = (unsigned long)&frame->sig.uc;
472 : : }
473 : :
474 : 22977 : return err;
475 : : }
476 : :
477 : : /*
478 : : * OK, we're invoking a handler
479 : : */
480 : 0 : static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
481 : : {
482 : : sigset_t *oldset = sigmask_to_save();
483 : : int ret;
484 : :
485 : : /*
486 : : * Set up the stack frame
487 : : */
488 [ + + ]: 1327599 : if (ksig->ka.sa.sa_flags & SA_SIGINFO)
489 : 22977 : ret = setup_rt_frame(ksig, oldset, regs);
490 : : else
491 : 1304622 : ret = setup_frame(ksig, oldset, regs);
492 : :
493 : : /*
494 : : * Check that the resulting registers are actually sane.
495 : : */
496 : 1327253 : ret |= !valid_user_regs(regs);
497 : :
498 : 1327253 : signal_setup_done(ret, ksig, 0);
499 : 1327556 : }
500 : :
501 : : /*
502 : : * Note that 'init' is a special process: it doesn't get signals it doesn't
503 : : * want to handle. Thus you cannot kill init even with a SIGKILL even by
504 : : * mistake.
505 : : *
506 : : * Note that we go through the signals twice: once to check the signals that
507 : : * the kernel can handle, and then we build all the user-level signal handling
508 : : * stack-frames in one go after that.
509 : : */
510 : 0 : static int do_signal(struct pt_regs *regs, int syscall)
511 : : {
512 : : unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
513 : : struct ksignal ksig;
514 : : int restart = 0;
515 : :
516 : : /*
517 : : * If we were from a system call, check for system call restarting...
518 : : */
519 [ + + ]: 1329741 : if (syscall) {
520 : 1299034 : continue_addr = regs->ARM_pc;
521 [ + + ]: 1299034 : restart_addr = continue_addr - (thumb_mode(regs) ? 2 : 4);
522 : 1299034 : retval = regs->ARM_r0;
523 : :
524 : : /*
525 : : * Prepare for system call restart. We do this here so that a
526 : : * debugger will see the already changed PSW.
527 : : */
528 [ + + + ]: 1299034 : switch (retval) {
529 : : case -ERESTART_RESTARTBLOCK:
530 : : restart -= 2;
531 : : case -ERESTARTNOHAND:
532 : : case -ERESTARTSYS:
533 : : case -ERESTARTNOINTR:
534 : 1395 : restart++;
535 : 1395 : regs->ARM_r0 = regs->ARM_ORIG_r0;
536 : 1395 : regs->ARM_pc = restart_addr;
537 : 1395 : break;
538 : : }
539 : : }
540 : :
541 : : /*
542 : : * Get the signal to deliver. When running under ptrace, at this
543 : : * point the debugger may change all our registers ...
544 : : */
545 : : /*
546 : : * Depending on the signal settings we may need to revert the
547 : : * decision to restart the system call. But skip this if a
548 : : * debugger has chosen to restart at a different PC.
549 : : */
550 [ + + ]: 1329741 : if (get_signal(&ksig)) {
551 : : /* handler */
552 [ + + ][ + - ]: 1328635 : if (unlikely(restart) && regs->ARM_pc == restart_addr) {
553 [ + + ]: 1305 : if (retval == -ERESTARTNOHAND ||
554 : 1305 : retval == -ERESTART_RESTARTBLOCK
555 [ + + ]: 21 : || (retval == -ERESTARTSYS
556 [ + + ]: 20 : && !(ksig.ka.sa.sa_flags & SA_RESTART))) {
557 : 1302 : regs->ARM_r0 = -EINTR;
558 : 1302 : regs->ARM_pc = continue_addr;
559 : : }
560 : : }
561 : 1328635 : handle_signal(&ksig, regs);
562 : : } else {
563 : : /* no handler */
564 : : restore_saved_sigmask();
565 [ + + ][ + - ]: 785 : if (unlikely(restart) && regs->ARM_pc == restart_addr) {
566 : 1 : regs->ARM_pc = continue_addr;
567 : 1 : return restart;
568 : : }
569 : : }
570 : : return 0;
571 : : }
572 : :
573 : : asmlinkage int
574 : 7880045 : do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
575 : : {
576 : : do {
577 [ + + ]: 7920401 : if (likely(thread_flags & _TIF_NEED_RESCHED)) {
578 : 3970145 : schedule();
579 : : } else {
580 [ + ]: 3950256 : if (unlikely(!user_mode(regs)))
581 : : return 0;
582 : : local_irq_enable();
583 [ + + ]: 3947776 : if (thread_flags & _TIF_SIGPENDING) {
584 : 1329722 : int restart = do_signal(regs, syscall);
585 [ + ]: 1328935 : if (unlikely(restart)) {
586 : : /*
587 : : * Restart without handlers.
588 : : * Deal with it without leaving
589 : : * the kernel space.
590 : : */
591 : : return restart;
592 : : }
593 : : syscall = 0;
594 [ - + ]: 2618054 : } else if (thread_flags & _TIF_UPROBE) {
595 : : clear_thread_flag(TIF_UPROBE);
596 : 0 : uprobe_notify_resume(regs);
597 : : } else {
598 : : clear_thread_flag(TIF_NOTIFY_RESUME);
599 : : tracehook_notify_resume(regs);
600 : : }
601 : : }
602 : : local_irq_disable();
603 : 7813249 : thread_flags = current_thread_info()->flags;
604 [ + + ]: 7813249 : } while (thread_flags & _TIF_WORK_MASK);
605 : : return 0;
606 : : }
607 : :
608 : 0 : struct page *get_signal_page(void)
609 : : {
610 : : unsigned long ptr;
611 : : unsigned offset;
612 : : struct page *page;
613 : : void *addr;
614 : :
615 : : page = alloc_pages(GFP_KERNEL, 0);
616 : :
617 [ # # ]: 0 : if (!page)
618 : : return NULL;
619 : :
620 : 0 : addr = page_address(page);
621 : :
622 : : /* Give the signal return code some randomness */
623 : 0 : offset = 0x200 + (get_random_int() & 0x7fc);
624 : 0 : signal_return_offset = offset;
625 : :
626 : : /*
627 : : * Copy signal return handlers into the vector page, and
628 : : * set sigreturn to be a pointer to these.
629 : : */
630 : 0 : memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
631 : :
632 : 0 : ptr = (unsigned long)addr + offset;
633 : 0 : flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
634 : :
635 : 0 : return page;
636 : : }
|