aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2014-03-02 18:57:16 -0500
committerJames Hogan <james.hogan@imgtec.com>2014-03-18 06:30:22 -0400
commitd3c7e5111122bc6c049e53f6761728cbac696636 (patch)
treeb65ac643c84261ab3e6f719e4a7b7d39842c9f21
parentcca7c66f2dab1343fa4fe854c3700bac3a1f71c0 (diff)
metag: Use get_signal() signal_setup_done()
Use the more generic functions get_signal() signal_setup_done() for signal delivery. [James Hogan: avoid reordering get_signal() and restart check.] Signed-off-by: Richard Weinberger <richard@nod.at> Signed-off-by: James Hogan <james.hogan@imgtec.com>
-rw-r--r--arch/metag/kernel/signal.c48
1 files changed, 21 insertions, 27 deletions
diff --git a/arch/metag/kernel/signal.c b/arch/metag/kernel/signal.c
index 3be61cf0b147..b9e4a82d2bd4 100644
--- a/arch/metag/kernel/signal.c
+++ b/arch/metag/kernel/signal.c
@@ -152,18 +152,18 @@ static void __user *get_sigframe(struct k_sigaction *ka, unsigned long sp,
152 return (void __user *)sp; 152 return (void __user *)sp;
153} 153}
154 154
155static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 155static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
156 sigset_t *set, struct pt_regs *regs) 156 struct pt_regs *regs)
157{ 157{
158 struct rt_sigframe __user *frame; 158 struct rt_sigframe __user *frame;
159 int err = -EFAULT; 159 int err;
160 unsigned long code; 160 unsigned long code;
161 161
162 frame = get_sigframe(ka, regs->REG_SP, sizeof(*frame)); 162 frame = get_sigframe(&ksig->ka, regs->REG_SP, sizeof(*frame));
163 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 163 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
164 goto out; 164 return -EFAULT;
165 165
166 err = copy_siginfo_to_user(&frame->info, info); 166 err = copy_siginfo_to_user(&frame->info, &ksig->info);
167 167
168 /* Create the ucontext. */ 168 /* Create the ucontext. */
169 err |= __put_user(0, &frame->uc.uc_flags); 169 err |= __put_user(0, &frame->uc.uc_flags);
@@ -174,7 +174,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
174 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 174 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
175 175
176 if (err) 176 if (err)
177 goto out; 177 return -EFAULT;
178 178
179 /* Set up to return from userspace. */ 179 /* Set up to return from userspace. */
180 180
@@ -187,15 +187,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
187 err |= __put_user(code, (unsigned long __user *)(&frame->retcode[1])); 187 err |= __put_user(code, (unsigned long __user *)(&frame->retcode[1]));
188 188
189 if (err) 189 if (err)
190 goto out; 190 return -EFAULT;
191 191
192 /* Set up registers for signal handler */ 192 /* Set up registers for signal handler */
193 regs->REG_RTP = (unsigned long) frame->retcode; 193 regs->REG_RTP = (unsigned long) frame->retcode;
194 regs->REG_SP = (unsigned long) frame + sizeof(*frame); 194 regs->REG_SP = (unsigned long) frame + sizeof(*frame);
195 regs->REG_ARG1 = sig; 195 regs->REG_ARG1 = ksig->sig;
196 regs->REG_ARG2 = (unsigned long) &frame->info; 196 regs->REG_ARG2 = (unsigned long) &frame->info;
197 regs->REG_ARG3 = (unsigned long) &frame->uc; 197 regs->REG_ARG3 = (unsigned long) &frame->uc;
198 regs->REG_PC = (unsigned long) ka->sa.sa_handler; 198 regs->REG_PC = (unsigned long) ksig->ka.sa.sa_handler;
199 199
200 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08x pr=%08x\n", 200 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08x pr=%08x\n",
201 current->comm, current->pid, frame, regs->REG_PC, 201 current->comm, current->pid, frame, regs->REG_PC,
@@ -205,24 +205,19 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
205 * effective cache flush - directed rather than 'full flush'. 205 * effective cache flush - directed rather than 'full flush'.
206 */ 206 */
207 flush_cache_sigtramp(regs->REG_RTP, sizeof(frame->retcode)); 207 flush_cache_sigtramp(regs->REG_RTP, sizeof(frame->retcode));
208out: 208
209 if (err) {
210 force_sigsegv(sig, current);
211 return -EFAULT;
212 }
213 return 0; 209 return 0;
214} 210}
215 211
216static void handle_signal(unsigned long sig, siginfo_t *info, 212static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
217 struct k_sigaction *ka, struct pt_regs *regs)
218{ 213{
219 sigset_t *oldset = sigmask_to_save(); 214 sigset_t *oldset = sigmask_to_save();
215 int ret;
220 216
221 /* Set up the stack frame */ 217 /* Set up the stack frame */
222 if (setup_rt_frame(sig, ka, info, oldset, regs)) 218 ret = setup_rt_frame(ksig, oldset, regs);
223 return;
224 219
225 signal_delivered(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP)); 220 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
226} 221}
227 222
228 /* 223 /*
@@ -235,10 +230,8 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
235static int do_signal(struct pt_regs *regs, int syscall) 230static int do_signal(struct pt_regs *regs, int syscall)
236{ 231{
237 unsigned int retval = 0, continue_addr = 0, restart_addr = 0; 232 unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
238 struct k_sigaction ka;
239 siginfo_t info;
240 int signr;
241 int restart = 0; 233 int restart = 0;
234 struct ksignal ksig;
242 235
243 /* 236 /*
244 * By the end of rt_sigreturn the context describes the point that the 237 * By the end of rt_sigreturn the context describes the point that the
@@ -275,7 +268,8 @@ static int do_signal(struct pt_regs *regs, int syscall)
275 * Get the signal to deliver. When running under ptrace, at this point 268 * Get the signal to deliver. When running under ptrace, at this point
276 * the debugger may change all our registers ... 269 * the debugger may change all our registers ...
277 */ 270 */
278 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 271 get_signal(&ksig);
272
279 /* 273 /*
280 * Depending on the signal settings we may need to revert the decision 274 * Depending on the signal settings we may need to revert the decision
281 * to restart the system call. But skip this if a debugger has chosen to 275 * to restart the system call. But skip this if a debugger has chosen to
@@ -283,19 +277,19 @@ static int do_signal(struct pt_regs *regs, int syscall)
283 */ 277 */
284 if (regs->REG_PC != restart_addr) 278 if (regs->REG_PC != restart_addr)
285 restart = 0; 279 restart = 0;
286 if (signr > 0) { 280 if (ksig.sig > 0) {
287 if (unlikely(restart)) { 281 if (unlikely(restart)) {
288 if (retval == -ERESTARTNOHAND 282 if (retval == -ERESTARTNOHAND
289 || retval == -ERESTART_RESTARTBLOCK 283 || retval == -ERESTART_RESTARTBLOCK
290 || (retval == -ERESTARTSYS 284 || (retval == -ERESTARTSYS
291 && !(ka.sa.sa_flags & SA_RESTART))) { 285 && !(ksig.ka.sa.sa_flags & SA_RESTART))) {
292 regs->REG_RETVAL = -EINTR; 286 regs->REG_RETVAL = -EINTR;
293 regs->REG_PC = continue_addr; 287 regs->REG_PC = continue_addr;
294 } 288 }
295 } 289 }
296 290
297 /* Whee! Actually deliver the signal. */ 291 /* Whee! Actually deliver the signal. */
298 handle_signal(signr, &info, &ka, regs); 292 handle_signal(&ksig, regs);
299 return 0; 293 return 0;
300 } 294 }
301 295