#include <asm/ppcdebug.h>
#include <asm/unistd.h>
#include <asm/cacheflush.h>
+#include <asm/vdso.h>
#define DEBUG_SIG 0
*
*/
struct rt_sigframe32 {
- struct compat_siginfo info;
+ compat_siginfo_t info;
struct ucontext32 uc;
/*
* Programs using the rs6000/xcoff abi can save up to 19 gp
* sigpending sys32_rt_sigpending
* sigprocmask sys32_rt_sigprocmask
* sigreturn sys32_rt_sigreturn
- * sigtimedwait sys32_rt_sigtimedwait
* sigqueueinfo sys32_rt_sigqueueinfo
* sigsuspend sys32_rt_sigsuspend
*
}
-static long copy_siginfo_to_user32(compat_siginfo_t __user *d, siginfo_t *s)
+int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
{
- long err;
+ int err;
if (!access_ok (VERIFY_WRITE, d, sizeof(*d)))
return -EFAULT;
return err;
}
-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;
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs();
- siginfo_t info;
-
- if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
- return -EFAULT;
- sigset_from_compat(&s, &s32);
- if (uts && get_compat_timespec(&t, uts))
- return -EFAULT;
- set_fs(KERNEL_DS);
- /* 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) {
- if (copy_siginfo_to_user32(uinfo, &info))
- return -EFAULT;
- }
- return ret;
-}
-
/*
* Note: it is necessary to treat pid and sig as unsigned ints, with the
* corresponding cast to a signed int to insure that the proper conversion
/* create a stack frame for the caller of the handler */
newsp -= __SIGNAL_FRAMESIZE32 + 16;
- if (verify_area(VERIFY_WRITE, (void __user *)newsp, origsp - newsp))
+ if (!access_ok(VERIFY_WRITE, (void __user *)newsp, origsp - newsp))
goto badframe;
compat_from_sigset(&c_oldset, oldset);
/* Save user registers on the stack */
frame = &rt_sf->uc.uc_mcontext;
- if (save_user_regs(regs, frame, __NR_rt_sigreturn))
+ if (put_user(regs->gpr[1], (u32 __user *)newsp))
goto badframe;
- if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
- goto badframe;
+ if (vdso32_rt_sigtramp && current->thread.vdso_base) {
+ if (save_user_regs(regs, frame, 0))
+ goto badframe;
+ regs->link = current->thread.vdso_base + vdso32_rt_sigtramp;
+ } else {
+ if (save_user_regs(regs, frame, __NR_rt_sigreturn))
+ goto badframe;
+ regs->link = (unsigned long) frame->tramp;
+ }
regs->gpr[1] = (unsigned long) newsp;
regs->gpr[3] = sig;
regs->gpr[4] = (unsigned long) &rt_sf->info;
regs->gpr[5] = (unsigned long) &rt_sf->uc;
regs->gpr[6] = (unsigned long) rt_sf;
regs->nip = (unsigned long) ka->sa.sa_handler;
- regs->link = (unsigned long) frame->tramp;
regs->trap = 0;
regs->result = 0;
if (old_ctx != NULL) {
compat_from_sigset(&c_set, ¤t->blocked);
- if (verify_area(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
+ if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
|| save_user_regs(regs, &old_ctx->uc_mcontext, 0)
|| __copy_to_user(&old_ctx->uc_sigmask, &c_set, sizeof(c_set))
|| __put_user((u32)(u64)&old_ctx->uc_mcontext, &old_ctx->uc_regs))
}
if (new_ctx == NULL)
return 0;
- if (verify_area(VERIFY_READ, new_ctx, sizeof(*new_ctx))
+ if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx))
|| __get_user(tmp, (u8 __user *) new_ctx)
|| __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1))
return -EFAULT;
* image of the user's registers, we can't just return -EFAULT
* because the user's registers will be corrupted. For instance
* the NIP value may have been updated but not some of the
- * other registers. Given that we have done the verify_area
+ * other registers. Given that we have done the access_ok
* and successfully read the first and last bytes of the region
* above, this should only happen in an out-of-memory situation
* or if another thread unmaps the region containing the context.
rt_sf = (struct rt_sigframe32 __user *)
(regs->gpr[1] + __SIGNAL_FRAMESIZE32 + 16);
- if (verify_area(VERIFY_READ, rt_sf, sizeof(*rt_sf)))
+ if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf)))
goto bad;
if (do_setcontext32(&rt_sf->uc, regs, 1))
goto bad;
/* create a stack frame for the caller of the handler */
newsp -= __SIGNAL_FRAMESIZE32;
- if (verify_area(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
+ if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
goto badframe;
#if _NSIG != 64
|| __put_user(sig, &sc->signal))
goto badframe;
- if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
- goto badframe;
+ if (vdso32_sigtramp && current->thread.vdso_base) {
+ if (save_user_regs(regs, &frame->mctx, 0))
+ goto badframe;
+ regs->link = current->thread.vdso_base + vdso32_sigtramp;
+ } else {
+ if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
+ goto badframe;
+ regs->link = (unsigned long) frame->mctx.tramp;
+ }
- if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
+ if (put_user(regs->gpr[1], (u32 __user *)newsp))
goto badframe;
regs->gpr[1] = (unsigned long) newsp;
regs->gpr[3] = sig;
regs->gpr[4] = (unsigned long) sc;
regs->nip = (unsigned long) ka->sa.sa_handler;
- regs->link = (unsigned long) frame->mctx.tramp;
regs->trap = 0;
regs->result = 0;
restore_sigmask(&set);
sr = (struct mcontext32 __user *)(u64)sigctx.regs;
- if (verify_area(VERIFY_READ, sr, sizeof(*sr))
+ if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
|| restore_user_regs(regs, sr, 1))
goto badframe;