All of lore.kernel.org
 help / color / mirror / Atom feed
* [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

* [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(&current->thread.fp_state, 0, sizeof(current->thread.fp_state));
 	current->thread.fp_save_area = NULL;
+#endif
 #ifdef CONFIG_ALTIVEC
 	memset(&current->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(&current->thread.fp_state, 0, sizeof(current->thread.fp_state));
 	current->thread.fp_save_area = NULL;
+#endif
 #ifdef CONFIG_ALTIVEC
 	memset(&current->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, &current->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(&current->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(&current->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, &current->thread.ckvr_state,
 				   ELF_NVRREG * sizeof(vector128)))
 			return 1;
-		if (msr & MSR_VEC) {
-			if (__copy_to_user(&tm_frame->mc_vregs,
-					   &current->thread.vr_state,
-					   ELF_NVRREG * sizeof(vector128)))
-				return 1;
-		} else {
-			if (__copy_to_user(&tm_frame->mc_vregs,
-					   &current->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,
+					   &current->thread.vr_state,
+					   ELF_NVRREG * sizeof(vector128)))
+				return 1;
+		} else {
+			if (__copy_to_user(&tm_frame->mc_vregs,
+					   &current->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, &current->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(&current->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(&current->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, &current->thread.ckvr_state,
 				   ELF_NVRREG * sizeof(vector128)))
 			return 1;
-		if (msr & MSR_VEC) {
-			if (__copy_to_user(&tm_frame->mc_vregs,
-					   &current->thread.vr_state,
-					   ELF_NVRREG * sizeof(vector128)))
-				return 1;
-		} else {
-			if (__copy_to_user(&tm_frame->mc_vregs,
-					   &current->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,
+					   &current->thread.vr_state,
+					   ELF_NVRREG * sizeof(vector128)))
+				return 1;
+		} else {
+			if (__copy_to_user(&tm_frame->mc_vregs,
+					   &current->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, &current->thread.vr_state,
-				   ELF_NVRREG * sizeof(vector128)))
-			return 1;
+		unsafe_copy_to_user(&frame->mc_vregs, &current->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(&current->thread.ckpt_regs, frame))
+	if (!user_write_access_begin(frame, sizeof(*frame)))
 		return 1;
 
+	if (save_general_regs(&current->thread.ckpt_regs, frame))
+		goto failed;
+
 #ifdef CONFIG_ALTIVEC
 	/* save altivec registers */
 	if (current->thread.used_vr) {
-		if (__copy_to_user(&frame->mc_vregs, &current->thread.ckvr_state,
-				   ELF_NVRREG * sizeof(vector128)))
-			return 1;
+		unsafe_copy_to_user(&frame->mc_vregs, &current->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,
-					   &current->thread.vr_state,
-					   ELF_NVRREG * sizeof(vector128)))
-				return 1;
-		} else {
-			if (__copy_to_user(&tm_frame->mc_vregs,
-					   &current->thread.ckvr_state,
-					   ELF_NVRREG * sizeof(vector128)))
-				return 1;
-		}
+		if (msr & MSR_VEC)
+			unsafe_copy_to_user(&tm_frame->mc_vregs,
+					    &current->thread.vr_state,
+					    ELF_NVRREG * sizeof(vector128), failed);
+		else
+			unsafe_copy_to_user(&tm_frame->mc_vregs,
+					    &current->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, &current->thread.vr_state,
-				   ELF_NVRREG * sizeof(vector128)))
-			return 1;
+		unsafe_copy_to_user(&frame->mc_vregs, &current->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(&current->thread.ckpt_regs, frame))
+	if (!user_write_access_begin(frame, sizeof(*frame)))
 		return 1;
 
+	if (save_general_regs(&current->thread.ckpt_regs, frame))
+		goto failed;
+
 #ifdef CONFIG_ALTIVEC
 	/* save altivec registers */
 	if (current->thread.used_vr) {
-		if (__copy_to_user(&frame->mc_vregs, &current->thread.ckvr_state,
-				   ELF_NVRREG * sizeof(vector128)))
-			return 1;
+		unsafe_copy_to_user(&frame->mc_vregs, &current->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,
-					   &current->thread.vr_state,
-					   ELF_NVRREG * sizeof(vector128)))
-				return 1;
-		} else {
-			if (__copy_to_user(&tm_frame->mc_vregs,
-					   &current->thread.ckvr_state,
-					   ELF_NVRREG * sizeof(vector128)))
-				return 1;
-		}
+		if (msr & MSR_VEC)
+			unsafe_copy_to_user(&tm_frame->mc_vregs,
+					    &current->thread.vr_state,
+					    ELF_NVRREG * sizeof(vector128), failed);
+		else
+			unsafe_copy_to_user(&tm_frame->mc_vregs,
+					    &current->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

* [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, &current->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, &current->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, &current->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, &current->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

* 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

* 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

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.