Re: [PATCH RESEND v3 6/6] powerpc/signal: Use unsafe_copy_siginfo_to_user()
From: Eric W. Biederman <hidden>
Date: 2021-09-13 16:21:57
ebiederm@xmission.com (Eric W. Biederman) writes:
Christophe Leroy [off-list ref] writes:quoted
Use unsafe_copy_siginfo_to_user() in order to do the copy within the user access block. On an mpc 8321 (book3s/32) the improvment is about 5% on a process sending a signal to itself.
If you can't make function calls from an unsafe macro there is another way to handle this that doesn't require everything to be inline. From a safety perspective it is probably even a better approach. Eric
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 0608581967f0..1b30bb78b863 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c@@ -205,6 +205,12 @@ struct sigframe { int abigap[56]; }; +#ifdef CONFIG_PPC64 +# define user_siginfo_t compat_siginfo_t +#else +# define user_siginfo_t siginfo_t +#endif + /* * When we have rt signals to deliver, we set up on the * user stack, going down from the original stack pointer:
@@ -217,11 +223,7 @@ struct sigframe { * */ struct rt_sigframe { -#ifdef CONFIG_PPC64 - compat_siginfo_t info; -#else - struct siginfo info; -#endif + user_siginfo_t info; struct ucontext uc; #ifdef CONFIG_PPC_TRANSACTIONAL_MEM struct ucontext uc_transact;
@@ -712,7 +714,7 @@ static long restore_tm_user_regs(struct pt_regs *regs, struct mcontext __user *s #ifdef CONFIG_PPC64 -#define copy_siginfo_to_user copy_siginfo_to_user32 +#define copy_siginfo_to_external copy_siginfo_to_external32 #endif /* CONFIG_PPC64 */
@@ -731,6 +733,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, struct pt_regs *regs = tsk->thread.regs; /* Save the thread's msr before get_tm_stackpointer() changes it */ unsigned long msr = regs->msr; + user_siginfo_t uinfo; /* Set up Signal Frame */ frame = get_sigframe(ksig, tsk, sizeof(*frame), 1);
@@ -743,6 +746,8 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, else prepare_save_user_regs(1); + copy_siginfo_to_external(&uinfo, &ksig->info); + if (!user_access_begin(frame, sizeof(*frame))) goto badframe;
@@ -778,12 +783,10 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0])); } unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, failed); + unsafe_copy_to_user(&frame->info, &uinfo, failed); user_access_end(); - if (copy_siginfo_to_user(&frame->info, &ksig->info)) - goto badframe; - regs->link = tramp; #ifdef CONFIG_PPC_FPU_REGS
Eric