aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m32r
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2010-10-12 10:41:22 -0400
committerThomas Gleixner <tglx@linutronix.de>2010-10-12 10:41:26 -0400
commit7c5f13519a67aa7ba3a99155f128d4bdef87d087 (patch)
treee4d0537092930a53a85932de83a7861990c58607 /arch/m32r
parent5e62feabcc3e4127a084701ec54ffe891985b7e8 (diff)
parent021989622810b02aab4b24f91e1f5ada2b654579 (diff)
Merge branch 'x86/urgent' of into irq/sparseirq
Reason: Pull in the latest io_apic bugfixes Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/m32r')
-rw-r--r--arch/m32r/include/asm/signal.h1
-rw-r--r--arch/m32r/include/asm/unistd.h1
-rw-r--r--arch/m32r/kernel/entry.S5
-rw-r--r--arch/m32r/kernel/ptrace.c7
-rw-r--r--arch/m32r/kernel/signal.c105
5 files changed, 48 insertions, 71 deletions
diff --git a/arch/m32r/include/asm/signal.h b/arch/m32r/include/asm/signal.h
index 9c1acb2b1a92..b2eeb0de1c8d 100644
--- a/arch/m32r/include/asm/signal.h
+++ b/arch/m32r/include/asm/signal.h
@@ -157,7 +157,6 @@ typedef struct sigaltstack {
157#undef __HAVE_ARCH_SIG_BITOPS 157#undef __HAVE_ARCH_SIG_BITOPS
158 158
159struct pt_regs; 159struct pt_regs;
160extern int do_signal(struct pt_regs *regs, sigset_t *oldset);
161 160
162#define ptrace_signal_deliver(regs, cookie) do { } while (0) 161#define ptrace_signal_deliver(regs, cookie) do { } while (0)
163 162
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h
index 76125777483c..c70545689da8 100644
--- a/arch/m32r/include/asm/unistd.h
+++ b/arch/m32r/include/asm/unistd.h
@@ -351,6 +351,7 @@
351#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/ 351#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
352#define __ARCH_WANT_SYS_OLDUMOUNT 352#define __ARCH_WANT_SYS_OLDUMOUNT
353#define __ARCH_WANT_SYS_RT_SIGACTION 353#define __ARCH_WANT_SYS_RT_SIGACTION
354#define __ARCH_WANT_SYS_RT_SIGSUSPEND
354 355
355#define __IGNORE_lchown 356#define __IGNORE_lchown
356#define __IGNORE_setuid 357#define __IGNORE_setuid
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index 403869833b98..225412bc227e 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -235,10 +235,9 @@ work_resched:
235work_notifysig: ; deal with pending signals and 235work_notifysig: ; deal with pending signals and
236 ; notify-resume requests 236 ; notify-resume requests
237 mv r0, sp ; arg1 : struct pt_regs *regs 237 mv r0, sp ; arg1 : struct pt_regs *regs
238 ldi r1, #0 ; arg2 : sigset_t *oldset 238 mv r1, r9 ; arg2 : __u32 thread_info_flags
239 mv r2, r9 ; arg3 : __u32 thread_info_flags
240 bl do_notify_resume 239 bl do_notify_resume
241 bra restore_all 240 bra resume_userspace
242 241
243 ; perform syscall exit tracing 242 ; perform syscall exit tracing
244 ALIGN 243 ALIGN
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index e555091eb97c..0021ade4cba8 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -592,16 +592,17 @@ void user_enable_single_step(struct task_struct *child)
592 592
593 if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) 593 if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
594 != sizeof(insn)) 594 != sizeof(insn))
595 break; 595 return -EIO;
596 596
597 compute_next_pc(insn, pc, &next_pc, child); 597 compute_next_pc(insn, pc, &next_pc, child);
598 if (next_pc & 0x80000000) 598 if (next_pc & 0x80000000)
599 break; 599 return -EIO;
600 600
601 if (embed_debug_trap(child, next_pc)) 601 if (embed_debug_trap(child, next_pc))
602 break; 602 return -EIO;
603 603
604 invalidate_cache(); 604 invalidate_cache();
605 return 0;
605} 606}
606 607
607void user_disable_single_step(struct task_struct *child) 608void user_disable_single_step(struct task_struct *child)
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 144b0f124fc7..7bbe38645ed5 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -28,37 +28,6 @@
28 28
29#define DEBUG_SIG 0 29#define DEBUG_SIG 0
30 30
31#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
32
33int do_signal(struct pt_regs *, sigset_t *);
34
35asmlinkage int
36sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
37 unsigned long r2, unsigned long r3, unsigned long r4,
38 unsigned long r5, unsigned long r6, struct pt_regs *regs)
39{
40 sigset_t newset;
41
42 /* XXX: Don't preclude handling different sized sigset_t's. */
43 if (sigsetsize != sizeof(sigset_t))
44 return -EINVAL;
45
46 if (copy_from_user(&newset, unewset, sizeof(newset)))
47 return -EFAULT;
48 sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
49
50 spin_lock_irq(&current->sighand->siglock);
51 current->saved_sigmask = current->blocked;
52 current->blocked = newset;
53 recalc_sigpending();
54 spin_unlock_irq(&current->sighand->siglock);
55
56 current->state = TASK_INTERRUPTIBLE;
57 schedule();
58 set_thread_flag(TIF_RESTORE_SIGMASK);
59 return -ERESTARTNOHAND;
60}
61
62asmlinkage int 31asmlinkage int
63sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 32sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
64 unsigned long r2, unsigned long r3, unsigned long r4, 33 unsigned long r2, unsigned long r3, unsigned long r4,
@@ -218,7 +187,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
218 return (void __user *)((sp - frame_size) & -8ul); 187 return (void __user *)((sp - frame_size) & -8ul);
219} 188}
220 189
221static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 190static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
222 sigset_t *set, struct pt_regs *regs) 191 sigset_t *set, struct pt_regs *regs)
223{ 192{
224 struct rt_sigframe __user *frame; 193 struct rt_sigframe __user *frame;
@@ -275,22 +244,34 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
275 current->comm, current->pid, frame, regs->pc); 244 current->comm, current->pid, frame, regs->pc);
276#endif 245#endif
277 246
278 return; 247 return 0;
279 248
280give_sigsegv: 249give_sigsegv:
281 force_sigsegv(sig, current); 250 force_sigsegv(sig, current);
251 return -EFAULT;
252}
253
254static int prev_insn(struct pt_regs *regs)
255{
256 u16 inst;
257 if (get_user(&inst, (u16 __user *)(regs->bpc - 2)))
258 return -EFAULT;
259 if ((inst & 0xfff0) == 0x10f0) /* trap ? */
260 regs->bpc -= 2;
261 else
262 regs->bpc -= 4;
263 regs->syscall_nr = -1;
264 return 0;
282} 265}
283 266
284/* 267/*
285 * OK, we're invoking a handler 268 * OK, we're invoking a handler
286 */ 269 */
287 270
288static void 271static int
289handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, 272handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
290 sigset_t *oldset, struct pt_regs *regs) 273 sigset_t *oldset, struct pt_regs *regs)
291{ 274{
292 unsigned short inst;
293
294 /* Are we from a system call? */ 275 /* Are we from a system call? */
295 if (regs->syscall_nr >= 0) { 276 if (regs->syscall_nr >= 0) {
296 /* If so, check system call restarting.. */ 277 /* If so, check system call restarting.. */
@@ -308,16 +289,14 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
308 /* fallthrough */ 289 /* fallthrough */
309 case -ERESTARTNOINTR: 290 case -ERESTARTNOINTR:
310 regs->r0 = regs->orig_r0; 291 regs->r0 = regs->orig_r0;
311 inst = *(unsigned short *)(regs->bpc - 2); 292 if (prev_insn(regs) < 0)
312 if ((inst & 0xfff0) == 0x10f0) /* trap ? */ 293 return -EFAULT;
313 regs->bpc -= 2;
314 else
315 regs->bpc -= 4;
316 } 294 }
317 } 295 }
318 296
319 /* Set up the stack frame */ 297 /* Set up the stack frame */
320 setup_rt_frame(sig, ka, info, oldset, regs); 298 if (setup_rt_frame(sig, ka, info, oldset, regs))
299 return -EFAULT;
321 300
322 spin_lock_irq(&current->sighand->siglock); 301 spin_lock_irq(&current->sighand->siglock);
323 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 302 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -325,6 +304,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
325 sigaddset(&current->blocked,sig); 304 sigaddset(&current->blocked,sig);
326 recalc_sigpending(); 305 recalc_sigpending();
327 spin_unlock_irq(&current->sighand->siglock); 306 spin_unlock_irq(&current->sighand->siglock);
307 return 0;
328} 308}
329 309
330/* 310/*
@@ -332,12 +312,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
332 * want to handle. Thus you cannot kill init even with a SIGKILL even by 312 * want to handle. Thus you cannot kill init even with a SIGKILL even by
333 * mistake. 313 * mistake.
334 */ 314 */
335int do_signal(struct pt_regs *regs, sigset_t *oldset) 315static void do_signal(struct pt_regs *regs)
336{ 316{
337 siginfo_t info; 317 siginfo_t info;
338 int signr; 318 int signr;
339 struct k_sigaction ka; 319 struct k_sigaction ka;
340 unsigned short inst; 320 sigset_t *oldset;
341 321
342 /* 322 /*
343 * We want the common case to go fast, which 323 * We want the common case to go fast, which
@@ -346,12 +326,14 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
346 * if so. 326 * if so.
347 */ 327 */
348 if (!user_mode(regs)) 328 if (!user_mode(regs))
349 return 1; 329 return;
350 330
351 if (try_to_freeze()) 331 if (try_to_freeze())
352 goto no_signal; 332 goto no_signal;
353 333
354 if (!oldset) 334 if (test_thread_flag(TIF_RESTORE_SIGMASK))
335 oldset = &current->saved_sigmask;
336 else
355 oldset = &current->blocked; 337 oldset = &current->blocked;
356 338
357 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 339 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -363,8 +345,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
363 */ 345 */
364 346
365 /* Whee! Actually deliver the signal. */ 347 /* Whee! Actually deliver the signal. */
366 handle_signal(signr, &ka, &info, oldset, regs); 348 if (handle_signal(signr, &ka, &info, oldset, regs) == 0)
367 return 1; 349 clear_thread_flag(TIF_RESTORE_SIGMASK);
350
351 return;
368 } 352 }
369 353
370 no_signal: 354 no_signal:
@@ -375,31 +359,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
375 regs->r0 == -ERESTARTSYS || 359 regs->r0 == -ERESTARTSYS ||
376 regs->r0 == -ERESTARTNOINTR) { 360 regs->r0 == -ERESTARTNOINTR) {
377 regs->r0 = regs->orig_r0; 361 regs->r0 = regs->orig_r0;
378 inst = *(unsigned short *)(regs->bpc - 2); 362 prev_insn(regs);
379 if ((inst & 0xfff0) == 0x10f0) /* trap ? */ 363 } else if (regs->r0 == -ERESTART_RESTARTBLOCK){
380 regs->bpc -= 2;
381 else
382 regs->bpc -= 4;
383 }
384 if (regs->r0 == -ERESTART_RESTARTBLOCK){
385 regs->r0 = regs->orig_r0; 364 regs->r0 = regs->orig_r0;
386 regs->r7 = __NR_restart_syscall; 365 regs->r7 = __NR_restart_syscall;
387 inst = *(unsigned short *)(regs->bpc - 2); 366 prev_insn(regs);
388 if ((inst & 0xfff0) == 0x10f0) /* trap ? */
389 regs->bpc -= 2;
390 else
391 regs->bpc -= 4;
392 } 367 }
393 } 368 }
394 return 0; 369 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
370 clear_thread_flag(TIF_RESTORE_SIGMASK);
371 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
372 }
395} 373}
396 374
397/* 375/*
398 * notification of userspace execution resumption 376 * notification of userspace execution resumption
399 * - triggered by current->work.notify_resume 377 * - triggered by current->work.notify_resume
400 */ 378 */
401void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, 379void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
402 __u32 thread_info_flags)
403{ 380{
404 /* Pending single-step? */ 381 /* Pending single-step? */
405 if (thread_info_flags & _TIF_SINGLESTEP) 382 if (thread_info_flags & _TIF_SINGLESTEP)
@@ -407,7 +384,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
407 384
408 /* deal with pending signal delivery */ 385 /* deal with pending signal delivery */
409 if (thread_info_flags & _TIF_SIGPENDING) 386 if (thread_info_flags & _TIF_SIGPENDING)
410 do_signal(regs,oldset); 387 do_signal(regs);
411 388
412 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 389 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
413 clear_thread_flag(TIF_NOTIFY_RESUME); 390 clear_thread_flag(TIF_NOTIFY_RESUME);