[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: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Родитель
efa58fbf19
Коммит
0be234a465
|
@ -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,
|
||||||
/* 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,
|
||||||
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, ¤t->thread.fpr, FP_REGS_SIZE);
|
err |= __copy_to_user(&sc->fp_regs, ¤t->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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче