powerpc/signal64: use scoped user access in setup_trampoline()

setup_trampoline() writes the seven words of the on-stack sigreturn
trampoline with __put_user(), relying on the frame having been checked
when the frame setup opened its user write access.  It is called after
that access has been closed again, so each of the seven writes opens and
closes user access on its own.

Write them inside one scoped_user_write_access_size() covering the
whole trampoline instead.  Everything in it is a store, so a write-only
window is enough, and the instruction cache flush stays outside it.

This is part of getting rid of __get_user() and __put_user() entirely.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2026-10-20 10:05:11 -10:00
parent 2f0bb47c00
commit 52907f0e47

View File

@ -624,24 +624,27 @@ static long restore_tm_sigcontexts(struct task_struct *tsk, struct sigcontext __
static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp)
{
int i;
long err = 0;
/* Call the handler and pop the dummy stackframe*/
err |= __put_user(PPC_RAW_BCTRL(), &tramp[0]);
err |= __put_user(PPC_RAW_ADDI(_R1, _R1, __SIGNAL_FRAMESIZE), &tramp[1]);
scoped_user_write_access_size(tramp, TRAMP_SIZE * sizeof(*tramp), efault) {
/* Call the handler and pop the dummy stackframe*/
unsafe_put_user(PPC_RAW_BCTRL(), &tramp[0], efault);
unsafe_put_user(PPC_RAW_ADDI(_R1, _R1, __SIGNAL_FRAMESIZE), &tramp[1], efault);
err |= __put_user(PPC_RAW_LI(_R0, syscall), &tramp[2]);
err |= __put_user(PPC_RAW_SC(), &tramp[3]);
unsafe_put_user(PPC_RAW_LI(_R0, syscall), &tramp[2], efault);
unsafe_put_user(PPC_RAW_SC(), &tramp[3], efault);
/* Minimal traceback info */
for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++)
err |= __put_user(0, &tramp[i]);
/* Minimal traceback info */
for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++)
unsafe_put_user(0, &tramp[i], efault);
}
if (!err)
flush_icache_range((unsigned long) &tramp[0],
flush_icache_range((unsigned long) &tramp[0],
(unsigned long) &tramp[TRAMP_SIZE]);
return err;
return 0;
efault:
return -EFAULT;
}
/*