powerpc/signal32: Move signal trampoline setup to handle_[rt_]signal32
Move signal trampoline setup into handle_signal32() and handle_rt_signal32(). At the same time, remove the define which hides the mc_pad field used for trampoline. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/e439cc0fa35aa45da6776520777a61848b92fd4b.1597770847.git.christophe.leroy@csgroup.eu
This commit is contained in:
parent
91b8ecd419
commit
8d33001dd6
@ -199,9 +199,6 @@ struct sigframe {
|
|||||||
int abigap[56];
|
int abigap[56];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* We use the mc_pad field for the signal return trampoline. */
|
|
||||||
#define tramp mc_pad
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When we have rt signals to deliver, we set up on the
|
* When we have rt signals to deliver, we set up on the
|
||||||
* user stack, going down from the original stack pointer:
|
* user stack, going down from the original stack pointer:
|
||||||
@ -236,8 +233,7 @@ struct rt_sigframe {
|
|||||||
* altivec/spe instructions at some point.
|
* altivec/spe instructions at some point.
|
||||||
*/
|
*/
|
||||||
static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
|
static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
|
||||||
struct mcontext __user *tm_frame, int sigret,
|
struct mcontext __user *tm_frame, int ctx_has_vsx_region)
|
||||||
int ctx_has_vsx_region)
|
|
||||||
{
|
{
|
||||||
unsigned long msr = regs->msr;
|
unsigned long msr = regs->msr;
|
||||||
|
|
||||||
@ -320,15 +316,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
|
|||||||
if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR]))
|
if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR]))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (sigret) {
|
|
||||||
/* Set up the sigreturn trampoline: li 0,sigret; sc */
|
|
||||||
if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
|
|
||||||
|| __put_user(PPC_INST_SC, &frame->tramp[1]))
|
|
||||||
return 1;
|
|
||||||
flush_icache_range((unsigned long) &frame->tramp[0],
|
|
||||||
(unsigned long) &frame->tramp[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,10 +329,8 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
|
|||||||
*
|
*
|
||||||
* See save_user_regs() and signal_64.c:setup_tm_sigcontexts().
|
* See save_user_regs() and signal_64.c:setup_tm_sigcontexts().
|
||||||
*/
|
*/
|
||||||
static int save_tm_user_regs(struct pt_regs *regs,
|
static int save_tm_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
|
||||||
struct mcontext __user *frame,
|
struct mcontext __user *tm_frame, unsigned long msr)
|
||||||
struct mcontext __user *tm_frame, int sigret,
|
|
||||||
unsigned long msr)
|
|
||||||
{
|
{
|
||||||
WARN_ON(tm_suspend_disabled);
|
WARN_ON(tm_suspend_disabled);
|
||||||
|
|
||||||
@ -461,14 +446,6 @@ static int save_tm_user_regs(struct pt_regs *regs,
|
|||||||
|
|
||||||
if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
|
if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
|
||||||
return 1;
|
return 1;
|
||||||
if (sigret) {
|
|
||||||
/* Set up the sigreturn trampoline: li 0,sigret; sc */
|
|
||||||
if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
|
|
||||||
|| __put_user(PPC_INST_SC, &frame->tramp[1]))
|
|
||||||
return 1;
|
|
||||||
flush_icache_range((unsigned long) &frame->tramp[0],
|
|
||||||
(unsigned long) &frame->tramp[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -755,7 +732,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||||||
struct mcontext __user *mctx;
|
struct mcontext __user *mctx;
|
||||||
struct mcontext __user *tm_mctx = NULL;
|
struct mcontext __user *tm_mctx = NULL;
|
||||||
unsigned long newsp = 0;
|
unsigned long newsp = 0;
|
||||||
int sigret;
|
|
||||||
unsigned long tramp;
|
unsigned long tramp;
|
||||||
struct pt_regs *regs = tsk->thread.regs;
|
struct pt_regs *regs = tsk->thread.regs;
|
||||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||||
@ -782,11 +758,15 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||||||
|
|
||||||
/* Save user registers on the stack */
|
/* Save user registers on the stack */
|
||||||
if (vdso32_rt_sigtramp && tsk->mm->context.vdso_base) {
|
if (vdso32_rt_sigtramp && tsk->mm->context.vdso_base) {
|
||||||
sigret = 0;
|
|
||||||
tramp = tsk->mm->context.vdso_base + vdso32_rt_sigtramp;
|
tramp = tsk->mm->context.vdso_base + vdso32_rt_sigtramp;
|
||||||
} else {
|
} else {
|
||||||
sigret = __NR_rt_sigreturn;
|
tramp = (unsigned long)mctx->mc_pad;
|
||||||
tramp = (unsigned long)mctx->tramp;
|
/* Set up the sigreturn trampoline: li r0,sigret; sc */
|
||||||
|
if (__put_user(PPC_INST_ADDI + __NR_sigreturn, &mctx->mc_pad[0]))
|
||||||
|
goto badframe;
|
||||||
|
if (__put_user(PPC_INST_SC, &mctx->mc_pad[1]))
|
||||||
|
goto badframe;
|
||||||
|
flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||||
@ -796,7 +776,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||||||
__put_user((unsigned long)tm_mctx,
|
__put_user((unsigned long)tm_mctx,
|
||||||
&frame->uc_transact.uc_regs))
|
&frame->uc_transact.uc_regs))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
if (save_tm_user_regs(regs, mctx, tm_mctx, sigret, msr))
|
if (save_tm_user_regs(regs, mctx, tm_mctx, msr))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -804,7 +784,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||||||
{
|
{
|
||||||
if (__put_user(0, &frame->uc.uc_link))
|
if (__put_user(0, &frame->uc.uc_link))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
if (save_user_regs(regs, mctx, tm_mctx, sigret, 1))
|
if (save_user_regs(regs, mctx, tm_mctx, 1))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
}
|
}
|
||||||
regs->link = tramp;
|
regs->link = tramp;
|
||||||
@ -847,7 +827,6 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||||||
struct mcontext __user *mctx;
|
struct mcontext __user *mctx;
|
||||||
struct mcontext __user *tm_mctx = NULL;
|
struct mcontext __user *tm_mctx = NULL;
|
||||||
unsigned long newsp = 0;
|
unsigned long newsp = 0;
|
||||||
int sigret;
|
|
||||||
unsigned long tramp;
|
unsigned long tramp;
|
||||||
struct pt_regs *regs = tsk->thread.regs;
|
struct pt_regs *regs = tsk->thread.regs;
|
||||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||||
@ -880,22 +859,26 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
||||||
if (vdso32_sigtramp && tsk->mm->context.vdso_base) {
|
if (vdso32_sigtramp && tsk->mm->context.vdso_base) {
|
||||||
sigret = 0;
|
|
||||||
tramp = tsk->mm->context.vdso_base + vdso32_sigtramp;
|
tramp = tsk->mm->context.vdso_base + vdso32_sigtramp;
|
||||||
} else {
|
} else {
|
||||||
sigret = __NR_sigreturn;
|
tramp = (unsigned long)mctx->mc_pad;
|
||||||
tramp = (unsigned long)mctx->tramp;
|
/* Set up the sigreturn trampoline: li r0,sigret; sc */
|
||||||
|
if (__put_user(PPC_INST_ADDI + __NR_sigreturn, &mctx->mc_pad[0]))
|
||||||
|
goto badframe;
|
||||||
|
if (__put_user(PPC_INST_SC, &mctx->mc_pad[1]))
|
||||||
|
goto badframe;
|
||||||
|
flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||||
if (MSR_TM_ACTIVE(msr)) {
|
if (MSR_TM_ACTIVE(msr)) {
|
||||||
if (save_tm_user_regs(regs, mctx, tm_mctx, sigret, msr))
|
if (save_tm_user_regs(regs, mctx, tm_mctx, msr))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (save_user_regs(regs, mctx, tm_mctx, sigret, 1))
|
if (save_user_regs(regs, mctx, tm_mctx, 1))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1047,7 +1030,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,
|
|||||||
mctx = (struct mcontext __user *)
|
mctx = (struct mcontext __user *)
|
||||||
((unsigned long) &old_ctx->uc_mcontext & ~0xfUL);
|
((unsigned long) &old_ctx->uc_mcontext & ~0xfUL);
|
||||||
if (!access_ok(old_ctx, ctx_size)
|
if (!access_ok(old_ctx, ctx_size)
|
||||||
|| save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region)
|
|| save_user_regs(regs, mctx, NULL, ctx_has_vsx_region)
|
||||||
|| put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked)
|
|| put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked)
|
||||||
|| __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
|
|| __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
Loading…
Reference in New Issue
Block a user