Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1c9bb1a01ac1bc92a0d98cf3e40a7922ee684dc0 Commit: 1c9bb1a01ac1bc92a0d98cf3e40a7922ee684dc0 Parent: bb63ab13515951f4d09b16c9e8bd6e50b0f20d1e Author: Paul Mackerras <[EMAIL PROTECTED]> AuthorDate: Wed Dec 20 13:57:06 2006 +1100 Committer: Paul Mackerras <[EMAIL PROTECTED]> CommitDate: Wed Dec 20 16:37:49 2006 +1100
[POWERPC] Fix register save area alignment for swapcontext syscall For 32-bit processes, the getcontext side of the swapcontext system call (i.e. the saving of the context when the first argument is non-NULL) has to set the ctx->uc_mcontext.uc_regs pointer to the place where it saves the registers. Which it does, but it doesn't ensure that the pointer is 16-byte aligned. 16-byte alignment is needed because the Altivec/VMX registers are saved in there, and they need to be on a 16-byte boundary. This fixes it by ensuring the appropriate alignment of the pointer. This issue was pointed out by Jakub Jelinek. Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]> --- arch/powerpc/kernel/signal_32.c | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index e4ebe1a..6b405a3 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -835,11 +835,21 @@ long sys_swapcontext(struct ucontext __user *old_ctx, return -EINVAL; if (old_ctx != NULL) { + struct mcontext __user *mctx; + + /* + * old_ctx might not be 16-byte aligned, in which + * case old_ctx->uc_mcontext won't be either. + * Because we have the old_ctx->uc_pad2 field + * before old_ctx->uc_mcontext, we need to round down + * from &old_ctx->uc_mcontext to a 16-byte boundary. + */ + mctx = (struct mcontext __user *) + ((unsigned long) &old_ctx->uc_mcontext & ~0xfUL); if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx)) - || save_user_regs(regs, &old_ctx->uc_mcontext, 0) + || save_user_regs(regs, mctx, 0) || put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked) - || __put_user(to_user_ptr(&old_ctx->uc_mcontext), - &old_ctx->uc_regs)) + || __put_user(to_user_ptr(mctx), &old_ctx->uc_regs)) return -EFAULT; } if (new_ctx == NULL) - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html