* We only save the altivec registers if the process has used
* altivec instructions at some point.
*/
-static int save_user_regs(struct pt_regs *regs, struct mcontext32 *frame, int sigret)
+static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, int sigret)
{
elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
int i, err = 0;
-
- /* Make sure floating point registers are stored in regs */
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
-
+
+ /* Make sure floating point registers are stored in regs */
+ flush_fp_to_thread(current);
+
/* save general and floating-point registers */
for (i = 0; i <= PT_RESULT; i ++)
err |= __put_user((unsigned int)gregs[i], &frame->mc_gregs[i]);
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
+ flush_altivec_to_thread(current);
if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
ELF_NVRREG32 * sizeof(vector128)))
return 1;
* significant bits of a vector, we "cheat" and stuff VRSAVE in the
* most significant bits of that same vector. --BenH
*/
- if (__put_user(current->thread.vrsave, (u32 *)&frame->mc_vregs[32]))
+ if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
return 1;
#endif /* CONFIG_ALTIVEC */
memset(¤t->thread.vr, 0, ELF_NVRREG32 * sizeof(vector128));
/* Always get VRSAVE back */
- if (__get_user(current->thread.vrsave, (u32 *)&sr->mc_vregs[32]))
+ if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
return 1;
#endif /* CONFIG_ALTIVEC */
}
}
-long sys32_sigaction(int sig, struct old_sigaction32 *act,
- struct old_sigaction32 *oact)
+long sys32_sigaction(int sig, struct old_sigaction32 __user *act,
+ struct old_sigaction32 __user *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;
if (act) {
compat_old_sigset_t mask;
+ compat_uptr_t handler, restorer;
- if (get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer) ||
+ if (get_user(handler, &act->sa_handler) ||
+ __get_user(restorer, &act->sa_restorer) ||
__get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
__get_user(mask, &act->sa_mask))
return -EFAULT;
+ new_ka.sa.sa_handler = compat_ptr(handler);
+ new_ka.sa.sa_restorer = compat_ptr(restorer);
siginitset(&new_ka.sa.sa_mask, mask);
}
*/
-long sys32_rt_sigaction(int sig, const struct sigaction32 *act,
- struct sigaction32 *oact, size_t sigsetsize)
+long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
+ struct sigaction32 __user *oact, size_t sigsetsize)
{
struct k_sigaction new_ka, old_ka;
int ret;
return -EINVAL;
if (act) {
- ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
+ compat_uptr_t handler;
+
+ ret = get_user(handler, &act->sa_handler);
+ new_ka.sa.sa_handler = compat_ptr(handler);
ret |= __copy_from_user(&set32, &act->sa_mask,
sizeof(compat_sigset_t));
sigset_from_compat(&new_ka.sa.sa_mask, &set32);
* of a signed int (msr in 32-bit mode) and the register representation
* of a signed int (msr in 64-bit mode) is performed.
*/
-long sys32_rt_sigprocmask(u32 how, compat_sigset_t *set,
- compat_sigset_t *oset, size_t sigsetsize)
+long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set,
+ compat_sigset_t __user *oset, size_t sigsetsize)
{
sigset_t s;
+ sigset_t __user *up;
compat_sigset_t s32;
int ret;
mm_segment_t old_fs = get_fs();
}
set_fs(KERNEL_DS);
- ret = sys_rt_sigprocmask((int)how, set ? &s : NULL, oset ? &s : NULL,
+ /* This is valid because of the set_fs() */
+ up = (sigset_t __user *) &s;
+ ret = sys_rt_sigprocmask((int)how, set ? up : NULL, oset ? up : NULL,
sigsetsize);
set_fs(old_fs);
if (ret)
return 0;
}
-long sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize)
+long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
{
sigset_t s;
compat_sigset_t s32;
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
- ret = sys_rt_sigpending(&s, sigsetsize);
+ /* The __user pointer cast is valid because of the set_fs() */
+ ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize);
set_fs(old_fs);
if (!ret) {
compat_from_sigset(&s32, &s);
}
-static long copy_siginfo_to_user32(compat_siginfo_t *d, siginfo_t *s)
+static long copy_siginfo_to_user32(compat_siginfo_t __user *d, siginfo_t *s)
{
long err;
return err;
}
-long sys32_rt_sigtimedwait(compat_sigset_t *uthese, compat_siginfo_t *uinfo,
- struct compat_timespec *uts, compat_size_t sigsetsize)
+long sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, compat_siginfo_t __user *uinfo,
+ struct compat_timespec __user *uts, compat_size_t sigsetsize)
{
sigset_t s;
compat_sigset_t s32;
if (uts && get_compat_timespec(&t, uts))
return -EFAULT;
set_fs(KERNEL_DS);
- ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL,
+ /* The __user pointer casts are valid because of the set_fs() */
+ ret = sys_rt_sigtimedwait((sigset_t __user *) &s,
+ uinfo ? (siginfo_t __user *) &info : NULL,
+ uts ? (struct timespec __user *) &t : NULL,
sigsetsize);
set_fs(old_fs);
if (ret >= 0 && uinfo) {
* (msr in 32-bit mode) and the register representation of a signed int
* (msr in 64-bit mode) is performed.
*/
-long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t *uinfo)
+long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
{
siginfo_t info;
int ret;
copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32))
return -EFAULT;
set_fs (KERNEL_DS);
- ret = sys_rt_sigqueueinfo((int)pid, (int)sig, &info);
+ /* The __user pointer cast is valid becasuse of the set_fs() */
+ ret = sys_rt_sigqueueinfo((int)pid, (int)sig, (siginfo_t __user *) &info);
set_fs (old_fs);
return ret;
}
-int sys32_rt_sigsuspend(compat_sigset_t* unewset, size_t sigsetsize, int p3,
+int sys32_rt_sigsuspend(compat_sigset_t __user * unewset, size_t sigsetsize, int p3,
int p4, int p6, int p7, struct pt_regs *regs)
{
sigset_t saveset, newset;
* sigaltatck sys32_sigaltstack
*/
-int sys32_sigaltstack(u32 newstack, u32 oldstack, int r5,
+int sys32_sigaltstack(u32 __new, u32 __old, int r5,
int r6, int r7, int r8, struct pt_regs *regs)
{
+ stack_32_t __user * newstack = (stack_32_t __user *)(long) __new;
+ stack_32_t __user * oldstack = (stack_32_t __user *)(long) __old;
stack_t uss, uoss;
int ret;
mm_segment_t old_fs;
unsigned long sp;
+ compat_uptr_t ss_sp;
/*
* set sp to the user stack on entry to the system call
sp = regs->gpr[1];
/* Put new stack info in local 64 bit stack struct */
- if (newstack &&
- (get_user((long)uss.ss_sp,
- &((stack_32_t *)(long)newstack)->ss_sp) ||
- __get_user(uss.ss_flags,
- &((stack_32_t *)(long)newstack)->ss_flags) ||
- __get_user(uss.ss_size,
- &((stack_32_t *)(long)newstack)->ss_size)))
- return -EFAULT;
+ if (newstack) {
+ if (get_user(ss_sp, &newstack->ss_sp) ||
+ __get_user(uss.ss_flags, &newstack->ss_flags) ||
+ __get_user(uss.ss_size, &newstack->ss_size))
+ return -EFAULT;
+ uss.ss_sp = compat_ptr(ss_sp);
+ }
old_fs = get_fs();
set_fs(KERNEL_DS);
- ret = do_sigaltstack(newstack ? &uss : NULL, oldstack ? &uoss : NULL,
- sp);
+ /* The __user pointer casts are valid because of the set_fs() */
+ ret = do_sigaltstack(
+ newstack ? (stack_t __user *) &uss : NULL,
+ oldstack ? (stack_t __user *) &uoss : NULL,
+ sp);
set_fs(old_fs);
/* Copy the stack information to the user output buffer */
if (!ret && oldstack &&
- (put_user((long)uoss.ss_sp,
- &((stack_32_t *)(long)oldstack)->ss_sp) ||
- __put_user(uoss.ss_flags,
- &((stack_32_t *)(long)oldstack)->ss_flags) ||
- __put_user(uoss.ss_size,
- &((stack_32_t *)(long)oldstack)->ss_size)))
+ (put_user((long)uoss.ss_sp, &oldstack->ss_sp) ||
+ __put_user(uoss.ss_flags, &oldstack->ss_flags) ||
+ __put_user(uoss.ss_size, &oldstack->ss_size)))
return -EFAULT;
return ret;
}
return -EFAULT;
sigset_from_compat(&set, &c_set);
restore_sigmask(&set);
- if (restore_user_regs(regs, (struct mcontext32 *)(u64)mcp, sig))
+ if (restore_user_regs(regs, (struct mcontext32 __user *)(u64)mcp, sig))
return -EFAULT;
return 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;
/*
/* create a stack frame for the caller of the handler */
newsp -= __SIGNAL_FRAMESIZE32;
- if (verify_area(VERIFY_WRITE, (void *) newsp, origsp - newsp))
+ if (verify_area(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
goto badframe;
#if _NSIG != 64
set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32);
restore_sigmask(&set);
- sr = (struct mcontext32 *)(u64)sigctx.regs;
+ sr = (struct mcontext32 __user *)(u64)sigctx.regs;
if (verify_area(VERIFY_READ, sr, sizeof(*sr))
|| restore_user_regs(regs, sr, 1))
goto badframe;
ka = (signr == 0)? NULL: ¤t->sighand->action[signr-1];
- if (regs->trap == 0x0C00 /* System Call! */
+ if (TRAP(regs) == 0x0C00 /* System Call! */
&& regs->ccr & 0x10000000 /* error signalled */
&& ((ret = regs->gpr[3]) == ERESTARTSYS
|| ret == ERESTARTNOHAND || ret == ERESTARTNOINTR