提交 0be234a4 编写于 作者: B Benjamin Herrenschmidt 提交者: Paul Mackerras

[POWERPC] Fix incorrect enabling of VMX when building signal or user context

When building a signal or a ucontext, we can incorrectly set the MSR_VEC
bit of the kernel pt_regs->msr before returning to userspace if the task
-ever- used VMX.

This can lead to funny result if that stack used it in the past, then
"lost" it (ie. it wasn't enabled after a context switch for example)
and then called get_context.  It can end up with VMX enabled and the
registers containing values from some other task.
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: NPaul Mackerras <paulus@samba.org>
上级 efa58fbf
...@@ -87,6 +87,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, ...@@ -87,6 +87,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
#ifdef CONFIG_ALTIVEC #ifdef CONFIG_ALTIVEC
elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *)(((unsigned long)sc->vmx_reserve + 15) & ~0xful); elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *)(((unsigned long)sc->vmx_reserve + 15) & ~0xful);
#endif #endif
unsigned long msr = regs->msr;
long err = 0; long err = 0;
flush_fp_to_thread(current); flush_fp_to_thread(current);
...@@ -102,7 +103,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, ...@@ -102,7 +103,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
/* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg) /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg)
* contains valid data. * contains valid data.
*/ */
regs->msr |= MSR_VEC; msr |= MSR_VEC;
} }
/* We always copy to/from vrsave, it's 0 if we don't have or don't /* We always copy to/from vrsave, it's 0 if we don't have or don't
* use altivec. * use altivec.
...@@ -114,6 +115,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, ...@@ -114,6 +115,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
err |= __put_user(&sc->gp_regs, &sc->regs); err |= __put_user(&sc->gp_regs, &sc->regs);
WARN_ON(!FULL_REGS(regs)); WARN_ON(!FULL_REGS(regs));
err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
err |= __put_user(msr, &sc->gp_regs[PT_MSR]);
err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE); err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE);
err |= __put_user(signr, &sc->signal); err |= __put_user(signr, &sc->signal);
err |= __put_user(handler, &sc->handler); err |= __put_user(handler, &sc->handler);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册