diff options
Diffstat (limited to 'arch/parisc')
-rw-r--r-- | arch/parisc/hpux/fs.c | 4 | ||||
-rw-r--r-- | arch/parisc/hpux/gate.S | 2 | ||||
-rw-r--r-- | arch/parisc/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/parisc/include/asm/exec.h | 6 | ||||
-rw-r--r-- | arch/parisc/include/asm/thread_info.h | 5 | ||||
-rw-r--r-- | arch/parisc/kernel/process.c | 4 | ||||
-rw-r--r-- | arch/parisc/kernel/signal.c | 45 | ||||
-rw-r--r-- | arch/parisc/kernel/sys_parisc32.c | 4 | ||||
-rw-r--r-- | arch/parisc/kernel/syscall.S | 9 |
9 files changed, 32 insertions, 48 deletions
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index 6785de7bd2a0..a0760b87fd4e 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c @@ -34,14 +34,14 @@ int hpux_execve(struct pt_regs *regs) { int error; - char *filename; + struct filename *filename; filename = getname((const char __user *) regs->gr[26]); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = do_execve(filename, + error = do_execve(filename->name, (const char __user *const __user *) regs->gr[25], (const char __user *const __user *) regs->gr[24], regs); diff --git a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S index 38a1c1b8d4e8..011468857e98 100644 --- a/arch/parisc/hpux/gate.S +++ b/arch/parisc/hpux/gate.S @@ -71,7 +71,7 @@ ENTRY(hpux_gateway_page) STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */ STREG %r27, TASK_PT_GR27(%r1) /* user dp */ STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */ - STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */ + STREG %r0, TASK_PT_ORIG_R28(%r1) /* don't prohibit restarts */ STREG %r29, TASK_PT_GR29(%r1) /* 8th argument */ STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */ diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index 0587f62e5b76..458371a1565a 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm header-y += pdc.h generic-y += clkdev.h generic-y += word-at-a-time.h +generic-y += exec.h diff --git a/arch/parisc/include/asm/exec.h b/arch/parisc/include/asm/exec.h deleted file mode 100644 index 6bb5af75b17a..000000000000 --- a/arch/parisc/include/asm/exec.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __PARISC_EXEC_H -#define __PARISC_EXEC_H - -#define arch_align_stack(x) (x) - -#endif /* __PARISC_EXEC_H */ diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h index 22b4726dee49..d1fb79a36f3d 100644 --- a/arch/parisc/include/asm/thread_info.h +++ b/arch/parisc/include/asm/thread_info.h @@ -68,13 +68,16 @@ struct thread_info { #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_32BIT (1 << TIF_32BIT) -#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP) #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \ _TIF_NEED_RESCHED) +#define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \ + _TIF_BLOCKSTEP) + +#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) #endif /* __KERNEL__ */ diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 8c6b6b6561f0..cbc37216bf90 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -342,13 +342,13 @@ unsigned long thread_saved_pc(struct task_struct *t) asmlinkage int sys_execve(struct pt_regs *regs) { int error; - char *filename; + struct filename *filename; filename = getname((const char __user *) regs->gr[26]); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = do_execve(filename, + error = do_execve(filename->name, (const char __user *const __user *) regs->gr[25], (const char __user *const __user *) regs->gr[24], regs); diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 594459bde14e..537996955998 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -113,6 +113,8 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) (usp - sigframe_size); DBG(2,"sys_rt_sigreturn: frame is %p\n", frame); + regs->orig_r28 = 1; /* no restarts for sigreturn */ + #ifdef CONFIG_64BIT compat_frame = (struct compat_rt_sigframe __user *)frame; @@ -437,7 +439,7 @@ give_sigsegv: * OK, we're invoking a handler. */ -static long +static void handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs, int in_syscall) { @@ -447,7 +449,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, /* Set up the stack frame */ if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) - return 0; + return; signal_delivered(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP) || @@ -455,13 +457,14 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n", regs->gr[28]); - - return 1; } static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) { + if (regs->orig_r28) + return; + regs->orig_r28 = 1; /* no more restarts */ /* Check the return code */ switch (regs->gr[28]) { case -ERESTART_RESTARTBLOCK: @@ -482,8 +485,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) * we have to do is fiddle the return pointer. */ regs->gr[31] -= 8; /* delayed branching */ - /* Preserve original r28. */ - regs->gr[28] = regs->orig_r28; break; } } @@ -491,6 +492,9 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) static inline void insert_restart_trampoline(struct pt_regs *regs) { + if (regs->orig_r28) + return; + regs->orig_r28 = 1; /* no more restarts */ switch(regs->gr[28]) { case -ERESTART_RESTARTBLOCK: { /* Restart the system call - no handlers present */ @@ -525,9 +529,6 @@ insert_restart_trampoline(struct pt_regs *regs) flush_user_icache_range(regs->gr[30], regs->gr[30] + 4); regs->gr[31] = regs->gr[30] + 8; - /* Preserve original r28. */ - regs->gr[28] = regs->orig_r28; - return; } case -ERESTARTNOHAND: @@ -539,9 +540,6 @@ insert_restart_trampoline(struct pt_regs *regs) * slot of the branch external instruction. */ regs->gr[31] -= 8; - /* Preserve original r28. */ - regs->gr[28] = regs->orig_r28; - return; } default: @@ -570,30 +568,17 @@ do_signal(struct pt_regs *regs, long in_syscall) DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n", regs, regs->sr[7], in_syscall); - /* Everyone else checks to see if they are in kernel mode at - this point and exits if that's the case. I'm not sure why - we would be called in that case, but for some reason we - are. */ - - /* May need to force signal if handle_signal failed to deliver */ - while (1) { - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); - if (signr <= 0) - break; - + if (signr > 0) { /* Restart a system call if necessary. */ if (in_syscall) syscall_restart(regs, &ka); - /* Whee! Actually deliver the signal. If the - delivery failed, we need to continue to iterate in - this loop so we can deliver the SIGSEGV... */ - if (handle_signal(signr, &info, &ka, regs, in_syscall)) - return; + handle_signal(signr, &info, &ka, regs, in_syscall); + return; } - /* end of while(1) looping forever if we can't force a signal */ /* Did we come from a system call? */ if (in_syscall) diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index dc9a62462323..bf5b93a885d3 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -60,14 +60,14 @@ asmlinkage int sys32_execve(struct pt_regs *regs) { int error; - char *filename; + struct filename *filename; DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26])); filename = getname((const char __user *) regs->gr[26]); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = compat_do_execve(filename, compat_ptr(regs->gr[25]), + error = compat_do_execve(filename->name, compat_ptr(regs->gr[25]), compat_ptr(regs->gr[24]), regs); putname(filename); out: diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 82a52b2fb13f..86742df0b194 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -156,7 +156,7 @@ linux_gateway_entry: STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */ STREG %r27, TASK_PT_GR27(%r1) /* user dp */ STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */ - STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */ + STREG %r0, TASK_PT_ORIG_R28(%r1) /* don't prohibit restarts */ STREG %r29, TASK_PT_GR29(%r1) /* return value 1 */ STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */ @@ -180,9 +180,10 @@ linux_gateway_entry: /* Are we being ptraced? */ mfctl %cr30, %r1 - LDREG TI_TASK(%r1),%r1 - ldw TASK_PTRACE(%r1), %r1 - bb,<,n %r1,31,.Ltracesys + LDREG TI_FLAGS(%r1),%r1 + ldi _TIF_SYSCALL_TRACE_MASK, %r19 + and,COND(=) %r1, %r19, %r0 + b,n .Ltracesys /* Note! We cannot use the syscall table that is mapped nearby since the gateway page is mapped execute-only. */ |