powerpc: Hard wire PT_SOFTE value to 1 in ptrace & signals

We have always had softe in pt_regs, and accessible via PT_SOFTE, even
though it is not userspace state.

The value userspace sees should always be 1, because we should never
be in userspace with interrupts soft disabled.

In a subsequent patch we will be changing the semantics of the kernel
softe value, so hard wire the value to 1 to retain the existing
semantics. As far as we know nothing ever looks at it, but better safe
than sorry.

Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
[mpe: Split out of larger patch, write change log]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
Madhavan Srinivasan 2017-08-20 23:28:24 +05:30 committed by Michael Ellerman
parent 7a074fc083
commit a8a4b03ab9
3 changed files with 23 additions and 0 deletions

View File

@ -283,6 +283,18 @@ int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data)
if (regno == PT_DSCR)
return get_user_dscr(task, data);
#ifdef CONFIG_PPC64
/*
* softe copies paca->soft_enabled variable state. Since soft_enabled is
* no more used as a flag, lets force usr to alway see the softe value as 1
* which means interrupts are not soft disabled.
*/
if (regno == PT_SOFTE) {
*data = 1;
return 0;
}
#endif
if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) {
*data = ((unsigned long *)task->thread.regs)[regno];
return 0;

View File

@ -111,12 +111,20 @@ static inline int save_general_regs(struct pt_regs *regs,
{
elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
int i;
/* Force usr to alway see softe as 1 (interrupts enabled) */
elf_greg_t64 softe = 0x1;
WARN_ON(!FULL_REGS(regs));
for (i = 0; i <= PT_RESULT; i ++) {
if (i == 14 && !FULL_REGS(regs))
i = 32;
if ( i == PT_SOFTE) {
if(__put_user((unsigned int)softe, &frame->mc_gregs[i]))
return -EFAULT;
else
continue;
}
if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i]))
return -EFAULT;
}

View File

@ -110,6 +110,8 @@ static long setup_sigcontext(struct sigcontext __user *sc,
struct pt_regs *regs = tsk->thread.regs;
unsigned long msr = regs->msr;
long err = 0;
/* Force usr to alway see softe as 1 (interrupts enabled) */
unsigned long softe = 0x1;
BUG_ON(tsk != current);
@ -169,6 +171,7 @@ static long setup_sigcontext(struct sigcontext __user *sc,
WARN_ON(!FULL_REGS(regs));
err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
err |= __put_user(msr, &sc->gp_regs[PT_MSR]);
err |= __put_user(softe, &sc->gp_regs[PT_SOFTE]);
err |= __put_user(signr, &sc->signal);
err |= __put_user(handler, &sc->handler);
if (set != NULL)