* [RFC PATCH v1 00/19] powerpc: Switch signal 32 to using user_access_begin() and friends @ 2020-08-12 12:05 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev This series replaces copies to users by unsafe_put_user() and friends with user_write_access_begin() dance in signal32. The advantages are: - No KUAP unlock/lock at every copy - More readable code. - Better generated code. Copying Al Viro who did it on x86 and may have suggestions, and Dmitry V. Levin who introduced put_compat_sigset() Christophe Leroy (19): powerpc/signal: Move inline functions in signal.h powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg() powerpc/ptrace: Consolidate reg index calculation powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr() powerpc/signal: Don't manage floating point regs when no FPU powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x powerpc/signal: Move access_ok() out of get_sigframe() powerpc/signal: Remove get_clean_sp() powerpc/signal: Call get_tm_stackpointer() from get_sigframe() powerpc/signal: Refactor bad frame logging powerpc/signal32: Simplify logging in handle_rt_signal32() powerpc/signal32: Regroup copies in save_user_regs() and save_tm_user_regs() powerpc/signal32: Create 'unsafe' versions of copy_[ck][fpr/vsx]_to_user() powerpc/signal32: Switch save_user_regs() and save_tm_user_regs() to user_access_begin() logic powerpc/signal32: Switch handle_signal32() to user_access_begin() logic powerpc/signal32: Switch handle_rt_signal32() to user_access_begin() logic signal: Add unsafe_put_compat_sigset() powerpc/signal32: Add and use unsafe_put_sigset_t() powerpc/signal32: Switch swap_context() to user_access_begin() logic arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/processor.h | 16 +- arch/powerpc/include/asm/ptrace.h | 6 - arch/powerpc/kernel/asm-offsets.c | 2 + arch/powerpc/kernel/process.c | 4 + arch/powerpc/kernel/ptrace/Makefile | 3 +- arch/powerpc/kernel/ptrace/ptrace-decl.h | 21 ++ arch/powerpc/kernel/ptrace/ptrace-fpu.c | 40 +++ arch/powerpc/kernel/ptrace/ptrace-view.c | 2 + arch/powerpc/kernel/ptrace/ptrace.c | 54 +--- arch/powerpc/kernel/signal.c | 59 ++-- arch/powerpc/kernel/signal.h | 109 ++++++- arch/powerpc/kernel/signal_32.c | 386 ++++++++++++----------- arch/powerpc/kernel/signal_64.c | 19 +- arch/powerpc/kernel/traps.c | 2 + arch/powerpc/platforms/Kconfig.cputype | 15 +- include/linux/compat.h | 32 ++ 17 files changed, 462 insertions(+), 309 deletions(-) create mode 100644 arch/powerpc/kernel/ptrace/ptrace-fpu.c -- 2.25.0 ^ permalink raw reply [flat|nested] 42+ messages in thread
* [RFC PATCH v1 00/19] powerpc: Switch signal 32 to using user_access_begin() and friends @ 2020-08-12 12:05 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel This series replaces copies to users by unsafe_put_user() and friends with user_write_access_begin() dance in signal32. The advantages are: - No KUAP unlock/lock at every copy - More readable code. - Better generated code. Copying Al Viro who did it on x86 and may have suggestions, and Dmitry V. Levin who introduced put_compat_sigset() Christophe Leroy (19): powerpc/signal: Move inline functions in signal.h powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg() powerpc/ptrace: Consolidate reg index calculation powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr() powerpc/signal: Don't manage floating point regs when no FPU powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x powerpc/signal: Move access_ok() out of get_sigframe() powerpc/signal: Remove get_clean_sp() powerpc/signal: Call get_tm_stackpointer() from get_sigframe() powerpc/signal: Refactor bad frame logging powerpc/signal32: Simplify logging in handle_rt_signal32() powerpc/signal32: Regroup copies in save_user_regs() and save_tm_user_regs() powerpc/signal32: Create 'unsafe' versions of copy_[ck][fpr/vsx]_to_user() powerpc/signal32: Switch save_user_regs() and save_tm_user_regs() to user_access_begin() logic powerpc/signal32: Switch handle_signal32() to user_access_begin() logic powerpc/signal32: Switch handle_rt_signal32() to user_access_begin() logic signal: Add unsafe_put_compat_sigset() powerpc/signal32: Add and use unsafe_put_sigset_t() powerpc/signal32: Switch swap_context() to user_access_begin() logic arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/processor.h | 16 +- arch/powerpc/include/asm/ptrace.h | 6 - arch/powerpc/kernel/asm-offsets.c | 2 + arch/powerpc/kernel/process.c | 4 + arch/powerpc/kernel/ptrace/Makefile | 3 +- arch/powerpc/kernel/ptrace/ptrace-decl.h | 21 ++ arch/powerpc/kernel/ptrace/ptrace-fpu.c | 40 +++ arch/powerpc/kernel/ptrace/ptrace-view.c | 2 + arch/powerpc/kernel/ptrace/ptrace.c | 54 +--- arch/powerpc/kernel/signal.c | 59 ++-- arch/powerpc/kernel/signal.h | 109 ++++++- arch/powerpc/kernel/signal_32.c | 386 ++++++++++++----------- arch/powerpc/kernel/signal_64.c | 19 +- arch/powerpc/kernel/traps.c | 2 + arch/powerpc/platforms/Kconfig.cputype | 15 +- include/linux/compat.h | 32 ++ 17 files changed, 462 insertions(+), 309 deletions(-) create mode 100644 arch/powerpc/kernel/ptrace/ptrace-fpu.c -- 2.25.0 ^ permalink raw reply [flat|nested] 42+ messages in thread
* [RFC PATCH v1 01/19] powerpc/signal: Move inline functions in signal.h 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:05 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev To really be inlined, the functions needs to be defined in the same C file as the caller, or in an included header. Move functions from signal .c defined inline in signal.h Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Fixes: 3dd4eb83a9c0 ("powerpc: move common register copy functions from signal_32.c to signal.c") --- arch/powerpc/kernel/signal.c | 30 -------------------------- arch/powerpc/kernel/signal.h | 41 +++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index d15a98c758b8..3b56db02b762 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -133,36 +133,6 @@ unsigned long copy_ckvsx_from_user(struct task_struct *task, return 0; } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -#else -inline unsigned long copy_fpr_to_user(void __user *to, - struct task_struct *task) -{ - return __copy_to_user(to, task->thread.fp_state.fpr, - ELF_NFPREG * sizeof(double)); -} - -inline unsigned long copy_fpr_from_user(struct task_struct *task, - void __user *from) -{ - return __copy_from_user(task->thread.fp_state.fpr, from, - ELF_NFPREG * sizeof(double)); -} - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -inline unsigned long copy_ckfpr_to_user(void __user *to, - struct task_struct *task) -{ - return __copy_to_user(to, task->thread.ckfp_state.fpr, - ELF_NFPREG * sizeof(double)); -} - -inline unsigned long copy_ckfpr_from_user(struct task_struct *task, - void __user *from) -{ - return __copy_from_user(task->thread.ckfp_state.fpr, from, - ELF_NFPREG * sizeof(double)); -} -#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #endif /* Log an error when sending an unhandled signal to a process. Controlled diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index d396efca4068..4626d39cc0f0 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -19,14 +19,6 @@ extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset, extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, struct task_struct *tsk); -extern unsigned long copy_fpr_to_user(void __user *to, - struct task_struct *task); -extern unsigned long copy_ckfpr_to_user(void __user *to, - struct task_struct *task); -extern unsigned long copy_fpr_from_user(struct task_struct *task, - void __user *from); -extern unsigned long copy_ckfpr_from_user(struct task_struct *task, - void __user *from); extern unsigned long get_tm_stackpointer(struct task_struct *tsk); #ifdef CONFIG_VSX @@ -38,6 +30,39 @@ extern unsigned long copy_vsx_from_user(struct task_struct *task, void __user *from); extern unsigned long copy_ckvsx_from_user(struct task_struct *task, void __user *from); +unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task); +unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task); +unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from); +unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from); +#else +static inline unsigned long +copy_fpr_to_user(void __user *to, struct task_struct *task) +{ + return __copy_to_user(to, task->thread.fp_state.fpr, + ELF_NFPREG * sizeof(double)); +} + +static inline unsigned long +copy_fpr_from_user(struct task_struct *task, void __user *from) +{ + return __copy_from_user(task->thread.fp_state.fpr, from, + ELF_NFPREG * sizeof(double)); +} + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task) +{ + return __copy_to_user(to, task->thread.ckfp_state.fpr, + ELF_NFPREG * sizeof(double)); +} + +static inline unsigned long +copy_ckfpr_from_user(struct task_struct *task, void __user *from) +{ + return __copy_from_user(task->thread.ckfp_state.fpr, from, + ELF_NFPREG * sizeof(double)); +} +#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #endif #ifdef CONFIG_PPC64 -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 01/19] powerpc/signal: Move inline functions in signal.h @ 2020-08-12 12:05 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel To really be inlined, the functions needs to be defined in the same C file as the caller, or in an included header. Move functions from signal .c defined inline in signal.h Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Fixes: 3dd4eb83a9c0 ("powerpc: move common register copy functions from signal_32.c to signal.c") --- arch/powerpc/kernel/signal.c | 30 -------------------------- arch/powerpc/kernel/signal.h | 41 +++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index d15a98c758b8..3b56db02b762 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -133,36 +133,6 @@ unsigned long copy_ckvsx_from_user(struct task_struct *task, return 0; } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -#else -inline unsigned long copy_fpr_to_user(void __user *to, - struct task_struct *task) -{ - return __copy_to_user(to, task->thread.fp_state.fpr, - ELF_NFPREG * sizeof(double)); -} - -inline unsigned long copy_fpr_from_user(struct task_struct *task, - void __user *from) -{ - return __copy_from_user(task->thread.fp_state.fpr, from, - ELF_NFPREG * sizeof(double)); -} - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -inline unsigned long copy_ckfpr_to_user(void __user *to, - struct task_struct *task) -{ - return __copy_to_user(to, task->thread.ckfp_state.fpr, - ELF_NFPREG * sizeof(double)); -} - -inline unsigned long copy_ckfpr_from_user(struct task_struct *task, - void __user *from) -{ - return __copy_from_user(task->thread.ckfp_state.fpr, from, - ELF_NFPREG * sizeof(double)); -} -#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #endif /* Log an error when sending an unhandled signal to a process. Controlled diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index d396efca4068..4626d39cc0f0 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -19,14 +19,6 @@ extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset, extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, struct task_struct *tsk); -extern unsigned long copy_fpr_to_user(void __user *to, - struct task_struct *task); -extern unsigned long copy_ckfpr_to_user(void __user *to, - struct task_struct *task); -extern unsigned long copy_fpr_from_user(struct task_struct *task, - void __user *from); -extern unsigned long copy_ckfpr_from_user(struct task_struct *task, - void __user *from); extern unsigned long get_tm_stackpointer(struct task_struct *tsk); #ifdef CONFIG_VSX @@ -38,6 +30,39 @@ extern unsigned long copy_vsx_from_user(struct task_struct *task, void __user *from); extern unsigned long copy_ckvsx_from_user(struct task_struct *task, void __user *from); +unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task); +unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task); +unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from); +unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from); +#else +static inline unsigned long +copy_fpr_to_user(void __user *to, struct task_struct *task) +{ + return __copy_to_user(to, task->thread.fp_state.fpr, + ELF_NFPREG * sizeof(double)); +} + +static inline unsigned long +copy_fpr_from_user(struct task_struct *task, void __user *from) +{ + return __copy_from_user(task->thread.fp_state.fpr, from, + ELF_NFPREG * sizeof(double)); +} + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task) +{ + return __copy_to_user(to, task->thread.ckfp_state.fpr, + ELF_NFPREG * sizeof(double)); +} + +static inline unsigned long +copy_ckfpr_from_user(struct task_struct *task, void __user *from) +{ + return __copy_from_user(task->thread.ckfp_state.fpr, from, + ELF_NFPREG * sizeof(double)); +} +#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #endif #ifdef CONFIG_PPC64 -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 02/19] powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg() 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:05 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev ptrace_get_reg() and ptrace_set_reg() are only used internally by ptrace. Move them in arch/powerpc/kernel/ptrace/ptrace-decl.h Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/include/asm/ptrace.h | 6 ------ arch/powerpc/kernel/ptrace/ptrace-decl.h | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 155a197c0aa1..3c3cf537c3bf 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h @@ -171,12 +171,6 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) set_thread_flag(TIF_NOERROR); \ } while(0) -struct task_struct; -extern int ptrace_get_reg(struct task_struct *task, int regno, - unsigned long *data); -extern int ptrace_put_reg(struct task_struct *task, int regno, - unsigned long data); - #define current_pt_regs() \ ((struct pt_regs *)((unsigned long)task_stack_page(current) + THREAD_SIZE) - 1) diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h index 67447a6197eb..2ddc68412fa8 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-decl.h +++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h @@ -159,6 +159,9 @@ int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset, /* ptrace-view */ +int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data); +int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data); + extern const struct user_regset_view user_ppc_native_view; /* ptrace-(no)adv */ -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 02/19] powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg() @ 2020-08-12 12:05 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel ptrace_get_reg() and ptrace_set_reg() are only used internally by ptrace. Move them in arch/powerpc/kernel/ptrace/ptrace-decl.h Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/include/asm/ptrace.h | 6 ------ arch/powerpc/kernel/ptrace/ptrace-decl.h | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 155a197c0aa1..3c3cf537c3bf 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h @@ -171,12 +171,6 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) set_thread_flag(TIF_NOERROR); \ } while(0) -struct task_struct; -extern int ptrace_get_reg(struct task_struct *task, int regno, - unsigned long *data); -extern int ptrace_put_reg(struct task_struct *task, int regno, - unsigned long data); - #define current_pt_regs() \ ((struct pt_regs *)((unsigned long)task_stack_page(current) + THREAD_SIZE) - 1) diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h index 67447a6197eb..2ddc68412fa8 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-decl.h +++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h @@ -159,6 +159,9 @@ int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset, /* ptrace-view */ +int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data); +int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data); + extern const struct user_regset_view user_ppc_native_view; /* ptrace-(no)adv */ -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [RFC PATCH v1 02/19] powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg() 2020-08-12 12:05 ` Christophe Leroy (?) @ 2020-08-12 15:47 ` kernel test robot -1 siblings, 0 replies; 42+ messages in thread From: kernel test robot @ 2020-08-12 15:47 UTC (permalink / raw) To: kbuild-all [-- Attachment #1: Type: text/plain, Size: 20831 bytes --] Hi Christophe, [FYI, it's a private test report for your RFC patch.] [auto build test ERROR on linus/master] [also build test ERROR on v5.8 next-20200812] [cannot apply to powerpc/next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Christophe-Leroy/powerpc-Switch-signal-32-to-using-user_access_begin-and-friends/20200812-200934 base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git fb893de323e2d39f7a1f6df425703a2edbdf56ea config: powerpc64-randconfig-r004-20200812 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 30c1633386e7cfb01c0a54b31ccf4c3a3873e71b) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install powerpc64 cross compiling tool for clang build # apt-get install binutils-powerpc64-linux-gnu # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> arch/powerpc/kernel/ptrace/ptrace32.c:86:10: error: implicit declaration of function 'ptrace_get_reg' [-Werror,-Wimplicit-function-declaration] ret = ptrace_get_reg(child, index, &tmp); ^ arch/powerpc/kernel/ptrace/ptrace32.c:141:10: error: implicit declaration of function 'ptrace_get_reg' [-Werror,-Wimplicit-function-declaration] ret = ptrace_get_reg(child, numReg, &tmp2); ^ >> arch/powerpc/kernel/ptrace/ptrace32.c:190:10: error: implicit declaration of function 'ptrace_put_reg' [-Werror,-Wimplicit-function-declaration] ret = ptrace_put_reg(child, index, data); ^ arch/powerpc/kernel/ptrace/ptrace32.c:230:10: error: implicit declaration of function 'ptrace_get_reg' [-Werror,-Wimplicit-function-declaration] ret = ptrace_get_reg(child, numReg, &freg); ^ arch/powerpc/kernel/ptrace/ptrace32.c:237:10: error: implicit declaration of function 'ptrace_put_reg' [-Werror,-Wimplicit-function-declaration] ret = ptrace_put_reg(child, numReg, freg); ^ 5 errors generated. vim +/ptrace_get_reg +86 arch/powerpc/kernel/ptrace/ptrace32.c 9c75a31c3525a1 arch/powerpc/kernel/ptrace32.c Michael Neuling 2008-06-26 35 81e695c026eeda arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-12-20 36 long compat_arch_ptrace(struct task_struct *child, compat_long_t request, 81e695c026eeda arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-12-20 37 compat_ulong_t caddr, compat_ulong_t cdata) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 38 { 81e695c026eeda arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-12-20 39 unsigned long addr = caddr; 81e695c026eeda arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-12-20 40 unsigned long data = cdata; 6b9c7ed8483775 arch/powerpc/kernel/ptrace32.c Christoph Hellwig 2006-01-08 41 int ret; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 42 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 43 switch (request) { ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 44 /* ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 45 * Read 4 bytes of the other process' storage ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 46 * data is a pointer specifying where the user wants the ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 47 * 4 bytes copied into ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 48 * addr is a pointer in the user's storage that contains an 8 byte ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 49 * address in the other process of the 4 bytes that is to be read ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 50 * (this is run in a 32-bit process looking at a 64-bit process) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 51 * when I and D space are separate, these will need to be fixed. ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 52 */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 53 case PPC_PTRACE_PEEKTEXT_3264: ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 54 case PPC_PTRACE_PEEKDATA_3264: { ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 55 u32 tmp; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 56 int copied; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 57 u32 __user * addrOthers; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 58 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 59 ret = -EIO; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 60 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 61 /* Get the addr in the other process that we want to read */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 62 if (get_user(addrOthers, (u32 __user * __user *)addr) != 0) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 63 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 64 84d77d3f06e7e8 arch/powerpc/kernel/ptrace32.c Eric W. Biederman 2016-11-22 65 copied = ptrace_access_vm(child, (u64)addrOthers, &tmp, f307ab6dcea03f arch/powerpc/kernel/ptrace32.c Lorenzo Stoakes 2016-10-13 66 sizeof(tmp), FOLL_FORCE); ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 67 if (copied != sizeof(tmp)) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 68 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 69 ret = put_user(tmp, (u32 __user *)data); ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 70 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 71 } ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 72 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 73 /* Read a register (specified by ADDR) out of the "user area" */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 74 case PTRACE_PEEKUSR: { ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 75 int index; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 76 unsigned long tmp; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 77 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 78 ret = -EIO; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 79 /* convert to index and check */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 80 index = (unsigned long) addr >> 2; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 81 if ((addr & 3) || (index > PT_FPSCR32)) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 82 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 83 fabca2c0a461bd arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-09-25 84 CHECK_FULL_REGS(child->thread.regs); ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 85 if (index < PT_FPR0) { ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 @86 ret = ptrace_get_reg(child, index, &tmp); ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 87 if (ret) ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 88 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 89 } else { ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 90 flush_fp_to_thread(child); ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 91 /* ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 92 * the user space code considers the floating point ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 93 * to be an array of unsigned int (32 bits) - the ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 94 * index passed in is based on this assumption. ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 95 */ de79f7b9f6f92e arch/powerpc/kernel/ptrace32.c Paul Mackerras 2013-09-10 96 tmp = ((unsigned int *)child->thread.fp_state.fpr) 9c75a31c3525a1 arch/powerpc/kernel/ptrace32.c Michael Neuling 2008-06-26 97 [FPRINDEX(index)]; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 98 } ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 99 ret = put_user((unsigned int)tmp, (u32 __user *)data); ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 100 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 101 } ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 102 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 103 /* ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 104 * Read 4 bytes out of the other process' pt_regs area ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 105 * data is a pointer specifying where the user wants the ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 106 * 4 bytes copied into ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 107 * addr is the offset into the other process' pt_regs structure ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 108 * that is to be read ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 109 * (this is run in a 32-bit process looking at a 64-bit process) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 110 */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 111 case PPC_PTRACE_PEEKUSR_3264: { ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 112 u32 index; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 113 u32 reg32bits; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 114 u64 tmp; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 115 u32 numReg; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 116 u32 part; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 117 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 118 ret = -EIO; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 119 /* Determine which register the user wants */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 120 index = (u64)addr >> 2; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 121 numReg = index / 2; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 122 /* Determine which part of the register the user wants */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 123 if (index % 2) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 124 part = 1; /* want the 2nd half of the register (right-most). */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 125 else ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 126 part = 0; /* want the 1st half of the register (left-most). */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 127 912000e73ee8fc arch/powerpc/kernel/ptrace32.c Benjamin Herrenschmidt 2007-06-04 128 /* Validate the input - check to see if address is on the wrong boundary 912000e73ee8fc arch/powerpc/kernel/ptrace32.c Benjamin Herrenschmidt 2007-06-04 129 * or beyond the end of the user area 912000e73ee8fc arch/powerpc/kernel/ptrace32.c Benjamin Herrenschmidt 2007-06-04 130 */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 131 if ((addr & 3) || numReg > PT_FPSCR) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 132 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 133 fabca2c0a461bd arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-09-25 134 CHECK_FULL_REGS(child->thread.regs); ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 135 if (numReg >= PT_FPR0) { ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 136 flush_fp_to_thread(child); bc826666e4252f arch/powerpc/kernel/ptrace32.c Michael Neuling 2009-04-05 137 /* get 64 bit FPR */ de79f7b9f6f92e arch/powerpc/kernel/ptrace32.c Paul Mackerras 2013-09-10 138 tmp = child->thread.fp_state.fpr[numReg - PT_FPR0][0]; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 139 } else { /* register within PT_REGS struct */ ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 140 unsigned long tmp2; ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 141 ret = ptrace_get_reg(child, numReg, &tmp2); ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 142 if (ret) ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 143 break; ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 144 tmp = tmp2; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 145 } ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 146 reg32bits = ((u32*)&tmp)[part]; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 147 ret = put_user(reg32bits, (u32 __user *)data); ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 148 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 149 } ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 150 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 151 /* ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 152 * Write 4 bytes into the other process' storage ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 153 * data is the 4 bytes that the user wants written ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 154 * addr is a pointer in the user's storage that contains an ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 155 * 8 byte address in the other process where the 4 bytes ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 156 * that is to be written ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 157 * (this is run in a 32-bit process looking at a 64-bit process) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 158 * when I and D space are separate, these will need to be fixed. ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 159 */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 160 case PPC_PTRACE_POKETEXT_3264: ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 161 case PPC_PTRACE_POKEDATA_3264: { ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 162 u32 tmp = data; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 163 u32 __user * addrOthers; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 164 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 165 /* Get the addr in the other process that we want to write into */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 166 ret = -EIO; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 167 if (get_user(addrOthers, (u32 __user * __user *)addr) != 0) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 168 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 169 ret = 0; 84d77d3f06e7e8 arch/powerpc/kernel/ptrace32.c Eric W. Biederman 2016-11-22 170 if (ptrace_access_vm(child, (u64)addrOthers, &tmp, f307ab6dcea03f arch/powerpc/kernel/ptrace32.c Lorenzo Stoakes 2016-10-13 171 sizeof(tmp), f307ab6dcea03f arch/powerpc/kernel/ptrace32.c Lorenzo Stoakes 2016-10-13 172 FOLL_FORCE | FOLL_WRITE) == sizeof(tmp)) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 173 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 174 ret = -EIO; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 175 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 176 } ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 177 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 178 /* write the word at location addr in the USER area */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 179 case PTRACE_POKEUSR: { ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 180 unsigned long index; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 181 ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 182 ret = -EIO; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 183 /* convert to index and check */ ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 184 index = (unsigned long) addr >> 2; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 185 if ((addr & 3) || (index > PT_FPSCR32)) ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 186 break; ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 187 fabca2c0a461bd arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-09-25 188 CHECK_FULL_REGS(child->thread.regs); ^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 189 if (index < PT_FPR0) { 865418d8e78b9c arch/powerpc/kernel/ptrace32.c Benjamin Herrenschmidt 2007-06-04 @190 ret = ptrace_put_reg(child, index, data); --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org [-- Attachment #2: config.gz --] [-- Type: application/gzip, Size: 27511 bytes --] ^ permalink raw reply [flat|nested] 42+ messages in thread
* [RFC PATCH v1 03/19] powerpc/ptrace: Consolidate reg index calculation 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:05 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev Today we have: #ifdef CONFIG_PPC32 index = addr >> 2; if ((addr & 3) || child->thread.regs == NULL) #else index = addr >> 3; if ((addr & 7)) #endif sizeof(long) has value 4 for PPC32 and value 8 for PPC64. Dividing by 4 is equivalent to >> 2 and dividing by 8 is equivalent to >> 3. And 3 and 7 are respectively (sizeof(long) - 1). Use sizeof(long) to get rid of the #ifdef CONFIG_PPC32 and consolidate the calculation and checking. thread.regs have to be not NULL on both PPC32 and PPC64 so adding that test on PPC64 is harmless. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/ptrace/ptrace.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c index f6e51be47c6e..0b4645a7a1b4 100644 --- a/arch/powerpc/kernel/ptrace/ptrace.c +++ b/arch/powerpc/kernel/ptrace/ptrace.c @@ -55,14 +55,8 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; /* convert to index and check */ -#ifdef CONFIG_PPC32 - index = addr >> 2; - if ((addr & 3) || (index > PT_FPSCR) - || (child->thread.regs == NULL)) -#else - index = addr >> 3; - if ((addr & 7) || (index > PT_FPSCR)) -#endif + index = addr / sizeof(long); + if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs) break; CHECK_FULL_REGS(child->thread.regs); @@ -90,14 +84,8 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; /* convert to index and check */ -#ifdef CONFIG_PPC32 - index = addr >> 2; - if ((addr & 3) || (index > PT_FPSCR) - || (child->thread.regs == NULL)) -#else - index = addr >> 3; - if ((addr & 7) || (index > PT_FPSCR)) -#endif + index = addr / sizeof(long); + if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs) break; CHECK_FULL_REGS(child->thread.regs); -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 03/19] powerpc/ptrace: Consolidate reg index calculation @ 2020-08-12 12:05 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel Today we have: #ifdef CONFIG_PPC32 index = addr >> 2; if ((addr & 3) || child->thread.regs == NULL) #else index = addr >> 3; if ((addr & 7)) #endif sizeof(long) has value 4 for PPC32 and value 8 for PPC64. Dividing by 4 is equivalent to >> 2 and dividing by 8 is equivalent to >> 3. And 3 and 7 are respectively (sizeof(long) - 1). Use sizeof(long) to get rid of the #ifdef CONFIG_PPC32 and consolidate the calculation and checking. thread.regs have to be not NULL on both PPC32 and PPC64 so adding that test on PPC64 is harmless. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/ptrace/ptrace.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c index f6e51be47c6e..0b4645a7a1b4 100644 --- a/arch/powerpc/kernel/ptrace/ptrace.c +++ b/arch/powerpc/kernel/ptrace/ptrace.c @@ -55,14 +55,8 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; /* convert to index and check */ -#ifdef CONFIG_PPC32 - index = addr >> 2; - if ((addr & 3) || (index > PT_FPSCR) - || (child->thread.regs == NULL)) -#else - index = addr >> 3; - if ((addr & 7) || (index > PT_FPSCR)) -#endif + index = addr / sizeof(long); + if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs) break; CHECK_FULL_REGS(child->thread.regs); @@ -90,14 +84,8 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; /* convert to index and check */ -#ifdef CONFIG_PPC32 - index = addr >> 2; - if ((addr & 3) || (index > PT_FPSCR) - || (child->thread.regs == NULL)) -#else - index = addr >> 3; - if ((addr & 7) || (index > PT_FPSCR)) -#endif + index = addr / sizeof(long); + if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs) break; CHECK_FULL_REGS(child->thread.regs); -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 04/19] powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr() 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:05 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev On the same model as ptrace_get_reg() and ptrace_put_reg(), create ptrace_get_fpr() and ptrace_put_fpr() to get/set the floating points registers. We move the boundary checkings in them. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/ptrace/Makefile | 1 + arch/powerpc/kernel/ptrace/ptrace-decl.h | 4 +++ arch/powerpc/kernel/ptrace/ptrace-fpu.c | 40 ++++++++++++++++++++++++ arch/powerpc/kernel/ptrace/ptrace.c | 38 +++++++--------------- 4 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 arch/powerpc/kernel/ptrace/ptrace-fpu.c diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile index c2f2402ebc8c..77abd1a5a508 100644 --- a/arch/powerpc/kernel/ptrace/Makefile +++ b/arch/powerpc/kernel/ptrace/Makefile @@ -6,6 +6,7 @@ CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' obj-y += ptrace.o ptrace-view.o +obj-y += ptrace-fpu.o obj-$(CONFIG_COMPAT) += ptrace32.o obj-$(CONFIG_VSX) += ptrace-vsx.o ifneq ($(CONFIG_VSX),y) diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h index 2ddc68412fa8..eafe5f0f6289 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-decl.h +++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h @@ -164,6 +164,10 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data); extern const struct user_regset_view user_ppc_native_view; +/* ptrace-fpu */ +int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data); +int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data); + /* ptrace-(no)adv */ void ppc_gethwdinfo(struct ppc_debug_info *dbginfo); int ptrace_get_debugreg(struct task_struct *child, unsigned long addr, diff --git a/arch/powerpc/kernel/ptrace/ptrace-fpu.c b/arch/powerpc/kernel/ptrace/ptrace-fpu.c new file mode 100644 index 000000000000..8301cb52dd99 --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-fpu.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> + +#include <asm/switch_to.h> + +#include "ptrace-decl.h" + +int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data) +{ + unsigned int fpidx = index - PT_FPR0; + + if (index > PT_FPSCR) + return -EIO; + + flush_fp_to_thread(child); + if (fpidx < (PT_FPSCR - PT_FPR0)) + memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long)); + else + *data = child->thread.fp_state.fpscr; + + return 0; +} + +int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data) +{ + unsigned int fpidx = index - PT_FPR0; + + if (index > PT_FPSCR) + return -EIO; + + flush_fp_to_thread(child); + if (fpidx < (PT_FPSCR - PT_FPR0)) + memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long)); + else + child->thread.fp_state.fpscr = data; + + return 0; +} + diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c index 0b4645a7a1b4..3d44b73adb83 100644 --- a/arch/powerpc/kernel/ptrace/ptrace.c +++ b/arch/powerpc/kernel/ptrace/ptrace.c @@ -56,24 +56,17 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; /* convert to index and check */ index = addr / sizeof(long); - if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs) + if ((addr & (sizeof(long) - 1)) || !child->thread.regs) break; CHECK_FULL_REGS(child->thread.regs); - if (index < PT_FPR0) { + if (index < PT_FPR0) ret = ptrace_get_reg(child, (int) index, &tmp); - if (ret) - break; - } else { - unsigned int fpidx = index - PT_FPR0; - - flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&tmp, &child->thread.TS_FPR(fpidx), - sizeof(long)); - else - tmp = child->thread.fp_state.fpscr; - } + else + ret = ptrace_get_fpr(child, index, &tmp); + + if (ret) + break; ret = put_user(tmp, datalp); break; } @@ -85,23 +78,14 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; /* convert to index and check */ index = addr / sizeof(long); - if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs) + if ((addr & (sizeof(long) - 1)) || !child->thread.regs) break; CHECK_FULL_REGS(child->thread.regs); - if (index < PT_FPR0) { + if (index < PT_FPR0) ret = ptrace_put_reg(child, index, data); - } else { - unsigned int fpidx = index - PT_FPR0; - - flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&child->thread.TS_FPR(fpidx), &data, - sizeof(long)); - else - child->thread.fp_state.fpscr = data; - ret = 0; - } + else + ret = ptrace_put_fpr(child, index, data); break; } -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 04/19] powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr() @ 2020-08-12 12:05 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel On the same model as ptrace_get_reg() and ptrace_put_reg(), create ptrace_get_fpr() and ptrace_put_fpr() to get/set the floating points registers. We move the boundary checkings in them. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/ptrace/Makefile | 1 + arch/powerpc/kernel/ptrace/ptrace-decl.h | 4 +++ arch/powerpc/kernel/ptrace/ptrace-fpu.c | 40 ++++++++++++++++++++++++ arch/powerpc/kernel/ptrace/ptrace.c | 38 +++++++--------------- 4 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 arch/powerpc/kernel/ptrace/ptrace-fpu.c diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile index c2f2402ebc8c..77abd1a5a508 100644 --- a/arch/powerpc/kernel/ptrace/Makefile +++ b/arch/powerpc/kernel/ptrace/Makefile @@ -6,6 +6,7 @@ CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' obj-y += ptrace.o ptrace-view.o +obj-y += ptrace-fpu.o obj-$(CONFIG_COMPAT) += ptrace32.o obj-$(CONFIG_VSX) += ptrace-vsx.o ifneq ($(CONFIG_VSX),y) diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h index 2ddc68412fa8..eafe5f0f6289 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-decl.h +++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h @@ -164,6 +164,10 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data); extern const struct user_regset_view user_ppc_native_view; +/* ptrace-fpu */ +int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data); +int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data); + /* ptrace-(no)adv */ void ppc_gethwdinfo(struct ppc_debug_info *dbginfo); int ptrace_get_debugreg(struct task_struct *child, unsigned long addr, diff --git a/arch/powerpc/kernel/ptrace/ptrace-fpu.c b/arch/powerpc/kernel/ptrace/ptrace-fpu.c new file mode 100644 index 000000000000..8301cb52dd99 --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-fpu.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> + +#include <asm/switch_to.h> + +#include "ptrace-decl.h" + +int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data) +{ + unsigned int fpidx = index - PT_FPR0; + + if (index > PT_FPSCR) + return -EIO; + + flush_fp_to_thread(child); + if (fpidx < (PT_FPSCR - PT_FPR0)) + memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long)); + else + *data = child->thread.fp_state.fpscr; + + return 0; +} + +int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data) +{ + unsigned int fpidx = index - PT_FPR0; + + if (index > PT_FPSCR) + return -EIO; + + flush_fp_to_thread(child); + if (fpidx < (PT_FPSCR - PT_FPR0)) + memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long)); + else + child->thread.fp_state.fpscr = data; + + return 0; +} + diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c index 0b4645a7a1b4..3d44b73adb83 100644 --- a/arch/powerpc/kernel/ptrace/ptrace.c +++ b/arch/powerpc/kernel/ptrace/ptrace.c @@ -56,24 +56,17 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; /* convert to index and check */ index = addr / sizeof(long); - if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs) + if ((addr & (sizeof(long) - 1)) || !child->thread.regs) break; CHECK_FULL_REGS(child->thread.regs); - if (index < PT_FPR0) { + if (index < PT_FPR0) ret = ptrace_get_reg(child, (int) index, &tmp); - if (ret) - break; - } else { - unsigned int fpidx = index - PT_FPR0; - - flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&tmp, &child->thread.TS_FPR(fpidx), - sizeof(long)); - else - tmp = child->thread.fp_state.fpscr; - } + else + ret = ptrace_get_fpr(child, index, &tmp); + + if (ret) + break; ret = put_user(tmp, datalp); break; } @@ -85,23 +78,14 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; /* convert to index and check */ index = addr / sizeof(long); - if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs) + if ((addr & (sizeof(long) - 1)) || !child->thread.regs) break; CHECK_FULL_REGS(child->thread.regs); - if (index < PT_FPR0) { + if (index < PT_FPR0) ret = ptrace_put_reg(child, index, data); - } else { - unsigned int fpidx = index - PT_FPR0; - - flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&child->thread.TS_FPR(fpidx), &data, - sizeof(long)); - else - child->thread.fp_state.fpscr = data; - ret = 0; - } + else + ret = ptrace_put_fpr(child, index, data); break; } -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 05/19] powerpc/signal: Don't manage floating point regs when no FPU 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:05 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev There is no point in copying floating point regs when there is no FPU and MATH_EMULATION is not selected. Create a new CONFIG_PPC_FPU_REGS bool that is selected by CONFIG_MATH_EMULATION and CONFIG_PPC_FPU, and use it to opt out everything related to fp_state in thread_struct. The asm const used only by fpu.S are opted out with CONFIG_PPC_FPU as fpu.S build is conditionnal to CONFIG_PPC_FPU. The following app spends approx 8.1 seconds system time on an 8xx without the patch, and 7.0 seconds with the patch. void sigusr1(int sig) { } int main(int argc, char **argv) { int i = 100000; signal(SIGUSR1, sigusr1); for (;i--;) raise(SIGUSR1); exit(0); } Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/processor.h | 2 ++ arch/powerpc/kernel/asm-offsets.c | 2 ++ arch/powerpc/kernel/process.c | 4 ++++ arch/powerpc/kernel/ptrace/Makefile | 4 ++-- arch/powerpc/kernel/ptrace/ptrace-decl.h | 14 ++++++++++++++ arch/powerpc/kernel/ptrace/ptrace-view.c | 2 ++ arch/powerpc/kernel/signal.h | 14 +++++++++++++- arch/powerpc/kernel/signal_32.c | 4 ++++ arch/powerpc/kernel/traps.c | 2 ++ arch/powerpc/platforms/Kconfig.cputype | 4 ++++ 11 files changed, 50 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 1f48bbfb3ce9..a2611880b904 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -416,6 +416,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE config MATH_EMULATION bool "Math emulation" depends on 4xx || PPC_8xx || PPC_MPC832x || BOOKE + select PPC_FPU_REGS help Some PowerPC chips designed for embedded applications do not have a floating-point unit and therefore do not implement the diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index ed0d633ab5aa..e20b0c5abe62 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -175,8 +175,10 @@ struct thread_struct { #endif /* Debug Registers */ struct debug_reg debug; +#ifdef CONFIG_PPC_FPU_REGS struct thread_fp_state fp_state; struct thread_fp_state *fp_save_area; +#endif int fpexc_mode; /* floating-point exception mode */ unsigned int align_ctl; /* alignment handling control */ #ifdef CONFIG_HAVE_HW_BREAKPOINT diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 8711c2164b45..6cb36c341c70 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -110,9 +110,11 @@ int main(void) #ifdef CONFIG_BOOKE OFFSET(THREAD_NORMSAVES, thread_struct, normsave[0]); #endif +#ifdef CONFIG_PPC_FPU OFFSET(THREAD_FPEXC_MODE, thread_struct, fpexc_mode); OFFSET(THREAD_FPSTATE, thread_struct, fp_state.fpr); OFFSET(THREAD_FPSAVEAREA, thread_struct, fp_save_area); +#endif OFFSET(FPSTATE_FPSCR, thread_fp_state, fpscr); OFFSET(THREAD_LOAD_FP, thread_struct, load_fp); #ifdef CONFIG_ALTIVEC diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 016bd831908e..7e0082ac0a39 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1694,7 +1694,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.ptrace_bps[i] = NULL; #endif +#ifdef CONFIG_PPC_FPU_REGS p->thread.fp_save_area = NULL; +#endif #ifdef CONFIG_ALTIVEC p->thread.vr_save_area = NULL; #endif @@ -1821,8 +1823,10 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) #endif current->thread.load_slb = 0; current->thread.load_fp = 0; +#ifdef CONFIG_PPC_FPU_REGS memset(¤t->thread.fp_state, 0, sizeof(current->thread.fp_state)); current->thread.fp_save_area = NULL; +#endif #ifdef CONFIG_ALTIVEC memset(¤t->thread.vr_state, 0, sizeof(current->thread.vr_state)); current->thread.vr_state.vscr.u[3] = 0x00010000; /* Java mode disabled */ diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile index 77abd1a5a508..8ebc11d1168d 100644 --- a/arch/powerpc/kernel/ptrace/Makefile +++ b/arch/powerpc/kernel/ptrace/Makefile @@ -6,11 +6,11 @@ CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' obj-y += ptrace.o ptrace-view.o -obj-y += ptrace-fpu.o +obj-$(CONFIG_PPC_FPU_REGS) += ptrace-fpu.o obj-$(CONFIG_COMPAT) += ptrace32.o obj-$(CONFIG_VSX) += ptrace-vsx.o ifneq ($(CONFIG_VSX),y) -obj-y += ptrace-novsx.o +obj-$(CONFIG_PPC_FPU_REGS) += ptrace-novsx.o endif obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o obj-$(CONFIG_SPE) += ptrace-spe.o diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h index eafe5f0f6289..3487f2c9735c 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-decl.h +++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h @@ -165,8 +165,22 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data); extern const struct user_regset_view user_ppc_native_view; /* ptrace-fpu */ +#ifdef CONFIG_PPC_FPU_REGS int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data); int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data); +#else +static inline int +ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data) +{ + return -EIO; +} + +static inline int +ptrace_put_fpr(struct task_struct *child, int index, unsigned long data) +{ + return -EIO; +} +#endif /* ptrace-(no)adv */ void ppc_gethwdinfo(struct ppc_debug_info *dbginfo); diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c index 7e6478e7ed07..f1df8c62baf1 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-view.c +++ b/arch/powerpc/kernel/ptrace/ptrace-view.c @@ -520,11 +520,13 @@ static const struct user_regset native_regsets[] = { .size = sizeof(long), .align = sizeof(long), .regset_get = gpr_get, .set = gpr_set }, +#ifdef CONFIG_PPC_FPU_REGS [REGSET_FPR] = { .core_note_type = NT_PRFPREG, .n = ELF_NFPREG, .size = sizeof(double), .align = sizeof(double), .regset_get = fpr_get, .set = fpr_set }, +#endif #ifdef CONFIG_ALTIVEC [REGSET_VMX] = { .core_note_type = NT_PPC_VMX, .n = 34, diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index 4626d39cc0f0..6c2a33ab042c 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -34,7 +34,7 @@ unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task); unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task); unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from); unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from); -#else +#elif defined(CONFIG_PPC_FPU_REGS) static inline unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) { @@ -63,6 +63,18 @@ copy_ckfpr_from_user(struct task_struct *task, void __user *from) ELF_NFPREG * sizeof(double)); } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ +#else +static inline unsigned long +copy_fpr_to_user(void __user *to, struct task_struct *task) +{ + return 0; +} + +static inline unsigned long +copy_fpr_from_user(struct task_struct *task, void __user *from) +{ + return 0; +} #endif #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 96950f189b5a..7b291707eb31 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -814,7 +814,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, } regs->link = tramp; +#ifdef CONFIG_PPC_FPU_REGS tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ +#endif /* create a stack frame for the caller of the handler */ newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16); @@ -1271,7 +1273,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, regs->link = tramp; +#ifdef CONFIG_PPC_FPU_REGS tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ +#endif /* create a stack frame for the caller of the handler */ newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index d1ebe152f210..5c68f0de905c 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1194,7 +1194,9 @@ static void parse_fpe(struct pt_regs *regs) flush_fp_to_thread(current); +#ifdef CONFIG_PPC_FPU_REGS code = __parse_fpscr(current->thread.fp_state.fpscr); +#endif _exception(SIGFPE, regs, code, regs->nip); } diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 87737ec86d39..40ffcdba42b8 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -225,9 +225,13 @@ config PPC_E500MC such as e5500/e6500), and must be disabled for running on e500v1 or e500v2. +config PPC_FPU_REGS + bool + config PPC_FPU bool default y if PPC64 + select PPC_FPU_REGS config FSL_EMB_PERFMON bool "Freescale Embedded Perfmon" -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 05/19] powerpc/signal: Don't manage floating point regs when no FPU @ 2020-08-12 12:05 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel There is no point in copying floating point regs when there is no FPU and MATH_EMULATION is not selected. Create a new CONFIG_PPC_FPU_REGS bool that is selected by CONFIG_MATH_EMULATION and CONFIG_PPC_FPU, and use it to opt out everything related to fp_state in thread_struct. The asm const used only by fpu.S are opted out with CONFIG_PPC_FPU as fpu.S build is conditionnal to CONFIG_PPC_FPU. The following app spends approx 8.1 seconds system time on an 8xx without the patch, and 7.0 seconds with the patch. void sigusr1(int sig) { } int main(int argc, char **argv) { int i = 100000; signal(SIGUSR1, sigusr1); for (;i--;) raise(SIGUSR1); exit(0); } Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/processor.h | 2 ++ arch/powerpc/kernel/asm-offsets.c | 2 ++ arch/powerpc/kernel/process.c | 4 ++++ arch/powerpc/kernel/ptrace/Makefile | 4 ++-- arch/powerpc/kernel/ptrace/ptrace-decl.h | 14 ++++++++++++++ arch/powerpc/kernel/ptrace/ptrace-view.c | 2 ++ arch/powerpc/kernel/signal.h | 14 +++++++++++++- arch/powerpc/kernel/signal_32.c | 4 ++++ arch/powerpc/kernel/traps.c | 2 ++ arch/powerpc/platforms/Kconfig.cputype | 4 ++++ 11 files changed, 50 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 1f48bbfb3ce9..a2611880b904 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -416,6 +416,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE config MATH_EMULATION bool "Math emulation" depends on 4xx || PPC_8xx || PPC_MPC832x || BOOKE + select PPC_FPU_REGS help Some PowerPC chips designed for embedded applications do not have a floating-point unit and therefore do not implement the diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index ed0d633ab5aa..e20b0c5abe62 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -175,8 +175,10 @@ struct thread_struct { #endif /* Debug Registers */ struct debug_reg debug; +#ifdef CONFIG_PPC_FPU_REGS struct thread_fp_state fp_state; struct thread_fp_state *fp_save_area; +#endif int fpexc_mode; /* floating-point exception mode */ unsigned int align_ctl; /* alignment handling control */ #ifdef CONFIG_HAVE_HW_BREAKPOINT diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 8711c2164b45..6cb36c341c70 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -110,9 +110,11 @@ int main(void) #ifdef CONFIG_BOOKE OFFSET(THREAD_NORMSAVES, thread_struct, normsave[0]); #endif +#ifdef CONFIG_PPC_FPU OFFSET(THREAD_FPEXC_MODE, thread_struct, fpexc_mode); OFFSET(THREAD_FPSTATE, thread_struct, fp_state.fpr); OFFSET(THREAD_FPSAVEAREA, thread_struct, fp_save_area); +#endif OFFSET(FPSTATE_FPSCR, thread_fp_state, fpscr); OFFSET(THREAD_LOAD_FP, thread_struct, load_fp); #ifdef CONFIG_ALTIVEC diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 016bd831908e..7e0082ac0a39 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1694,7 +1694,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.ptrace_bps[i] = NULL; #endif +#ifdef CONFIG_PPC_FPU_REGS p->thread.fp_save_area = NULL; +#endif #ifdef CONFIG_ALTIVEC p->thread.vr_save_area = NULL; #endif @@ -1821,8 +1823,10 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) #endif current->thread.load_slb = 0; current->thread.load_fp = 0; +#ifdef CONFIG_PPC_FPU_REGS memset(¤t->thread.fp_state, 0, sizeof(current->thread.fp_state)); current->thread.fp_save_area = NULL; +#endif #ifdef CONFIG_ALTIVEC memset(¤t->thread.vr_state, 0, sizeof(current->thread.vr_state)); current->thread.vr_state.vscr.u[3] = 0x00010000; /* Java mode disabled */ diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile index 77abd1a5a508..8ebc11d1168d 100644 --- a/arch/powerpc/kernel/ptrace/Makefile +++ b/arch/powerpc/kernel/ptrace/Makefile @@ -6,11 +6,11 @@ CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' obj-y += ptrace.o ptrace-view.o -obj-y += ptrace-fpu.o +obj-$(CONFIG_PPC_FPU_REGS) += ptrace-fpu.o obj-$(CONFIG_COMPAT) += ptrace32.o obj-$(CONFIG_VSX) += ptrace-vsx.o ifneq ($(CONFIG_VSX),y) -obj-y += ptrace-novsx.o +obj-$(CONFIG_PPC_FPU_REGS) += ptrace-novsx.o endif obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o obj-$(CONFIG_SPE) += ptrace-spe.o diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h index eafe5f0f6289..3487f2c9735c 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-decl.h +++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h @@ -165,8 +165,22 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data); extern const struct user_regset_view user_ppc_native_view; /* ptrace-fpu */ +#ifdef CONFIG_PPC_FPU_REGS int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data); int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data); +#else +static inline int +ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data) +{ + return -EIO; +} + +static inline int +ptrace_put_fpr(struct task_struct *child, int index, unsigned long data) +{ + return -EIO; +} +#endif /* ptrace-(no)adv */ void ppc_gethwdinfo(struct ppc_debug_info *dbginfo); diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c index 7e6478e7ed07..f1df8c62baf1 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-view.c +++ b/arch/powerpc/kernel/ptrace/ptrace-view.c @@ -520,11 +520,13 @@ static const struct user_regset native_regsets[] = { .size = sizeof(long), .align = sizeof(long), .regset_get = gpr_get, .set = gpr_set }, +#ifdef CONFIG_PPC_FPU_REGS [REGSET_FPR] = { .core_note_type = NT_PRFPREG, .n = ELF_NFPREG, .size = sizeof(double), .align = sizeof(double), .regset_get = fpr_get, .set = fpr_set }, +#endif #ifdef CONFIG_ALTIVEC [REGSET_VMX] = { .core_note_type = NT_PPC_VMX, .n = 34, diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index 4626d39cc0f0..6c2a33ab042c 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -34,7 +34,7 @@ unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task); unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task); unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from); unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from); -#else +#elif defined(CONFIG_PPC_FPU_REGS) static inline unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) { @@ -63,6 +63,18 @@ copy_ckfpr_from_user(struct task_struct *task, void __user *from) ELF_NFPREG * sizeof(double)); } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ +#else +static inline unsigned long +copy_fpr_to_user(void __user *to, struct task_struct *task) +{ + return 0; +} + +static inline unsigned long +copy_fpr_from_user(struct task_struct *task, void __user *from) +{ + return 0; +} #endif #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 96950f189b5a..7b291707eb31 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -814,7 +814,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, } regs->link = tramp; +#ifdef CONFIG_PPC_FPU_REGS tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ +#endif /* create a stack frame for the caller of the handler */ newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16); @@ -1271,7 +1273,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, regs->link = tramp; +#ifdef CONFIG_PPC_FPU_REGS tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ +#endif /* create a stack frame for the caller of the handler */ newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index d1ebe152f210..5c68f0de905c 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1194,7 +1194,9 @@ static void parse_fpe(struct pt_regs *regs) flush_fp_to_thread(current); +#ifdef CONFIG_PPC_FPU_REGS code = __parse_fpscr(current->thread.fp_state.fpscr); +#endif _exception(SIGFPE, regs, code, regs->nip); } diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 87737ec86d39..40ffcdba42b8 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -225,9 +225,13 @@ config PPC_E500MC such as e5500/e6500), and must be disabled for running on e500v1 or e500v2. +config PPC_FPU_REGS + bool + config PPC_FPU bool default y if PPC64 + select PPC_FPU_REGS config FSL_EMB_PERFMON bool "Freescale Embedded Perfmon" -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 06/19] powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:05 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev The e300c2 core which is embedded in mpc832x CPU doesn't have an FPU. Make it possible to not select CONFIG_PPC_FPU when building a kernel dedicated to that target. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/platforms/Kconfig.cputype | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 40ffcdba42b8..d4fd109f177e 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -32,7 +32,7 @@ choice config PPC_BOOK3S_6xx bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx except 601" select PPC_BOOK3S_32 - select PPC_FPU + imply PPC_FPU select PPC_HAVE_PMU_SUPPORT select PPC_HAVE_KUEP select PPC_HAVE_KUAP @@ -229,9 +229,16 @@ config PPC_FPU_REGS bool config PPC_FPU - bool + bool "Support for Floating Point Unit (FPU)" if PPC_MPC832x default y if PPC64 select PPC_FPU_REGS + help + This must be enabled to support the Floating Point Unit + Most 6xx have an FPU but e300c2 core (mpc832x) don't have + an FPU, so when building an embedded kernel for that target + you can disable FPU support. + + If unsure say Y. config FSL_EMB_PERFMON bool "Freescale Embedded Perfmon" -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 06/19] powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x @ 2020-08-12 12:05 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel The e300c2 core which is embedded in mpc832x CPU doesn't have an FPU. Make it possible to not select CONFIG_PPC_FPU when building a kernel dedicated to that target. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/platforms/Kconfig.cputype | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 40ffcdba42b8..d4fd109f177e 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -32,7 +32,7 @@ choice config PPC_BOOK3S_6xx bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx except 601" select PPC_BOOK3S_32 - select PPC_FPU + imply PPC_FPU select PPC_HAVE_PMU_SUPPORT select PPC_HAVE_KUEP select PPC_HAVE_KUAP @@ -229,9 +229,16 @@ config PPC_FPU_REGS bool config PPC_FPU - bool + bool "Support for Floating Point Unit (FPU)" if PPC_MPC832x default y if PPC64 select PPC_FPU_REGS + help + This must be enabled to support the Floating Point Unit + Most 6xx have an FPU but e300c2 core (mpc832x) don't have + an FPU, so when building an embedded kernel for that target + you can disable FPU support. + + If unsure say Y. config FSL_EMB_PERFMON bool "Freescale Embedded Perfmon" -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 07/19] powerpc/signal: Move access_ok() out of get_sigframe() 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:05 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev This access_ok() will soon be performed by user_access_begin(). So move it out of get_sigframe() Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal.c | 4 ---- arch/powerpc/kernel/signal_32.c | 4 ++-- arch/powerpc/kernel/signal_64.c | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 3b56db02b762..1be5fd01f866 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -154,10 +154,6 @@ void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, oldsp = sigsp(oldsp, ksig); newsp = (oldsp - frame_size) & ~0xFUL; - /* Check access */ - if (!access_ok((void __user *)newsp, oldsp - newsp)) - return NULL; - return (void __user *)newsp; } diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 7b291707eb31..5a838188a181 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -770,7 +770,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Put a Real Time Context onto stack */ rt_sf = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*rt_sf), 1); addr = rt_sf; - if (unlikely(rt_sf == NULL)) + if (!access_ok(rt_sf, sizeof(*rt_sf))) goto badframe; /* Put the siginfo & fill in most of the ucontext */ @@ -1231,7 +1231,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 1); - if (unlikely(frame == NULL)) + if (!access_ok(frame, sizeof(*frame))) goto badframe; sc = (struct sigcontext __user *) &frame->sctx; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index bfc939360bad..ec259a0efe24 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -825,7 +825,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, BUG_ON(tsk != current); frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 0); - if (unlikely(frame == NULL)) + if (!access_ok(frame, sizeof(*frame))) goto badframe; err |= __put_user(&frame->info, &frame->pinfo); -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 07/19] powerpc/signal: Move access_ok() out of get_sigframe() @ 2020-08-12 12:05 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel This access_ok() will soon be performed by user_access_begin(). So move it out of get_sigframe() Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal.c | 4 ---- arch/powerpc/kernel/signal_32.c | 4 ++-- arch/powerpc/kernel/signal_64.c | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 3b56db02b762..1be5fd01f866 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -154,10 +154,6 @@ void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, oldsp = sigsp(oldsp, ksig); newsp = (oldsp - frame_size) & ~0xFUL; - /* Check access */ - if (!access_ok((void __user *)newsp, oldsp - newsp)) - return NULL; - return (void __user *)newsp; } diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 7b291707eb31..5a838188a181 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -770,7 +770,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Put a Real Time Context onto stack */ rt_sf = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*rt_sf), 1); addr = rt_sf; - if (unlikely(rt_sf == NULL)) + if (!access_ok(rt_sf, sizeof(*rt_sf))) goto badframe; /* Put the siginfo & fill in most of the ucontext */ @@ -1231,7 +1231,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 1); - if (unlikely(frame == NULL)) + if (!access_ok(frame, sizeof(*frame))) goto badframe; sc = (struct sigcontext __user *) &frame->sctx; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index bfc939360bad..ec259a0efe24 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -825,7 +825,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, BUG_ON(tsk != current); frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 0); - if (unlikely(frame == NULL)) + if (!access_ok(frame, sizeof(*frame))) goto badframe; err |= __put_user(&frame->info, &frame->pinfo); -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 08/19] powerpc/signal: Remove get_clean_sp() 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:05 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev get_clean_sp() is only used once in kernel/signal.c . And GCC is smart enough to see that x & 0xffffffff is a nop calculation on PPC32, no need of a special PPC32 trivial version. Include the logic from the PPC64 version of get_clean_sp() directly in get_sigframe() Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/include/asm/processor.h | 14 -------------- arch/powerpc/kernel/signal.c | 5 ++++- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index e20b0c5abe62..8320aedbdca3 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -406,20 +406,6 @@ static inline void prefetchw(const void *x) #define HAVE_ARCH_PICK_MMAP_LAYOUT -#ifdef CONFIG_PPC64 -static inline unsigned long get_clean_sp(unsigned long sp, int is_32) -{ - if (is_32) - return sp & 0x0ffffffffUL; - return sp; -} -#else -static inline unsigned long get_clean_sp(unsigned long sp, int is_32) -{ - return sp; -} -#endif - /* asm stubs */ extern unsigned long isa300_idle_stop_noloss(unsigned long psscr_val); extern unsigned long isa300_idle_stop_mayloss(unsigned long psscr_val); diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 1be5fd01f866..a295d482adec 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -150,7 +150,10 @@ void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, unsigned long oldsp, newsp; /* Default to using normal stack */ - oldsp = get_clean_sp(sp, is_32); + if (is_32) + oldsp = sp & 0x0ffffffffUL; + else + oldsp = sp; oldsp = sigsp(oldsp, ksig); newsp = (oldsp - frame_size) & ~0xFUL; -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 08/19] powerpc/signal: Remove get_clean_sp() @ 2020-08-12 12:05 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel get_clean_sp() is only used once in kernel/signal.c . And GCC is smart enough to see that x & 0xffffffff is a nop calculation on PPC32, no need of a special PPC32 trivial version. Include the logic from the PPC64 version of get_clean_sp() directly in get_sigframe() Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/include/asm/processor.h | 14 -------------- arch/powerpc/kernel/signal.c | 5 ++++- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index e20b0c5abe62..8320aedbdca3 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -406,20 +406,6 @@ static inline void prefetchw(const void *x) #define HAVE_ARCH_PICK_MMAP_LAYOUT -#ifdef CONFIG_PPC64 -static inline unsigned long get_clean_sp(unsigned long sp, int is_32) -{ - if (is_32) - return sp & 0x0ffffffffUL; - return sp; -} -#else -static inline unsigned long get_clean_sp(unsigned long sp, int is_32) -{ - return sp; -} -#endif - /* asm stubs */ extern unsigned long isa300_idle_stop_noloss(unsigned long psscr_val); extern unsigned long isa300_idle_stop_mayloss(unsigned long psscr_val); diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 1be5fd01f866..a295d482adec 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -150,7 +150,10 @@ void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, unsigned long oldsp, newsp; /* Default to using normal stack */ - oldsp = get_clean_sp(sp, is_32); + if (is_32) + oldsp = sp & 0x0ffffffffUL; + else + oldsp = sp; oldsp = sigsp(oldsp, ksig); newsp = (oldsp - frame_size) & ~0xFUL; -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 09/19] powerpc/signal: Call get_tm_stackpointer() from get_sigframe() 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev Instead of calling get_tm_stackpointer() from the caller, call it directly from get_sigframe(). This avoids a double call and allows get_tm_stackpointer() to become static and be inlined into get_sigframe() by GCC. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal.c | 9 ++++++--- arch/powerpc/kernel/signal.h | 6 ++---- arch/powerpc/kernel/signal_32.c | 4 ++-- arch/powerpc/kernel/signal_64.c | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index a295d482adec..5edded5c5d20 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -144,10 +144,13 @@ int show_unhandled_signals = 1; /* * Allocate space for the signal frame */ -void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, - size_t frame_size, int is_32) +static unsigned long get_tm_stackpointer(struct task_struct *tsk); + +void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk, + size_t frame_size, int is_32) { unsigned long oldsp, newsp; + unsigned long sp = get_tm_stackpointer(tsk); /* Default to using normal stack */ if (is_32) @@ -304,7 +307,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) user_enter(); } -unsigned long get_tm_stackpointer(struct task_struct *tsk) +static unsigned long get_tm_stackpointer(struct task_struct *tsk) { /* When in an active transaction that takes a signal, we need to be * careful with the stack. It's possible that the stack has moved back diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index 6c2a33ab042c..fb98731348c3 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -10,8 +10,8 @@ #ifndef _POWERPC_ARCH_SIGNAL_H #define _POWERPC_ARCH_SIGNAL_H -extern void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, - size_t frame_size, int is_32); +void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk, + size_t frame_size, int is_32); extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset, struct task_struct *tsk); @@ -19,8 +19,6 @@ extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset, extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, struct task_struct *tsk); -extern unsigned long get_tm_stackpointer(struct task_struct *tsk); - #ifdef CONFIG_VSX extern unsigned long copy_vsx_to_user(void __user *to, struct task_struct *task); diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 5a838188a181..3356f6aba4ae 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -768,7 +768,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ /* Put a Real Time Context onto stack */ - rt_sf = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*rt_sf), 1); + rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1); addr = rt_sf; if (!access_ok(rt_sf, sizeof(*rt_sf))) goto badframe; @@ -1230,7 +1230,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, BUG_ON(tsk != current); /* Set up Signal Frame */ - frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 1); + frame = get_sigframe(ksig, tsk, sizeof(*frame), 1); if (!access_ok(frame, sizeof(*frame))) goto badframe; sc = (struct sigcontext __user *) &frame->sctx; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index ec259a0efe24..92d152c1155c 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -824,7 +824,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, BUG_ON(tsk != current); - frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 0); + frame = get_sigframe(ksig, tsk, sizeof(*frame), 0); if (!access_ok(frame, sizeof(*frame))) goto badframe; -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 09/19] powerpc/signal: Call get_tm_stackpointer() from get_sigframe() @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel Instead of calling get_tm_stackpointer() from the caller, call it directly from get_sigframe(). This avoids a double call and allows get_tm_stackpointer() to become static and be inlined into get_sigframe() by GCC. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal.c | 9 ++++++--- arch/powerpc/kernel/signal.h | 6 ++---- arch/powerpc/kernel/signal_32.c | 4 ++-- arch/powerpc/kernel/signal_64.c | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index a295d482adec..5edded5c5d20 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -144,10 +144,13 @@ int show_unhandled_signals = 1; /* * Allocate space for the signal frame */ -void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, - size_t frame_size, int is_32) +static unsigned long get_tm_stackpointer(struct task_struct *tsk); + +void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk, + size_t frame_size, int is_32) { unsigned long oldsp, newsp; + unsigned long sp = get_tm_stackpointer(tsk); /* Default to using normal stack */ if (is_32) @@ -304,7 +307,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) user_enter(); } -unsigned long get_tm_stackpointer(struct task_struct *tsk) +static unsigned long get_tm_stackpointer(struct task_struct *tsk) { /* When in an active transaction that takes a signal, we need to be * careful with the stack. It's possible that the stack has moved back diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index 6c2a33ab042c..fb98731348c3 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -10,8 +10,8 @@ #ifndef _POWERPC_ARCH_SIGNAL_H #define _POWERPC_ARCH_SIGNAL_H -extern void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, - size_t frame_size, int is_32); +void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk, + size_t frame_size, int is_32); extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset, struct task_struct *tsk); @@ -19,8 +19,6 @@ extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset, extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, struct task_struct *tsk); -extern unsigned long get_tm_stackpointer(struct task_struct *tsk); - #ifdef CONFIG_VSX extern unsigned long copy_vsx_to_user(void __user *to, struct task_struct *task); diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 5a838188a181..3356f6aba4ae 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -768,7 +768,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ /* Put a Real Time Context onto stack */ - rt_sf = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*rt_sf), 1); + rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1); addr = rt_sf; if (!access_ok(rt_sf, sizeof(*rt_sf))) goto badframe; @@ -1230,7 +1230,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, BUG_ON(tsk != current); /* Set up Signal Frame */ - frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 1); + frame = get_sigframe(ksig, tsk, sizeof(*frame), 1); if (!access_ok(frame, sizeof(*frame))) goto badframe; sc = (struct sigcontext __user *) &frame->sctx; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index ec259a0efe24..92d152c1155c 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -824,7 +824,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, BUG_ON(tsk != current); - frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 0); + frame = get_sigframe(ksig, tsk, sizeof(*frame), 0); if (!access_ok(frame, sizeof(*frame))) goto badframe; -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 10/19] powerpc/signal: Refactor bad frame logging 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev The logging of bad frame appears half a dozen of times and is pretty similar. Create signal_fault() fonction to perform that logging. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal.c | 11 +++++++++++ arch/powerpc/kernel/signal.h | 3 +++ arch/powerpc/kernel/signal_32.c | 35 +++++---------------------------- arch/powerpc/kernel/signal_64.c | 15 ++------------ 4 files changed, 21 insertions(+), 43 deletions(-) diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 5edded5c5d20..53b4987a45b5 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -355,3 +355,14 @@ static unsigned long get_tm_stackpointer(struct task_struct *tsk) #endif return ret; } + +static const char fmt32[] = KERN_INFO "%s[%d]: bad frame in %s: %p nip %08lx lr %08lx\n"; +static const char fmt64[] = KERN_INFO "%s[%d]: bad frame in %s: %p nip %016lx lr %016lx\n"; + +void signal_fault(struct task_struct *tsk, struct pt_regs *regs, + const char *where, void __user *ptr) +{ + if (show_unhandled_signals) + printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, tsk->comm, + task_pid_nr(tsk), where, ptr, regs->nip, regs->link); +} diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index fb98731348c3..f610cfafa478 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -93,4 +93,7 @@ static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, #endif /* !defined(CONFIG_PPC64) */ +void signal_fault(struct task_struct *tsk, struct pt_regs *regs, + const char *where, void __user *ptr); + #endif /* _POWERPC_ARCH_SIGNAL_H */ diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 3356f6aba4ae..d1087dd87174 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -837,12 +837,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in handle_rt_signal32: " - "%p nip %08lx lr %08lx\n", - tsk->comm, tsk->pid, - addr, regs->nip, regs->link); + signal_fault(tsk, regs, "handle_rt_signal32", addr); return 1; } @@ -1094,12 +1089,7 @@ SYSCALL_DEFINE0(rt_sigreturn) return 0; bad: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in sys_rt_sigreturn: " - "%p nip %08lx lr %08lx\n", - current->comm, current->pid, - rt_sf, regs->nip, regs->link); + signal_fault(current, regs, "sys_rt_sigreturn", rt_sf); force_sig(SIGSEGV); return 0; @@ -1183,12 +1173,7 @@ SYSCALL_DEFINE3(debug_setcontext, struct ucontext __user *, ctx, * We kill the task with a SIGSEGV in this situation. */ if (do_setcontext(ctx, regs, 1)) { - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO "%s[%d]: bad frame in " - "sys_debug_setcontext: %p nip %08lx " - "lr %08lx\n", - current->comm, current->pid, - ctx, regs->nip, regs->link); + signal_fault(current, regs, "sys_debug_setcontext", ctx); force_sig(SIGSEGV); goto out; @@ -1291,12 +1276,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in handle_signal32: " - "%p nip %08lx lr %08lx\n", - tsk->comm, tsk->pid, - frame, regs->nip, regs->link); + signal_fault(tsk, regs, "handle_signal32", frame); return 1; } @@ -1367,12 +1347,7 @@ SYSCALL_DEFINE0(sigreturn) return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in sys_sigreturn: " - "%p nip %08lx lr %08lx\n", - current->comm, current->pid, - addr, regs->nip, regs->link); + signal_fault(current, regs, "sys_sigreturn", addr); force_sig(SIGSEGV); return 0; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 92d152c1155c..a10b0bb14131 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -66,11 +66,6 @@ struct rt_sigframe { char abigap[USER_REDZONE_SIZE]; } __attribute__ ((aligned (16))); -static const char fmt32[] = KERN_INFO \ - "%s[%d]: bad frame in %s: %08lx nip %08lx lr %08lx\n"; -static const char fmt64[] = KERN_INFO \ - "%s[%d]: bad frame in %s: %016lx nip %016lx lr %016lx\n"; - /* * This computes a quad word aligned pointer inside the vmx_reserve array * element. For historical reasons sigcontext might not be quad word aligned, @@ -801,10 +796,7 @@ SYSCALL_DEFINE0(rt_sigreturn) return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, - current->comm, current->pid, "rt_sigreturn", - (long)uc, regs->nip, regs->link); + signal_fault(current, regs, "rt_sigreturn", uc); force_sig(SIGSEGV); return 0; @@ -913,10 +905,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, - tsk->comm, tsk->pid, "setup_rt_frame", - (long)frame, regs->nip, regs->link); + signal_fault(current, regs, "handle_rt_signal64", frame); return 1; } -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 10/19] powerpc/signal: Refactor bad frame logging @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel The logging of bad frame appears half a dozen of times and is pretty similar. Create signal_fault() fonction to perform that logging. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal.c | 11 +++++++++++ arch/powerpc/kernel/signal.h | 3 +++ arch/powerpc/kernel/signal_32.c | 35 +++++---------------------------- arch/powerpc/kernel/signal_64.c | 15 ++------------ 4 files changed, 21 insertions(+), 43 deletions(-) diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 5edded5c5d20..53b4987a45b5 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -355,3 +355,14 @@ static unsigned long get_tm_stackpointer(struct task_struct *tsk) #endif return ret; } + +static const char fmt32[] = KERN_INFO "%s[%d]: bad frame in %s: %p nip %08lx lr %08lx\n"; +static const char fmt64[] = KERN_INFO "%s[%d]: bad frame in %s: %p nip %016lx lr %016lx\n"; + +void signal_fault(struct task_struct *tsk, struct pt_regs *regs, + const char *where, void __user *ptr) +{ + if (show_unhandled_signals) + printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, tsk->comm, + task_pid_nr(tsk), where, ptr, regs->nip, regs->link); +} diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index fb98731348c3..f610cfafa478 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -93,4 +93,7 @@ static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, #endif /* !defined(CONFIG_PPC64) */ +void signal_fault(struct task_struct *tsk, struct pt_regs *regs, + const char *where, void __user *ptr); + #endif /* _POWERPC_ARCH_SIGNAL_H */ diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 3356f6aba4ae..d1087dd87174 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -837,12 +837,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in handle_rt_signal32: " - "%p nip %08lx lr %08lx\n", - tsk->comm, tsk->pid, - addr, regs->nip, regs->link); + signal_fault(tsk, regs, "handle_rt_signal32", addr); return 1; } @@ -1094,12 +1089,7 @@ SYSCALL_DEFINE0(rt_sigreturn) return 0; bad: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in sys_rt_sigreturn: " - "%p nip %08lx lr %08lx\n", - current->comm, current->pid, - rt_sf, regs->nip, regs->link); + signal_fault(current, regs, "sys_rt_sigreturn", rt_sf); force_sig(SIGSEGV); return 0; @@ -1183,12 +1173,7 @@ SYSCALL_DEFINE3(debug_setcontext, struct ucontext __user *, ctx, * We kill the task with a SIGSEGV in this situation. */ if (do_setcontext(ctx, regs, 1)) { - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO "%s[%d]: bad frame in " - "sys_debug_setcontext: %p nip %08lx " - "lr %08lx\n", - current->comm, current->pid, - ctx, regs->nip, regs->link); + signal_fault(current, regs, "sys_debug_setcontext", ctx); force_sig(SIGSEGV); goto out; @@ -1291,12 +1276,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in handle_signal32: " - "%p nip %08lx lr %08lx\n", - tsk->comm, tsk->pid, - frame, regs->nip, regs->link); + signal_fault(tsk, regs, "handle_signal32", frame); return 1; } @@ -1367,12 +1347,7 @@ SYSCALL_DEFINE0(sigreturn) return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in sys_sigreturn: " - "%p nip %08lx lr %08lx\n", - current->comm, current->pid, - addr, regs->nip, regs->link); + signal_fault(current, regs, "sys_sigreturn", addr); force_sig(SIGSEGV); return 0; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 92d152c1155c..a10b0bb14131 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -66,11 +66,6 @@ struct rt_sigframe { char abigap[USER_REDZONE_SIZE]; } __attribute__ ((aligned (16))); -static const char fmt32[] = KERN_INFO \ - "%s[%d]: bad frame in %s: %08lx nip %08lx lr %08lx\n"; -static const char fmt64[] = KERN_INFO \ - "%s[%d]: bad frame in %s: %016lx nip %016lx lr %016lx\n"; - /* * This computes a quad word aligned pointer inside the vmx_reserve array * element. For historical reasons sigcontext might not be quad word aligned, @@ -801,10 +796,7 @@ SYSCALL_DEFINE0(rt_sigreturn) return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, - current->comm, current->pid, "rt_sigreturn", - (long)uc, regs->nip, regs->link); + signal_fault(current, regs, "rt_sigreturn", uc); force_sig(SIGSEGV); return 0; @@ -913,10 +905,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, - tsk->comm, tsk->pid, "setup_rt_frame", - (long)frame, regs->nip, regs->link); + signal_fault(current, regs, "handle_rt_signal64", frame); return 1; } -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 11/19] powerpc/signal32: Simplify logging in handle_rt_signal32() 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev If something is bad in the frame, there is no point in knowing which part of the frame exactly is wrong as it got allocated as a single block. Always print the root address of the frame in case on failed user access, just like handle_signal32(). Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index d1087dd87174..495bee1b713d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -754,7 +754,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, struct rt_sigframe __user *rt_sf; struct mcontext __user *frame; struct mcontext __user *tm_frame = NULL; - void __user *addr; unsigned long newsp = 0; int sigret; unsigned long tramp; @@ -769,7 +768,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ /* Put a Real Time Context onto stack */ rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1); - addr = rt_sf; if (!access_ok(rt_sf, sizeof(*rt_sf))) goto badframe; @@ -784,7 +782,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Save user registers on the stack */ frame = &rt_sf->uc.uc_mcontext; - addr = frame; if (vdso32_rt_sigtramp && tsk->mm->context.vdso_base) { sigret = 0; tramp = tsk->mm->context.vdso_base + vdso32_rt_sigtramp; @@ -820,7 +817,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* create a stack frame for the caller of the handler */ newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16); - addr = (void __user *)regs->gpr[1]; if (put_user(regs->gpr[1], (u32 __user *)newsp)) goto badframe; @@ -837,7 +833,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, return 0; badframe: - signal_fault(tsk, regs, "handle_rt_signal32", addr); + signal_fault(tsk, regs, "handle_rt_signal32", rt_sf); return 1; } -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 11/19] powerpc/signal32: Simplify logging in handle_rt_signal32() @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel If something is bad in the frame, there is no point in knowing which part of the frame exactly is wrong as it got allocated as a single block. Always print the root address of the frame in case on failed user access, just like handle_signal32(). Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index d1087dd87174..495bee1b713d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -754,7 +754,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, struct rt_sigframe __user *rt_sf; struct mcontext __user *frame; struct mcontext __user *tm_frame = NULL; - void __user *addr; unsigned long newsp = 0; int sigret; unsigned long tramp; @@ -769,7 +768,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ /* Put a Real Time Context onto stack */ rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1); - addr = rt_sf; if (!access_ok(rt_sf, sizeof(*rt_sf))) goto badframe; @@ -784,7 +782,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Save user registers on the stack */ frame = &rt_sf->uc.uc_mcontext; - addr = frame; if (vdso32_rt_sigtramp && tsk->mm->context.vdso_base) { sigret = 0; tramp = tsk->mm->context.vdso_base + vdso32_rt_sigtramp; @@ -820,7 +817,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* create a stack frame for the caller of the handler */ newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16); - addr = (void __user *)regs->gpr[1]; if (put_user(regs->gpr[1], (u32 __user *)newsp)) goto badframe; @@ -837,7 +833,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, return 0; badframe: - signal_fault(tsk, regs, "handle_rt_signal32", addr); + signal_fault(tsk, regs, "handle_rt_signal32", rt_sf); return 1; } -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 12/19] powerpc/signal32: Regroup copies in save_user_regs() and save_tm_user_regs() 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev Reorder actions in save_user_regs() and save_tm_user_regs() to regroup copies together in order to switch to user_access_begin() logic in a later patch. In save_tm_user_regs(), first perform copies to frame, then perform copies to tm_frame. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 153 +++++++++++++++++++------------- 1 file changed, 91 insertions(+), 62 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 495bee1b713d..2c3d5d4400ec 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -243,6 +243,20 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, /* Make sure floating point registers are stored in regs */ flush_fp_to_thread(current); +#ifdef CONFIG_ALTIVEC + if (current->thread.used_vr) + flush_altivec_to_thread(current); + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + current->thread.vrsave = mfspr(SPRN_VRSAVE); +#endif +#ifdef CONFIG_VSX + if (current->thread.used_vsr && ctx_has_vsx_region) + flush_vsx_to_thread(current); +#endif +#ifdef CONFIG_SPE + if (current->thread.used_spe) + flush_spe_to_thread(current); +#endif /* save general registers */ if (save_general_regs(regs, frame)) @@ -251,7 +265,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, #ifdef CONFIG_ALTIVEC /* save altivec registers */ if (current->thread.used_vr) { - flush_altivec_to_thread(current); if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state, ELF_NVRREG * sizeof(vector128))) return 1; @@ -267,8 +280,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * most significant bits of that same vector. --BenH * Note that the current VRSAVE value is in the SPR at this point. */ - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - current->thread.vrsave = mfspr(SPRN_VRSAVE); if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32])) return 1; #endif /* CONFIG_ALTIVEC */ @@ -288,7 +299,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * contains valid data */ if (current->thread.used_vsr && ctx_has_vsx_region) { - flush_vsx_to_thread(current); if (copy_vsx_to_user(&frame->mc_vsregs, current)) return 1; msr |= MSR_VSX; @@ -297,7 +307,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, #ifdef CONFIG_SPE /* save spe registers */ if (current->thread.used_spe) { - flush_spe_to_thread(current); if (__copy_to_user(&frame->mc_vregs, current->thread.evr, ELF_NEVRREG * sizeof(u32))) return 1; @@ -314,20 +323,22 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, if (__put_user(msr, &frame->mc_gregs[PT_MSR])) return 1; - /* We need to write 0 the MSR top 32 bits in the tm frame so that we - * can check it on the restore to see if TM is active - */ - if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR])) - 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; + } + if (sigret) flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); - } + + /* We need to write 0 the MSR top 32 bits in the tm frame so that we + * can check it on the restore to see if TM is active + */ + if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR])) + return 1; return 0; } @@ -349,18 +360,16 @@ static int save_tm_user_regs(struct pt_regs *regs, { WARN_ON(tm_suspend_disabled); - /* Save both sets of general registers */ - if (save_general_regs(¤t->thread.ckpt_regs, frame) - || save_general_regs(regs, tm_frame)) - return 1; +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + current->thread.ckvrsave = mfspr(SPRN_VRSAVE); +#endif +#ifdef CONFIG_SPE + if (current->thread.used_spe) + flush_spe_to_thread(current); +#endif - /* Stash the top half of the 64bit MSR into the 32bit MSR word - * of the transactional mcontext. This way we have a backward-compatible - * MSR in the 'normal' (checkpointed) mcontext and additionally one can - * also look at what type of transaction (T or S) was active at the - * time of the signal. - */ - if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR])) + if (save_general_regs(¤t->thread.ckpt_regs, frame)) return 1; #ifdef CONFIG_ALTIVEC @@ -369,17 +378,6 @@ static int save_tm_user_regs(struct pt_regs *regs, if (__copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state, ELF_NVRREG * sizeof(vector128))) return 1; - if (msr & MSR_VEC) { - if (__copy_to_user(&tm_frame->mc_vregs, - ¤t->thread.vr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - } else { - if (__copy_to_user(&tm_frame->mc_vregs, - ¤t->thread.ckvr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - } /* set MSR_VEC in the saved MSR value to indicate that * frame->mc_vregs contains valid data @@ -392,32 +390,13 @@ static int save_tm_user_regs(struct pt_regs *regs, * significant bits of a vector, we "cheat" and stuff VRSAVE in the * most significant bits of that same vector. --BenH */ - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - current->thread.ckvrsave = mfspr(SPRN_VRSAVE); if (__put_user(current->thread.ckvrsave, (u32 __user *)&frame->mc_vregs[32])) return 1; - if (msr & MSR_VEC) { - if (__put_user(current->thread.vrsave, - (u32 __user *)&tm_frame->mc_vregs[32])) - return 1; - } else { - if (__put_user(current->thread.ckvrsave, - (u32 __user *)&tm_frame->mc_vregs[32])) - return 1; - } #endif /* CONFIG_ALTIVEC */ if (copy_ckfpr_to_user(&frame->mc_fregs, current)) return 1; - if (msr & MSR_FP) { - if (copy_fpr_to_user(&tm_frame->mc_fregs, current)) - return 1; - } else { - if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current)) - return 1; - } - #ifdef CONFIG_VSX /* * Copy VSR 0-31 upper half from thread_struct to local @@ -428,15 +407,6 @@ static int save_tm_user_regs(struct pt_regs *regs, if (current->thread.used_vsr) { if (copy_ckvsx_to_user(&frame->mc_vsregs, current)) return 1; - if (msr & MSR_VSX) { - if (copy_vsx_to_user(&tm_frame->mc_vsregs, - current)) - return 1; - } else { - if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current)) - return 1; - } - msr |= MSR_VSX; } #endif /* CONFIG_VSX */ @@ -445,7 +415,6 @@ static int save_tm_user_regs(struct pt_regs *regs, * simply the same as in save_user_regs(). */ if (current->thread.used_spe) { - flush_spe_to_thread(current); if (__copy_to_user(&frame->mc_vregs, current->thread.evr, ELF_NEVRREG * sizeof(u32))) return 1; @@ -466,9 +435,69 @@ static int save_tm_user_regs(struct pt_regs *regs, if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0]) || __put_user(PPC_INST_SC, &frame->tramp[1])) return 1; + } + if (sigret) flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); + + if (save_general_regs(regs, tm_frame)) + return 1; + + /* Stash the top half of the 64bit MSR into the 32bit MSR word + * of the transactional mcontext. This way we have a backward-compatible + * MSR in the 'normal' (checkpointed) mcontext and additionally one can + * also look at what type of transaction (T or S) was active at the + * time of the signal. + */ + if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR])) + return 1; + +#ifdef CONFIG_ALTIVEC + if (current->thread.used_vr) { + if (msr & MSR_VEC) { + if (__copy_to_user(&tm_frame->mc_vregs, + ¤t->thread.vr_state, + ELF_NVRREG * sizeof(vector128))) + return 1; + } else { + if (__copy_to_user(&tm_frame->mc_vregs, + ¤t->thread.ckvr_state, + ELF_NVRREG * sizeof(vector128))) + return 1; + } + } + + if (msr & MSR_VEC) { + if (__put_user(current->thread.vrsave, + (u32 __user *)&tm_frame->mc_vregs[32])) + return 1; + } else { + if (__put_user(current->thread.ckvrsave, + (u32 __user *)&tm_frame->mc_vregs[32])) + return 1; } +#endif /* CONFIG_ALTIVEC */ + + if (msr & MSR_FP) { + if (copy_fpr_to_user(&tm_frame->mc_fregs, current)) + return 1; + } else { + if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current)) + return 1; + } + +#ifdef CONFIG_VSX + if (current->thread.used_vsr) { + if (msr & MSR_VSX) { + if (copy_vsx_to_user(&tm_frame->mc_vsregs, + current)) + return 1; + } else { + if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current)) + return 1; + } + } +#endif /* CONFIG_VSX */ return 0; } -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 12/19] powerpc/signal32: Regroup copies in save_user_regs() and save_tm_user_regs() @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel Reorder actions in save_user_regs() and save_tm_user_regs() to regroup copies together in order to switch to user_access_begin() logic in a later patch. In save_tm_user_regs(), first perform copies to frame, then perform copies to tm_frame. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 153 +++++++++++++++++++------------- 1 file changed, 91 insertions(+), 62 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 495bee1b713d..2c3d5d4400ec 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -243,6 +243,20 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, /* Make sure floating point registers are stored in regs */ flush_fp_to_thread(current); +#ifdef CONFIG_ALTIVEC + if (current->thread.used_vr) + flush_altivec_to_thread(current); + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + current->thread.vrsave = mfspr(SPRN_VRSAVE); +#endif +#ifdef CONFIG_VSX + if (current->thread.used_vsr && ctx_has_vsx_region) + flush_vsx_to_thread(current); +#endif +#ifdef CONFIG_SPE + if (current->thread.used_spe) + flush_spe_to_thread(current); +#endif /* save general registers */ if (save_general_regs(regs, frame)) @@ -251,7 +265,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, #ifdef CONFIG_ALTIVEC /* save altivec registers */ if (current->thread.used_vr) { - flush_altivec_to_thread(current); if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state, ELF_NVRREG * sizeof(vector128))) return 1; @@ -267,8 +280,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * most significant bits of that same vector. --BenH * Note that the current VRSAVE value is in the SPR at this point. */ - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - current->thread.vrsave = mfspr(SPRN_VRSAVE); if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32])) return 1; #endif /* CONFIG_ALTIVEC */ @@ -288,7 +299,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * contains valid data */ if (current->thread.used_vsr && ctx_has_vsx_region) { - flush_vsx_to_thread(current); if (copy_vsx_to_user(&frame->mc_vsregs, current)) return 1; msr |= MSR_VSX; @@ -297,7 +307,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, #ifdef CONFIG_SPE /* save spe registers */ if (current->thread.used_spe) { - flush_spe_to_thread(current); if (__copy_to_user(&frame->mc_vregs, current->thread.evr, ELF_NEVRREG * sizeof(u32))) return 1; @@ -314,20 +323,22 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, if (__put_user(msr, &frame->mc_gregs[PT_MSR])) return 1; - /* We need to write 0 the MSR top 32 bits in the tm frame so that we - * can check it on the restore to see if TM is active - */ - if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR])) - 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; + } + if (sigret) flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); - } + + /* We need to write 0 the MSR top 32 bits in the tm frame so that we + * can check it on the restore to see if TM is active + */ + if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR])) + return 1; return 0; } @@ -349,18 +360,16 @@ static int save_tm_user_regs(struct pt_regs *regs, { WARN_ON(tm_suspend_disabled); - /* Save both sets of general registers */ - if (save_general_regs(¤t->thread.ckpt_regs, frame) - || save_general_regs(regs, tm_frame)) - return 1; +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + current->thread.ckvrsave = mfspr(SPRN_VRSAVE); +#endif +#ifdef CONFIG_SPE + if (current->thread.used_spe) + flush_spe_to_thread(current); +#endif - /* Stash the top half of the 64bit MSR into the 32bit MSR word - * of the transactional mcontext. This way we have a backward-compatible - * MSR in the 'normal' (checkpointed) mcontext and additionally one can - * also look at what type of transaction (T or S) was active at the - * time of the signal. - */ - if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR])) + if (save_general_regs(¤t->thread.ckpt_regs, frame)) return 1; #ifdef CONFIG_ALTIVEC @@ -369,17 +378,6 @@ static int save_tm_user_regs(struct pt_regs *regs, if (__copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state, ELF_NVRREG * sizeof(vector128))) return 1; - if (msr & MSR_VEC) { - if (__copy_to_user(&tm_frame->mc_vregs, - ¤t->thread.vr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - } else { - if (__copy_to_user(&tm_frame->mc_vregs, - ¤t->thread.ckvr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - } /* set MSR_VEC in the saved MSR value to indicate that * frame->mc_vregs contains valid data @@ -392,32 +390,13 @@ static int save_tm_user_regs(struct pt_regs *regs, * significant bits of a vector, we "cheat" and stuff VRSAVE in the * most significant bits of that same vector. --BenH */ - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - current->thread.ckvrsave = mfspr(SPRN_VRSAVE); if (__put_user(current->thread.ckvrsave, (u32 __user *)&frame->mc_vregs[32])) return 1; - if (msr & MSR_VEC) { - if (__put_user(current->thread.vrsave, - (u32 __user *)&tm_frame->mc_vregs[32])) - return 1; - } else { - if (__put_user(current->thread.ckvrsave, - (u32 __user *)&tm_frame->mc_vregs[32])) - return 1; - } #endif /* CONFIG_ALTIVEC */ if (copy_ckfpr_to_user(&frame->mc_fregs, current)) return 1; - if (msr & MSR_FP) { - if (copy_fpr_to_user(&tm_frame->mc_fregs, current)) - return 1; - } else { - if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current)) - return 1; - } - #ifdef CONFIG_VSX /* * Copy VSR 0-31 upper half from thread_struct to local @@ -428,15 +407,6 @@ static int save_tm_user_regs(struct pt_regs *regs, if (current->thread.used_vsr) { if (copy_ckvsx_to_user(&frame->mc_vsregs, current)) return 1; - if (msr & MSR_VSX) { - if (copy_vsx_to_user(&tm_frame->mc_vsregs, - current)) - return 1; - } else { - if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current)) - return 1; - } - msr |= MSR_VSX; } #endif /* CONFIG_VSX */ @@ -445,7 +415,6 @@ static int save_tm_user_regs(struct pt_regs *regs, * simply the same as in save_user_regs(). */ if (current->thread.used_spe) { - flush_spe_to_thread(current); if (__copy_to_user(&frame->mc_vregs, current->thread.evr, ELF_NEVRREG * sizeof(u32))) return 1; @@ -466,9 +435,69 @@ static int save_tm_user_regs(struct pt_regs *regs, if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0]) || __put_user(PPC_INST_SC, &frame->tramp[1])) return 1; + } + if (sigret) flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); + + if (save_general_regs(regs, tm_frame)) + return 1; + + /* Stash the top half of the 64bit MSR into the 32bit MSR word + * of the transactional mcontext. This way we have a backward-compatible + * MSR in the 'normal' (checkpointed) mcontext and additionally one can + * also look at what type of transaction (T or S) was active at the + * time of the signal. + */ + if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR])) + return 1; + +#ifdef CONFIG_ALTIVEC + if (current->thread.used_vr) { + if (msr & MSR_VEC) { + if (__copy_to_user(&tm_frame->mc_vregs, + ¤t->thread.vr_state, + ELF_NVRREG * sizeof(vector128))) + return 1; + } else { + if (__copy_to_user(&tm_frame->mc_vregs, + ¤t->thread.ckvr_state, + ELF_NVRREG * sizeof(vector128))) + return 1; + } + } + + if (msr & MSR_VEC) { + if (__put_user(current->thread.vrsave, + (u32 __user *)&tm_frame->mc_vregs[32])) + return 1; + } else { + if (__put_user(current->thread.ckvrsave, + (u32 __user *)&tm_frame->mc_vregs[32])) + return 1; } +#endif /* CONFIG_ALTIVEC */ + + if (msr & MSR_FP) { + if (copy_fpr_to_user(&tm_frame->mc_fregs, current)) + return 1; + } else { + if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current)) + return 1; + } + +#ifdef CONFIG_VSX + if (current->thread.used_vsr) { + if (msr & MSR_VSX) { + if (copy_vsx_to_user(&tm_frame->mc_vsregs, + current)) + return 1; + } else { + if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current)) + return 1; + } + } +#endif /* CONFIG_VSX */ return 0; } -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 13/19] powerpc/signal32: Create 'unsafe' versions of copy_[ck][fpr/vsx]_to_user() 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev For the non VSX version, that's trivial. Just use unsafe_copy_to_user() instead of __copy_to_user(). For the VSX version, remove the intermediate step through a buffer and use unsafe_put_user() directly. This generates a far smaller code which is acceptable to inline, see below: Standard VSX version: 0000000000000000 <.copy_fpr_to_user>: 0: 7c 08 02 a6 mflr r0 4: fb e1 ff f8 std r31,-8(r1) 8: 39 00 00 20 li r8,32 c: 39 24 0b 80 addi r9,r4,2944 10: 7d 09 03 a6 mtctr r8 14: f8 01 00 10 std r0,16(r1) 18: f8 21 fe 71 stdu r1,-400(r1) 1c: 39 41 00 68 addi r10,r1,104 20: e9 09 00 00 ld r8,0(r9) 24: 39 4a 00 08 addi r10,r10,8 28: 39 29 00 10 addi r9,r9,16 2c: f9 0a 00 00 std r8,0(r10) 30: 42 00 ff f0 bdnz 20 <.copy_fpr_to_user+0x20> 34: e9 24 0d 80 ld r9,3456(r4) 38: 3d 42 00 00 addis r10,r2,0 3a: R_PPC64_TOC16_HA .toc 3c: eb ea 00 00 ld r31,0(r10) 3e: R_PPC64_TOC16_LO_DS .toc 40: f9 21 01 70 std r9,368(r1) 44: e9 3f 00 00 ld r9,0(r31) 48: 81 29 00 20 lwz r9,32(r9) 4c: 2f 89 00 00 cmpwi cr7,r9,0 50: 40 9c 00 18 bge cr7,68 <.copy_fpr_to_user+0x68> 54: 4c 00 01 2c isync 58: 3d 20 40 00 lis r9,16384 5c: 79 29 07 c6 rldicr r9,r9,32,31 60: 7d 3d 03 a6 mtspr 29,r9 64: 4c 00 01 2c isync 68: 38 a0 01 08 li r5,264 6c: 38 81 00 70 addi r4,r1,112 70: 48 00 00 01 bl 70 <.copy_fpr_to_user+0x70> 70: R_PPC64_REL24 .__copy_tofrom_user 74: 60 00 00 00 nop 78: e9 3f 00 00 ld r9,0(r31) 7c: 81 29 00 20 lwz r9,32(r9) 80: 2f 89 00 00 cmpwi cr7,r9,0 84: 40 9c 00 18 bge cr7,9c <.copy_fpr_to_user+0x9c> 88: 4c 00 01 2c isync 8c: 39 20 ff ff li r9,-1 90: 79 29 00 44 rldicr r9,r9,0,1 94: 7d 3d 03 a6 mtspr 29,r9 98: 4c 00 01 2c isync 9c: 38 21 01 90 addi r1,r1,400 a0: e8 01 00 10 ld r0,16(r1) a4: eb e1 ff f8 ld r31,-8(r1) a8: 7c 08 03 a6 mtlr r0 ac: 4e 80 00 20 blr 'unsafe' simulated VSX version (The ... are only nops) using unsafe_copy_fpr_to_user() macro: unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) { unsafe_copy_fpr_to_user(to, task, failed); return 0; failed: return 1; } 0000000000000000 <.copy_fpr_to_user>: 0: 39 00 00 20 li r8,32 4: 39 44 0b 80 addi r10,r4,2944 8: 7d 09 03 a6 mtctr r8 c: 7c 69 1b 78 mr r9,r3 ... 20: e9 0a 00 00 ld r8,0(r10) 24: f9 09 00 00 std r8,0(r9) 28: 39 4a 00 10 addi r10,r10,16 2c: 39 29 00 08 addi r9,r9,8 30: 42 00 ff f0 bdnz 20 <.copy_fpr_to_user+0x20> 34: e9 24 0d 80 ld r9,3456(r4) 38: f9 23 01 00 std r9,256(r3) 3c: 38 60 00 00 li r3,0 40: 4e 80 00 20 blr ... 50: 38 60 00 01 li r3,1 54: 4e 80 00 20 blr Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal.h | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index f610cfafa478..abe570f06c12 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -32,7 +32,49 @@ unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task); unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task); unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from); unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from); + +#define unsafe_copy_fpr_to_user(to, task, label) do { \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NFPREG - 1 ; i++) \ + unsafe_put_user(task->thread.TS_FPR(i), &buf[i], label);\ + unsafe_put_user(task->thread.fp_state.fpscr, &buf[i], label); \ +} while (0) + +#define unsafe_copy_vsx_to_user(to, task, label) do { \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NVSRHALFREG ; i++) \ + unsafe_put_user(task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \ + &buf[i], label);\ +} while (0) + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +#define unsafe_copy_ckfpr_to_user(to, task, label) do { \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NFPREG - 1 ; i++) \ + unsafe_put_user(task->thread.TS_CKFPR(i), &buf[i], label);\ + unsafe_put_user(task->thread.ckfp_state.fpscr, &buf[i], label); \ +} while (0) + +#define unsafe_copy_ckvsx_to_user(to, task, label) do { \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NVSRHALFREG ; i++) \ + unsafe_put_user(task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \ + &buf[i], label);\ +} while (0) +#endif #elif defined(CONFIG_PPC_FPU_REGS) + +#define unsafe_copy_fpr_to_user(to, task, label) \ + unsafe_copy_to_user(to, task->thread.fp_state.fpr, ELF_NFPREG * sizeof(double), label) + static inline unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) { @@ -48,6 +90,9 @@ copy_fpr_from_user(struct task_struct *task, void __user *from) } #ifdef CONFIG_PPC_TRANSACTIONAL_MEM +#define unsafe_copy_ckfpr_to_user(to, task, label) \ + unsafe_copy_to_user(to, task->thread.ckfp_state.fpr, ELF_NFPREG * sizeof(double), label) + inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task) { return __copy_to_user(to, task->thread.ckfp_state.fpr, @@ -62,6 +107,8 @@ copy_ckfpr_from_user(struct task_struct *task, void __user *from) } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #else +#define unsafe_copy_fpr_to_user(to, task, label) do { } while (0) + static inline unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) { -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 13/19] powerpc/signal32: Create 'unsafe' versions of copy_[ck][fpr/vsx]_to_user() @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel For the non VSX version, that's trivial. Just use unsafe_copy_to_user() instead of __copy_to_user(). For the VSX version, remove the intermediate step through a buffer and use unsafe_put_user() directly. This generates a far smaller code which is acceptable to inline, see below: Standard VSX version: 0000000000000000 <.copy_fpr_to_user>: 0: 7c 08 02 a6 mflr r0 4: fb e1 ff f8 std r31,-8(r1) 8: 39 00 00 20 li r8,32 c: 39 24 0b 80 addi r9,r4,2944 10: 7d 09 03 a6 mtctr r8 14: f8 01 00 10 std r0,16(r1) 18: f8 21 fe 71 stdu r1,-400(r1) 1c: 39 41 00 68 addi r10,r1,104 20: e9 09 00 00 ld r8,0(r9) 24: 39 4a 00 08 addi r10,r10,8 28: 39 29 00 10 addi r9,r9,16 2c: f9 0a 00 00 std r8,0(r10) 30: 42 00 ff f0 bdnz 20 <.copy_fpr_to_user+0x20> 34: e9 24 0d 80 ld r9,3456(r4) 38: 3d 42 00 00 addis r10,r2,0 3a: R_PPC64_TOC16_HA .toc 3c: eb ea 00 00 ld r31,0(r10) 3e: R_PPC64_TOC16_LO_DS .toc 40: f9 21 01 70 std r9,368(r1) 44: e9 3f 00 00 ld r9,0(r31) 48: 81 29 00 20 lwz r9,32(r9) 4c: 2f 89 00 00 cmpwi cr7,r9,0 50: 40 9c 00 18 bge cr7,68 <.copy_fpr_to_user+0x68> 54: 4c 00 01 2c isync 58: 3d 20 40 00 lis r9,16384 5c: 79 29 07 c6 rldicr r9,r9,32,31 60: 7d 3d 03 a6 mtspr 29,r9 64: 4c 00 01 2c isync 68: 38 a0 01 08 li r5,264 6c: 38 81 00 70 addi r4,r1,112 70: 48 00 00 01 bl 70 <.copy_fpr_to_user+0x70> 70: R_PPC64_REL24 .__copy_tofrom_user 74: 60 00 00 00 nop 78: e9 3f 00 00 ld r9,0(r31) 7c: 81 29 00 20 lwz r9,32(r9) 80: 2f 89 00 00 cmpwi cr7,r9,0 84: 40 9c 00 18 bge cr7,9c <.copy_fpr_to_user+0x9c> 88: 4c 00 01 2c isync 8c: 39 20 ff ff li r9,-1 90: 79 29 00 44 rldicr r9,r9,0,1 94: 7d 3d 03 a6 mtspr 29,r9 98: 4c 00 01 2c isync 9c: 38 21 01 90 addi r1,r1,400 a0: e8 01 00 10 ld r0,16(r1) a4: eb e1 ff f8 ld r31,-8(r1) a8: 7c 08 03 a6 mtlr r0 ac: 4e 80 00 20 blr 'unsafe' simulated VSX version (The ... are only nops) using unsafe_copy_fpr_to_user() macro: unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) { unsafe_copy_fpr_to_user(to, task, failed); return 0; failed: return 1; } 0000000000000000 <.copy_fpr_to_user>: 0: 39 00 00 20 li r8,32 4: 39 44 0b 80 addi r10,r4,2944 8: 7d 09 03 a6 mtctr r8 c: 7c 69 1b 78 mr r9,r3 ... 20: e9 0a 00 00 ld r8,0(r10) 24: f9 09 00 00 std r8,0(r9) 28: 39 4a 00 10 addi r10,r10,16 2c: 39 29 00 08 addi r9,r9,8 30: 42 00 ff f0 bdnz 20 <.copy_fpr_to_user+0x20> 34: e9 24 0d 80 ld r9,3456(r4) 38: f9 23 01 00 std r9,256(r3) 3c: 38 60 00 00 li r3,0 40: 4e 80 00 20 blr ... 50: 38 60 00 01 li r3,1 54: 4e 80 00 20 blr Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal.h | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index f610cfafa478..abe570f06c12 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -32,7 +32,49 @@ unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task); unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task); unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from); unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from); + +#define unsafe_copy_fpr_to_user(to, task, label) do { \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NFPREG - 1 ; i++) \ + unsafe_put_user(task->thread.TS_FPR(i), &buf[i], label);\ + unsafe_put_user(task->thread.fp_state.fpscr, &buf[i], label); \ +} while (0) + +#define unsafe_copy_vsx_to_user(to, task, label) do { \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NVSRHALFREG ; i++) \ + unsafe_put_user(task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \ + &buf[i], label);\ +} while (0) + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +#define unsafe_copy_ckfpr_to_user(to, task, label) do { \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NFPREG - 1 ; i++) \ + unsafe_put_user(task->thread.TS_CKFPR(i), &buf[i], label);\ + unsafe_put_user(task->thread.ckfp_state.fpscr, &buf[i], label); \ +} while (0) + +#define unsafe_copy_ckvsx_to_user(to, task, label) do { \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NVSRHALFREG ; i++) \ + unsafe_put_user(task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \ + &buf[i], label);\ +} while (0) +#endif #elif defined(CONFIG_PPC_FPU_REGS) + +#define unsafe_copy_fpr_to_user(to, task, label) \ + unsafe_copy_to_user(to, task->thread.fp_state.fpr, ELF_NFPREG * sizeof(double), label) + static inline unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) { @@ -48,6 +90,9 @@ copy_fpr_from_user(struct task_struct *task, void __user *from) } #ifdef CONFIG_PPC_TRANSACTIONAL_MEM +#define unsafe_copy_ckfpr_to_user(to, task, label) \ + unsafe_copy_to_user(to, task->thread.ckfp_state.fpr, ELF_NFPREG * sizeof(double), label) + inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task) { return __copy_to_user(to, task->thread.ckfp_state.fpr, @@ -62,6 +107,8 @@ copy_ckfpr_from_user(struct task_struct *task, void __user *from) } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #else +#define unsafe_copy_fpr_to_user(to, task, label) do { } while (0) + static inline unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) { -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 14/19] powerpc/signal32: Switch save_user_regs() and save_tm_user_regs() to user_access_begin() logic 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 168 ++++++++++++++++---------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 2c3d5d4400ec..0d076c2a9f6c 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -98,7 +98,7 @@ static inline int get_sigset_t(sigset_t *set, #define to_user_ptr(p) ptr_to_compat(p) #define from_user_ptr(p) compat_ptr(p) -static inline int save_general_regs(struct pt_regs *regs, +static __always_inline int save_general_regs(struct pt_regs *regs, struct mcontext __user *frame) { elf_greg_t64 *gregs = (elf_greg_t64 *)regs; @@ -113,10 +113,12 @@ static inline int save_general_regs(struct pt_regs *regs, else val = gregs[i]; - if (__put_user(val, &frame->mc_gregs[i])) - return -EFAULT; + unsafe_put_user(val, &frame->mc_gregs[i], failed); } return 0; + +failed: + return 1; } static inline int restore_general_regs(struct pt_regs *regs, @@ -151,11 +153,15 @@ static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset) #define to_user_ptr(p) ((unsigned long)(p)) #define from_user_ptr(p) ((void __user *)(p)) -static inline int save_general_regs(struct pt_regs *regs, +static __always_inline int save_general_regs(struct pt_regs *regs, struct mcontext __user *frame) { WARN_ON(!FULL_REGS(regs)); - return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE); + unsafe_copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE, failed); + return 0; + +failed: + return 1; } static inline int restore_general_regs(struct pt_regs *regs, @@ -258,16 +264,18 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, flush_spe_to_thread(current); #endif + if (!user_write_access_begin(frame, sizeof(*frame))) + return 1; + /* save general registers */ if (save_general_regs(regs, frame)) - return 1; + goto failed; #ifdef CONFIG_ALTIVEC /* save altivec registers */ if (current->thread.used_vr) { - if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state, + ELF_NVRREG * sizeof(vector128), failed); /* set MSR_VEC in the saved MSR value to indicate that frame->mc_vregs contains valid data */ msr |= MSR_VEC; @@ -280,11 +288,9 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * most significant bits of that same vector. --BenH * Note that the current VRSAVE value is in the SPR at this point. */ - if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32])) - return 1; + unsafe_put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32], failed); #endif /* CONFIG_ALTIVEC */ - if (copy_fpr_to_user(&frame->mc_fregs, current)) - return 1; + unsafe_copy_fpr_to_user(&frame->mc_fregs, current, failed); /* * Clear the MSR VSX bit to indicate there is no valid state attached @@ -299,17 +305,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * contains valid data */ if (current->thread.used_vsr && ctx_has_vsx_region) { - if (copy_vsx_to_user(&frame->mc_vsregs, current)) - return 1; + unsafe_copy_vsx_to_user(&frame->mc_vsregs, current, failed); msr |= MSR_VSX; } #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE /* save spe registers */ if (current->thread.used_spe) { - if (__copy_to_user(&frame->mc_vregs, current->thread.evr, - ELF_NEVRREG * sizeof(u32))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr, + ELF_NEVRREG * sizeof(u32)), failed); /* set MSR_SPE in the saved MSR value to indicate that frame->mc_vregs contains valid data */ msr |= MSR_SPE; @@ -317,19 +321,18 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, /* else assert((regs->msr & MSR_SPE) == 0) */ /* We always copy to/from spefscr */ - if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG)) - return 1; + unsafe_put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG, failed); #endif /* CONFIG_SPE */ - if (__put_user(msr, &frame->mc_gregs[PT_MSR])) - return 1; + unsafe_put_user(msr, &frame->mc_gregs[PT_MSR], failed); 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; + unsafe_put_user(PPC_INST_ADDI + sigret, &frame->tramp[0], failed); + unsafe_put_user(PPC_INST_SC, &frame->tramp[1], failed); } + user_write_access_end(); + if (sigret) flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); @@ -341,6 +344,10 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, return 1; return 0; + +failed: + user_write_access_end(); + return 1; } #ifdef CONFIG_PPC_TRANSACTIONAL_MEM @@ -369,15 +376,17 @@ static int save_tm_user_regs(struct pt_regs *regs, flush_spe_to_thread(current); #endif - if (save_general_regs(¤t->thread.ckpt_regs, frame)) + if (!user_write_access_begin(frame, sizeof(*frame))) return 1; + if (save_general_regs(¤t->thread.ckpt_regs, frame)) + goto failed; + #ifdef CONFIG_ALTIVEC /* save altivec registers */ if (current->thread.used_vr) { - if (__copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state, + ELF_NVRREG * sizeof(vector128), failed); /* set MSR_VEC in the saved MSR value to indicate that * frame->mc_vregs contains valid data @@ -390,13 +399,11 @@ static int save_tm_user_regs(struct pt_regs *regs, * significant bits of a vector, we "cheat" and stuff VRSAVE in the * most significant bits of that same vector. --BenH */ - if (__put_user(current->thread.ckvrsave, - (u32 __user *)&frame->mc_vregs[32])) - return 1; + unsafe_put_user(current->thread.ckvrsave, + (u32 __user *)&frame->mc_vregs[32], failed); #endif /* CONFIG_ALTIVEC */ - if (copy_ckfpr_to_user(&frame->mc_fregs, current)) - return 1; + unsafe_copy_ckfpr_to_user(&frame->mc_fregs, current, failed); #ifdef CONFIG_VSX /* * Copy VSR 0-31 upper half from thread_struct to local @@ -405,8 +412,7 @@ static int save_tm_user_regs(struct pt_regs *regs, * contains valid data */ if (current->thread.used_vsr) { - if (copy_ckvsx_to_user(&frame->mc_vsregs, current)) - return 1; + unsafe_copy_ckvsx_to_user(&frame->mc_vsregs, current, failed); msr |= MSR_VSX; } #endif /* CONFIG_VSX */ @@ -415,91 +421,85 @@ static int save_tm_user_regs(struct pt_regs *regs, * simply the same as in save_user_regs(). */ if (current->thread.used_spe) { - if (__copy_to_user(&frame->mc_vregs, current->thread.evr, - ELF_NEVRREG * sizeof(u32))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr, + ELF_NEVRREG * sizeof(u32), failed); /* set MSR_SPE in the saved MSR value to indicate that * frame->mc_vregs contains valid data */ msr |= MSR_SPE; } /* We always copy to/from spefscr */ - if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG)) - return 1; + unsafe_put_user(current->thread.spefscr, + (u32 __user *)&frame->mc_vregs + ELF_NEVRREG, failed); #endif /* CONFIG_SPE */ - if (__put_user(msr, &frame->mc_gregs[PT_MSR])) - return 1; + unsafe_put_user(msr, &frame->mc_gregs[PT_MSR], failed); + 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; + unsafe_put_user(PPC_INST_ADDI + sigret, &frame->tramp[0], failed); + unsafe_put_user(PPC_INST_SC, &frame->tramp[1], failed); } + user_write_access_end(); + if (sigret) flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); - if (save_general_regs(regs, tm_frame)) + if (!user_write_access_begin(tm_frame, sizeof(*tm_frame))) return 1; + if (save_general_regs(regs, tm_frame)) + goto failed; + /* Stash the top half of the 64bit MSR into the 32bit MSR word * of the transactional mcontext. This way we have a backward-compatible * MSR in the 'normal' (checkpointed) mcontext and additionally one can * also look at what type of transaction (T or S) was active at the * time of the signal. */ - if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR])) - return 1; + unsafe_put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR], failed); #ifdef CONFIG_ALTIVEC if (current->thread.used_vr) { - if (msr & MSR_VEC) { - if (__copy_to_user(&tm_frame->mc_vregs, - ¤t->thread.vr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - } else { - if (__copy_to_user(&tm_frame->mc_vregs, - ¤t->thread.ckvr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - } + if (msr & MSR_VEC) + unsafe_copy_to_user(&tm_frame->mc_vregs, + ¤t->thread.vr_state, + ELF_NVRREG * sizeof(vector128), failed); + else + unsafe_copy_to_user(&tm_frame->mc_vregs, + ¤t->thread.ckvr_state, + ELF_NVRREG * sizeof(vector128), failed); } - if (msr & MSR_VEC) { - if (__put_user(current->thread.vrsave, - (u32 __user *)&tm_frame->mc_vregs[32])) - return 1; - } else { - if (__put_user(current->thread.ckvrsave, - (u32 __user *)&tm_frame->mc_vregs[32])) - return 1; - } + if (msr & MSR_VEC) + unsafe_put_user(current->thread.vrsave, + (u32 __user *)&tm_frame->mc_vregs[32], failed); + else + unsafe_put_user(current->thread.ckvrsave, + (u32 __user *)&tm_frame->mc_vregs[32], failed); #endif /* CONFIG_ALTIVEC */ - if (msr & MSR_FP) { - if (copy_fpr_to_user(&tm_frame->mc_fregs, current)) - return 1; - } else { - if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current)) - return 1; - } + if (msr & MSR_FP) + unsafe_copy_fpr_to_user(&tm_frame->mc_fregs, current, failed); + else + unsafe_copy_ckfpr_to_user(&tm_frame->mc_fregs, current, failed); #ifdef CONFIG_VSX if (current->thread.used_vsr) { - if (msr & MSR_VSX) { - if (copy_vsx_to_user(&tm_frame->mc_vsregs, - current)) - return 1; - } else { - if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current)) - return 1; - } + if (msr & MSR_VSX) + unsafe_copy_vsx_to_user(&tm_frame->mc_vsregs, current, failed); + else + unsafe_copy_ckvsx_to_user(&tm_frame->mc_vsregs, current, failed); } #endif /* CONFIG_VSX */ + user_write_access_end(); return 0; + +failed: + user_write_access_end(); + return 1; } #endif -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 14/19] powerpc/signal32: Switch save_user_regs() and save_tm_user_regs() to user_access_begin() logic @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 168 ++++++++++++++++---------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 2c3d5d4400ec..0d076c2a9f6c 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -98,7 +98,7 @@ static inline int get_sigset_t(sigset_t *set, #define to_user_ptr(p) ptr_to_compat(p) #define from_user_ptr(p) compat_ptr(p) -static inline int save_general_regs(struct pt_regs *regs, +static __always_inline int save_general_regs(struct pt_regs *regs, struct mcontext __user *frame) { elf_greg_t64 *gregs = (elf_greg_t64 *)regs; @@ -113,10 +113,12 @@ static inline int save_general_regs(struct pt_regs *regs, else val = gregs[i]; - if (__put_user(val, &frame->mc_gregs[i])) - return -EFAULT; + unsafe_put_user(val, &frame->mc_gregs[i], failed); } return 0; + +failed: + return 1; } static inline int restore_general_regs(struct pt_regs *regs, @@ -151,11 +153,15 @@ static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset) #define to_user_ptr(p) ((unsigned long)(p)) #define from_user_ptr(p) ((void __user *)(p)) -static inline int save_general_regs(struct pt_regs *regs, +static __always_inline int save_general_regs(struct pt_regs *regs, struct mcontext __user *frame) { WARN_ON(!FULL_REGS(regs)); - return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE); + unsafe_copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE, failed); + return 0; + +failed: + return 1; } static inline int restore_general_regs(struct pt_regs *regs, @@ -258,16 +264,18 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, flush_spe_to_thread(current); #endif + if (!user_write_access_begin(frame, sizeof(*frame))) + return 1; + /* save general registers */ if (save_general_regs(regs, frame)) - return 1; + goto failed; #ifdef CONFIG_ALTIVEC /* save altivec registers */ if (current->thread.used_vr) { - if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state, + ELF_NVRREG * sizeof(vector128), failed); /* set MSR_VEC in the saved MSR value to indicate that frame->mc_vregs contains valid data */ msr |= MSR_VEC; @@ -280,11 +288,9 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * most significant bits of that same vector. --BenH * Note that the current VRSAVE value is in the SPR at this point. */ - if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32])) - return 1; + unsafe_put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32], failed); #endif /* CONFIG_ALTIVEC */ - if (copy_fpr_to_user(&frame->mc_fregs, current)) - return 1; + unsafe_copy_fpr_to_user(&frame->mc_fregs, current, failed); /* * Clear the MSR VSX bit to indicate there is no valid state attached @@ -299,17 +305,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * contains valid data */ if (current->thread.used_vsr && ctx_has_vsx_region) { - if (copy_vsx_to_user(&frame->mc_vsregs, current)) - return 1; + unsafe_copy_vsx_to_user(&frame->mc_vsregs, current, failed); msr |= MSR_VSX; } #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE /* save spe registers */ if (current->thread.used_spe) { - if (__copy_to_user(&frame->mc_vregs, current->thread.evr, - ELF_NEVRREG * sizeof(u32))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr, + ELF_NEVRREG * sizeof(u32)), failed); /* set MSR_SPE in the saved MSR value to indicate that frame->mc_vregs contains valid data */ msr |= MSR_SPE; @@ -317,19 +321,18 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, /* else assert((regs->msr & MSR_SPE) == 0) */ /* We always copy to/from spefscr */ - if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG)) - return 1; + unsafe_put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG, failed); #endif /* CONFIG_SPE */ - if (__put_user(msr, &frame->mc_gregs[PT_MSR])) - return 1; + unsafe_put_user(msr, &frame->mc_gregs[PT_MSR], failed); 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; + unsafe_put_user(PPC_INST_ADDI + sigret, &frame->tramp[0], failed); + unsafe_put_user(PPC_INST_SC, &frame->tramp[1], failed); } + user_write_access_end(); + if (sigret) flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); @@ -341,6 +344,10 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, return 1; return 0; + +failed: + user_write_access_end(); + return 1; } #ifdef CONFIG_PPC_TRANSACTIONAL_MEM @@ -369,15 +376,17 @@ static int save_tm_user_regs(struct pt_regs *regs, flush_spe_to_thread(current); #endif - if (save_general_regs(¤t->thread.ckpt_regs, frame)) + if (!user_write_access_begin(frame, sizeof(*frame))) return 1; + if (save_general_regs(¤t->thread.ckpt_regs, frame)) + goto failed; + #ifdef CONFIG_ALTIVEC /* save altivec registers */ if (current->thread.used_vr) { - if (__copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state, + ELF_NVRREG * sizeof(vector128), failed); /* set MSR_VEC in the saved MSR value to indicate that * frame->mc_vregs contains valid data @@ -390,13 +399,11 @@ static int save_tm_user_regs(struct pt_regs *regs, * significant bits of a vector, we "cheat" and stuff VRSAVE in the * most significant bits of that same vector. --BenH */ - if (__put_user(current->thread.ckvrsave, - (u32 __user *)&frame->mc_vregs[32])) - return 1; + unsafe_put_user(current->thread.ckvrsave, + (u32 __user *)&frame->mc_vregs[32], failed); #endif /* CONFIG_ALTIVEC */ - if (copy_ckfpr_to_user(&frame->mc_fregs, current)) - return 1; + unsafe_copy_ckfpr_to_user(&frame->mc_fregs, current, failed); #ifdef CONFIG_VSX /* * Copy VSR 0-31 upper half from thread_struct to local @@ -405,8 +412,7 @@ static int save_tm_user_regs(struct pt_regs *regs, * contains valid data */ if (current->thread.used_vsr) { - if (copy_ckvsx_to_user(&frame->mc_vsregs, current)) - return 1; + unsafe_copy_ckvsx_to_user(&frame->mc_vsregs, current, failed); msr |= MSR_VSX; } #endif /* CONFIG_VSX */ @@ -415,91 +421,85 @@ static int save_tm_user_regs(struct pt_regs *regs, * simply the same as in save_user_regs(). */ if (current->thread.used_spe) { - if (__copy_to_user(&frame->mc_vregs, current->thread.evr, - ELF_NEVRREG * sizeof(u32))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr, + ELF_NEVRREG * sizeof(u32), failed); /* set MSR_SPE in the saved MSR value to indicate that * frame->mc_vregs contains valid data */ msr |= MSR_SPE; } /* We always copy to/from spefscr */ - if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG)) - return 1; + unsafe_put_user(current->thread.spefscr, + (u32 __user *)&frame->mc_vregs + ELF_NEVRREG, failed); #endif /* CONFIG_SPE */ - if (__put_user(msr, &frame->mc_gregs[PT_MSR])) - return 1; + unsafe_put_user(msr, &frame->mc_gregs[PT_MSR], failed); + 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; + unsafe_put_user(PPC_INST_ADDI + sigret, &frame->tramp[0], failed); + unsafe_put_user(PPC_INST_SC, &frame->tramp[1], failed); } + user_write_access_end(); + if (sigret) flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); - if (save_general_regs(regs, tm_frame)) + if (!user_write_access_begin(tm_frame, sizeof(*tm_frame))) return 1; + if (save_general_regs(regs, tm_frame)) + goto failed; + /* Stash the top half of the 64bit MSR into the 32bit MSR word * of the transactional mcontext. This way we have a backward-compatible * MSR in the 'normal' (checkpointed) mcontext and additionally one can * also look at what type of transaction (T or S) was active at the * time of the signal. */ - if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR])) - return 1; + unsafe_put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR], failed); #ifdef CONFIG_ALTIVEC if (current->thread.used_vr) { - if (msr & MSR_VEC) { - if (__copy_to_user(&tm_frame->mc_vregs, - ¤t->thread.vr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - } else { - if (__copy_to_user(&tm_frame->mc_vregs, - ¤t->thread.ckvr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - } + if (msr & MSR_VEC) + unsafe_copy_to_user(&tm_frame->mc_vregs, + ¤t->thread.vr_state, + ELF_NVRREG * sizeof(vector128), failed); + else + unsafe_copy_to_user(&tm_frame->mc_vregs, + ¤t->thread.ckvr_state, + ELF_NVRREG * sizeof(vector128), failed); } - if (msr & MSR_VEC) { - if (__put_user(current->thread.vrsave, - (u32 __user *)&tm_frame->mc_vregs[32])) - return 1; - } else { - if (__put_user(current->thread.ckvrsave, - (u32 __user *)&tm_frame->mc_vregs[32])) - return 1; - } + if (msr & MSR_VEC) + unsafe_put_user(current->thread.vrsave, + (u32 __user *)&tm_frame->mc_vregs[32], failed); + else + unsafe_put_user(current->thread.ckvrsave, + (u32 __user *)&tm_frame->mc_vregs[32], failed); #endif /* CONFIG_ALTIVEC */ - if (msr & MSR_FP) { - if (copy_fpr_to_user(&tm_frame->mc_fregs, current)) - return 1; - } else { - if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current)) - return 1; - } + if (msr & MSR_FP) + unsafe_copy_fpr_to_user(&tm_frame->mc_fregs, current, failed); + else + unsafe_copy_ckfpr_to_user(&tm_frame->mc_fregs, current, failed); #ifdef CONFIG_VSX if (current->thread.used_vsr) { - if (msr & MSR_VSX) { - if (copy_vsx_to_user(&tm_frame->mc_vsregs, - current)) - return 1; - } else { - if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current)) - return 1; - } + if (msr & MSR_VSX) + unsafe_copy_vsx_to_user(&tm_frame->mc_vsregs, current, failed); + else + unsafe_copy_ckvsx_to_user(&tm_frame->mc_vsregs, current, failed); } #endif /* CONFIG_VSX */ + user_write_access_end(); return 0; + +failed: + user_write_access_end(); + return 1; } #endif -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 15/19] powerpc/signal32: Switch handle_signal32() to user_access_begin() logic 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 0d076c2a9f6c..4ea83578ba9d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -1241,23 +1241,23 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ frame = get_sigframe(ksig, tsk, sizeof(*frame), 1); - if (!access_ok(frame, sizeof(*frame))) + if (!user_write_access_begin(frame, sizeof(*frame))) goto badframe; sc = (struct sigcontext __user *) &frame->sctx; #if _NSIG != 64 #error "Please adjust handle_signal()" #endif - if (__put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler) - || __put_user(oldset->sig[0], &sc->oldmask) + unsafe_put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler, failed); + unsafe_put_user(oldset->sig[0], &sc->oldmask, failed); #ifdef CONFIG_PPC64 - || __put_user((oldset->sig[0] >> 32), &sc->_unused[3]) + unsafe_put_user((oldset->sig[0] >> 32), &sc->_unused[3], failed); #else - || __put_user(oldset->sig[1], &sc->_unused[3]) + unsafe_put_user(oldset->sig[1], &sc->_unused[3], failed); #endif - || __put_user(to_user_ptr(&frame->mctx), &sc->regs) - || __put_user(ksig->sig, &sc->signal)) - goto badframe; + unsafe_put_user(to_user_ptr(&frame->mctx), &sc->regs, failed); + unsafe_put_user(ksig->sig, &sc->signal, failed); + user_write_access_end(); if (vdso32_sigtramp && tsk->mm->context.vdso_base) { sigret = 0; @@ -1300,6 +1300,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, regs->msr &= ~MSR_LE; return 0; +failed: + user_write_access_end(); + badframe: signal_fault(tsk, regs, "handle_signal32", frame); -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 15/19] powerpc/signal32: Switch handle_signal32() to user_access_begin() logic @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 0d076c2a9f6c..4ea83578ba9d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -1241,23 +1241,23 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ frame = get_sigframe(ksig, tsk, sizeof(*frame), 1); - if (!access_ok(frame, sizeof(*frame))) + if (!user_write_access_begin(frame, sizeof(*frame))) goto badframe; sc = (struct sigcontext __user *) &frame->sctx; #if _NSIG != 64 #error "Please adjust handle_signal()" #endif - if (__put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler) - || __put_user(oldset->sig[0], &sc->oldmask) + unsafe_put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler, failed); + unsafe_put_user(oldset->sig[0], &sc->oldmask, failed); #ifdef CONFIG_PPC64 - || __put_user((oldset->sig[0] >> 32), &sc->_unused[3]) + unsafe_put_user((oldset->sig[0] >> 32), &sc->_unused[3], failed); #else - || __put_user(oldset->sig[1], &sc->_unused[3]) + unsafe_put_user(oldset->sig[1], &sc->_unused[3], failed); #endif - || __put_user(to_user_ptr(&frame->mctx), &sc->regs) - || __put_user(ksig->sig, &sc->signal)) - goto badframe; + unsafe_put_user(to_user_ptr(&frame->mctx), &sc->regs, failed); + unsafe_put_user(ksig->sig, &sc->signal, failed); + user_write_access_end(); if (vdso32_sigtramp && tsk->mm->context.vdso_base) { sigret = 0; @@ -1300,6 +1300,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, regs->msr &= ~MSR_LE; return 0; +failed: + user_write_access_end(); + badframe: signal_fault(tsk, regs, "handle_signal32", frame); -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 16/19] powerpc/signal32: Switch handle_rt_signal32() to user_access_begin() logic 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 47 +++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 4ea83578ba9d..d03ba3d8eb68 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -58,8 +58,6 @@ #define mcontext mcontext32 #define ucontext ucontext32 -#define __save_altstack __compat_save_altstack - /* * Userspace code may pass a ucontext which doesn't include VSX added * at the end. We need to check for this case. @@ -797,16 +795,36 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ /* Put a Real Time Context onto stack */ rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1); - if (!access_ok(rt_sf, sizeof(*rt_sf))) + if (!user_write_access_begin(rt_sf, sizeof(*rt_sf))) goto badframe; /* Put the siginfo & fill in most of the ucontext */ - if (copy_siginfo_to_user(&rt_sf->info, &ksig->info) - || __put_user(0, &rt_sf->uc.uc_flags) - || __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1]) - || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), - &rt_sf->uc.uc_regs) - || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) + unsafe_put_user(0, &rt_sf->uc.uc_flags, failed); +#ifdef CONFIG_PPC64 + unsafe_compat_save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1], failed); +#else + unsafe_save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1], failed); +#endif + unsafe_put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), &rt_sf->uc.uc_regs, failed); + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + tm_frame = &rt_sf->uc_transact.uc_mcontext; + if (MSR_TM_ACTIVE(msr)) { + unsafe_put_user((unsigned long)&rt_sf->uc_transact, + &rt_sf->uc.uc_link, failed); + unsafe_put_user((unsigned long)tm_frame, + &rt_sf->uc_transact.uc_regs, failed); + } + else +#endif + { + unsafe_put_user(0, &rt_sf->uc.uc_link, failed); + } + user_write_access_end(); + + if (put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) + goto badframe; + if (copy_siginfo_to_user(&rt_sf->info, &ksig->info)) goto badframe; /* Save user registers on the stack */ @@ -820,21 +838,13 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, } #ifdef CONFIG_PPC_TRANSACTIONAL_MEM - tm_frame = &rt_sf->uc_transact.uc_mcontext; if (MSR_TM_ACTIVE(msr)) { - if (__put_user((unsigned long)&rt_sf->uc_transact, - &rt_sf->uc.uc_link) || - __put_user((unsigned long)tm_frame, - &rt_sf->uc_transact.uc_regs)) - goto badframe; if (save_tm_user_regs(regs, frame, tm_frame, sigret, msr)) goto badframe; } else #endif { - if (__put_user(0, &rt_sf->uc.uc_link)) - goto badframe; if (save_user_regs(regs, frame, tm_frame, sigret, 1)) goto badframe; } @@ -861,6 +871,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, regs->msr |= (MSR_KERNEL & MSR_LE); return 0; +failed: + user_write_access_end(); + badframe: signal_fault(tsk, regs, "handle_rt_signal32", rt_sf); -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 16/19] powerpc/signal32: Switch handle_rt_signal32() to user_access_begin() logic @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 47 +++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 4ea83578ba9d..d03ba3d8eb68 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -58,8 +58,6 @@ #define mcontext mcontext32 #define ucontext ucontext32 -#define __save_altstack __compat_save_altstack - /* * Userspace code may pass a ucontext which doesn't include VSX added * at the end. We need to check for this case. @@ -797,16 +795,36 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ /* Put a Real Time Context onto stack */ rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1); - if (!access_ok(rt_sf, sizeof(*rt_sf))) + if (!user_write_access_begin(rt_sf, sizeof(*rt_sf))) goto badframe; /* Put the siginfo & fill in most of the ucontext */ - if (copy_siginfo_to_user(&rt_sf->info, &ksig->info) - || __put_user(0, &rt_sf->uc.uc_flags) - || __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1]) - || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), - &rt_sf->uc.uc_regs) - || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) + unsafe_put_user(0, &rt_sf->uc.uc_flags, failed); +#ifdef CONFIG_PPC64 + unsafe_compat_save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1], failed); +#else + unsafe_save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1], failed); +#endif + unsafe_put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), &rt_sf->uc.uc_regs, failed); + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + tm_frame = &rt_sf->uc_transact.uc_mcontext; + if (MSR_TM_ACTIVE(msr)) { + unsafe_put_user((unsigned long)&rt_sf->uc_transact, + &rt_sf->uc.uc_link, failed); + unsafe_put_user((unsigned long)tm_frame, + &rt_sf->uc_transact.uc_regs, failed); + } + else +#endif + { + unsafe_put_user(0, &rt_sf->uc.uc_link, failed); + } + user_write_access_end(); + + if (put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) + goto badframe; + if (copy_siginfo_to_user(&rt_sf->info, &ksig->info)) goto badframe; /* Save user registers on the stack */ @@ -820,21 +838,13 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, } #ifdef CONFIG_PPC_TRANSACTIONAL_MEM - tm_frame = &rt_sf->uc_transact.uc_mcontext; if (MSR_TM_ACTIVE(msr)) { - if (__put_user((unsigned long)&rt_sf->uc_transact, - &rt_sf->uc.uc_link) || - __put_user((unsigned long)tm_frame, - &rt_sf->uc_transact.uc_regs)) - goto badframe; if (save_tm_user_regs(regs, frame, tm_frame, sigret, msr)) goto badframe; } else #endif { - if (__put_user(0, &rt_sf->uc.uc_link)) - goto badframe; if (save_user_regs(regs, frame, tm_frame, sigret, 1)) goto badframe; } @@ -861,6 +871,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, regs->msr |= (MSR_KERNEL & MSR_LE); return 0; +failed: + user_write_access_end(); + badframe: signal_fault(tsk, regs, "handle_rt_signal32", rt_sf); -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 17/19] signal: Add unsafe_put_compat_sigset() 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev Implement 'unsafe' version of put_compat_sigset() For the bigendian, use unsafe_put_user() directly to avoid intermediate copy through the stack. For the littleendian, use a straight unsafe_copy_to_user(). Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Cc: Dmitry V. Levin <ldv@altlinux.org> Cc: Al Viro <viro@zeniv.linux.org.uk> --- include/linux/compat.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/linux/compat.h b/include/linux/compat.h index c4255d8a4a8a..bbe5f9658ed1 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -442,6 +442,38 @@ put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set, #endif } +#ifdef CONFIG_CPU_BIG_ENDIAN +#define unsafe_put_compat_sigset(compat, set, label) do { \ + compat_sigset_t __user *__c = compat; \ + const sigset_t *__s = set; \ + \ + switch (_NSIG_WORDS) { \ + case 4: \ + unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \ + unsafe_put_user(__s->sig[3], __c->sig[6], label); \ + fallthrough; \ + case 3: \ + unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \ + unsafe_put_user(__s->sig[2], __c->sig[4], label); \ + fallthrough; \ + case 2: \ + unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \ + unsafe_put_user(__s->sig[1], __c->sig[2], label); \ + fallthrough; \ + case 1: \ + unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \ + unsafe_put_user(__s->sig[0], __c->sig[0], label); \ + } \ +} while (0) +#else +#define unsafe_put_compat_sigset(compat, set, label) do { \ + compat_sigset_t __user *__c = compat; \ + const sigset_t *__s = set; \ + \ + unsafe_copy_to_user(__c, __s, sizeof(*__c), label); \ +} while (0) +#endif + extern int compat_ptrace_request(struct task_struct *child, compat_long_t request, compat_ulong_t addr, compat_ulong_t data); -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 17/19] signal: Add unsafe_put_compat_sigset() @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel Implement 'unsafe' version of put_compat_sigset() For the bigendian, use unsafe_put_user() directly to avoid intermediate copy through the stack. For the littleendian, use a straight unsafe_copy_to_user(). Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Cc: Dmitry V. Levin <ldv@altlinux.org> Cc: Al Viro <viro@zeniv.linux.org.uk> --- include/linux/compat.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/linux/compat.h b/include/linux/compat.h index c4255d8a4a8a..bbe5f9658ed1 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -442,6 +442,38 @@ put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set, #endif } +#ifdef CONFIG_CPU_BIG_ENDIAN +#define unsafe_put_compat_sigset(compat, set, label) do { \ + compat_sigset_t __user *__c = compat; \ + const sigset_t *__s = set; \ + \ + switch (_NSIG_WORDS) { \ + case 4: \ + unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \ + unsafe_put_user(__s->sig[3], __c->sig[6], label); \ + fallthrough; \ + case 3: \ + unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \ + unsafe_put_user(__s->sig[2], __c->sig[4], label); \ + fallthrough; \ + case 2: \ + unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \ + unsafe_put_user(__s->sig[1], __c->sig[2], label); \ + fallthrough; \ + case 1: \ + unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \ + unsafe_put_user(__s->sig[0], __c->sig[0], label); \ + } \ +} while (0) +#else +#define unsafe_put_compat_sigset(compat, set, label) do { \ + compat_sigset_t __user *__c = compat; \ + const sigset_t *__s = set; \ + \ + unsafe_copy_to_user(__c, __s, sizeof(*__c), label); \ +} while (0) +#endif + extern int compat_ptrace_request(struct task_struct *child, compat_long_t request, compat_ulong_t addr, compat_ulong_t data); -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 18/19] powerpc/signal32: Add and use unsafe_put_sigset_t() 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev put_sigset_t() calls copy_to_user() for copying two words. Because INLINE_COPY_TO_USER is not defined on powerpc, copy_to_user() doesn't get optimised and falls back to copy_tofrom_user() with the relevant glue. This is terribly inefficient for copying two words. By switching to unsafe_put_user(), we end up with something as simple as: 3cc: 81 3d 00 00 lwz r9,0(r29) 3d0: 91 26 00 b4 stw r9,180(r6) 3d4: 81 3d 00 04 lwz r9,4(r29) 3d8: 91 26 00 b8 stw r9,184(r6) Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index d03ba3d8eb68..6cbff0293ff4 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -87,6 +87,8 @@ static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) return put_compat_sigset(uset, set, sizeof(*uset)); } +#define unsafe_put_sigset_t unsafe_put_compat_sigset + static inline int get_sigset_t(sigset_t *set, const compat_sigset_t __user *uset) { @@ -143,6 +145,13 @@ static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) return copy_to_user(uset, set, sizeof(*uset)); } +#define unsafe_put_sigset_t(uset, set, label) do { \ + sigset_t __user *__us = uset ; \ + const sigset_t *__s = set; \ + \ + unsafe_copy_to_user(__us, __s, sizeof(*__us), label); \ +} while (0) + static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset) { return copy_from_user(set, uset, sizeof(*uset)); @@ -820,10 +829,11 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, { unsafe_put_user(0, &rt_sf->uc.uc_link, failed); } + + unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); + user_write_access_end(); - if (put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) - goto badframe; if (copy_siginfo_to_user(&rt_sf->info, &ksig->info)) goto badframe; -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 18/19] powerpc/signal32: Add and use unsafe_put_sigset_t() @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel put_sigset_t() calls copy_to_user() for copying two words. Because INLINE_COPY_TO_USER is not defined on powerpc, copy_to_user() doesn't get optimised and falls back to copy_tofrom_user() with the relevant glue. This is terribly inefficient for copying two words. By switching to unsafe_put_user(), we end up with something as simple as: 3cc: 81 3d 00 00 lwz r9,0(r29) 3d0: 91 26 00 b4 stw r9,180(r6) 3d4: 81 3d 00 04 lwz r9,4(r29) 3d8: 91 26 00 b8 stw r9,184(r6) Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index d03ba3d8eb68..6cbff0293ff4 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -87,6 +87,8 @@ static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) return put_compat_sigset(uset, set, sizeof(*uset)); } +#define unsafe_put_sigset_t unsafe_put_compat_sigset + static inline int get_sigset_t(sigset_t *set, const compat_sigset_t __user *uset) { @@ -143,6 +145,13 @@ static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) return copy_to_user(uset, set, sizeof(*uset)); } +#define unsafe_put_sigset_t(uset, set, label) do { \ + sigset_t __user *__us = uset ; \ + const sigset_t *__s = set; \ + \ + unsafe_copy_to_user(__us, __s, sizeof(*__us), label); \ +} while (0) + static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset) { return copy_from_user(set, uset, sizeof(*uset)); @@ -820,10 +829,11 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, { unsafe_put_user(0, &rt_sf->uc.uc_link, failed); } + + unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); + user_write_access_end(); - if (put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) - goto badframe; if (copy_siginfo_to_user(&rt_sf->info, &ksig->info)) goto badframe; -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [RFC PATCH v1 18/19] powerpc/signal32: Add and use unsafe_put_sigset_t() 2020-08-12 12:06 ` Christophe Leroy (?) @ 2020-08-12 14:01 ` kernel test robot -1 siblings, 0 replies; 42+ messages in thread From: kernel test robot @ 2020-08-12 14:01 UTC (permalink / raw) To: kbuild-all [-- Attachment #1: Type: text/plain, Size: 89916 bytes --] Hi Christophe, [FYI, it's a private test report for your RFC patch.] [auto build test WARNING on linus/master] [also build test WARNING on next-20200812] [cannot apply to powerpc/next v5.8] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Christophe-Leroy/powerpc-Switch-signal-32-to-using-user_access_begin-and-friends/20200812-200934 base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git fb893de323e2d39f7a1f6df425703a2edbdf56ea config: powerpc-allyesconfig (attached as .config) compiler: powerpc64-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from include/linux/uaccess.h:11, from include/linux/sched/task.h:11, from include/linux/sched/signal.h:9, from include/linux/rcuwait.h:6, from include/linux/percpu-rwsem.h:7, from include/linux/fs.h:33, from include/linux/huge_mm.h:8, from include/linux/mm.h:675, from arch/powerpc/kernel/signal_32.c:17: arch/powerpc/kernel/signal_32.c: In function 'handle_rt_signal32': arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user' 452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ >> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion] 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user' 452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto' 280 | switch (size) { \ | ^~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user' 452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user' 452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user' 452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user' 452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto' 284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user' 452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user' 453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ >> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion] 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user' 453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto' 280 | switch (size) { \ | ^~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user' 453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user' 453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user' 453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user' 453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto' 284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user' 453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user' 456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ >> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion] 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user' 456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto' 280 | switch (size) { \ | ^~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user' 456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user' 456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user' 456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user' 456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto' 284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user' 456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user' 457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ >> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion] 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user' 457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto' 280 | switch (size) { \ | ^~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user' 457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user' 457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user' 457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user' 457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto' 284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user' 457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user' 460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ >> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion] 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user' 460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto' 280 | switch (size) { \ | ^~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user' 460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user' 460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user' 460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user' 460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto' 284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user' 460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user' 461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ >> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion] 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user' 461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto' 280 | switch (size) { \ | ^~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user' 461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user' 461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user' 461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user' 461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto' 284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user' 461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user' 464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ >> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion] 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user' 464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto' 280 | switch (size) { \ | ^~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user' 464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user' 464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user' 464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user' 464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto' 284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user' 464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:465:3: note: in expansion of macro 'unsafe_put_user' 465 | unsafe_put_user(__s->sig[0], __c->sig[0], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ >> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion] 291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ | ^ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:465:3: note: in expansion of macro 'unsafe_put_user' 465 | unsafe_put_user(__s->sig[0], __c->sig[0], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto' 280 | switch (size) { \ | ^~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:465:3: note: in expansion of macro 'unsafe_put_user' 465 | unsafe_put_user(__s->sig[0], __c->sig[0], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:465:3: note: in expansion of macro 'unsafe_put_user' 465 | unsafe_put_user(__s->sig[0], __c->sig[0], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) | ^~~~~~~~~~~~~~~ include/linux/compat.h:465:3: note: in expansion of macro 'unsafe_put_user' 465 | unsafe_put_user(__s->sig[0], __c->sig[0], label); \ | ^~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset' 90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t' 833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed); | ^~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'}) 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~ arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto' 258 | : "r" (x), "m" (*addr) \ | ^ arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto' 295 | __put_user_size_goto((x), __pu_addr, (size), label); \ | ^~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto' 98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) | ^~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto' 604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e) vim +291 arch/powerpc/include/asm/uaccess.h 334710b1496af8 Christophe Leroy 2020-04-17 288 334710b1496af8 Christophe Leroy 2020-04-17 289 #define __put_user_nocheck_goto(x, ptr, size, label) \ 334710b1496af8 Christophe Leroy 2020-04-17 290 do { \ 334710b1496af8 Christophe Leroy 2020-04-17 @291 __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ 334710b1496af8 Christophe Leroy 2020-04-17 292 if (!is_kernel_addr((unsigned long)__pu_addr)) \ 334710b1496af8 Christophe Leroy 2020-04-17 293 might_fault(); \ 334710b1496af8 Christophe Leroy 2020-04-17 294 __chk_user_ptr(ptr); \ 334710b1496af8 Christophe Leroy 2020-04-17 295 __put_user_size_goto((x), __pu_addr, (size), label); \ 334710b1496af8 Christophe Leroy 2020-04-17 296 } while (0) 334710b1496af8 Christophe Leroy 2020-04-17 297 334710b1496af8 Christophe Leroy 2020-04-17 298 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org [-- Attachment #2: config.gz --] [-- Type: application/gzip, Size: 70328 bytes --] ^ permalink raw reply [flat|nested] 42+ messages in thread
* [RFC PATCH v1 19/19] powerpc/signal32: Switch swap_context() to user_access_begin() logic 2020-08-12 12:05 ` Christophe Leroy @ 2020-08-12 12:06 ` Christophe Leroy -1 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linux-kernel, linuxppc-dev As this was the last user of put_sigset_t(), remove it as well. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 6cbff0293ff4..399d823782cf 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -82,11 +82,6 @@ * Functions for flipping sigsets (thanks to brain dead generic * implementation that makes things simple for little endian only) */ -static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) -{ - return put_compat_sigset(uset, set, sizeof(*uset)); -} - #define unsafe_put_sigset_t unsafe_put_compat_sigset static inline int get_sigset_t(sigset_t *set, @@ -140,11 +135,6 @@ static inline int restore_general_regs(struct pt_regs *regs, #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) -static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) -{ - return copy_to_user(uset, set, sizeof(*uset)); -} - #define unsafe_put_sigset_t(uset, set, label) do { \ sigset_t __user *__us = uset ; \ const sigset_t *__s = set; \ @@ -1012,11 +1002,13 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, */ mctx = (struct mcontext __user *) ((unsigned long) &old_ctx->uc_mcontext & ~0xfUL); - if (!access_ok(old_ctx, ctx_size) - || save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region) - || put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked) - || __put_user(to_user_ptr(mctx), &old_ctx->uc_regs)) + if (save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region)) + return -EFAULT; + if (!user_write_access_begin(old_ctx, ctx_size)) return -EFAULT; + unsafe_put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked, failed); + unsafe_put_user(to_user_ptr(mctx), &old_ctx->uc_regs, failed); + user_write_access_end(); } if (new_ctx == NULL) return 0; @@ -1040,6 +1032,10 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, set_thread_flag(TIF_RESTOREALL); return 0; + +failed: + user_write_access_end(); + return -EFAULT; } #ifdef CONFIG_PPC64 -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 19/19] powerpc/signal32: Switch swap_context() to user_access_begin() logic @ 2020-08-12 12:06 ` Christophe Leroy 0 siblings, 0 replies; 42+ messages in thread From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw) To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro Cc: linuxppc-dev, linux-kernel As this was the last user of put_sigset_t(), remove it as well. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- arch/powerpc/kernel/signal_32.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 6cbff0293ff4..399d823782cf 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -82,11 +82,6 @@ * Functions for flipping sigsets (thanks to brain dead generic * implementation that makes things simple for little endian only) */ -static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) -{ - return put_compat_sigset(uset, set, sizeof(*uset)); -} - #define unsafe_put_sigset_t unsafe_put_compat_sigset static inline int get_sigset_t(sigset_t *set, @@ -140,11 +135,6 @@ static inline int restore_general_regs(struct pt_regs *regs, #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) -static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) -{ - return copy_to_user(uset, set, sizeof(*uset)); -} - #define unsafe_put_sigset_t(uset, set, label) do { \ sigset_t __user *__us = uset ; \ const sigset_t *__s = set; \ @@ -1012,11 +1002,13 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, */ mctx = (struct mcontext __user *) ((unsigned long) &old_ctx->uc_mcontext & ~0xfUL); - if (!access_ok(old_ctx, ctx_size) - || save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region) - || put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked) - || __put_user(to_user_ptr(mctx), &old_ctx->uc_regs)) + if (save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region)) + return -EFAULT; + if (!user_write_access_begin(old_ctx, ctx_size)) return -EFAULT; + unsafe_put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked, failed); + unsafe_put_user(to_user_ptr(mctx), &old_ctx->uc_regs, failed); + user_write_access_end(); } if (new_ctx == NULL) return 0; @@ -1040,6 +1032,10 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, set_thread_flag(TIF_RESTOREALL); return 0; + +failed: + user_write_access_end(); + return -EFAULT; } #ifdef CONFIG_PPC64 -- 2.25.0 ^ permalink raw reply related [flat|nested] 42+ messages in thread
end of thread, other threads:[~2020-08-12 15:47 UTC | newest] Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-08-12 12:05 [RFC PATCH v1 00/19] powerpc: Switch signal 32 to using user_access_begin() and friends Christophe Leroy 2020-08-12 12:05 ` Christophe Leroy 2020-08-12 12:05 ` [RFC PATCH v1 01/19] powerpc/signal: Move inline functions in signal.h Christophe Leroy 2020-08-12 12:05 ` Christophe Leroy 2020-08-12 12:05 ` [RFC PATCH v1 02/19] powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg() Christophe Leroy 2020-08-12 12:05 ` Christophe Leroy 2020-08-12 15:47 ` kernel test robot 2020-08-12 12:05 ` [RFC PATCH v1 03/19] powerpc/ptrace: Consolidate reg index calculation Christophe Leroy 2020-08-12 12:05 ` Christophe Leroy 2020-08-12 12:05 ` [RFC PATCH v1 04/19] powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr() Christophe Leroy 2020-08-12 12:05 ` Christophe Leroy 2020-08-12 12:05 ` [RFC PATCH v1 05/19] powerpc/signal: Don't manage floating point regs when no FPU Christophe Leroy 2020-08-12 12:05 ` Christophe Leroy 2020-08-12 12:05 ` [RFC PATCH v1 06/19] powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x Christophe Leroy 2020-08-12 12:05 ` Christophe Leroy 2020-08-12 12:05 ` [RFC PATCH v1 07/19] powerpc/signal: Move access_ok() out of get_sigframe() Christophe Leroy 2020-08-12 12:05 ` Christophe Leroy 2020-08-12 12:05 ` [RFC PATCH v1 08/19] powerpc/signal: Remove get_clean_sp() Christophe Leroy 2020-08-12 12:05 ` Christophe Leroy 2020-08-12 12:06 ` [RFC PATCH v1 09/19] powerpc/signal: Call get_tm_stackpointer() from get_sigframe() Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy 2020-08-12 12:06 ` [RFC PATCH v1 10/19] powerpc/signal: Refactor bad frame logging Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy 2020-08-12 12:06 ` [RFC PATCH v1 11/19] powerpc/signal32: Simplify logging in handle_rt_signal32() Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy 2020-08-12 12:06 ` [RFC PATCH v1 12/19] powerpc/signal32: Regroup copies in save_user_regs() and save_tm_user_regs() Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy 2020-08-12 12:06 ` [RFC PATCH v1 13/19] powerpc/signal32: Create 'unsafe' versions of copy_[ck][fpr/vsx]_to_user() Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy 2020-08-12 12:06 ` [RFC PATCH v1 14/19] powerpc/signal32: Switch save_user_regs() and save_tm_user_regs() to user_access_begin() logic Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy 2020-08-12 12:06 ` [RFC PATCH v1 15/19] powerpc/signal32: Switch handle_signal32() " Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy 2020-08-12 12:06 ` [RFC PATCH v1 16/19] powerpc/signal32: Switch handle_rt_signal32() " Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy 2020-08-12 12:06 ` [RFC PATCH v1 17/19] signal: Add unsafe_put_compat_sigset() Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy 2020-08-12 12:06 ` [RFC PATCH v1 18/19] powerpc/signal32: Add and use unsafe_put_sigset_t() Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy 2020-08-12 14:01 ` kernel test robot 2020-08-12 12:06 ` [RFC PATCH v1 19/19] powerpc/signal32: Switch swap_context() to user_access_begin() logic Christophe Leroy 2020-08-12 12:06 ` Christophe Leroy
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.