diff options
Diffstat (limited to 'arch/blackfin/kernel/signal.c')
-rw-r--r-- | arch/blackfin/kernel/signal.c | 51 |
1 files changed, 19 insertions, 32 deletions
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index b022af6c48f8..ef275571d885 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c | |||
@@ -135,40 +135,31 @@ static inline int rt_setup_sigcontext(struct sigcontext *sc, struct pt_regs *reg | |||
135 | return err; | 135 | return err; |
136 | } | 136 | } |
137 | 137 | ||
138 | static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 138 | static inline void *get_sigframe(struct ksignal *ksig, |
139 | size_t frame_size) | 139 | size_t frame_size) |
140 | { | 140 | { |
141 | unsigned long usp; | 141 | unsigned long usp = sigsp(rdusp(), ksig); |
142 | 142 | ||
143 | /* Default to using normal stack. */ | ||
144 | usp = rdusp(); | ||
145 | |||
146 | /* This is the X/Open sanctioned signal stack switching. */ | ||
147 | if (ka->sa.sa_flags & SA_ONSTACK) { | ||
148 | if (!on_sig_stack(usp)) | ||
149 | usp = current->sas_ss_sp + current->sas_ss_size; | ||
150 | } | ||
151 | return (void *)((usp - frame_size) & -8UL); | 143 | return (void *)((usp - frame_size) & -8UL); |
152 | } | 144 | } |
153 | 145 | ||
154 | static int | 146 | static int |
155 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, | 147 | setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) |
156 | sigset_t * set, struct pt_regs *regs) | ||
157 | { | 148 | { |
158 | struct rt_sigframe *frame; | 149 | struct rt_sigframe *frame; |
159 | int err = 0; | 150 | int err = 0; |
160 | 151 | ||
161 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 152 | frame = get_sigframe(ksig, sizeof(*frame)); |
162 | 153 | ||
163 | err |= __put_user((current_thread_info()->exec_domain | 154 | err |= __put_user((current_thread_info()->exec_domain |
164 | && current_thread_info()->exec_domain->signal_invmap | 155 | && current_thread_info()->exec_domain->signal_invmap |
165 | && sig < 32 | 156 | && ksig->sig < 32 |
166 | ? current_thread_info()->exec_domain-> | 157 | ? current_thread_info()->exec_domain-> |
167 | signal_invmap[sig] : sig), &frame->sig); | 158 | signal_invmap[ksig->sig] : ksig->sig), &frame->sig); |
168 | 159 | ||
169 | err |= __put_user(&frame->info, &frame->pinfo); | 160 | err |= __put_user(&frame->info, &frame->pinfo); |
170 | err |= __put_user(&frame->uc, &frame->puc); | 161 | err |= __put_user(&frame->uc, &frame->puc); |
171 | err |= copy_siginfo_to_user(&frame->info, info); | 162 | err |= copy_siginfo_to_user(&frame->info, &ksig->info); |
172 | 163 | ||
173 | /* Create the ucontext. */ | 164 | /* Create the ucontext. */ |
174 | err |= __put_user(0, &frame->uc.uc_flags); | 165 | err |= __put_user(0, &frame->uc.uc_flags); |
@@ -183,7 +174,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, | |||
183 | /* Set up registers for signal handler */ | 174 | /* Set up registers for signal handler */ |
184 | if (current->personality & FDPIC_FUNCPTRS) { | 175 | if (current->personality & FDPIC_FUNCPTRS) { |
185 | struct fdpic_func_descriptor __user *funcptr = | 176 | struct fdpic_func_descriptor __user *funcptr = |
186 | (struct fdpic_func_descriptor *) ka->sa.sa_handler; | 177 | (struct fdpic_func_descriptor *) ksig->ka.sa.sa_handler; |
187 | u32 pc, p3; | 178 | u32 pc, p3; |
188 | err |= __get_user(pc, &funcptr->text); | 179 | err |= __get_user(pc, &funcptr->text); |
189 | err |= __get_user(p3, &funcptr->GOT); | 180 | err |= __get_user(p3, &funcptr->GOT); |
@@ -192,7 +183,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, | |||
192 | regs->pc = pc; | 183 | regs->pc = pc; |
193 | regs->p3 = p3; | 184 | regs->p3 = p3; |
194 | } else | 185 | } else |
195 | regs->pc = (unsigned long)ka->sa.sa_handler; | 186 | regs->pc = (unsigned long)ksig->ka.sa.sa_handler; |
196 | wrusp((unsigned long)frame); | 187 | wrusp((unsigned long)frame); |
197 | regs->rets = SIGRETURN_STUB; | 188 | regs->rets = SIGRETURN_STUB; |
198 | 189 | ||
@@ -237,20 +228,19 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) | |||
237 | * OK, we're invoking a handler | 228 | * OK, we're invoking a handler |
238 | */ | 229 | */ |
239 | static void | 230 | static void |
240 | handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, | 231 | handle_signal(struct ksignal *ksig, struct pt_regs *regs) |
241 | struct pt_regs *regs) | ||
242 | { | 232 | { |
233 | int ret; | ||
234 | |||
243 | /* are we from a system call? to see pt_regs->orig_p0 */ | 235 | /* are we from a system call? to see pt_regs->orig_p0 */ |
244 | if (regs->orig_p0 >= 0) | 236 | if (regs->orig_p0 >= 0) |
245 | /* If so, check system call restarting.. */ | 237 | /* If so, check system call restarting.. */ |
246 | handle_restart(regs, ka, 1); | 238 | handle_restart(regs, &ksig->ka, 1); |
247 | 239 | ||
248 | /* set up the stack frame */ | 240 | /* set up the stack frame */ |
249 | if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) | 241 | ret = setup_rt_frame(ksig, sigmask_to_save(), regs); |
250 | force_sigsegv(sig, current); | 242 | |
251 | else | 243 | signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); |
252 | signal_delivered(sig, info, ka, regs, | ||
253 | test_thread_flag(TIF_SINGLESTEP)); | ||
254 | } | 244 | } |
255 | 245 | ||
256 | /* | 246 | /* |
@@ -264,16 +254,13 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, | |||
264 | */ | 254 | */ |
265 | asmlinkage void do_signal(struct pt_regs *regs) | 255 | asmlinkage void do_signal(struct pt_regs *regs) |
266 | { | 256 | { |
267 | siginfo_t info; | 257 | struct ksignal ksig; |
268 | int signr; | ||
269 | struct k_sigaction ka; | ||
270 | 258 | ||
271 | current->thread.esp0 = (unsigned long)regs; | 259 | current->thread.esp0 = (unsigned long)regs; |
272 | 260 | ||
273 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 261 | if (get_signal(&ksig)) { |
274 | if (signr > 0) { | ||
275 | /* Whee! Actually deliver the signal. */ | 262 | /* Whee! Actually deliver the signal. */ |
276 | handle_signal(signr, &info, &ka, regs); | 263 | handle_signal(&ksig, regs); |
277 | return; | 264 | return; |
278 | } | 265 | } |
279 | 266 | ||