2 * linux/arch/unicore32/kernel/signal.c
4 * Code specific to PKUnity SoC and UniCore ISA
6 * Copyright (C) 2001-2010 GUAN Xue-tao
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 #include <linux/errno.h>
13 #include <linux/signal.h>
14 #include <linux/personality.h>
15 #include <linux/freezer.h>
16 #include <linux/uaccess.h>
17 #include <linux/tracehook.h>
18 #include <linux/elf.h>
19 #include <linux/unistd.h>
21 #include <asm/cacheflush.h>
22 #include <asm/ucontext.h>
24 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
27 * For UniCore syscalls, we encode the syscall number into the instruction.
29 #define SWI_SYS_SIGRETURN (0xff000000) /* error number for new abi */
30 #define SWI_SYS_RT_SIGRETURN (0xff000000 | (__NR_rt_sigreturn))
31 #define SWI_SYS_RESTART (0xff000000 | (__NR_restart_syscall))
33 #define KERN_SIGRETURN_CODE (KUSER_VECPAGE_BASE + 0x00000500)
34 #define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
36 const unsigned long sigreturn_codes
[3] = {
37 SWI_SYS_SIGRETURN
, SWI_SYS_RT_SIGRETURN
,
40 const unsigned long syscall_restart_code
[2] = {
41 SWI_SYS_RESTART
, /* swi __NR_restart_syscall */
42 0x69efc004, /* ldr pc, [sp], #4 */
46 * Do a signal return; undo the signal stack. These are aligned to 64-bit.
50 unsigned long retcode
[2];
58 static int restore_sigframe(struct pt_regs
*regs
, struct sigframe __user
*sf
)
63 err
= __copy_from_user(&set
, &sf
->uc
.uc_sigmask
, sizeof(set
));
65 sigdelsetmask(&set
, ~_BLOCKABLE
);
66 spin_lock_irq(¤t
->sighand
->siglock
);
67 current
->blocked
= set
;
69 spin_unlock_irq(¤t
->sighand
->siglock
);
72 err
|= __get_user(regs
->UCreg_00
, &sf
->uc
.uc_mcontext
.regs
.UCreg_00
);
73 err
|= __get_user(regs
->UCreg_01
, &sf
->uc
.uc_mcontext
.regs
.UCreg_01
);
74 err
|= __get_user(regs
->UCreg_02
, &sf
->uc
.uc_mcontext
.regs
.UCreg_02
);
75 err
|= __get_user(regs
->UCreg_03
, &sf
->uc
.uc_mcontext
.regs
.UCreg_03
);
76 err
|= __get_user(regs
->UCreg_04
, &sf
->uc
.uc_mcontext
.regs
.UCreg_04
);
77 err
|= __get_user(regs
->UCreg_05
, &sf
->uc
.uc_mcontext
.regs
.UCreg_05
);
78 err
|= __get_user(regs
->UCreg_06
, &sf
->uc
.uc_mcontext
.regs
.UCreg_06
);
79 err
|= __get_user(regs
->UCreg_07
, &sf
->uc
.uc_mcontext
.regs
.UCreg_07
);
80 err
|= __get_user(regs
->UCreg_08
, &sf
->uc
.uc_mcontext
.regs
.UCreg_08
);
81 err
|= __get_user(regs
->UCreg_09
, &sf
->uc
.uc_mcontext
.regs
.UCreg_09
);
82 err
|= __get_user(regs
->UCreg_10
, &sf
->uc
.uc_mcontext
.regs
.UCreg_10
);
83 err
|= __get_user(regs
->UCreg_11
, &sf
->uc
.uc_mcontext
.regs
.UCreg_11
);
84 err
|= __get_user(regs
->UCreg_12
, &sf
->uc
.uc_mcontext
.regs
.UCreg_12
);
85 err
|= __get_user(regs
->UCreg_13
, &sf
->uc
.uc_mcontext
.regs
.UCreg_13
);
86 err
|= __get_user(regs
->UCreg_14
, &sf
->uc
.uc_mcontext
.regs
.UCreg_14
);
87 err
|= __get_user(regs
->UCreg_15
, &sf
->uc
.uc_mcontext
.regs
.UCreg_15
);
88 err
|= __get_user(regs
->UCreg_16
, &sf
->uc
.uc_mcontext
.regs
.UCreg_16
);
89 err
|= __get_user(regs
->UCreg_17
, &sf
->uc
.uc_mcontext
.regs
.UCreg_17
);
90 err
|= __get_user(regs
->UCreg_18
, &sf
->uc
.uc_mcontext
.regs
.UCreg_18
);
91 err
|= __get_user(regs
->UCreg_19
, &sf
->uc
.uc_mcontext
.regs
.UCreg_19
);
92 err
|= __get_user(regs
->UCreg_20
, &sf
->uc
.uc_mcontext
.regs
.UCreg_20
);
93 err
|= __get_user(regs
->UCreg_21
, &sf
->uc
.uc_mcontext
.regs
.UCreg_21
);
94 err
|= __get_user(regs
->UCreg_22
, &sf
->uc
.uc_mcontext
.regs
.UCreg_22
);
95 err
|= __get_user(regs
->UCreg_23
, &sf
->uc
.uc_mcontext
.regs
.UCreg_23
);
96 err
|= __get_user(regs
->UCreg_24
, &sf
->uc
.uc_mcontext
.regs
.UCreg_24
);
97 err
|= __get_user(regs
->UCreg_25
, &sf
->uc
.uc_mcontext
.regs
.UCreg_25
);
98 err
|= __get_user(regs
->UCreg_26
, &sf
->uc
.uc_mcontext
.regs
.UCreg_26
);
99 err
|= __get_user(regs
->UCreg_fp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_fp
);
100 err
|= __get_user(regs
->UCreg_ip
, &sf
->uc
.uc_mcontext
.regs
.UCreg_ip
);
101 err
|= __get_user(regs
->UCreg_sp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_sp
);
102 err
|= __get_user(regs
->UCreg_lr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_lr
);
103 err
|= __get_user(regs
->UCreg_pc
, &sf
->uc
.uc_mcontext
.regs
.UCreg_pc
);
104 err
|= __get_user(regs
->UCreg_asr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_asr
);
106 err
|= !valid_user_regs(regs
);
111 asmlinkage
int __sys_rt_sigreturn(struct pt_regs
*regs
)
113 struct rt_sigframe __user
*frame
;
115 /* Always make any pending restarted system calls return -EINTR */
116 current_thread_info()->restart_block
.fn
= do_no_restart_syscall
;
119 * Since we stacked the signal on a 64-bit boundary,
120 * then 'sp' should be word aligned here. If it's
121 * not, then the user is trying to mess with us.
123 if (regs
->UCreg_sp
& 7)
126 frame
= (struct rt_sigframe __user
*)regs
->UCreg_sp
;
128 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
131 if (restore_sigframe(regs
, &frame
->sig
))
134 if (do_sigaltstack(&frame
->sig
.uc
.uc_stack
, NULL
, regs
->UCreg_sp
)
138 return regs
->UCreg_00
;
141 force_sig(SIGSEGV
, current
);
145 static int setup_sigframe(struct sigframe __user
*sf
, struct pt_regs
*regs
,
150 err
|= __put_user(regs
->UCreg_00
, &sf
->uc
.uc_mcontext
.regs
.UCreg_00
);
151 err
|= __put_user(regs
->UCreg_01
, &sf
->uc
.uc_mcontext
.regs
.UCreg_01
);
152 err
|= __put_user(regs
->UCreg_02
, &sf
->uc
.uc_mcontext
.regs
.UCreg_02
);
153 err
|= __put_user(regs
->UCreg_03
, &sf
->uc
.uc_mcontext
.regs
.UCreg_03
);
154 err
|= __put_user(regs
->UCreg_04
, &sf
->uc
.uc_mcontext
.regs
.UCreg_04
);
155 err
|= __put_user(regs
->UCreg_05
, &sf
->uc
.uc_mcontext
.regs
.UCreg_05
);
156 err
|= __put_user(regs
->UCreg_06
, &sf
->uc
.uc_mcontext
.regs
.UCreg_06
);
157 err
|= __put_user(regs
->UCreg_07
, &sf
->uc
.uc_mcontext
.regs
.UCreg_07
);
158 err
|= __put_user(regs
->UCreg_08
, &sf
->uc
.uc_mcontext
.regs
.UCreg_08
);
159 err
|= __put_user(regs
->UCreg_09
, &sf
->uc
.uc_mcontext
.regs
.UCreg_09
);
160 err
|= __put_user(regs
->UCreg_10
, &sf
->uc
.uc_mcontext
.regs
.UCreg_10
);
161 err
|= __put_user(regs
->UCreg_11
, &sf
->uc
.uc_mcontext
.regs
.UCreg_11
);
162 err
|= __put_user(regs
->UCreg_12
, &sf
->uc
.uc_mcontext
.regs
.UCreg_12
);
163 err
|= __put_user(regs
->UCreg_13
, &sf
->uc
.uc_mcontext
.regs
.UCreg_13
);
164 err
|= __put_user(regs
->UCreg_14
, &sf
->uc
.uc_mcontext
.regs
.UCreg_14
);
165 err
|= __put_user(regs
->UCreg_15
, &sf
->uc
.uc_mcontext
.regs
.UCreg_15
);
166 err
|= __put_user(regs
->UCreg_16
, &sf
->uc
.uc_mcontext
.regs
.UCreg_16
);
167 err
|= __put_user(regs
->UCreg_17
, &sf
->uc
.uc_mcontext
.regs
.UCreg_17
);
168 err
|= __put_user(regs
->UCreg_18
, &sf
->uc
.uc_mcontext
.regs
.UCreg_18
);
169 err
|= __put_user(regs
->UCreg_19
, &sf
->uc
.uc_mcontext
.regs
.UCreg_19
);
170 err
|= __put_user(regs
->UCreg_20
, &sf
->uc
.uc_mcontext
.regs
.UCreg_20
);
171 err
|= __put_user(regs
->UCreg_21
, &sf
->uc
.uc_mcontext
.regs
.UCreg_21
);
172 err
|= __put_user(regs
->UCreg_22
, &sf
->uc
.uc_mcontext
.regs
.UCreg_22
);
173 err
|= __put_user(regs
->UCreg_23
, &sf
->uc
.uc_mcontext
.regs
.UCreg_23
);
174 err
|= __put_user(regs
->UCreg_24
, &sf
->uc
.uc_mcontext
.regs
.UCreg_24
);
175 err
|= __put_user(regs
->UCreg_25
, &sf
->uc
.uc_mcontext
.regs
.UCreg_25
);
176 err
|= __put_user(regs
->UCreg_26
, &sf
->uc
.uc_mcontext
.regs
.UCreg_26
);
177 err
|= __put_user(regs
->UCreg_fp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_fp
);
178 err
|= __put_user(regs
->UCreg_ip
, &sf
->uc
.uc_mcontext
.regs
.UCreg_ip
);
179 err
|= __put_user(regs
->UCreg_sp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_sp
);
180 err
|= __put_user(regs
->UCreg_lr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_lr
);
181 err
|= __put_user(regs
->UCreg_pc
, &sf
->uc
.uc_mcontext
.regs
.UCreg_pc
);
182 err
|= __put_user(regs
->UCreg_asr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_asr
);
184 err
|= __put_user(current
->thread
.trap_no
,
185 &sf
->uc
.uc_mcontext
.trap_no
);
186 err
|= __put_user(current
->thread
.error_code
,
187 &sf
->uc
.uc_mcontext
.error_code
);
188 err
|= __put_user(current
->thread
.address
,
189 &sf
->uc
.uc_mcontext
.fault_address
);
190 err
|= __put_user(set
->sig
[0], &sf
->uc
.uc_mcontext
.oldmask
);
192 err
|= __copy_to_user(&sf
->uc
.uc_sigmask
, set
, sizeof(*set
));
197 static inline void __user
*get_sigframe(struct k_sigaction
*ka
,
198 struct pt_regs
*regs
, int framesize
)
200 unsigned long sp
= regs
->UCreg_sp
;
204 * This is the X/Open sanctioned signal stack switching.
206 if ((ka
->sa
.sa_flags
& SA_ONSTACK
) && !sas_ss_flags(sp
))
207 sp
= current
->sas_ss_sp
+ current
->sas_ss_size
;
210 * ATPCS B01 mandates 8-byte alignment
212 frame
= (void __user
*)((sp
- framesize
) & ~7);
215 * Check that we can actually write to the signal frame.
217 if (!access_ok(VERIFY_WRITE
, frame
, framesize
))
223 static int setup_return(struct pt_regs
*regs
, struct k_sigaction
*ka
,
224 unsigned long __user
*rc
, void __user
*frame
, int usig
)
226 unsigned long handler
= (unsigned long)ka
->sa
.sa_handler
;
227 unsigned long retcode
;
228 unsigned long asr
= regs
->UCreg_asr
& ~PSR_f
;
230 unsigned int idx
= 0;
232 if (ka
->sa
.sa_flags
& SA_SIGINFO
)
235 if (__put_user(sigreturn_codes
[idx
], rc
) ||
236 __put_user(sigreturn_codes
[idx
+1], rc
+1))
239 retcode
= KERN_SIGRETURN_CODE
+ (idx
<< 2);
241 regs
->UCreg_00
= usig
;
242 regs
->UCreg_sp
= (unsigned long)frame
;
243 regs
->UCreg_lr
= retcode
;
244 regs
->UCreg_pc
= handler
;
245 regs
->UCreg_asr
= asr
;
250 static int setup_frame(int usig
, struct k_sigaction
*ka
,
251 sigset_t
*set
, struct pt_regs
*regs
)
253 struct sigframe __user
*frame
= get_sigframe(ka
, regs
, sizeof(*frame
));
260 * Set uc.uc_flags to a value which sc.trap_no would never have.
262 err
|= __put_user(0x5ac3c35a, &frame
->uc
.uc_flags
);
264 err
|= setup_sigframe(frame
, regs
, set
);
266 err
|= setup_return(regs
, ka
, frame
->retcode
, frame
, usig
);
271 static int setup_rt_frame(int usig
, struct k_sigaction
*ka
, siginfo_t
*info
,
272 sigset_t
*set
, struct pt_regs
*regs
)
274 struct rt_sigframe __user
*frame
=
275 get_sigframe(ka
, regs
, sizeof(*frame
));
282 err
|= copy_siginfo_to_user(&frame
->info
, info
);
284 err
|= __put_user(0, &frame
->sig
.uc
.uc_flags
);
285 err
|= __put_user(NULL
, &frame
->sig
.uc
.uc_link
);
287 memset(&stack
, 0, sizeof(stack
));
288 stack
.ss_sp
= (void __user
*)current
->sas_ss_sp
;
289 stack
.ss_flags
= sas_ss_flags(regs
->UCreg_sp
);
290 stack
.ss_size
= current
->sas_ss_size
;
291 err
|= __copy_to_user(&frame
->sig
.uc
.uc_stack
, &stack
, sizeof(stack
));
293 err
|= setup_sigframe(&frame
->sig
, regs
, set
);
295 err
|= setup_return(regs
, ka
, frame
->sig
.retcode
, frame
, usig
);
299 * For realtime signals we must also set the second and third
300 * arguments for the signal handler.
302 regs
->UCreg_01
= (unsigned long)&frame
->info
;
303 regs
->UCreg_02
= (unsigned long)&frame
->sig
.uc
;
309 static inline void setup_syscall_restart(struct pt_regs
*regs
)
311 regs
->UCreg_00
= regs
->UCreg_ORIG_00
;
316 * OK, we're invoking a handler
318 static int handle_signal(unsigned long sig
, struct k_sigaction
*ka
,
319 siginfo_t
*info
, sigset_t
*oldset
,
320 struct pt_regs
*regs
, int syscall
)
322 struct thread_info
*thread
= current_thread_info();
323 struct task_struct
*tsk
= current
;
328 * If we were from a system call, check for system call restarting...
331 switch (regs
->UCreg_00
) {
332 case -ERESTART_RESTARTBLOCK
:
333 case -ERESTARTNOHAND
:
334 regs
->UCreg_00
= -EINTR
;
337 if (!(ka
->sa
.sa_flags
& SA_RESTART
)) {
338 regs
->UCreg_00
= -EINTR
;
342 case -ERESTARTNOINTR
:
343 setup_syscall_restart(regs
);
348 * translate the signal
350 if (usig
< 32 && thread
->exec_domain
351 && thread
->exec_domain
->signal_invmap
)
352 usig
= thread
->exec_domain
->signal_invmap
[usig
];
355 * Set up the stack frame
357 if (ka
->sa
.sa_flags
& SA_SIGINFO
)
358 ret
= setup_rt_frame(usig
, ka
, info
, oldset
, regs
);
360 ret
= setup_frame(usig
, ka
, oldset
, regs
);
363 * Check that the resulting registers are actually sane.
365 ret
|= !valid_user_regs(regs
);
368 force_sigsegv(sig
, tsk
);
373 * Block the signal if we were successful.
375 spin_lock_irq(&tsk
->sighand
->siglock
);
376 sigorsets(&tsk
->blocked
, &tsk
->blocked
,
378 if (!(ka
->sa
.sa_flags
& SA_NODEFER
))
379 sigaddset(&tsk
->blocked
, sig
);
381 spin_unlock_irq(&tsk
->sighand
->siglock
);
387 * Note that 'init' is a special process: it doesn't get signals it doesn't
388 * want to handle. Thus you cannot kill init even with a SIGKILL even by
391 * Note that we go through the signals twice: once to check the signals that
392 * the kernel can handle, and then we build all the user-level signal handling
393 * stack-frames in one go after that.
395 static void do_signal(struct pt_regs
*regs
, int syscall
)
397 struct k_sigaction ka
;
402 * We want the common case to go fast, which
403 * is why we may in certain cases get here from
404 * kernel mode. Just return without doing anything
407 if (!user_mode(regs
))
413 signr
= get_signal_to_deliver(&info
, &ka
, regs
, NULL
);
417 if (test_thread_flag(TIF_RESTORE_SIGMASK
))
418 oldset
= ¤t
->saved_sigmask
;
420 oldset
= ¤t
->blocked
;
421 if (handle_signal(signr
, &ka
, &info
, oldset
, regs
, syscall
)
424 * A signal was successfully delivered; the saved
425 * sigmask will have been stored in the signal frame,
426 * and will be restored by sigreturn, so we can simply
427 * clear the TIF_RESTORE_SIGMASK flag.
429 if (test_thread_flag(TIF_RESTORE_SIGMASK
))
430 clear_thread_flag(TIF_RESTORE_SIGMASK
);
437 * No signal to deliver to the process - restart the syscall.
440 if (regs
->UCreg_00
== -ERESTART_RESTARTBLOCK
) {
444 usp
= (u32 __user
*)regs
->UCreg_sp
;
446 if (put_user(regs
->UCreg_pc
, usp
) == 0) {
447 regs
->UCreg_pc
= KERN_RESTART_CODE
;
450 force_sigsegv(0, current
);
453 if (regs
->UCreg_00
== -ERESTARTNOHAND
||
454 regs
->UCreg_00
== -ERESTARTSYS
||
455 regs
->UCreg_00
== -ERESTARTNOINTR
) {
456 setup_syscall_restart(regs
);
459 /* If there's no signal to deliver, we just put the saved
462 if (test_thread_flag(TIF_RESTORE_SIGMASK
)) {
463 clear_thread_flag(TIF_RESTORE_SIGMASK
);
464 sigprocmask(SIG_SETMASK
, ¤t
->saved_sigmask
, NULL
);
469 asmlinkage
void do_notify_resume(struct pt_regs
*regs
,
470 unsigned int thread_flags
, int syscall
)
472 if (thread_flags
& _TIF_SIGPENDING
)
473 do_signal(regs
, syscall
);
475 if (thread_flags
& _TIF_NOTIFY_RESUME
) {
476 clear_thread_flag(TIF_NOTIFY_RESUME
);
477 tracehook_notify_resume(regs
);
478 if (current
->replacement_session_keyring
)
479 key_replace_session_keyring();
484 * Copy signal return handlers into the vector page, and
485 * set sigreturn to be a pointer to these.
487 void __init
early_signal_init(void)
489 memcpy((void *)kuser_vecpage_to_vectors(KERN_SIGRETURN_CODE
),
490 sigreturn_codes
, sizeof(sigreturn_codes
));
491 memcpy((void *)kuser_vecpage_to_vectors(KERN_RESTART_CODE
),
492 syscall_restart_code
, sizeof(syscall_restart_code
));
493 /* Need not to flush icache, since early_trap_init will do it last. */