#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/elf.h>
-#include <asm/ppc32.h>
#include <asm/sigcontext.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
-long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4,
+long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4,
int p6, int p7, struct pt_regs *regs)
{
sigset_t saveset, newset;
}
}
-long sys_sigaltstack(const stack_t *uss, stack_t *uoss, unsigned long r5,
+long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r5,
unsigned long r6, unsigned long r7, unsigned long r8,
struct pt_regs *regs)
{
* Set up the sigcontext for the signal frame.
*/
-static long setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
int signr, sigset_t *set, unsigned long handler)
{
/* When CONFIG_ALTIVEC is set, we _always_ setup v_regs even if the
* v_regs pointer or not
*/
#ifdef CONFIG_ALTIVEC
- elf_vrreg_t *v_regs = (elf_vrreg_t *)(((unsigned long)sc->vmx_reserve) & ~0xful);
+ elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *)(((unsigned long)sc->vmx_reserve + 15) & ~0xful);
#endif
long err = 0;
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
+ flush_fp_to_thread(current);
/* Make sure signal doesn't get spurrious FP exceptions */
current->thread.fpscr = 0;
err |= __put_user(v_regs, &sc->v_regs);
/* save altivec registers */
- if (current->thread.used_vr) {
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
+ if (current->thread.used_vr) {
+ flush_altivec_to_thread(current);
/* Copy 33 vec registers (vr0..31 and vscr) to the stack */
err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128));
/* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg)
/* We always copy to/from vrsave, it's 0 if we don't have or don't
* use altivec.
*/
- err |= __put_user(current->thread.vrsave, (u32 *)&v_regs[33]);
+ err |= __put_user(current->thread.vrsave, (u32 __user *)&v_regs[33]);
#else /* CONFIG_ALTIVEC */
err |= __put_user(0, &sc->v_regs);
#endif /* CONFIG_ALTIVEC */
*/
static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
- struct sigcontext *sc)
+ struct sigcontext __user *sc)
{
#ifdef CONFIG_ALTIVEC
- elf_vrreg_t *v_regs;
+ elf_vrreg_t __user *v_regs;
#endif
unsigned long err = 0;
- unsigned long save_r13;
+ unsigned long save_r13 = 0;
elf_greg_t *gregs = (elf_greg_t *)regs;
int i;
memset(¤t->thread.vr, 0, 33);
/* Always get VRSAVE back */
if (v_regs != 0)
- err |= __get_user(current->thread.vrsave, (u32 *)&v_regs[33]);
+ err |= __get_user(current->thread.vrsave, (u32 __user *)&v_regs[33]);
else
current->thread.vrsave = 0;
#endif /* CONFIG_ALTIVEC */
/*
* Allocate space for the signal frame
*/
-static inline void * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
size_t frame_size)
{
unsigned long newsp;
newsp = (current->sas_ss_sp + current->sas_ss_size);
}
- return (void *)((newsp - frame_size) & -8ul);
+ return (void __user *)((newsp - frame_size) & -8ul);
}
/*
* Setup the trampoline code on the stack
*/
-static long setup_trampoline(unsigned int syscall, unsigned int *tramp)
+static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp)
{
int i;
long err = 0;
if (new_ctx == NULL)
return 0;
if (verify_area(VERIFY_READ, new_ctx, sizeof(*new_ctx))
- || __get_user(tmp, (u8 *) new_ctx)
- || __get_user(tmp, (u8 *) (new_ctx + 1) - 1))
+ || __get_user(tmp, (u8 __user *) new_ctx)
+ || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1))
return -EFAULT;
/*
unsigned long r6, unsigned long r7, unsigned long r8,
struct pt_regs *regs)
{
- struct ucontext *uc = (struct ucontext *)regs->gpr[1];
+ struct ucontext __user *uc = (struct ucontext __user *)regs->gpr[1];
sigset_t set;
/* Always make any pending restarted system calls return -EINTR */
printk("badframe in sys_rt_sigreturn, regs=%p uc=%p &uc->uc_mcontext=%p\n",
regs, uc, &uc->uc_mcontext);
#endif
- do_exit(SIGSEGV);
+ force_sig(SIGSEGV, current);
+ return 0;
}
static void setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
* descriptor is the entry address of signal and the second
* entry is the TOC value we need to use.
*/
- func_descr_t *funct_desc_ptr;
- struct rt_sigframe *frame;
+ func_descr_t __user *funct_desc_ptr;
+ struct rt_sigframe __user *frame;
unsigned long newsp = 0;
long err = 0;
if (err)
goto badframe;
- funct_desc_ptr = (func_descr_t *) ka->sa.sa_handler;
+ funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler;
/* Allocate a dummy caller frame for the signal handler. */
newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE;
- err |= put_user(0, (unsigned long *)newsp);
+ err |= put_user(0, (unsigned long __user *)newsp);
/* Set up "regs" so we "return" to the signal handler. */
err |= get_user(regs->nip, &funct_desc_ptr->entry);
regs->gpr[3] = signr;
regs->result = 0;
if (ka->sa.sa_flags & SA_SIGINFO) {
- err |= get_user(regs->gpr[4], (unsigned long *)&frame->pinfo);
- err |= get_user(regs->gpr[5], (unsigned long *)&frame->puc);
+ err |= get_user(regs->gpr[4], (unsigned long __user *)&frame->pinfo);
+ err |= get_user(regs->gpr[5], (unsigned long __user *)&frame->puc);
regs->gpr[6] = (unsigned long) frame;
} else {
regs->gpr[4] = (unsigned long)&frame->uc.uc_mcontext;
printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
#endif
- do_exit(SIGSEGV);
+ force_sigsegv(signr, current);
}
/* Set up Signal Frame */
setup_rt_frame(sig, ka, info, oldset, regs);
- if (ka->sa.sa_flags & SA_ONESHOT)
- ka->sa.sa_handler = SIG_DFL;
-
if (!(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(¤t->sighand->siglock);
- sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
+ sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask);
sigaddset(¤t->blocked,sig);
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
}
- return;
}
static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
{
siginfo_t info;
int signr;
+ struct k_sigaction ka;
/*
* If the current thread is 32 bit - invoke the
if (!oldset)
oldset = ¤t->blocked;
- signr = get_signal_to_deliver(&info, regs, NULL);
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
- struct k_sigaction *ka = ¤t->sighand->action[signr-1];
-
/* Whee! Actually deliver the signal. */
- if (regs->trap == 0x0C00)
- syscall_restart(regs, ka);
- handle_signal(signr, ka, &info, oldset, regs);
+ if (TRAP(regs) == 0x0C00)
+ syscall_restart(regs, &ka);
+ handle_signal(signr, &ka, &info, oldset, regs);
return 1;
}
- if (regs->trap == 0x0C00) { /* System Call! */
+ if (TRAP(regs) == 0x0C00) { /* System Call! */
if ((int)regs->result == -ERESTARTNOHAND ||
(int)regs->result == -ERESTARTSYS ||
(int)regs->result == -ERESTARTNOINTR) {