aboutsummaryrefslogtreecommitdiffstats
path: root/arch/c6x
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-09 12:58:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-09 12:58:12 -0400
commit63b12bdb0d21aca527996fb2c547387bfd3e14b8 (patch)
tree6ab83b2a1c289f30fea18b88f04138ee69c37c6f /arch/c6x
parentad1f5caf34390bb20fdbb4eaf71b0494e89936f0 (diff)
parent059ade650ae57cfd371af690fdba887af04aded8 (diff)
Merge branch 'signal-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc
Pull arch signal handling cleanup from Richard Weinberger: "This patch series moves all remaining archs to the get_signal(), signal_setup_done() and sigsp() functions. Currently these archs use open coded variants of the said functions. Further, unused parameters get removed from get_signal_to_deliver(), tracehook_signal_handler() and signal_delivered(). At the end of the day we save around 500 lines of code." * 'signal-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc: (43 commits) powerpc: Use sigsp() openrisc: Use sigsp() mn10300: Use sigsp() mips: Use sigsp() microblaze: Use sigsp() metag: Use sigsp() m68k: Use sigsp() m32r: Use sigsp() hexagon: Use sigsp() frv: Use sigsp() cris: Use sigsp() c6x: Use sigsp() blackfin: Use sigsp() avr32: Use sigsp() arm64: Use sigsp() arc: Use sigsp() sas_ss_flags: Remove nested ternary if Rip out get_signal_to_deliver() Clean up signal_delivered() tracehook_signal_handler: Remove sig, info, ka and regs ...
Diffstat (limited to 'arch/c6x')
-rw-r--r--arch/c6x/kernel/signal.c53
1 files changed, 20 insertions, 33 deletions
diff --git a/arch/c6x/kernel/signal.c b/arch/c6x/kernel/signal.c
index 3998b24e26f2..fe68226f6c4d 100644
--- a/arch/c6x/kernel/signal.c
+++ b/arch/c6x/kernel/signal.c
@@ -127,17 +127,11 @@ static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
127 return err; 127 return err;
128} 128}
129 129
130static inline void __user *get_sigframe(struct k_sigaction *ka, 130static inline void __user *get_sigframe(struct ksignal *ksig,
131 struct pt_regs *regs, 131 struct pt_regs *regs,
132 unsigned long framesize) 132 unsigned long framesize)
133{ 133{
134 unsigned long sp = regs->sp; 134 unsigned long sp = sigsp(regs->sp, ksig);
135
136 /*
137 * This is the X/Open sanctioned signal stack switching.
138 */
139 if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp) == 0)
140 sp = current->sas_ss_sp + current->sas_ss_size;
141 135
142 /* 136 /*
143 * No matter what happens, 'sp' must be dword 137 * No matter what happens, 'sp' must be dword
@@ -146,21 +140,21 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
146 return (void __user *)((sp - framesize) & ~7); 140 return (void __user *)((sp - framesize) & ~7);
147} 141}
148 142
149static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, 143static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
150 sigset_t *set, struct pt_regs *regs) 144 struct pt_regs *regs)
151{ 145{
152 struct rt_sigframe __user *frame; 146 struct rt_sigframe __user *frame;
153 unsigned long __user *retcode; 147 unsigned long __user *retcode;
154 int err = 0; 148 int err = 0;
155 149
156 frame = get_sigframe(ka, regs, sizeof(*frame)); 150 frame = get_sigframe(ksig, regs, sizeof(*frame));
157 151
158 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 152 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
159 goto segv_and_exit; 153 return -EFAULT;
160 154
161 err |= __put_user(&frame->info, &frame->pinfo); 155 err |= __put_user(&frame->info, &frame->pinfo);
162 err |= __put_user(&frame->uc, &frame->puc); 156 err |= __put_user(&frame->uc, &frame->puc);
163 err |= copy_siginfo_to_user(&frame->info, info); 157 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
164 158
165 /* Clear all the bits of the ucontext we don't use. */ 159 /* Clear all the bits of the ucontext we don't use. */
166 err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); 160 err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
@@ -188,7 +182,7 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
188#undef COPY 182#undef COPY
189 183
190 if (err) 184 if (err)
191 goto segv_and_exit; 185 return -EFAULT;
192 186
193 flush_icache_range((unsigned long) &frame->retcode, 187 flush_icache_range((unsigned long) &frame->retcode,
194 (unsigned long) &frame->retcode + RETCODE_SIZE); 188 (unsigned long) &frame->retcode + RETCODE_SIZE);
@@ -198,10 +192,10 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
198 /* Change user context to branch to signal handler */ 192 /* Change user context to branch to signal handler */
199 regs->sp = (unsigned long) frame - 8; 193 regs->sp = (unsigned long) frame - 8;
200 regs->b3 = (unsigned long) retcode; 194 regs->b3 = (unsigned long) retcode;
201 regs->pc = (unsigned long) ka->sa.sa_handler; 195 regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
202 196
203 /* Give the signal number to the handler */ 197 /* Give the signal number to the handler */
204 regs->a4 = signr; 198 regs->a4 = ksig->sig;
205 199
206 /* 200 /*
207 * For realtime signals we must also set the second and third 201 * For realtime signals we must also set the second and third
@@ -212,10 +206,6 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
212 regs->a6 = (unsigned long)&frame->uc; 206 regs->a6 = (unsigned long)&frame->uc;
213 207
214 return 0; 208 return 0;
215
216segv_and_exit:
217 force_sigsegv(signr, current);
218 return -EFAULT;
219} 209}
220 210
221static inline void 211static inline void
@@ -245,10 +235,11 @@ do_restart:
245/* 235/*
246 * handle the actual delivery of a signal to userspace 236 * handle the actual delivery of a signal to userspace
247 */ 237 */
248static void handle_signal(int sig, 238static void handle_signal(struct ksignal *ksig, struct pt_regs *regs,
249 siginfo_t *info, struct k_sigaction *ka, 239 int syscall)
250 struct pt_regs *regs, int syscall)
251{ 240{
241 int ret;
242
252 /* Are we from a system call? */ 243 /* Are we from a system call? */
253 if (syscall) { 244 if (syscall) {
254 /* If so, check system call restarting.. */ 245 /* If so, check system call restarting.. */
@@ -259,7 +250,7 @@ static void handle_signal(int sig,
259 break; 250 break;
260 251
261 case -ERESTARTSYS: 252 case -ERESTARTSYS:
262 if (!(ka->sa.sa_flags & SA_RESTART)) { 253 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
263 regs->a4 = -EINTR; 254 regs->a4 = -EINTR;
264 break; 255 break;
265 } 256 }
@@ -272,9 +263,8 @@ static void handle_signal(int sig,
272 } 263 }
273 264
274 /* Set up the stack frame */ 265 /* Set up the stack frame */
275 if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) 266 ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
276 return; 267 signal_setup_done(ret, ksig, 0);
277 signal_delivered(sig, info, ka, regs, 0);
278} 268}
279 269
280/* 270/*
@@ -282,18 +272,15 @@ static void handle_signal(int sig,
282 */ 272 */
283static void do_signal(struct pt_regs *regs, int syscall) 273static void do_signal(struct pt_regs *regs, int syscall)
284{ 274{
285 struct k_sigaction ka; 275 struct ksignal ksig;
286 siginfo_t info;
287 int signr;
288 276
289 /* we want the common case to go fast, which is why we may in certain 277 /* we want the common case to go fast, which is why we may in certain
290 * cases get here from kernel mode */ 278 * cases get here from kernel mode */
291 if (!user_mode(regs)) 279 if (!user_mode(regs))
292 return; 280 return;
293 281
294 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 282 if (get_signal(&ksig)) {
295 if (signr > 0) { 283 handle_signal(&ksig, regs, syscall);
296 handle_signal(signr, &info, &ka, regs, syscall);
297 return; 284 return;
298 } 285 }
299 286