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/uaccess.h>
16 #include <linux/tracehook.h>
17 #include <linux/elf.h>
18 #include <linux/unistd.h>
20 #include <asm/cacheflush.h>
21 #include <asm/ucontext.h>
24 * For UniCore syscalls, we encode the syscall number into the instruction.
26 #define SWI_SYS_SIGRETURN (0xff000000) /* error number for new abi */
27 #define SWI_SYS_RT_SIGRETURN (0xff000000 | (__NR_rt_sigreturn))
28 #define SWI_SYS_RESTART (0xff000000 | (__NR_restart_syscall))
30 #define KERN_SIGRETURN_CODE (KUSER_VECPAGE_BASE + 0x00000500)
31 #define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
33 const unsigned long sigreturn_codes
[3] = {
34 SWI_SYS_SIGRETURN
, SWI_SYS_RT_SIGRETURN
,
37 const unsigned long syscall_restart_code
[2] = {
38 SWI_SYS_RESTART
, /* swi __NR_restart_syscall */
39 0x69efc004, /* ldr pc, [sp], #4 */
43 * Do a signal return; undo the signal stack. These are aligned to 64-bit.
47 unsigned long retcode
[2];
55 static int restore_sigframe(struct pt_regs
*regs
, struct sigframe __user
*sf
)
60 err
= __copy_from_user(&set
, &sf
->uc
.uc_sigmask
, sizeof(set
));
62 set_current_blocked(&set
);
64 err
|= __get_user(regs
->UCreg_00
, &sf
->uc
.uc_mcontext
.regs
.UCreg_00
);
65 err
|= __get_user(regs
->UCreg_01
, &sf
->uc
.uc_mcontext
.regs
.UCreg_01
);
66 err
|= __get_user(regs
->UCreg_02
, &sf
->uc
.uc_mcontext
.regs
.UCreg_02
);
67 err
|= __get_user(regs
->UCreg_03
, &sf
->uc
.uc_mcontext
.regs
.UCreg_03
);
68 err
|= __get_user(regs
->UCreg_04
, &sf
->uc
.uc_mcontext
.regs
.UCreg_04
);
69 err
|= __get_user(regs
->UCreg_05
, &sf
->uc
.uc_mcontext
.regs
.UCreg_05
);
70 err
|= __get_user(regs
->UCreg_06
, &sf
->uc
.uc_mcontext
.regs
.UCreg_06
);
71 err
|= __get_user(regs
->UCreg_07
, &sf
->uc
.uc_mcontext
.regs
.UCreg_07
);
72 err
|= __get_user(regs
->UCreg_08
, &sf
->uc
.uc_mcontext
.regs
.UCreg_08
);
73 err
|= __get_user(regs
->UCreg_09
, &sf
->uc
.uc_mcontext
.regs
.UCreg_09
);
74 err
|= __get_user(regs
->UCreg_10
, &sf
->uc
.uc_mcontext
.regs
.UCreg_10
);
75 err
|= __get_user(regs
->UCreg_11
, &sf
->uc
.uc_mcontext
.regs
.UCreg_11
);
76 err
|= __get_user(regs
->UCreg_12
, &sf
->uc
.uc_mcontext
.regs
.UCreg_12
);
77 err
|= __get_user(regs
->UCreg_13
, &sf
->uc
.uc_mcontext
.regs
.UCreg_13
);
78 err
|= __get_user(regs
->UCreg_14
, &sf
->uc
.uc_mcontext
.regs
.UCreg_14
);
79 err
|= __get_user(regs
->UCreg_15
, &sf
->uc
.uc_mcontext
.regs
.UCreg_15
);
80 err
|= __get_user(regs
->UCreg_16
, &sf
->uc
.uc_mcontext
.regs
.UCreg_16
);
81 err
|= __get_user(regs
->UCreg_17
, &sf
->uc
.uc_mcontext
.regs
.UCreg_17
);
82 err
|= __get_user(regs
->UCreg_18
, &sf
->uc
.uc_mcontext
.regs
.UCreg_18
);
83 err
|= __get_user(regs
->UCreg_19
, &sf
->uc
.uc_mcontext
.regs
.UCreg_19
);
84 err
|= __get_user(regs
->UCreg_20
, &sf
->uc
.uc_mcontext
.regs
.UCreg_20
);
85 err
|= __get_user(regs
->UCreg_21
, &sf
->uc
.uc_mcontext
.regs
.UCreg_21
);
86 err
|= __get_user(regs
->UCreg_22
, &sf
->uc
.uc_mcontext
.regs
.UCreg_22
);
87 err
|= __get_user(regs
->UCreg_23
, &sf
->uc
.uc_mcontext
.regs
.UCreg_23
);
88 err
|= __get_user(regs
->UCreg_24
, &sf
->uc
.uc_mcontext
.regs
.UCreg_24
);
89 err
|= __get_user(regs
->UCreg_25
, &sf
->uc
.uc_mcontext
.regs
.UCreg_25
);
90 err
|= __get_user(regs
->UCreg_26
, &sf
->uc
.uc_mcontext
.regs
.UCreg_26
);
91 err
|= __get_user(regs
->UCreg_fp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_fp
);
92 err
|= __get_user(regs
->UCreg_ip
, &sf
->uc
.uc_mcontext
.regs
.UCreg_ip
);
93 err
|= __get_user(regs
->UCreg_sp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_sp
);
94 err
|= __get_user(regs
->UCreg_lr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_lr
);
95 err
|= __get_user(regs
->UCreg_pc
, &sf
->uc
.uc_mcontext
.regs
.UCreg_pc
);
96 err
|= __get_user(regs
->UCreg_asr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_asr
);
98 err
|= !valid_user_regs(regs
);
103 asmlinkage
int __sys_rt_sigreturn(struct pt_regs
*regs
)
105 struct rt_sigframe __user
*frame
;
107 /* Always make any pending restarted system calls return -EINTR */
108 current
->restart_block
.fn
= do_no_restart_syscall
;
111 * Since we stacked the signal on a 64-bit boundary,
112 * then 'sp' should be word aligned here. If it's
113 * not, then the user is trying to mess with us.
115 if (regs
->UCreg_sp
& 7)
118 frame
= (struct rt_sigframe __user
*)regs
->UCreg_sp
;
120 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
123 if (restore_sigframe(regs
, &frame
->sig
))
126 if (restore_altstack(&frame
->sig
.uc
.uc_stack
))
129 return regs
->UCreg_00
;
132 force_sig(SIGSEGV
, current
);
136 static int setup_sigframe(struct sigframe __user
*sf
, struct pt_regs
*regs
,
141 err
|= __put_user(regs
->UCreg_00
, &sf
->uc
.uc_mcontext
.regs
.UCreg_00
);
142 err
|= __put_user(regs
->UCreg_01
, &sf
->uc
.uc_mcontext
.regs
.UCreg_01
);
143 err
|= __put_user(regs
->UCreg_02
, &sf
->uc
.uc_mcontext
.regs
.UCreg_02
);
144 err
|= __put_user(regs
->UCreg_03
, &sf
->uc
.uc_mcontext
.regs
.UCreg_03
);
145 err
|= __put_user(regs
->UCreg_04
, &sf
->uc
.uc_mcontext
.regs
.UCreg_04
);
146 err
|= __put_user(regs
->UCreg_05
, &sf
->uc
.uc_mcontext
.regs
.UCreg_05
);
147 err
|= __put_user(regs
->UCreg_06
, &sf
->uc
.uc_mcontext
.regs
.UCreg_06
);
148 err
|= __put_user(regs
->UCreg_07
, &sf
->uc
.uc_mcontext
.regs
.UCreg_07
);
149 err
|= __put_user(regs
->UCreg_08
, &sf
->uc
.uc_mcontext
.regs
.UCreg_08
);
150 err
|= __put_user(regs
->UCreg_09
, &sf
->uc
.uc_mcontext
.regs
.UCreg_09
);
151 err
|= __put_user(regs
->UCreg_10
, &sf
->uc
.uc_mcontext
.regs
.UCreg_10
);
152 err
|= __put_user(regs
->UCreg_11
, &sf
->uc
.uc_mcontext
.regs
.UCreg_11
);
153 err
|= __put_user(regs
->UCreg_12
, &sf
->uc
.uc_mcontext
.regs
.UCreg_12
);
154 err
|= __put_user(regs
->UCreg_13
, &sf
->uc
.uc_mcontext
.regs
.UCreg_13
);
155 err
|= __put_user(regs
->UCreg_14
, &sf
->uc
.uc_mcontext
.regs
.UCreg_14
);
156 err
|= __put_user(regs
->UCreg_15
, &sf
->uc
.uc_mcontext
.regs
.UCreg_15
);
157 err
|= __put_user(regs
->UCreg_16
, &sf
->uc
.uc_mcontext
.regs
.UCreg_16
);
158 err
|= __put_user(regs
->UCreg_17
, &sf
->uc
.uc_mcontext
.regs
.UCreg_17
);
159 err
|= __put_user(regs
->UCreg_18
, &sf
->uc
.uc_mcontext
.regs
.UCreg_18
);
160 err
|= __put_user(regs
->UCreg_19
, &sf
->uc
.uc_mcontext
.regs
.UCreg_19
);
161 err
|= __put_user(regs
->UCreg_20
, &sf
->uc
.uc_mcontext
.regs
.UCreg_20
);
162 err
|= __put_user(regs
->UCreg_21
, &sf
->uc
.uc_mcontext
.regs
.UCreg_21
);
163 err
|= __put_user(regs
->UCreg_22
, &sf
->uc
.uc_mcontext
.regs
.UCreg_22
);
164 err
|= __put_user(regs
->UCreg_23
, &sf
->uc
.uc_mcontext
.regs
.UCreg_23
);
165 err
|= __put_user(regs
->UCreg_24
, &sf
->uc
.uc_mcontext
.regs
.UCreg_24
);
166 err
|= __put_user(regs
->UCreg_25
, &sf
->uc
.uc_mcontext
.regs
.UCreg_25
);
167 err
|= __put_user(regs
->UCreg_26
, &sf
->uc
.uc_mcontext
.regs
.UCreg_26
);
168 err
|= __put_user(regs
->UCreg_fp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_fp
);
169 err
|= __put_user(regs
->UCreg_ip
, &sf
->uc
.uc_mcontext
.regs
.UCreg_ip
);
170 err
|= __put_user(regs
->UCreg_sp
, &sf
->uc
.uc_mcontext
.regs
.UCreg_sp
);
171 err
|= __put_user(regs
->UCreg_lr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_lr
);
172 err
|= __put_user(regs
->UCreg_pc
, &sf
->uc
.uc_mcontext
.regs
.UCreg_pc
);
173 err
|= __put_user(regs
->UCreg_asr
, &sf
->uc
.uc_mcontext
.regs
.UCreg_asr
);
175 err
|= __put_user(current
->thread
.trap_no
,
176 &sf
->uc
.uc_mcontext
.trap_no
);
177 err
|= __put_user(current
->thread
.error_code
,
178 &sf
->uc
.uc_mcontext
.error_code
);
179 err
|= __put_user(current
->thread
.address
,
180 &sf
->uc
.uc_mcontext
.fault_address
);
181 err
|= __put_user(set
->sig
[0], &sf
->uc
.uc_mcontext
.oldmask
);
183 err
|= __copy_to_user(&sf
->uc
.uc_sigmask
, set
, sizeof(*set
));
188 static inline void __user
*get_sigframe(struct k_sigaction
*ka
,
189 struct pt_regs
*regs
, int framesize
)
191 unsigned long sp
= regs
->UCreg_sp
;
195 * This is the X/Open sanctioned signal stack switching.
197 if ((ka
->sa
.sa_flags
& SA_ONSTACK
) && !sas_ss_flags(sp
))
198 sp
= current
->sas_ss_sp
+ current
->sas_ss_size
;
201 * ATPCS B01 mandates 8-byte alignment
203 frame
= (void __user
*)((sp
- framesize
) & ~7);
206 * Check that we can actually write to the signal frame.
208 if (!access_ok(VERIFY_WRITE
, frame
, framesize
))
214 static int setup_return(struct pt_regs
*regs
, struct k_sigaction
*ka
,
215 unsigned long __user
*rc
, void __user
*frame
, int usig
)
217 unsigned long handler
= (unsigned long)ka
->sa
.sa_handler
;
218 unsigned long retcode
;
219 unsigned long asr
= regs
->UCreg_asr
& ~PSR_f
;
221 unsigned int idx
= 0;
223 if (ka
->sa
.sa_flags
& SA_SIGINFO
)
226 if (__put_user(sigreturn_codes
[idx
], rc
) ||
227 __put_user(sigreturn_codes
[idx
+1], rc
+1))
230 retcode
= KERN_SIGRETURN_CODE
+ (idx
<< 2);
232 regs
->UCreg_00
= usig
;
233 regs
->UCreg_sp
= (unsigned long)frame
;
234 regs
->UCreg_lr
= retcode
;
235 regs
->UCreg_pc
= handler
;
236 regs
->UCreg_asr
= asr
;
241 static int setup_frame(struct ksignal
*ksig
, sigset_t
*set
,
242 struct pt_regs
*regs
)
244 struct sigframe __user
*frame
= get_sigframe(&ksig
->ka
, regs
, sizeof(*frame
));
251 * Set uc.uc_flags to a value which sc.trap_no would never have.
253 err
|= __put_user(0x5ac3c35a, &frame
->uc
.uc_flags
);
255 err
|= setup_sigframe(frame
, regs
, set
);
257 err
|= setup_return(regs
, &ksig
->ka
, frame
->retcode
, frame
,
263 static int setup_rt_frame(struct ksignal
*ksig
, sigset_t
*set
,
264 struct pt_regs
*regs
)
266 struct rt_sigframe __user
*frame
=
267 get_sigframe(&ksig
->ka
, regs
, sizeof(*frame
));
273 err
|= copy_siginfo_to_user(&frame
->info
, &ksig
->info
);
275 err
|= __put_user(0, &frame
->sig
.uc
.uc_flags
);
276 err
|= __put_user(NULL
, &frame
->sig
.uc
.uc_link
);
277 err
|= __save_altstack(&frame
->sig
.uc
.uc_stack
, regs
->UCreg_sp
);
278 err
|= setup_sigframe(&frame
->sig
, regs
, set
);
280 err
|= setup_return(regs
, &ksig
->ka
, frame
->sig
.retcode
, frame
,
285 * For realtime signals we must also set the second and third
286 * arguments for the signal handler.
288 regs
->UCreg_01
= (unsigned long)&frame
->info
;
289 regs
->UCreg_02
= (unsigned long)&frame
->sig
.uc
;
295 static inline void setup_syscall_restart(struct pt_regs
*regs
)
297 regs
->UCreg_00
= regs
->UCreg_ORIG_00
;
302 * OK, we're invoking a handler
304 static void handle_signal(struct ksignal
*ksig
, struct pt_regs
*regs
,
307 struct thread_info
*thread
= current_thread_info();
308 sigset_t
*oldset
= sigmask_to_save();
309 int usig
= ksig
->sig
;
313 * If we were from a system call, check for system call restarting...
316 switch (regs
->UCreg_00
) {
317 case -ERESTART_RESTARTBLOCK
:
318 case -ERESTARTNOHAND
:
319 regs
->UCreg_00
= -EINTR
;
322 if (!(ksig
->ka
.sa
.sa_flags
& SA_RESTART
)) {
323 regs
->UCreg_00
= -EINTR
;
327 case -ERESTARTNOINTR
:
328 setup_syscall_restart(regs
);
333 * Set up the stack frame
335 if (ksig
->ka
.sa
.sa_flags
& SA_SIGINFO
)
336 ret
= setup_rt_frame(ksig
, oldset
, regs
);
338 ret
= setup_frame(ksig
, oldset
, regs
);
341 * Check that the resulting registers are actually sane.
343 ret
|= !valid_user_regs(regs
);
345 signal_setup_done(ret
, ksig
, 0);
349 * Note that 'init' is a special process: it doesn't get signals it doesn't
350 * want to handle. Thus you cannot kill init even with a SIGKILL even by
353 * Note that we go through the signals twice: once to check the signals that
354 * the kernel can handle, and then we build all the user-level signal handling
355 * stack-frames in one go after that.
357 static void do_signal(struct pt_regs
*regs
, int syscall
)
362 * We want the common case to go fast, which
363 * is why we may in certain cases get here from
364 * kernel mode. Just return without doing anything
367 if (!user_mode(regs
))
370 if (get_signal(&ksig
)) {
371 handle_signal(&ksig
, regs
, syscall
);
376 * No signal to deliver to the process - restart the syscall.
379 if (regs
->UCreg_00
== -ERESTART_RESTARTBLOCK
) {
383 usp
= (u32 __user
*)regs
->UCreg_sp
;
385 if (put_user(regs
->UCreg_pc
, usp
) == 0) {
386 regs
->UCreg_pc
= KERN_RESTART_CODE
;
389 force_sigsegv(0, current
);
392 if (regs
->UCreg_00
== -ERESTARTNOHAND
||
393 regs
->UCreg_00
== -ERESTARTSYS
||
394 regs
->UCreg_00
== -ERESTARTNOINTR
) {
395 setup_syscall_restart(regs
);
398 /* If there's no signal to deliver, we just put the saved
401 restore_saved_sigmask();
404 asmlinkage
void do_notify_resume(struct pt_regs
*regs
,
405 unsigned int thread_flags
, int syscall
)
407 if (thread_flags
& _TIF_SIGPENDING
)
408 do_signal(regs
, syscall
);
410 if (thread_flags
& _TIF_NOTIFY_RESUME
) {
411 clear_thread_flag(TIF_NOTIFY_RESUME
);
412 tracehook_notify_resume(regs
);
417 * Copy signal return handlers into the vector page, and
418 * set sigreturn to be a pointer to these.
420 void __init
early_signal_init(void)
422 memcpy((void *)kuser_vecpage_to_vectors(KERN_SIGRETURN_CODE
),
423 sigreturn_codes
, sizeof(sigreturn_codes
));
424 memcpy((void *)kuser_vecpage_to_vectors(KERN_RESTART_CODE
),
425 syscall_restart_code
, sizeof(syscall_restart_code
));
426 /* Need not to flush icache, since early_trap_init will do it last. */