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 set_current_blocked(&set
);
69 err
|= __get_user(regs
->UCreg_00
, &sf
->uc
.uc_mcontext
.regs
.UCreg_00
);
70 err
|= __get_user(regs
->UCreg_01
, &sf
->uc
.uc_mcontext
.regs
.UCreg_01
);
71 err
|= __get_user(regs
->UCreg_02
, &sf
->uc
.uc_mcontext
.regs
.UCreg_02
);
72 err
|= __get_user(regs
->UCreg_03
, &sf
->uc
.uc_mcontext
.regs
.UCreg_03
);
73 err
|= __get_user(regs
->UCreg_04
, &sf
->uc
.uc_mcontext
.regs
.UCreg_04
);
74 err
|= __get_user(regs
->UCreg_05
, &sf
->uc
.uc_mcontext
.regs
.UCreg_05
);
75 err
|= __get_user(regs
->UCreg_06
, &sf
->uc
.uc_mcontext
.regs
.UCreg_06
);
76 err
|= __get_user(regs
->UCreg_07
, &sf
->uc
.uc_mcontext
.regs
.UCreg_07
);
77 err
|= __get_user(regs
->UCreg_08
, &sf
->uc
.uc_mcontext
.regs
.UCreg_08
);
78 err
|= __get_user(regs
->UCreg_09
, &sf
->uc
.uc_mcontext
.regs
.UCreg_09
);
79 err
|= __get_user(regs
->UCreg_10
, &sf
->uc
.uc_mcontext
.regs
.UCreg_10
);
80 err
|= __get_user(regs
->UCreg_11
, &sf
->uc
.uc_mcontext
.regs
.UCreg_11
);
81 err
|= __get_user(regs
->UCreg_12
, &sf
->uc
.uc_mcontext
.regs
.UCreg_12
);
82 err
|= __get_user(regs
->UCreg_13
, &sf
->uc
.uc_mcontext
.regs
.UCreg_13
);
83 err
|= __get_user(regs
->UCreg_14
, &sf
->uc
.uc_mcontext
.regs
.UCreg_14
);
84 err
|= __get_user(regs
->UCreg_15
, &sf
->uc
.uc_mcontext
.regs
.UCreg_15
);
85 err
|= __get_user(regs
->UCreg_16
, &sf
->uc
.uc_mcontext
.regs
.UCreg_16
);
86 err
|= __get_user(regs
->UCreg_17
, &sf
->uc
.uc_mcontext
.regs
.UCreg_17
);
87 err
|= __get_user(regs
->UCreg_18
, &sf
->uc
.uc_mcontext
.regs
.UCreg_18
);
88 err
|= __get_user(regs
->UCreg_19
, &sf
->uc
.uc_mcontext
.regs
.UCreg_19
);
89 err
|= __get_user(regs
->UCreg_20
, &sf
->uc
.uc_mcontext
.regs
.UCreg_20
);
90 err
|= __get_user(regs
->UCreg_21
, &sf
->uc
.uc_mcontext
.regs
.UCreg_21
);
91 err
|= __get_user(regs
->UCreg_22
, &sf
->uc
.uc_mcontext
.regs
.UCreg_22
);
92 err
|= __get_user(regs
->UCreg_23
, &sf
->uc
.uc_mcontext
.regs
.UCreg_23
);
93 err
|= __get_user(regs
->UCreg_24
, &sf
->uc
.uc_mcontext
.regs
.UCreg_24
);
94 err
|= __get_user(regs
->UCreg_25
, &sf
->uc
.uc_mcontext
.regs
.UCreg_25
);
95 err
|= __get_user(regs
->UCreg_26
, &sf
->uc
.uc_mcontext
.regs
.UCreg_26
);
96 err
|= __get_user(regs
->UCreg_fp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_fp
);
97 err
|= __get_user(regs
->UCreg_ip
, &sf
->uc
.uc_mcontext
.regs
.UCreg_ip
);
98 err
|= __get_user(regs
->UCreg_sp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_sp
);
99 err
|= __get_user(regs
->UCreg_lr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_lr
);
100 err
|= __get_user(regs
->UCreg_pc
, &sf
->uc
.uc_mcontext
.regs
.UCreg_pc
);
101 err
|= __get_user(regs
->UCreg_asr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_asr
);
103 err
|= !valid_user_regs(regs
);
108 asmlinkage
int __sys_rt_sigreturn(struct pt_regs
*regs
)
110 struct rt_sigframe __user
*frame
;
112 /* Always make any pending restarted system calls return -EINTR */
113 current_thread_info()->restart_block
.fn
= do_no_restart_syscall
;
116 * Since we stacked the signal on a 64-bit boundary,
117 * then 'sp' should be word aligned here. If it's
118 * not, then the user is trying to mess with us.
120 if (regs
->UCreg_sp
& 7)
123 frame
= (struct rt_sigframe __user
*)regs
->UCreg_sp
;
125 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
128 if (restore_sigframe(regs
, &frame
->sig
))
131 if (do_sigaltstack(&frame
->sig
.uc
.uc_stack
, NULL
, regs
->UCreg_sp
)
135 return regs
->UCreg_00
;
138 force_sig(SIGSEGV
, current
);
142 static int setup_sigframe(struct sigframe __user
*sf
, struct pt_regs
*regs
,
147 err
|= __put_user(regs
->UCreg_00
, &sf
->uc
.uc_mcontext
.regs
.UCreg_00
);
148 err
|= __put_user(regs
->UCreg_01
, &sf
->uc
.uc_mcontext
.regs
.UCreg_01
);
149 err
|= __put_user(regs
->UCreg_02
, &sf
->uc
.uc_mcontext
.regs
.UCreg_02
);
150 err
|= __put_user(regs
->UCreg_03
, &sf
->uc
.uc_mcontext
.regs
.UCreg_03
);
151 err
|= __put_user(regs
->UCreg_04
, &sf
->uc
.uc_mcontext
.regs
.UCreg_04
);
152 err
|= __put_user(regs
->UCreg_05
, &sf
->uc
.uc_mcontext
.regs
.UCreg_05
);
153 err
|= __put_user(regs
->UCreg_06
, &sf
->uc
.uc_mcontext
.regs
.UCreg_06
);
154 err
|= __put_user(regs
->UCreg_07
, &sf
->uc
.uc_mcontext
.regs
.UCreg_07
);
155 err
|= __put_user(regs
->UCreg_08
, &sf
->uc
.uc_mcontext
.regs
.UCreg_08
);
156 err
|= __put_user(regs
->UCreg_09
, &sf
->uc
.uc_mcontext
.regs
.UCreg_09
);
157 err
|= __put_user(regs
->UCreg_10
, &sf
->uc
.uc_mcontext
.regs
.UCreg_10
);
158 err
|= __put_user(regs
->UCreg_11
, &sf
->uc
.uc_mcontext
.regs
.UCreg_11
);
159 err
|= __put_user(regs
->UCreg_12
, &sf
->uc
.uc_mcontext
.regs
.UCreg_12
);
160 err
|= __put_user(regs
->UCreg_13
, &sf
->uc
.uc_mcontext
.regs
.UCreg_13
);
161 err
|= __put_user(regs
->UCreg_14
, &sf
->uc
.uc_mcontext
.regs
.UCreg_14
);
162 err
|= __put_user(regs
->UCreg_15
, &sf
->uc
.uc_mcontext
.regs
.UCreg_15
);
163 err
|= __put_user(regs
->UCreg_16
, &sf
->uc
.uc_mcontext
.regs
.UCreg_16
);
164 err
|= __put_user(regs
->UCreg_17
, &sf
->uc
.uc_mcontext
.regs
.UCreg_17
);
165 err
|= __put_user(regs
->UCreg_18
, &sf
->uc
.uc_mcontext
.regs
.UCreg_18
);
166 err
|= __put_user(regs
->UCreg_19
, &sf
->uc
.uc_mcontext
.regs
.UCreg_19
);
167 err
|= __put_user(regs
->UCreg_20
, &sf
->uc
.uc_mcontext
.regs
.UCreg_20
);
168 err
|= __put_user(regs
->UCreg_21
, &sf
->uc
.uc_mcontext
.regs
.UCreg_21
);
169 err
|= __put_user(regs
->UCreg_22
, &sf
->uc
.uc_mcontext
.regs
.UCreg_22
);
170 err
|= __put_user(regs
->UCreg_23
, &sf
->uc
.uc_mcontext
.regs
.UCreg_23
);
171 err
|= __put_user(regs
->UCreg_24
, &sf
->uc
.uc_mcontext
.regs
.UCreg_24
);
172 err
|= __put_user(regs
->UCreg_25
, &sf
->uc
.uc_mcontext
.regs
.UCreg_25
);
173 err
|= __put_user(regs
->UCreg_26
, &sf
->uc
.uc_mcontext
.regs
.UCreg_26
);
174 err
|= __put_user(regs
->UCreg_fp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_fp
);
175 err
|= __put_user(regs
->UCreg_ip
, &sf
->uc
.uc_mcontext
.regs
.UCreg_ip
);
176 err
|= __put_user(regs
->UCreg_sp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_sp
);
177 err
|= __put_user(regs
->UCreg_lr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_lr
);
178 err
|= __put_user(regs
->UCreg_pc
, &sf
->uc
.uc_mcontext
.regs
.UCreg_pc
);
179 err
|= __put_user(regs
->UCreg_asr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_asr
);
181 err
|= __put_user(current
->thread
.trap_no
,
182 &sf
->uc
.uc_mcontext
.trap_no
);
183 err
|= __put_user(current
->thread
.error_code
,
184 &sf
->uc
.uc_mcontext
.error_code
);
185 err
|= __put_user(current
->thread
.address
,
186 &sf
->uc
.uc_mcontext
.fault_address
);
187 err
|= __put_user(set
->sig
[0], &sf
->uc
.uc_mcontext
.oldmask
);
189 err
|= __copy_to_user(&sf
->uc
.uc_sigmask
, set
, sizeof(*set
));
194 static inline void __user
*get_sigframe(struct k_sigaction
*ka
,
195 struct pt_regs
*regs
, int framesize
)
197 unsigned long sp
= regs
->UCreg_sp
;
201 * This is the X/Open sanctioned signal stack switching.
203 if ((ka
->sa
.sa_flags
& SA_ONSTACK
) && !sas_ss_flags(sp
))
204 sp
= current
->sas_ss_sp
+ current
->sas_ss_size
;
207 * ATPCS B01 mandates 8-byte alignment
209 frame
= (void __user
*)((sp
- framesize
) & ~7);
212 * Check that we can actually write to the signal frame.
214 if (!access_ok(VERIFY_WRITE
, frame
, framesize
))
220 static int setup_return(struct pt_regs
*regs
, struct k_sigaction
*ka
,
221 unsigned long __user
*rc
, void __user
*frame
, int usig
)
223 unsigned long handler
= (unsigned long)ka
->sa
.sa_handler
;
224 unsigned long retcode
;
225 unsigned long asr
= regs
->UCreg_asr
& ~PSR_f
;
227 unsigned int idx
= 0;
229 if (ka
->sa
.sa_flags
& SA_SIGINFO
)
232 if (__put_user(sigreturn_codes
[idx
], rc
) ||
233 __put_user(sigreturn_codes
[idx
+1], rc
+1))
236 retcode
= KERN_SIGRETURN_CODE
+ (idx
<< 2);
238 regs
->UCreg_00
= usig
;
239 regs
->UCreg_sp
= (unsigned long)frame
;
240 regs
->UCreg_lr
= retcode
;
241 regs
->UCreg_pc
= handler
;
242 regs
->UCreg_asr
= asr
;
247 static int setup_frame(int usig
, struct k_sigaction
*ka
,
248 sigset_t
*set
, struct pt_regs
*regs
)
250 struct sigframe __user
*frame
= get_sigframe(ka
, regs
, sizeof(*frame
));
257 * Set uc.uc_flags to a value which sc.trap_no would never have.
259 err
|= __put_user(0x5ac3c35a, &frame
->uc
.uc_flags
);
261 err
|= setup_sigframe(frame
, regs
, set
);
263 err
|= setup_return(regs
, ka
, frame
->retcode
, frame
, usig
);
268 static int setup_rt_frame(int usig
, struct k_sigaction
*ka
, siginfo_t
*info
,
269 sigset_t
*set
, struct pt_regs
*regs
)
271 struct rt_sigframe __user
*frame
=
272 get_sigframe(ka
, regs
, sizeof(*frame
));
279 err
|= copy_siginfo_to_user(&frame
->info
, info
);
281 err
|= __put_user(0, &frame
->sig
.uc
.uc_flags
);
282 err
|= __put_user(NULL
, &frame
->sig
.uc
.uc_link
);
284 memset(&stack
, 0, sizeof(stack
));
285 stack
.ss_sp
= (void __user
*)current
->sas_ss_sp
;
286 stack
.ss_flags
= sas_ss_flags(regs
->UCreg_sp
);
287 stack
.ss_size
= current
->sas_ss_size
;
288 err
|= __copy_to_user(&frame
->sig
.uc
.uc_stack
, &stack
, sizeof(stack
));
290 err
|= setup_sigframe(&frame
->sig
, regs
, set
);
292 err
|= setup_return(regs
, ka
, frame
->sig
.retcode
, frame
, usig
);
296 * For realtime signals we must also set the second and third
297 * arguments for the signal handler.
299 regs
->UCreg_01
= (unsigned long)&frame
->info
;
300 regs
->UCreg_02
= (unsigned long)&frame
->sig
.uc
;
306 static inline void setup_syscall_restart(struct pt_regs
*regs
)
308 regs
->UCreg_00
= regs
->UCreg_ORIG_00
;
313 * OK, we're invoking a handler
315 static int handle_signal(unsigned long sig
, struct k_sigaction
*ka
,
316 siginfo_t
*info
, sigset_t
*oldset
,
317 struct pt_regs
*regs
, int syscall
)
319 struct thread_info
*thread
= current_thread_info();
320 struct task_struct
*tsk
= current
;
326 * If we were from a system call, check for system call restarting...
329 switch (regs
->UCreg_00
) {
330 case -ERESTART_RESTARTBLOCK
:
331 case -ERESTARTNOHAND
:
332 regs
->UCreg_00
= -EINTR
;
335 if (!(ka
->sa
.sa_flags
& SA_RESTART
)) {
336 regs
->UCreg_00
= -EINTR
;
340 case -ERESTARTNOINTR
:
341 setup_syscall_restart(regs
);
346 * translate the signal
348 if (usig
< 32 && thread
->exec_domain
349 && thread
->exec_domain
->signal_invmap
)
350 usig
= thread
->exec_domain
->signal_invmap
[usig
];
353 * Set up the stack frame
355 if (ka
->sa
.sa_flags
& SA_SIGINFO
)
356 ret
= setup_rt_frame(usig
, ka
, info
, oldset
, regs
);
358 ret
= setup_frame(usig
, ka
, oldset
, regs
);
361 * Check that the resulting registers are actually sane.
363 ret
|= !valid_user_regs(regs
);
366 force_sigsegv(sig
, tsk
);
371 * Block the signal if we were successful.
373 sigorsets(&blocked
, &tsk
->blocked
, &ka
->sa
.sa_mask
);
374 if (!(ka
->sa
.sa_flags
& SA_NODEFER
))
375 sigaddset(&blocked
, sig
);
376 set_current_blocked(&blocked
);
382 * Note that 'init' is a special process: it doesn't get signals it doesn't
383 * want to handle. Thus you cannot kill init even with a SIGKILL even by
386 * Note that we go through the signals twice: once to check the signals that
387 * the kernel can handle, and then we build all the user-level signal handling
388 * stack-frames in one go after that.
390 static void do_signal(struct pt_regs
*regs
, int syscall
)
392 struct k_sigaction ka
;
397 * We want the common case to go fast, which
398 * is why we may in certain cases get here from
399 * kernel mode. Just return without doing anything
402 if (!user_mode(regs
))
408 signr
= get_signal_to_deliver(&info
, &ka
, regs
, NULL
);
412 if (test_thread_flag(TIF_RESTORE_SIGMASK
))
413 oldset
= ¤t
->saved_sigmask
;
415 oldset
= ¤t
->blocked
;
416 if (handle_signal(signr
, &ka
, &info
, oldset
, regs
, syscall
)
419 * A signal was successfully delivered; the saved
420 * sigmask will have been stored in the signal frame,
421 * and will be restored by sigreturn, so we can simply
422 * clear the TIF_RESTORE_SIGMASK flag.
424 if (test_thread_flag(TIF_RESTORE_SIGMASK
))
425 clear_thread_flag(TIF_RESTORE_SIGMASK
);
432 * No signal to deliver to the process - restart the syscall.
435 if (regs
->UCreg_00
== -ERESTART_RESTARTBLOCK
) {
439 usp
= (u32 __user
*)regs
->UCreg_sp
;
441 if (put_user(regs
->UCreg_pc
, usp
) == 0) {
442 regs
->UCreg_pc
= KERN_RESTART_CODE
;
445 force_sigsegv(0, current
);
448 if (regs
->UCreg_00
== -ERESTARTNOHAND
||
449 regs
->UCreg_00
== -ERESTARTSYS
||
450 regs
->UCreg_00
== -ERESTARTNOINTR
) {
451 setup_syscall_restart(regs
);
454 /* If there's no signal to deliver, we just put the saved
457 if (test_thread_flag(TIF_RESTORE_SIGMASK
)) {
458 clear_thread_flag(TIF_RESTORE_SIGMASK
);
459 sigprocmask(SIG_SETMASK
, ¤t
->saved_sigmask
, NULL
);
464 asmlinkage
void do_notify_resume(struct pt_regs
*regs
,
465 unsigned int thread_flags
, int syscall
)
467 if (thread_flags
& _TIF_SIGPENDING
)
468 do_signal(regs
, syscall
);
470 if (thread_flags
& _TIF_NOTIFY_RESUME
) {
471 clear_thread_flag(TIF_NOTIFY_RESUME
);
472 tracehook_notify_resume(regs
);
473 if (current
->replacement_session_keyring
)
474 key_replace_session_keyring();
479 * Copy signal return handlers into the vector page, and
480 * set sigreturn to be a pointer to these.
482 void __init
early_signal_init(void)
484 memcpy((void *)kuser_vecpage_to_vectors(KERN_SIGRETURN_CODE
),
485 sigreturn_codes
, sizeof(sigreturn_codes
));
486 memcpy((void *)kuser_vecpage_to_vectors(KERN_RESTART_CODE
),
487 syscall_restart_code
, sizeof(syscall_restart_code
));
488 /* Need not to flush icache, since early_trap_init will do it last. */