linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/6] Disable compat cruft on ppc64le v6
@ 2019-08-30 18:57 Michal Suchanek
  2019-08-30 18:57 ` [PATCH v6 1/6] powerpc: make llseek 32bit-only Michal Suchanek
                   ` (5 more replies)
  0 siblings, 6 replies; 41+ messages in thread
From: Michal Suchanek @ 2019-08-30 18:57 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange, Allison Randal,
	Geert Uytterhoeven, Joel Stanley, Firoz Khan, Michal Suchanek,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini

Less code means less bugs so add a knob to skip the compat stuff.

This is tested on ppc64le top of

https://patchwork.ozlabs.org/cover/1153556/

Changes in v2: saner CONFIG_COMPAT ifdefs
Changes in v3:
 - change llseek to 32bit instead of builing it unconditionally in fs
 - clanup the makefile conditionals
 - remove some ifdefs or convert to IS_DEFINED where possible
Changes in v4:
 - cleanup is_32bit_task and current_is_64bit
 - more makefile cleanup
Changes in v5:
 - more current_is_64bit cleanup
 - split off callchain.c 32bit and 64bit parts
Changes in v6:
 - cleanup makefile after split
 - consolidate read_user_stack_32
 - fix some checkpatch warnings

Michal Suchanek (6):
  powerpc: make llseek 32bit-only.
  powerpc: move common register copy functions from signal_32.c to
    signal.c
  powerpc/perf: consolidate read_user_stack_32
  powerpc/64: make buildable without CONFIG_COMPAT
  powerpc/64: Make COMPAT user-selectable disabled on littleendian by
    default.
  powerpc/perf: split callchain.c by bitness

 arch/powerpc/Kconfig                     |   5 +-
 arch/powerpc/include/asm/thread_info.h   |   4 +-
 arch/powerpc/kernel/Makefile             |   7 +-
 arch/powerpc/kernel/entry_64.S           |   2 +
 arch/powerpc/kernel/signal.c             | 144 ++++++++-
 arch/powerpc/kernel/signal_32.c          | 140 ---------
 arch/powerpc/kernel/syscall_64.c         |   6 +-
 arch/powerpc/kernel/syscalls/syscall.tbl |   2 +-
 arch/powerpc/kernel/vdso.c               |   5 +-
 arch/powerpc/perf/Makefile               |   5 +-
 arch/powerpc/perf/callchain.c            | 377 +----------------------
 arch/powerpc/perf/callchain.h            |  11 +
 arch/powerpc/perf/callchain_32.c         | 204 ++++++++++++
 arch/powerpc/perf/callchain_64.c         | 185 +++++++++++
 14 files changed, 564 insertions(+), 533 deletions(-)
 create mode 100644 arch/powerpc/perf/callchain.h
 create mode 100644 arch/powerpc/perf/callchain_32.c
 create mode 100644 arch/powerpc/perf/callchain_64.c

-- 
2.22.0


^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v6 1/6] powerpc: make llseek 32bit-only.
  2019-08-30 18:57 [PATCH v6 0/6] Disable compat cruft on ppc64le v6 Michal Suchanek
@ 2019-08-30 18:57 ` Michal Suchanek
  2019-08-30 19:46   ` [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro" Michal Suchanek
  2019-08-30 18:57 ` [PATCH v6 2/6] powerpc: move common register copy functions from signal_32.c to signal.c Michal Suchanek
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 41+ messages in thread
From: Michal Suchanek @ 2019-08-30 18:57 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange, Allison Randal,
	Geert Uytterhoeven, Joel Stanley, Firoz Khan, Michal Suchanek,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini

The llseek syscall is not built in fs/read_write.c when !64bit && !COMPAT
With the syscall marked as common in syscall.tbl build fails in this
case.

The llseek interface does not make sense on 64bit and it is explicitly
described as 32bit interface. Use on 64bit is not well-defined so just
drop it for 64bit.

Fixes: caf6f9c8a326 ("asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro")
Link: https://lore.kernel.org/lkml/20190828151552.GA16855@infradead.org/
Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/

Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
v5: update commit message.
---
 arch/powerpc/kernel/syscalls/syscall.tbl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index 010b9f445586..53e427606f6c 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -188,7 +188,7 @@
 137	common	afs_syscall			sys_ni_syscall
 138	common	setfsuid			sys_setfsuid
 139	common	setfsgid			sys_setfsgid
-140	common	_llseek				sys_llseek
+140	32	_llseek				sys_llseek
 141	common	getdents			sys_getdents			compat_sys_getdents
 142	common	_newselect			sys_select			compat_sys_select
 143	common	flock				sys_flock
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v6 2/6] powerpc: move common register copy functions from signal_32.c to signal.c
  2019-08-30 18:57 [PATCH v6 0/6] Disable compat cruft on ppc64le v6 Michal Suchanek
  2019-08-30 18:57 ` [PATCH v6 1/6] powerpc: make llseek 32bit-only Michal Suchanek
@ 2019-08-30 18:57 ` Michal Suchanek
  2019-08-30 20:22   ` Christophe Leroy
  2019-08-30 18:57 ` [PATCH v6 3/6] powerpc/perf: consolidate read_user_stack_32 Michal Suchanek
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 41+ messages in thread
From: Michal Suchanek @ 2019-08-30 18:57 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange, Allison Randal,
	Geert Uytterhoeven, Joel Stanley, Firoz Khan, Michal Suchanek,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini

These functions are required for 64bit as well.

Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
 arch/powerpc/kernel/signal.c    | 141 ++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/signal_32.c | 140 -------------------------------
 2 files changed, 141 insertions(+), 140 deletions(-)

diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index e6c30cee6abf..60436432399f 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -18,12 +18,153 @@
 #include <linux/syscalls.h>
 #include <asm/hw_breakpoint.h>
 #include <linux/uaccess.h>
+#include <asm/switch_to.h>
 #include <asm/unistd.h>
 #include <asm/debug.h>
 #include <asm/tm.h>
 
 #include "signal.h"
 
+#ifdef CONFIG_VSX
+unsigned long copy_fpr_to_user(void __user *to,
+			       struct task_struct *task)
+{
+	u64 buf[ELF_NFPREG];
+	int i;
+
+	/* save FPR copy to local buffer then write to the thread_struct */
+	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+		buf[i] = task->thread.TS_FPR(i);
+	buf[i] = task->thread.fp_state.fpscr;
+	return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
+}
+
+unsigned long copy_fpr_from_user(struct task_struct *task,
+				 void __user *from)
+{
+	u64 buf[ELF_NFPREG];
+	int i;
+
+	if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
+		return 1;
+	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+		task->thread.TS_FPR(i) = buf[i];
+	task->thread.fp_state.fpscr = buf[i];
+
+	return 0;
+}
+
+unsigned long copy_vsx_to_user(void __user *to,
+			       struct task_struct *task)
+{
+	u64 buf[ELF_NVSRHALFREG];
+	int i;
+
+	/* save FPR copy to local buffer then write to the thread_struct */
+	for (i = 0; i < ELF_NVSRHALFREG; i++)
+		buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
+	return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
+}
+
+unsigned long copy_vsx_from_user(struct task_struct *task,
+				 void __user *from)
+{
+	u64 buf[ELF_NVSRHALFREG];
+	int i;
+
+	if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
+		return 1;
+	for (i = 0; i < ELF_NVSRHALFREG ; i++)
+		task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+	return 0;
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+unsigned long copy_ckfpr_to_user(void __user *to,
+				  struct task_struct *task)
+{
+	u64 buf[ELF_NFPREG];
+	int i;
+
+	/* save FPR copy to local buffer then write to the thread_struct */
+	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+		buf[i] = task->thread.TS_CKFPR(i);
+	buf[i] = task->thread.ckfp_state.fpscr;
+	return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
+}
+
+unsigned long copy_ckfpr_from_user(struct task_struct *task,
+					  void __user *from)
+{
+	u64 buf[ELF_NFPREG];
+	int i;
+
+	if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
+		return 1;
+	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+		task->thread.TS_CKFPR(i) = buf[i];
+	task->thread.ckfp_state.fpscr = buf[i];
+
+	return 0;
+}
+
+unsigned long copy_ckvsx_to_user(void __user *to,
+				  struct task_struct *task)
+{
+	u64 buf[ELF_NVSRHALFREG];
+	int i;
+
+	/* save FPR copy to local buffer then write to the thread_struct */
+	for (i = 0; i < ELF_NVSRHALFREG; i++)
+		buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
+	return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
+}
+
+unsigned long copy_ckvsx_from_user(struct task_struct *task,
+					  void __user *from)
+{
+	u64 buf[ELF_NVSRHALFREG];
+	int i;
+
+	if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
+		return 1;
+	for (i = 0; i < ELF_NVSRHALFREG ; i++)
+		task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+	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
  * through debug.exception-trace sysctl.
  */
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 98600b276f76..c93c937ea568 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -235,146 +235,6 @@ struct rt_sigframe {
 	int			abigap[56];
 };
 
-#ifdef CONFIG_VSX
-unsigned long copy_fpr_to_user(void __user *to,
-			       struct task_struct *task)
-{
-	u64 buf[ELF_NFPREG];
-	int i;
-
-	/* save FPR copy to local buffer then write to the thread_struct */
-	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
-		buf[i] = task->thread.TS_FPR(i);
-	buf[i] = task->thread.fp_state.fpscr;
-	return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
-}
-
-unsigned long copy_fpr_from_user(struct task_struct *task,
-				 void __user *from)
-{
-	u64 buf[ELF_NFPREG];
-	int i;
-
-	if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
-		return 1;
-	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
-		task->thread.TS_FPR(i) = buf[i];
-	task->thread.fp_state.fpscr = buf[i];
-
-	return 0;
-}
-
-unsigned long copy_vsx_to_user(void __user *to,
-			       struct task_struct *task)
-{
-	u64 buf[ELF_NVSRHALFREG];
-	int i;
-
-	/* save FPR copy to local buffer then write to the thread_struct */
-	for (i = 0; i < ELF_NVSRHALFREG; i++)
-		buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
-	return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
-}
-
-unsigned long copy_vsx_from_user(struct task_struct *task,
-				 void __user *from)
-{
-	u64 buf[ELF_NVSRHALFREG];
-	int i;
-
-	if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
-		return 1;
-	for (i = 0; i < ELF_NVSRHALFREG ; i++)
-		task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
-	return 0;
-}
-
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-unsigned long copy_ckfpr_to_user(void __user *to,
-				  struct task_struct *task)
-{
-	u64 buf[ELF_NFPREG];
-	int i;
-
-	/* save FPR copy to local buffer then write to the thread_struct */
-	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
-		buf[i] = task->thread.TS_CKFPR(i);
-	buf[i] = task->thread.ckfp_state.fpscr;
-	return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
-}
-
-unsigned long copy_ckfpr_from_user(struct task_struct *task,
-					  void __user *from)
-{
-	u64 buf[ELF_NFPREG];
-	int i;
-
-	if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
-		return 1;
-	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
-		task->thread.TS_CKFPR(i) = buf[i];
-	task->thread.ckfp_state.fpscr = buf[i];
-
-	return 0;
-}
-
-unsigned long copy_ckvsx_to_user(void __user *to,
-				  struct task_struct *task)
-{
-	u64 buf[ELF_NVSRHALFREG];
-	int i;
-
-	/* save FPR copy to local buffer then write to the thread_struct */
-	for (i = 0; i < ELF_NVSRHALFREG; i++)
-		buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
-	return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
-}
-
-unsigned long copy_ckvsx_from_user(struct task_struct *task,
-					  void __user *from)
-{
-	u64 buf[ELF_NVSRHALFREG];
-	int i;
-
-	if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
-		return 1;
-	for (i = 0; i < ELF_NVSRHALFREG ; i++)
-		task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
-	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
-
 /*
  * Save the current user registers on the user stack.
  * We only save the altivec/spe registers if the process has used
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v6 3/6] powerpc/perf: consolidate read_user_stack_32
  2019-08-30 18:57 [PATCH v6 0/6] Disable compat cruft on ppc64le v6 Michal Suchanek
  2019-08-30 18:57 ` [PATCH v6 1/6] powerpc: make llseek 32bit-only Michal Suchanek
  2019-08-30 18:57 ` [PATCH v6 2/6] powerpc: move common register copy functions from signal_32.c to signal.c Michal Suchanek
@ 2019-08-30 18:57 ` Michal Suchanek
  2019-08-30 20:21   ` Christophe Leroy
  2019-08-30 18:57 ` [PATCH v6 4/6] powerpc/64: make buildable without CONFIG_COMPAT Michal Suchanek
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 41+ messages in thread
From: Michal Suchanek @ 2019-08-30 18:57 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange, Allison Randal,
	Geert Uytterhoeven, Joel Stanley, Firoz Khan, Michal Suchanek,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini

There are two almost identical copies for 32bit and 64bit.

The function is used only in 32bit code which will be split out in next
patch so consolidate to one function.

Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
new patch in v6
---
 arch/powerpc/perf/callchain.c | 25 +++++++++----------------
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index c84bbd4298a0..b7cdcce20280 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -165,22 +165,6 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
 	return read_user_stack_slow(ptr, ret, 8);
 }
 
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
-	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
-	    ((unsigned long)ptr & 3))
-		return -EFAULT;
-
-	pagefault_disable();
-	if (!__get_user_inatomic(*ret, ptr)) {
-		pagefault_enable();
-		return 0;
-	}
-	pagefault_enable();
-
-	return read_user_stack_slow(ptr, ret, 4);
-}
-
 static inline int valid_user_sp(unsigned long sp, int is_64)
 {
 	if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32)
@@ -295,6 +279,12 @@ static inline int current_is_64bit(void)
 }
 
 #else  /* CONFIG_PPC64 */
+static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
+{
+	return 0;
+}
+#endif /* CONFIG_PPC64 */
+
 /*
  * On 32-bit we just access the address and let hash_page create a
  * HPTE if necessary, so there is no need to fall back to reading
@@ -313,9 +303,12 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
 	rc = __get_user_inatomic(*ret, ptr);
 	pagefault_enable();
 
+	if (IS_ENABLED(CONFIG_PPC64) && rc)
+		return read_user_stack_slow(ptr, ret, 4);
 	return rc;
 }
 
+#ifndef CONFIG_PPC64
 static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
 					  struct pt_regs *regs)
 {
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v6 4/6] powerpc/64: make buildable without CONFIG_COMPAT
  2019-08-30 18:57 [PATCH v6 0/6] Disable compat cruft on ppc64le v6 Michal Suchanek
                   ` (2 preceding siblings ...)
  2019-08-30 18:57 ` [PATCH v6 3/6] powerpc/perf: consolidate read_user_stack_32 Michal Suchanek
@ 2019-08-30 18:57 ` Michal Suchanek
  2019-08-30 20:21   ` Christophe Leroy
  2019-08-30 18:57 ` [PATCH v6 5/6] powerpc/64: Make COMPAT user-selectable disabled on littleendian by default Michal Suchanek
  2019-08-30 18:57 ` [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness Michal Suchanek
  5 siblings, 1 reply; 41+ messages in thread
From: Michal Suchanek @ 2019-08-30 18:57 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange, Allison Randal,
	Geert Uytterhoeven, Joel Stanley, Firoz Khan, Michal Suchanek,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini

There are numerous references to 32bit functions in generic and 64bit
code so ifdef them out.

Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
v2:
- fix 32bit ifdef condition in signal.c
- simplify the compat ifdef condition in vdso.c - 64bit is redundant
- simplify the compat ifdef condition in callchain.c - 64bit is redundant
v3:
- use IS_ENABLED and maybe_unused where possible
- do not ifdef declarations
- clean up Makefile
v4:
- further makefile cleanup
- simplify is_32bit_task conditions
- avoid ifdef in condition by using return
v5:
- avoid unreachable code on 32bit
- make is_current_64bit constant on !COMPAT
- add stub perf_callchain_user_32 to avoid some ifdefs
v6:
- consolidate current_is_64bit
---
 arch/powerpc/include/asm/thread_info.h |  4 +--
 arch/powerpc/kernel/Makefile           |  7 +++--
 arch/powerpc/kernel/entry_64.S         |  2 ++
 arch/powerpc/kernel/signal.c           |  3 +--
 arch/powerpc/kernel/syscall_64.c       |  6 ++---
 arch/powerpc/kernel/vdso.c             |  5 ++--
 arch/powerpc/perf/callchain.c          | 37 +++++++++++++++-----------
 7 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index 8e1d0195ac36..c128d8a48ea3 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -144,10 +144,10 @@ static inline bool test_thread_local_flags(unsigned int flags)
 	return (ti->local_flags & flags) != 0;
 }
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_COMPAT
 #define is_32bit_task()	(test_thread_flag(TIF_32BIT))
 #else
-#define is_32bit_task()	(1)
+#define is_32bit_task()	(IS_ENABLED(CONFIG_PPC32))
 #endif
 
 #if defined(CONFIG_PPC64)
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 1d646a94d96c..9d8772e863b9 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -44,16 +44,15 @@ CFLAGS_btext.o += -DDISABLE_BRANCH_PROFILING
 endif
 
 obj-y				:= cputable.o ptrace.o syscalls.o \
-				   irq.o align.o signal_32.o pmc.o vdso.o \
+				   irq.o align.o signal_$(BITS).o pmc.o vdso.o \
 				   process.o systbl.o idle.o \
 				   signal.o sysfs.o cacheinfo.o time.o \
 				   prom.o traps.o setup-common.o \
 				   udbg.o misc.o io.o misc_$(BITS).o \
 				   of_platform.o prom_parse.o
-obj-$(CONFIG_PPC64)		+= setup_64.o sys_ppc32.o \
-				   signal_64.o ptrace32.o \
-				   paca.o nvram_64.o firmware.o \
+obj-$(CONFIG_PPC64)		+= setup_64.o paca.o nvram_64.o firmware.o \
 				   syscall_64.o
+obj-$(CONFIG_COMPAT)		+= sys_ppc32.o ptrace32.o signal_32.o
 obj-$(CONFIG_VDSO32)		+= vdso32/
 obj-$(CONFIG_PPC_WATCHDOG)	+= watchdog.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2ec825a85f5b..a2dbf216f607 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -51,8 +51,10 @@
 SYS_CALL_TABLE:
 	.tc sys_call_table[TC],sys_call_table
 
+#ifdef CONFIG_COMPAT
 COMPAT_SYS_CALL_TABLE:
 	.tc compat_sys_call_table[TC],compat_sys_call_table
+#endif
 
 /* This value is used to mark exception frames on the stack. */
 exception_marker:
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 60436432399f..61678cb0e6a1 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -247,7 +247,6 @@ static void do_signal(struct task_struct *tsk)
 	sigset_t *oldset = sigmask_to_save();
 	struct ksignal ksig = { .sig = 0 };
 	int ret;
-	int is32 = is_32bit_task();
 
 	BUG_ON(tsk != current);
 
@@ -277,7 +276,7 @@ static void do_signal(struct task_struct *tsk)
 
 	rseq_signal_deliver(&ksig, tsk->thread.regs);
 
-	if (is32) {
+	if (is_32bit_task()) {
         	if (ksig.ka.sa.sa_flags & SA_SIGINFO)
 			ret = handle_rt_signal32(&ksig, oldset, tsk);
 		else
diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/syscall_64.c
index 98ed970796d5..0d5cbbe54cf1 100644
--- a/arch/powerpc/kernel/syscall_64.c
+++ b/arch/powerpc/kernel/syscall_64.c
@@ -38,7 +38,6 @@ typedef long (*syscall_fn)(long, long, long, long, long, long);
 
 long system_call_exception(long r3, long r4, long r5, long r6, long r7, long r8, unsigned long r0, struct pt_regs *regs)
 {
-	unsigned long ti_flags;
 	syscall_fn f;
 
 	BUG_ON(!(regs->msr & MSR_PR));
@@ -83,8 +82,7 @@ long system_call_exception(long r3, long r4, long r5, long r6, long r7, long r8,
 	 */
 	regs->softe = IRQS_ENABLED;
 
-	ti_flags = current_thread_info()->flags;
-	if (unlikely(ti_flags & _TIF_SYSCALL_DOTRACE)) {
+	if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) {
 		/*
 		 * We use the return value of do_syscall_trace_enter() as the
 		 * syscall number. If the syscall was rejected for any reason
@@ -100,7 +98,7 @@ long system_call_exception(long r3, long r4, long r5, long r6, long r7, long r8,
 	/* May be faster to do array_index_nospec? */
 	barrier_nospec();
 
-	if (unlikely(ti_flags & _TIF_32BIT)) {
+	if (unlikely(is_32bit_task())) {
 		f = (void *)compat_sys_call_table[r0];
 
 		r3 &= 0x00000000ffffffffULL;
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index d60598113a9f..6d4a077f74d6 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -667,9 +667,7 @@ static void __init vdso_setup_syscall_map(void)
 {
 	unsigned int i;
 	extern unsigned long *sys_call_table;
-#ifdef CONFIG_PPC64
 	extern unsigned long *compat_sys_call_table;
-#endif
 	extern unsigned long sys_ni_syscall;
 
 
@@ -678,7 +676,8 @@ static void __init vdso_setup_syscall_map(void)
 		if (sys_call_table[i] != sys_ni_syscall)
 			vdso_data->syscall_map_64[i >> 5] |=
 				0x80000000UL >> (i & 0x1f);
-		if (compat_sys_call_table[i] != sys_ni_syscall)
+		if (IS_ENABLED(CONFIG_COMPAT) &&
+		    compat_sys_call_table[i] != sys_ni_syscall)
 			vdso_data->syscall_map_32[i >> 5] |=
 				0x80000000UL >> (i & 0x1f);
 #else /* CONFIG_PPC64 */
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index b7cdcce20280..788ad2c63f18 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -15,7 +15,7 @@
 #include <asm/sigcontext.h>
 #include <asm/ucontext.h>
 #include <asm/vdso.h>
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_COMPAT
 #include "../kernel/ppc32.h"
 #endif
 #include <asm/pte-walk.h>
@@ -268,16 +268,6 @@ static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
 	}
 }
 
-static inline int current_is_64bit(void)
-{
-	/*
-	 * We can't use test_thread_flag() here because we may be on an
-	 * interrupt stack, and the thread flags don't get copied over
-	 * from the thread_info on the main stack to the interrupt stack.
-	 */
-	return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
-}
-
 #else  /* CONFIG_PPC64 */
 static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
 {
@@ -314,11 +304,6 @@ static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry
 {
 }
 
-static inline int current_is_64bit(void)
-{
-	return 0;
-}
-
 static inline int valid_user_sp(unsigned long sp, int is_64)
 {
 	if (!sp || (sp & 7) || sp > TASK_SIZE - 32)
@@ -334,6 +319,7 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
 
 #endif /* CONFIG_PPC64 */
 
+#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
 /*
  * Layout for non-RT signal frames
  */
@@ -475,6 +461,25 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
 		sp = next_sp;
 	}
 }
+#else /* 32bit */
+static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
+				   struct pt_regs *regs)
+{
+	(void)&read_user_stack_32; /* unused if !COMPAT */
+}
+#endif /* 32bit */
+
+static inline int current_is_64bit(void)
+{
+	if (!IS_ENABLED(CONFIG_COMPAT))
+		return IS_ENABLED(CONFIG_PPC64);
+	/*
+	 * We can't use test_thread_flag() here because we may be on an
+	 * interrupt stack, and the thread flags don't get copied over
+	 * from the thread_info on the main stack to the interrupt stack.
+	 */
+	return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
+}
 
 void
 perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v6 5/6] powerpc/64: Make COMPAT user-selectable disabled on littleendian by default.
  2019-08-30 18:57 [PATCH v6 0/6] Disable compat cruft on ppc64le v6 Michal Suchanek
                   ` (3 preceding siblings ...)
  2019-08-30 18:57 ` [PATCH v6 4/6] powerpc/64: make buildable without CONFIG_COMPAT Michal Suchanek
@ 2019-08-30 18:57 ` Michal Suchanek
  2019-08-30 20:23   ` Christophe Leroy
  2019-08-30 18:57 ` [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness Michal Suchanek
  5 siblings, 1 reply; 41+ messages in thread
From: Michal Suchanek @ 2019-08-30 18:57 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange, Allison Randal,
	Geert Uytterhoeven, Joel Stanley, Firoz Khan, Michal Suchanek,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini

On bigendian ppc64 it is common to have 32bit legacy binaries but much
less so on littleendian.

Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
v3: make configurable
---
 arch/powerpc/Kconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5bab0bb6b833..b0339e892329 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -264,8 +264,9 @@ config PANIC_TIMEOUT
 	default 180
 
 config COMPAT
-	bool
-	default y if PPC64
+	bool "Enable support for 32bit binaries"
+	depends on PPC64
+	default y if !CPU_LITTLE_ENDIAN
 	select COMPAT_BINFMT_ELF
 	select ARCH_WANT_OLD_COMPAT_IPC
 	select COMPAT_OLD_SIGACTION
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness
  2019-08-30 18:57 [PATCH v6 0/6] Disable compat cruft on ppc64le v6 Michal Suchanek
                   ` (4 preceding siblings ...)
  2019-08-30 18:57 ` [PATCH v6 5/6] powerpc/64: Make COMPAT user-selectable disabled on littleendian by default Michal Suchanek
@ 2019-08-30 18:57 ` Michal Suchanek
  2019-08-30 19:06   ` Michal Suchánek
  2019-08-30 20:28   ` Christophe Leroy
  5 siblings, 2 replies; 41+ messages in thread
From: Michal Suchanek @ 2019-08-30 18:57 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange, Allison Randal,
	Geert Uytterhoeven, Joel Stanley, Firoz Khan, Michal Suchanek,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini

Building callchain.c with !COMPAT proved quite ugly with all the
defines. Splitting out the 32bit and 64bit parts looks better.

No code change intended.

Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
v6:
 - move current_is_64bit consolidetaion to earlier patch
 - move defines to the top of callchain_32.c
 - Makefile cleanup
---
 arch/powerpc/perf/Makefile       |   5 +-
 arch/powerpc/perf/callchain.c    | 371 +------------------------------
 arch/powerpc/perf/callchain.h    |  11 +
 arch/powerpc/perf/callchain_32.c | 204 +++++++++++++++++
 arch/powerpc/perf/callchain_64.c | 185 +++++++++++++++
 5 files changed, 405 insertions(+), 371 deletions(-)
 create mode 100644 arch/powerpc/perf/callchain.h
 create mode 100644 arch/powerpc/perf/callchain_32.c
 create mode 100644 arch/powerpc/perf/callchain_64.c

diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index c155dcbb8691..53d614e98537 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -1,6 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-$(CONFIG_PERF_EVENTS)	+= callchain.o perf_regs.o
+obj-$(CONFIG_PERF_EVENTS)	+= callchain.o callchain_$(BITS).o perf_regs.o
+ifdef CONFIG_COMPAT
+obj-$(CONFIG_PERF_EVENTS)	+= callchain_32.o
+endif
 
 obj-$(CONFIG_PPC_PERF_CTRS)	+= core-book3s.o bhrb.o
 obj64-$(CONFIG_PPC_PERF_CTRS)	+= ppc970-pmu.o power5-pmu.o \
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index 788ad2c63f18..8f30f1b47c78 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -15,11 +15,9 @@
 #include <asm/sigcontext.h>
 #include <asm/ucontext.h>
 #include <asm/vdso.h>
-#ifdef CONFIG_COMPAT
-#include "../kernel/ppc32.h"
-#endif
 #include <asm/pte-walk.h>
 
+#include "callchain.h"
 
 /*
  * Is sp valid as the address of the next kernel stack frame after prev_sp?
@@ -102,373 +100,6 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
 	}
 }
 
-#ifdef CONFIG_PPC64
-/*
- * On 64-bit we don't want to invoke hash_page on user addresses from
- * interrupt context, so if the access faults, we read the page tables
- * to find which page (if any) is mapped and access it directly.
- */
-static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
-{
-	int ret = -EFAULT;
-	pgd_t *pgdir;
-	pte_t *ptep, pte;
-	unsigned shift;
-	unsigned long addr = (unsigned long) ptr;
-	unsigned long offset;
-	unsigned long pfn, flags;
-	void *kaddr;
-
-	pgdir = current->mm->pgd;
-	if (!pgdir)
-		return -EFAULT;
-
-	local_irq_save(flags);
-	ptep = find_current_mm_pte(pgdir, addr, NULL, &shift);
-	if (!ptep)
-		goto err_out;
-	if (!shift)
-		shift = PAGE_SHIFT;
-
-	/* align address to page boundary */
-	offset = addr & ((1UL << shift) - 1);
-
-	pte = READ_ONCE(*ptep);
-	if (!pte_present(pte) || !pte_user(pte))
-		goto err_out;
-	pfn = pte_pfn(pte);
-	if (!page_is_ram(pfn))
-		goto err_out;
-
-	/* no highmem to worry about here */
-	kaddr = pfn_to_kaddr(pfn);
-	memcpy(buf, kaddr + offset, nb);
-	ret = 0;
-err_out:
-	local_irq_restore(flags);
-	return ret;
-}
-
-static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
-{
-	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) ||
-	    ((unsigned long)ptr & 7))
-		return -EFAULT;
-
-	pagefault_disable();
-	if (!__get_user_inatomic(*ret, ptr)) {
-		pagefault_enable();
-		return 0;
-	}
-	pagefault_enable();
-
-	return read_user_stack_slow(ptr, ret, 8);
-}
-
-static inline int valid_user_sp(unsigned long sp, int is_64)
-{
-	if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32)
-		return 0;
-	return 1;
-}
-
-/*
- * 64-bit user processes use the same stack frame for RT and non-RT signals.
- */
-struct signal_frame_64 {
-	char		dummy[__SIGNAL_FRAMESIZE];
-	struct ucontext	uc;
-	unsigned long	unused[2];
-	unsigned int	tramp[6];
-	struct siginfo	*pinfo;
-	void		*puc;
-	struct siginfo	info;
-	char		abigap[288];
-};
-
-static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
-{
-	if (nip == fp + offsetof(struct signal_frame_64, tramp))
-		return 1;
-	if (vdso64_rt_sigtramp && current->mm->context.vdso_base &&
-	    nip == current->mm->context.vdso_base + vdso64_rt_sigtramp)
-		return 1;
-	return 0;
-}
-
-/*
- * Do some sanity checking on the signal frame pointed to by sp.
- * We check the pinfo and puc pointers in the frame.
- */
-static int sane_signal_64_frame(unsigned long sp)
-{
-	struct signal_frame_64 __user *sf;
-	unsigned long pinfo, puc;
-
-	sf = (struct signal_frame_64 __user *) sp;
-	if (read_user_stack_64((unsigned long __user *) &sf->pinfo, &pinfo) ||
-	    read_user_stack_64((unsigned long __user *) &sf->puc, &puc))
-		return 0;
-	return pinfo == (unsigned long) &sf->info &&
-		puc == (unsigned long) &sf->uc;
-}
-
-static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
-				   struct pt_regs *regs)
-{
-	unsigned long sp, next_sp;
-	unsigned long next_ip;
-	unsigned long lr;
-	long level = 0;
-	struct signal_frame_64 __user *sigframe;
-	unsigned long __user *fp, *uregs;
-
-	next_ip = perf_instruction_pointer(regs);
-	lr = regs->link;
-	sp = regs->gpr[1];
-	perf_callchain_store(entry, next_ip);
-
-	while (entry->nr < entry->max_stack) {
-		fp = (unsigned long __user *) sp;
-		if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp))
-			return;
-		if (level > 0 && read_user_stack_64(&fp[2], &next_ip))
-			return;
-
-		/*
-		 * Note: the next_sp - sp >= signal frame size check
-		 * is true when next_sp < sp, which can happen when
-		 * transitioning from an alternate signal stack to the
-		 * normal stack.
-		 */
-		if (next_sp - sp >= sizeof(struct signal_frame_64) &&
-		    (is_sigreturn_64_address(next_ip, sp) ||
-		     (level <= 1 && is_sigreturn_64_address(lr, sp))) &&
-		    sane_signal_64_frame(sp)) {
-			/*
-			 * This looks like an signal frame
-			 */
-			sigframe = (struct signal_frame_64 __user *) sp;
-			uregs = sigframe->uc.uc_mcontext.gp_regs;
-			if (read_user_stack_64(&uregs[PT_NIP], &next_ip) ||
-			    read_user_stack_64(&uregs[PT_LNK], &lr) ||
-			    read_user_stack_64(&uregs[PT_R1], &sp))
-				return;
-			level = 0;
-			perf_callchain_store_context(entry, PERF_CONTEXT_USER);
-			perf_callchain_store(entry, next_ip);
-			continue;
-		}
-
-		if (level == 0)
-			next_ip = lr;
-		perf_callchain_store(entry, next_ip);
-		++level;
-		sp = next_sp;
-	}
-}
-
-#else  /* CONFIG_PPC64 */
-static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
-{
-	return 0;
-}
-#endif /* CONFIG_PPC64 */
-
-/*
- * On 32-bit we just access the address and let hash_page create a
- * HPTE if necessary, so there is no need to fall back to reading
- * the page tables.  Since this is called at interrupt level,
- * do_page_fault() won't treat a DSI as a page fault.
- */
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
-	int rc;
-
-	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
-	    ((unsigned long)ptr & 3))
-		return -EFAULT;
-
-	pagefault_disable();
-	rc = __get_user_inatomic(*ret, ptr);
-	pagefault_enable();
-
-	if (IS_ENABLED(CONFIG_PPC64) && rc)
-		return read_user_stack_slow(ptr, ret, 4);
-	return rc;
-}
-
-#ifndef CONFIG_PPC64
-static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
-					  struct pt_regs *regs)
-{
-}
-
-static inline int valid_user_sp(unsigned long sp, int is_64)
-{
-	if (!sp || (sp & 7) || sp > TASK_SIZE - 32)
-		return 0;
-	return 1;
-}
-
-#define __SIGNAL_FRAMESIZE32	__SIGNAL_FRAMESIZE
-#define sigcontext32		sigcontext
-#define mcontext32		mcontext
-#define ucontext32		ucontext
-#define compat_siginfo_t	struct siginfo
-
-#endif /* CONFIG_PPC64 */
-
-#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
-/*
- * Layout for non-RT signal frames
- */
-struct signal_frame_32 {
-	char			dummy[__SIGNAL_FRAMESIZE32];
-	struct sigcontext32	sctx;
-	struct mcontext32	mctx;
-	int			abigap[56];
-};
-
-/*
- * Layout for RT signal frames
- */
-struct rt_signal_frame_32 {
-	char			dummy[__SIGNAL_FRAMESIZE32 + 16];
-	compat_siginfo_t	info;
-	struct ucontext32	uc;
-	int			abigap[56];
-};
-
-static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
-{
-	if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
-		return 1;
-	if (vdso32_sigtramp && current->mm->context.vdso_base &&
-	    nip == current->mm->context.vdso_base + vdso32_sigtramp)
-		return 1;
-	return 0;
-}
-
-static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp)
-{
-	if (nip == fp + offsetof(struct rt_signal_frame_32,
-				 uc.uc_mcontext.mc_pad))
-		return 1;
-	if (vdso32_rt_sigtramp && current->mm->context.vdso_base &&
-	    nip == current->mm->context.vdso_base + vdso32_rt_sigtramp)
-		return 1;
-	return 0;
-}
-
-static int sane_signal_32_frame(unsigned int sp)
-{
-	struct signal_frame_32 __user *sf;
-	unsigned int regs;
-
-	sf = (struct signal_frame_32 __user *) (unsigned long) sp;
-	if (read_user_stack_32((unsigned int __user *) &sf->sctx.regs, &regs))
-		return 0;
-	return regs == (unsigned long) &sf->mctx;
-}
-
-static int sane_rt_signal_32_frame(unsigned int sp)
-{
-	struct rt_signal_frame_32 __user *sf;
-	unsigned int regs;
-
-	sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
-	if (read_user_stack_32((unsigned int __user *) &sf->uc.uc_regs, &regs))
-		return 0;
-	return regs == (unsigned long) &sf->uc.uc_mcontext;
-}
-
-static unsigned int __user *signal_frame_32_regs(unsigned int sp,
-				unsigned int next_sp, unsigned int next_ip)
-{
-	struct mcontext32 __user *mctx = NULL;
-	struct signal_frame_32 __user *sf;
-	struct rt_signal_frame_32 __user *rt_sf;
-
-	/*
-	 * Note: the next_sp - sp >= signal frame size check
-	 * is true when next_sp < sp, for example, when
-	 * transitioning from an alternate signal stack to the
-	 * normal stack.
-	 */
-	if (next_sp - sp >= sizeof(struct signal_frame_32) &&
-	    is_sigreturn_32_address(next_ip, sp) &&
-	    sane_signal_32_frame(sp)) {
-		sf = (struct signal_frame_32 __user *) (unsigned long) sp;
-		mctx = &sf->mctx;
-	}
-
-	if (!mctx && next_sp - sp >= sizeof(struct rt_signal_frame_32) &&
-	    is_rt_sigreturn_32_address(next_ip, sp) &&
-	    sane_rt_signal_32_frame(sp)) {
-		rt_sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
-		mctx = &rt_sf->uc.uc_mcontext;
-	}
-
-	if (!mctx)
-		return NULL;
-	return mctx->mc_gregs;
-}
-
-static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
-				   struct pt_regs *regs)
-{
-	unsigned int sp, next_sp;
-	unsigned int next_ip;
-	unsigned int lr;
-	long level = 0;
-	unsigned int __user *fp, *uregs;
-
-	next_ip = perf_instruction_pointer(regs);
-	lr = regs->link;
-	sp = regs->gpr[1];
-	perf_callchain_store(entry, next_ip);
-
-	while (entry->nr < entry->max_stack) {
-		fp = (unsigned int __user *) (unsigned long) sp;
-		if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp))
-			return;
-		if (level > 0 && read_user_stack_32(&fp[1], &next_ip))
-			return;
-
-		uregs = signal_frame_32_regs(sp, next_sp, next_ip);
-		if (!uregs && level <= 1)
-			uregs = signal_frame_32_regs(sp, next_sp, lr);
-		if (uregs) {
-			/*
-			 * This looks like an signal frame, so restart
-			 * the stack trace with the values in it.
-			 */
-			if (read_user_stack_32(&uregs[PT_NIP], &next_ip) ||
-			    read_user_stack_32(&uregs[PT_LNK], &lr) ||
-			    read_user_stack_32(&uregs[PT_R1], &sp))
-				return;
-			level = 0;
-			perf_callchain_store_context(entry, PERF_CONTEXT_USER);
-			perf_callchain_store(entry, next_ip);
-			continue;
-		}
-
-		if (level == 0)
-			next_ip = lr;
-		perf_callchain_store(entry, next_ip);
-		++level;
-		sp = next_sp;
-	}
-}
-#else /* 32bit */
-static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
-				   struct pt_regs *regs)
-{
-	(void)&read_user_stack_32; /* unused if !COMPAT */
-}
-#endif /* 32bit */
-
 static inline int current_is_64bit(void)
 {
 	if (!IS_ENABLED(CONFIG_COMPAT))
diff --git a/arch/powerpc/perf/callchain.h b/arch/powerpc/perf/callchain.h
new file mode 100644
index 000000000000..63ffb43f3668
--- /dev/null
+++ b/arch/powerpc/perf/callchain.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _POWERPC_PERF_CALLCHAIN_H
+#define _POWERPC_PERF_CALLCHAIN_H
+
+int read_user_stack_slow(void __user *ptr, void *buf, int nb);
+void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
+			    struct pt_regs *regs);
+void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
+			    struct pt_regs *regs);
+
+#endif /* _POWERPC_PERF_CALLCHAIN_H */
diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c
new file mode 100644
index 000000000000..01a38d929078
--- /dev/null
+++ b/arch/powerpc/perf/callchain_32.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Performance counter callchain support - powerpc architecture code
+ *
+ * Copyright © 2009 Paul Mackerras, IBM Corporation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <linux/uaccess.h>
+#include <linux/mm.h>
+#include <asm/ptrace.h>
+#include <asm/pgtable.h>
+#include <asm/sigcontext.h>
+#include <asm/ucontext.h>
+#include <asm/vdso.h>
+#include <asm/pte-walk.h>
+
+#include "callchain.h"
+
+#ifdef CONFIG_PPC64
+#include "../kernel/ppc32.h"
+#else  /* CONFIG_PPC64 */
+
+#define __SIGNAL_FRAMESIZE32	__SIGNAL_FRAMESIZE
+#define sigcontext32		sigcontext
+#define mcontext32		mcontext
+#define ucontext32		ucontext
+#define compat_siginfo_t	struct siginfo
+
+#endif /* CONFIG_PPC64 */
+
+/*
+ * On 32-bit we just access the address and let hash_page create a
+ * HPTE if necessary, so there is no need to fall back to reading
+ * the page tables.  Since this is called at interrupt level,
+ * do_page_fault() won't treat a DSI as a page fault.
+ */
+static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
+{
+	int rc;
+
+	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
+	    ((unsigned long)ptr & 3))
+		return -EFAULT;
+
+	pagefault_disable();
+	rc = __get_user_inatomic(*ret, ptr);
+	pagefault_enable();
+
+	if (IS_ENABLED(CONFIG_PPC64) && rc)
+		return read_user_stack_slow(ptr, ret, 4);
+	return rc;
+}
+
+static inline int valid_user_sp(unsigned long sp, int is_64)
+{
+	if (!sp || (sp & 7) || sp > TASK_SIZE - 32)
+		return 0;
+	return 1;
+}
+
+/*
+ * Layout for non-RT signal frames
+ */
+struct signal_frame_32 {
+	char			dummy[__SIGNAL_FRAMESIZE32];
+	struct sigcontext32	sctx;
+	struct mcontext32	mctx;
+	int			abigap[56];
+};
+
+/*
+ * Layout for RT signal frames
+ */
+struct rt_signal_frame_32 {
+	char			dummy[__SIGNAL_FRAMESIZE32 + 16];
+	compat_siginfo_t	info;
+	struct ucontext32	uc;
+	int			abigap[56];
+};
+
+static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
+{
+	if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
+		return 1;
+	if (vdso32_sigtramp && current->mm->context.vdso_base &&
+	    nip == current->mm->context.vdso_base + vdso32_sigtramp)
+		return 1;
+	return 0;
+}
+
+static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp)
+{
+	if (nip == fp + offsetof(struct rt_signal_frame_32,
+				 uc.uc_mcontext.mc_pad))
+		return 1;
+	if (vdso32_rt_sigtramp && current->mm->context.vdso_base &&
+	    nip == current->mm->context.vdso_base + vdso32_rt_sigtramp)
+		return 1;
+	return 0;
+}
+
+static int sane_signal_32_frame(unsigned int sp)
+{
+	struct signal_frame_32 __user *sf;
+	unsigned int regs;
+
+	sf = (struct signal_frame_32 __user *) (unsigned long) sp;
+	if (read_user_stack_32((unsigned int __user *) &sf->sctx.regs, &regs))
+		return 0;
+	return regs == (unsigned long) &sf->mctx;
+}
+
+static int sane_rt_signal_32_frame(unsigned int sp)
+{
+	struct rt_signal_frame_32 __user *sf;
+	unsigned int regs;
+
+	sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
+	if (read_user_stack_32((unsigned int __user *) &sf->uc.uc_regs, &regs))
+		return 0;
+	return regs == (unsigned long) &sf->uc.uc_mcontext;
+}
+
+static unsigned int __user *signal_frame_32_regs(unsigned int sp,
+				unsigned int next_sp, unsigned int next_ip)
+{
+	struct mcontext32 __user *mctx = NULL;
+	struct signal_frame_32 __user *sf;
+	struct rt_signal_frame_32 __user *rt_sf;
+
+	/*
+	 * Note: the next_sp - sp >= signal frame size check
+	 * is true when next_sp < sp, for example, when
+	 * transitioning from an alternate signal stack to the
+	 * normal stack.
+	 */
+	if (next_sp - sp >= sizeof(struct signal_frame_32) &&
+	    is_sigreturn_32_address(next_ip, sp) &&
+	    sane_signal_32_frame(sp)) {
+		sf = (struct signal_frame_32 __user *) (unsigned long) sp;
+		mctx = &sf->mctx;
+	}
+
+	if (!mctx && next_sp - sp >= sizeof(struct rt_signal_frame_32) &&
+	    is_rt_sigreturn_32_address(next_ip, sp) &&
+	    sane_rt_signal_32_frame(sp)) {
+		rt_sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
+		mctx = &rt_sf->uc.uc_mcontext;
+	}
+
+	if (!mctx)
+		return NULL;
+	return mctx->mc_gregs;
+}
+
+void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
+			    struct pt_regs *regs)
+{
+	unsigned int sp, next_sp;
+	unsigned int next_ip;
+	unsigned int lr;
+	long level = 0;
+	unsigned int __user *fp, *uregs;
+
+	next_ip = perf_instruction_pointer(regs);
+	lr = regs->link;
+	sp = regs->gpr[1];
+	perf_callchain_store(entry, next_ip);
+
+	while (entry->nr < entry->max_stack) {
+		fp = (unsigned int __user *) (unsigned long) sp;
+		if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp))
+			return;
+		if (level > 0 && read_user_stack_32(&fp[1], &next_ip))
+			return;
+
+		uregs = signal_frame_32_regs(sp, next_sp, next_ip);
+		if (!uregs && level <= 1)
+			uregs = signal_frame_32_regs(sp, next_sp, lr);
+		if (uregs) {
+			/*
+			 * This looks like an signal frame, so restart
+			 * the stack trace with the values in it.
+			 */
+			if (read_user_stack_32(&uregs[PT_NIP], &next_ip) ||
+			    read_user_stack_32(&uregs[PT_LNK], &lr) ||
+			    read_user_stack_32(&uregs[PT_R1], &sp))
+				return;
+			level = 0;
+			perf_callchain_store_context(entry, PERF_CONTEXT_USER);
+			perf_callchain_store(entry, next_ip);
+			continue;
+		}
+
+		if (level == 0)
+			next_ip = lr;
+		perf_callchain_store(entry, next_ip);
+		++level;
+		sp = next_sp;
+	}
+}
diff --git a/arch/powerpc/perf/callchain_64.c b/arch/powerpc/perf/callchain_64.c
new file mode 100644
index 000000000000..60308c2221a8
--- /dev/null
+++ b/arch/powerpc/perf/callchain_64.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Performance counter callchain support - powerpc architecture code
+ *
+ * Copyright © 2009 Paul Mackerras, IBM Corporation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <linux/uaccess.h>
+#include <linux/mm.h>
+#include <asm/ptrace.h>
+#include <asm/pgtable.h>
+#include <asm/sigcontext.h>
+#include <asm/ucontext.h>
+#include <asm/vdso.h>
+#include <asm/pte-walk.h>
+
+#include "callchain.h"
+
+/*
+ * On 64-bit we don't want to invoke hash_page on user addresses from
+ * interrupt context, so if the access faults, we read the page tables
+ * to find which page (if any) is mapped and access it directly.
+ */
+int read_user_stack_slow(void __user *ptr, void *buf, int nb)
+{
+	int ret = -EFAULT;
+	pgd_t *pgdir;
+	pte_t *ptep, pte;
+	unsigned int shift;
+	unsigned long addr = (unsigned long) ptr;
+	unsigned long offset;
+	unsigned long pfn, flags;
+	void *kaddr;
+
+	pgdir = current->mm->pgd;
+	if (!pgdir)
+		return -EFAULT;
+
+	local_irq_save(flags);
+	ptep = find_current_mm_pte(pgdir, addr, NULL, &shift);
+	if (!ptep)
+		goto err_out;
+	if (!shift)
+		shift = PAGE_SHIFT;
+
+	/* align address to page boundary */
+	offset = addr & ((1UL << shift) - 1);
+
+	pte = READ_ONCE(*ptep);
+	if (!pte_present(pte) || !pte_user(pte))
+		goto err_out;
+	pfn = pte_pfn(pte);
+	if (!page_is_ram(pfn))
+		goto err_out;
+
+	/* no highmem to worry about here */
+	kaddr = pfn_to_kaddr(pfn);
+	memcpy(buf, kaddr + offset, nb);
+	ret = 0;
+err_out:
+	local_irq_restore(flags);
+	return ret;
+}
+
+static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
+{
+	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) ||
+	    ((unsigned long)ptr & 7))
+		return -EFAULT;
+
+	pagefault_disable();
+	if (!__get_user_inatomic(*ret, ptr)) {
+		pagefault_enable();
+		return 0;
+	}
+	pagefault_enable();
+
+	return read_user_stack_slow(ptr, ret, 8);
+}
+
+static inline int valid_user_sp(unsigned long sp, int is_64)
+{
+	if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32)
+		return 0;
+	return 1;
+}
+
+/*
+ * 64-bit user processes use the same stack frame for RT and non-RT signals.
+ */
+struct signal_frame_64 {
+	char		dummy[__SIGNAL_FRAMESIZE];
+	struct ucontext	uc;
+	unsigned long	unused[2];
+	unsigned int	tramp[6];
+	struct siginfo	*pinfo;
+	void		*puc;
+	struct siginfo	info;
+	char		abigap[288];
+};
+
+static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
+{
+	if (nip == fp + offsetof(struct signal_frame_64, tramp))
+		return 1;
+	if (vdso64_rt_sigtramp && current->mm->context.vdso_base &&
+	    nip == current->mm->context.vdso_base + vdso64_rt_sigtramp)
+		return 1;
+	return 0;
+}
+
+/*
+ * Do some sanity checking on the signal frame pointed to by sp.
+ * We check the pinfo and puc pointers in the frame.
+ */
+static int sane_signal_64_frame(unsigned long sp)
+{
+	struct signal_frame_64 __user *sf;
+	unsigned long pinfo, puc;
+
+	sf = (struct signal_frame_64 __user *) sp;
+	if (read_user_stack_64((unsigned long __user *) &sf->pinfo, &pinfo) ||
+	    read_user_stack_64((unsigned long __user *) &sf->puc, &puc))
+		return 0;
+	return pinfo == (unsigned long) &sf->info &&
+		puc == (unsigned long) &sf->uc;
+}
+
+void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
+			    struct pt_regs *regs)
+{
+	unsigned long sp, next_sp;
+	unsigned long next_ip;
+	unsigned long lr;
+	long level = 0;
+	struct signal_frame_64 __user *sigframe;
+	unsigned long __user *fp, *uregs;
+
+	next_ip = perf_instruction_pointer(regs);
+	lr = regs->link;
+	sp = regs->gpr[1];
+	perf_callchain_store(entry, next_ip);
+
+	while (entry->nr < entry->max_stack) {
+		fp = (unsigned long __user *) sp;
+		if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp))
+			return;
+		if (level > 0 && read_user_stack_64(&fp[2], &next_ip))
+			return;
+
+		/*
+		 * Note: the next_sp - sp >= signal frame size check
+		 * is true when next_sp < sp, which can happen when
+		 * transitioning from an alternate signal stack to the
+		 * normal stack.
+		 */
+		if (next_sp - sp >= sizeof(struct signal_frame_64) &&
+		    (is_sigreturn_64_address(next_ip, sp) ||
+		     (level <= 1 && is_sigreturn_64_address(lr, sp))) &&
+		    sane_signal_64_frame(sp)) {
+			/*
+			 * This looks like an signal frame
+			 */
+			sigframe = (struct signal_frame_64 __user *) sp;
+			uregs = sigframe->uc.uc_mcontext.gp_regs;
+			if (read_user_stack_64(&uregs[PT_NIP], &next_ip) ||
+			    read_user_stack_64(&uregs[PT_LNK], &lr) ||
+			    read_user_stack_64(&uregs[PT_R1], &sp))
+				return;
+			level = 0;
+			perf_callchain_store_context(entry, PERF_CONTEXT_USER);
+			perf_callchain_store(entry, next_ip);
+			continue;
+		}
+
+		if (level == 0)
+			next_ip = lr;
+		perf_callchain_store(entry, next_ip);
+		++level;
+		sp = next_sp;
+	}
+}
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness
  2019-08-30 18:57 ` [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness Michal Suchanek
@ 2019-08-30 19:06   ` Michal Suchánek
  2019-09-02  2:51     ` Michael Ellerman
  2019-08-30 20:28   ` Christophe Leroy
  1 sibling, 1 reply; 41+ messages in thread
From: Michal Suchánek @ 2019-08-30 19:06 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange,
	Geert Uytterhoeven, Allison Randal, Firoz Khan, Joel Stanley,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini

On Fri, 30 Aug 2019 20:57:57 +0200
Michal Suchanek <msuchanek@suse.de> wrote:

> Building callchain.c with !COMPAT proved quite ugly with all the
> defines. Splitting out the 32bit and 64bit parts looks better.
> 

BTW the powerpc callchain.c does not match any of the patterns of PERF
CORE in MAINTAINERS (unlike callchain implementation on other
platforms). Is that intentional?

Thanks

Michal

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro"
  2019-08-30 18:57 ` [PATCH v6 1/6] powerpc: make llseek 32bit-only Michal Suchanek
@ 2019-08-30 19:46   ` Michal Suchanek
  2019-08-30 19:54     ` Arnd Bergmann
  0 siblings, 1 reply; 41+ messages in thread
From: Michal Suchanek @ 2019-08-30 19:46 UTC (permalink / raw)
  To: linux-arch
  Cc: Rich Felker, linux-sh, Heiko Carstens, linux-mips,
	James E.J. Bottomley, Max Filippov, Guo Ren, H. Peter Anvin,
	sparclinux, Vincenzo Frascino, Will Deacon, linux-s390,
	Arnd Bergmann, Yoshinori Sato, Helge Deller, x86, Russell King,
	Christian Borntraeger, Ingo Molnar, Geert Uytterhoeven,
	linux-arm-kernel, Catalin Marinas, James Hogan, Firoz Khan,
	Michal Suchanek, linux-xtensa, Vasily Gorbik, linux-m68k,
	Borislav Petkov, Alexander Viro, David Howells, Thomas Gleixner,
	Christian Brauner, Chris Zankel, Michal Simek, linux-parisc,
	Greg Kroah-Hartman, linux-kernel, Ralf Baechle, Paul Burton,
	linux-fsdevel, Paul Mackerras, linuxppc-dev, David S. Miller

This reverts commit caf6f9c8a326cffd1d4b3ff3f1cfba75d159d70b.

Maybe it was needed after all.

When CONFIG_COMPAT is disabled on ppc64 the kernel does not build.

There is resistance to both removing the llseek syscall from the 64bit
syscall tables and building the llseek interface unconditionally.

Link: https://lore.kernel.org/lkml/20190828151552.GA16855@infradead.org/
Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/

Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
 arch/arm/include/asm/unistd.h        |  1 +
 arch/arm64/include/asm/unistd.h      |  1 +
 arch/csky/include/asm/unistd.h       |  2 +-
 arch/m68k/include/asm/unistd.h       |  1 +
 arch/microblaze/include/asm/unistd.h |  1 +
 arch/mips/include/asm/unistd.h       |  1 +
 arch/parisc/include/asm/unistd.h     |  1 +
 arch/powerpc/include/asm/unistd.h    |  1 +
 arch/s390/include/asm/unistd.h       |  1 +
 arch/sh/include/asm/unistd.h         |  1 +
 arch/sparc/include/asm/unistd.h      |  1 +
 arch/x86/include/asm/unistd.h        |  1 +
 arch/xtensa/include/asm/unistd.h     |  1 +
 fs/read_write.c                      |  2 +-
 include/asm-generic/unistd.h         | 12 ++++++++++++
 15 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 include/asm-generic/unistd.h

diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 3676e82cf95c..e35ec8100a21 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -18,6 +18,7 @@
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 2629a68b8724..2c9d8d91e347 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -7,6 +7,7 @@
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/csky/include/asm/unistd.h b/arch/csky/include/asm/unistd.h
index da7a18295615..bee8ba8309e7 100644
--- a/arch/csky/include/asm/unistd.h
+++ b/arch/csky/include/asm/unistd.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
 
-#include <uapi/asm/unistd.h>
+#include <asm-generic/unistd.h>
 
 #define NR_syscalls (__NR_syscalls)
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index 2e0047cf86f8..54c04eb4495a 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -21,6 +21,7 @@
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLD_MMAP
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
index d79d35ac6253..c5fcbce1f997 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -27,6 +27,7 @@
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 /* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */
 #define __ARCH_WANT_SYS_OLDUMOUNT
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index 071053ece677..8e8c7cab95ca 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -38,6 +38,7 @@
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_UNAME
 #define __ARCH_WANT_SYS_OLDUMOUNT
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index cd438e4150f6..29bd46381f2e 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -159,6 +159,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index b0720c7c3fcf..700fcdac2e3c 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -31,6 +31,7 @@
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLD_UNAME
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 9e9f75ef046a..52e9e2fe3768 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -21,6 +21,7 @@
 #define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLD_MMAP
diff --git a/arch/sh/include/asm/unistd.h b/arch/sh/include/asm/unistd.h
index 9c7d9d9999c6..4899b6b72f1a 100644
--- a/arch/sh/include/asm/unistd.h
+++ b/arch/sh/include/asm/unistd.h
@@ -22,6 +22,7 @@
 # define __ARCH_WANT_SYS_SOCKETCALL
 # define __ARCH_WANT_SYS_FADVISE64
 # define __ARCH_WANT_SYS_GETPGRP
+# define __ARCH_WANT_SYS_LLSEEK
 # define __ARCH_WANT_SYS_NICE
 # define __ARCH_WANT_SYS_OLD_GETRLIMIT
 # define __ARCH_WANT_SYS_OLD_UNAME
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index 1e66278ba4a5..7edfc208e2af 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -36,6 +36,7 @@
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 097589753fec..9e5a1748b4ce 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -39,6 +39,7 @@
 # define __ARCH_WANT_SYS_FADVISE64
 # define __ARCH_WANT_SYS_GETHOSTNAME
 # define __ARCH_WANT_SYS_GETPGRP
+# define __ARCH_WANT_SYS_LLSEEK
 # define __ARCH_WANT_SYS_NICE
 # define __ARCH_WANT_SYS_OLDUMOUNT
 # define __ARCH_WANT_SYS_OLD_GETRLIMIT
diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h
index b52236245e51..9fd236a7825e 100644
--- a/arch/xtensa/include/asm/unistd.h
+++ b/arch/xtensa/include/asm/unistd.h
@@ -9,6 +9,7 @@
 #define __ARCH_WANT_NEW_STAT
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_UTIME32
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_GETPGRP
 
 #define NR_syscalls				__NR_syscalls
diff --git a/fs/read_write.c b/fs/read_write.c
index 5bbf587f5bc1..2f3c4bb138c4 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -331,7 +331,7 @@ COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, compat_off_t, offset, unsigned i
 }
 #endif
 
-#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
+#ifdef __ARCH_WANT_SYS_LLSEEK
 SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
 		unsigned long, offset_low, loff_t __user *, result,
 		unsigned int, whence)
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h
new file mode 100644
index 000000000000..ea74eca8463f
--- /dev/null
+++ b/include/asm-generic/unistd.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <uapi/asm-generic/unistd.h>
+#include <linux/export.h>
+
+/*
+ * These are required system calls, we should
+ * invert the logic eventually and let them
+ * be selected by default.
+ */
+#if __BITS_PER_LONG == 32
+#define __ARCH_WANT_SYS_LLSEEK
+#endif
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro"
  2019-08-30 19:46   ` [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro" Michal Suchanek
@ 2019-08-30 19:54     ` Arnd Bergmann
  2019-08-30 20:13       ` Michal Suchánek
                         ` (2 more replies)
  0 siblings, 3 replies; 41+ messages in thread
From: Arnd Bergmann @ 2019-08-30 19:54 UTC (permalink / raw)
  To: Michal Suchanek
  Cc: Rich Felker, Linux-sh list, Heiko Carstens, linux-mips,
	James E.J. Bottomley, Max Filippov, Guo Ren, H. Peter Anvin,
	sparclinux, Vincenzo Frascino, Will Deacon, linux-arch,
	linux-s390, Yoshinori Sato, Helge Deller,
	the arch/x86 maintainers, Russell King, Christian Borntraeger,
	Ingo Molnar, Geert Uytterhoeven, Linux ARM, Catalin Marinas,
	James Hogan, Firoz Khan, linux-xtensa, Vasily Gorbik, linux-m68k,
	Borislav Petkov, Alexander Viro, David Howells, Thomas Gleixner,
	Christian Brauner, Chris Zankel, Michal Simek, Parisc List,
	Greg Kroah-Hartman, Linux Kernel Mailing List, Ralf Baechle,
	Paul Burton, Linux FS-devel Mailing List, Paul Mackerras,
	linuxppc-dev, David S. Miller

On Fri, Aug 30, 2019 at 9:46 PM Michal Suchanek <msuchanek@suse.de> wrote:
>
> This reverts commit caf6f9c8a326cffd1d4b3ff3f1cfba75d159d70b.
>
> Maybe it was needed after all.
>
> When CONFIG_COMPAT is disabled on ppc64 the kernel does not build.
>
> There is resistance to both removing the llseek syscall from the 64bit
> syscall tables and building the llseek interface unconditionally.
>
> Link: https://lore.kernel.org/lkml/20190828151552.GA16855@infradead.org/
> Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/
>
> Signed-off-by: Michal Suchanek <msuchanek@suse.de>

This seems like the right idea in principle.

> index 5bbf587f5bc1..2f3c4bb138c4 100644
> --- a/fs/read_write.c
> +++ b/fs/read_write.c
> @@ -331,7 +331,7 @@ COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, compat_off_t, offset, unsigned i
>  }
>  #endif
>
> -#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
> +#ifdef __ARCH_WANT_SYS_LLSEEK
>  SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
>                 unsigned long, offset_low, loff_t __user *, result,
>                 unsigned int, whence)

However, only reverting the patch will now break all newly added
32-bit architectures that don't define __ARCH_WANT_SYS_LLSEEK:
at least nds32 and riscv32 come to mind, not sure if there is another.

I think the easiest way however would be to combine the two checks
above and make it

#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) ||
defined(__ARCH_WANT_SYS_LLSEEK)

and then only set __ARCH_WANT_SYS_LLSEEK for powerpc.

     Arnd

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro"
  2019-08-30 19:54     ` Arnd Bergmann
@ 2019-08-30 20:13       ` Michal Suchánek
  2019-08-30 20:37         ` Arnd Bergmann
       [not found]       ` <20190830202959.3539-1-msuchanek@suse.de>
  2019-08-31  8:38       ` [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro" Christoph Hellwig
  2 siblings, 1 reply; 41+ messages in thread
From: Michal Suchánek @ 2019-08-30 20:13 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rich Felker, Linux-sh list, Heiko Carstens, linux-mips,
	James E.J. Bottomley, Max Filippov, Guo Ren, H. Peter Anvin,
	sparclinux, Vincenzo Frascino, Will Deacon, linux-arch,
	linux-s390, Yoshinori Sato, Helge Deller,
	the arch/x86 maintainers, Russell King, Christian Borntraeger,
	Ingo Molnar, Geert Uytterhoeven, Linux ARM, Catalin Marinas,
	James Hogan, Firoz Khan, linux-xtensa, Vasily Gorbik, linux-m68k,
	Borislav Petkov, Alexander Viro, David Howells, Thomas Gleixner,
	Christian Brauner, Chris Zankel, Michal Simek, Parisc List,
	Greg Kroah-Hartman, Linux Kernel Mailing List, Ralf Baechle,
	Paul Burton, Linux FS-devel Mailing List, Paul Mackerras,
	linuxppc-dev, David S. Miller

On Fri, 30 Aug 2019 21:54:43 +0200
Arnd Bergmann <arnd@arndb.de> wrote:

> On Fri, Aug 30, 2019 at 9:46 PM Michal Suchanek <msuchanek@suse.de> wrote:
> >
> > This reverts commit caf6f9c8a326cffd1d4b3ff3f1cfba75d159d70b.
> >
> > Maybe it was needed after all.
> >
> > When CONFIG_COMPAT is disabled on ppc64 the kernel does not build.
> >
> > There is resistance to both removing the llseek syscall from the 64bit
> > syscall tables and building the llseek interface unconditionally.
> >
> > Link: https://lore.kernel.org/lkml/20190828151552.GA16855@infradead.org/
> > Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/
> >
> > Signed-off-by: Michal Suchanek <msuchanek@suse.de>  
> 
> This seems like the right idea in principle.
> 
> > index 5bbf587f5bc1..2f3c4bb138c4 100644
> > --- a/fs/read_write.c
> > +++ b/fs/read_write.c
> > @@ -331,7 +331,7 @@ COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, compat_off_t, offset, unsigned i
> >  }
> >  #endif
> >
> > -#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
> > +#ifdef __ARCH_WANT_SYS_LLSEEK
> >  SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
> >                 unsigned long, offset_low, loff_t __user *, result,
> >                 unsigned int, whence)  
> 
> However, only reverting the patch will now break all newly added
> 32-bit architectures that don't define __ARCH_WANT_SYS_LLSEEK:
> at least nds32 and riscv32 come to mind, not sure if there is another.

AFAICT nds32 never had the syscall. Its headers were added without
__ARCH_WANT_SYS_LLSEEK before the define was removed.

The new architecture csky should be handled.

> 
> I think the easiest way however would be to combine the two checks
> above and make it
> 
> #if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) ||
> defined(__ARCH_WANT_SYS_LLSEEK)
> 
> and then only set __ARCH_WANT_SYS_LLSEEK for powerpc.

Yes, that limits the use of __ARCH_WANT_SYS_LLSEEK, does not require
resurrecting the old headers, and may fix some architectures like nds32
that forgot to add it.

Thanks

Michal

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 4/6] powerpc/64: make buildable without CONFIG_COMPAT
  2019-08-30 18:57 ` [PATCH v6 4/6] powerpc/64: make buildable without CONFIG_COMPAT Michal Suchanek
@ 2019-08-30 20:21   ` Christophe Leroy
  2019-08-30 20:35     ` Michal Suchánek
  0 siblings, 1 reply; 41+ messages in thread
From: Christophe Leroy @ 2019-08-30 20:21 UTC (permalink / raw)
  To: Michal Suchanek, linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange,
	Geert Uytterhoeven, Allison Randal, Firoz Khan, Joel Stanley,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini



Le 30/08/2019 à 20:57, Michal Suchanek a écrit :
> There are numerous references to 32bit functions in generic and 64bit
> code so ifdef them out.
> 
> Signed-off-by: Michal Suchanek <msuchanek@suse.de>
> ---
> v2:
> - fix 32bit ifdef condition in signal.c
> - simplify the compat ifdef condition in vdso.c - 64bit is redundant
> - simplify the compat ifdef condition in callchain.c - 64bit is redundant
> v3:
> - use IS_ENABLED and maybe_unused where possible
> - do not ifdef declarations
> - clean up Makefile
> v4:
> - further makefile cleanup
> - simplify is_32bit_task conditions
> - avoid ifdef in condition by using return
> v5:
> - avoid unreachable code on 32bit
> - make is_current_64bit constant on !COMPAT
> - add stub perf_callchain_user_32 to avoid some ifdefs
> v6:
> - consolidate current_is_64bit
> ---
>   arch/powerpc/include/asm/thread_info.h |  4 +--
>   arch/powerpc/kernel/Makefile           |  7 +++--
>   arch/powerpc/kernel/entry_64.S         |  2 ++
>   arch/powerpc/kernel/signal.c           |  3 +--
>   arch/powerpc/kernel/syscall_64.c       |  6 ++---
>   arch/powerpc/kernel/vdso.c             |  5 ++--
>   arch/powerpc/perf/callchain.c          | 37 +++++++++++++++-----------
>   7 files changed, 33 insertions(+), 31 deletions(-)
> 

[...]

> diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
> index b7cdcce20280..788ad2c63f18 100644
> --- a/arch/powerpc/perf/callchain.c
> +++ b/arch/powerpc/perf/callchain.c
> @@ -15,7 +15,7 @@
>   #include <asm/sigcontext.h>
>   #include <asm/ucontext.h>
>   #include <asm/vdso.h>
> -#ifdef CONFIG_PPC64
> +#ifdef CONFIG_COMPAT
>   #include "../kernel/ppc32.h"
>   #endif
>   #include <asm/pte-walk.h>
> @@ -268,16 +268,6 @@ static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
>   	}
>   }
>   
> -static inline int current_is_64bit(void)
> -{
> -	/*
> -	 * We can't use test_thread_flag() here because we may be on an
> -	 * interrupt stack, and the thread flags don't get copied over
> -	 * from the thread_info on the main stack to the interrupt stack.
> -	 */
> -	return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> -}
> -
>   #else  /* CONFIG_PPC64 */
>   static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
>   {
> @@ -314,11 +304,6 @@ static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry
>   {
>   }
>   
> -static inline int current_is_64bit(void)
> -{
> -	return 0;
> -}
> -
>   static inline int valid_user_sp(unsigned long sp, int is_64)
>   {
>   	if (!sp || (sp & 7) || sp > TASK_SIZE - 32)
> @@ -334,6 +319,7 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
>   
>   #endif /* CONFIG_PPC64 */
>   
> +#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
>   /*
>    * Layout for non-RT signal frames
>    */
> @@ -475,6 +461,25 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
>   		sp = next_sp;
>   	}
>   }
> +#else /* 32bit */
> +static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> +				   struct pt_regs *regs)
> +{
> +	(void)&read_user_stack_32; /* unused if !COMPAT */

You don't need that anymore do you ?

Christophe

> +}
> +#endif /* 32bit */
> +
> +static inline int current_is_64bit(void)
> +{
> +	if (!IS_ENABLED(CONFIG_COMPAT))
> +		return IS_ENABLED(CONFIG_PPC64);
> +	/*
> +	 * We can't use test_thread_flag() here because we may be on an
> +	 * interrupt stack, and the thread flags don't get copied over
> +	 * from the thread_info on the main stack to the interrupt stack.
> +	 */
> +	return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> +}
>   
>   void
>   perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 3/6] powerpc/perf: consolidate read_user_stack_32
  2019-08-30 18:57 ` [PATCH v6 3/6] powerpc/perf: consolidate read_user_stack_32 Michal Suchanek
@ 2019-08-30 20:21   ` Christophe Leroy
  0 siblings, 0 replies; 41+ messages in thread
From: Christophe Leroy @ 2019-08-30 20:21 UTC (permalink / raw)
  To: Michal Suchanek, linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange,
	Geert Uytterhoeven, Allison Randal, Firoz Khan, Joel Stanley,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini



Le 30/08/2019 à 20:57, Michal Suchanek a écrit :
> There are two almost identical copies for 32bit and 64bit.
> 
> The function is used only in 32bit code which will be split out in next
> patch so consolidate to one function.
> 
> Signed-off-by: Michal Suchanek <msuchanek@suse.de>

Reviewed-by: Christophe.Leroy@c-s.fr

> ---
> new patch in v6
> ---
>   arch/powerpc/perf/callchain.c | 25 +++++++++----------------
>   1 file changed, 9 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
> index c84bbd4298a0..b7cdcce20280 100644
> --- a/arch/powerpc/perf/callchain.c
> +++ b/arch/powerpc/perf/callchain.c
> @@ -165,22 +165,6 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
>   	return read_user_stack_slow(ptr, ret, 8);
>   }
>   
> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> -{
> -	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> -	    ((unsigned long)ptr & 3))
> -		return -EFAULT;
> -
> -	pagefault_disable();
> -	if (!__get_user_inatomic(*ret, ptr)) {
> -		pagefault_enable();
> -		return 0;
> -	}
> -	pagefault_enable();
> -
> -	return read_user_stack_slow(ptr, ret, 4);
> -}
> -
>   static inline int valid_user_sp(unsigned long sp, int is_64)
>   {
>   	if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32)
> @@ -295,6 +279,12 @@ static inline int current_is_64bit(void)
>   }
>   
>   #else  /* CONFIG_PPC64 */
> +static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
> +{
> +	return 0;
> +}
> +#endif /* CONFIG_PPC64 */
> +
>   /*
>    * On 32-bit we just access the address and let hash_page create a
>    * HPTE if necessary, so there is no need to fall back to reading
> @@ -313,9 +303,12 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
>   	rc = __get_user_inatomic(*ret, ptr);
>   	pagefault_enable();
>   
> +	if (IS_ENABLED(CONFIG_PPC64) && rc)
> +		return read_user_stack_slow(ptr, ret, 4);
>   	return rc;
>   }
>   
> +#ifndef CONFIG_PPC64
>   static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
>   					  struct pt_regs *regs)
>   {
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 2/6] powerpc: move common register copy functions from signal_32.c to signal.c
  2019-08-30 18:57 ` [PATCH v6 2/6] powerpc: move common register copy functions from signal_32.c to signal.c Michal Suchanek
@ 2019-08-30 20:22   ` Christophe Leroy
  0 siblings, 0 replies; 41+ messages in thread
From: Christophe Leroy @ 2019-08-30 20:22 UTC (permalink / raw)
  To: Michal Suchanek, linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange,
	Geert Uytterhoeven, Allison Randal, Firoz Khan, Joel Stanley,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini



Le 30/08/2019 à 20:57, Michal Suchanek a écrit :
> These functions are required for 64bit as well.
> 
> Signed-off-by: Michal Suchanek <msuchanek@suse.de>

Reviewed-by: christophe.leroy@c-s.fr


> ---
>   arch/powerpc/kernel/signal.c    | 141 ++++++++++++++++++++++++++++++++
>   arch/powerpc/kernel/signal_32.c | 140 -------------------------------
>   2 files changed, 141 insertions(+), 140 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
> index e6c30cee6abf..60436432399f 100644
> --- a/arch/powerpc/kernel/signal.c
> +++ b/arch/powerpc/kernel/signal.c
> @@ -18,12 +18,153 @@
>   #include <linux/syscalls.h>
>   #include <asm/hw_breakpoint.h>
>   #include <linux/uaccess.h>
> +#include <asm/switch_to.h>
>   #include <asm/unistd.h>
>   #include <asm/debug.h>
>   #include <asm/tm.h>
>   
>   #include "signal.h"
>   
> +#ifdef CONFIG_VSX
> +unsigned long copy_fpr_to_user(void __user *to,
> +			       struct task_struct *task)
> +{
> +	u64 buf[ELF_NFPREG];
> +	int i;
> +
> +	/* save FPR copy to local buffer then write to the thread_struct */
> +	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
> +		buf[i] = task->thread.TS_FPR(i);
> +	buf[i] = task->thread.fp_state.fpscr;
> +	return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
> +}
> +
> +unsigned long copy_fpr_from_user(struct task_struct *task,
> +				 void __user *from)
> +{
> +	u64 buf[ELF_NFPREG];
> +	int i;
> +
> +	if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
> +		return 1;
> +	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
> +		task->thread.TS_FPR(i) = buf[i];
> +	task->thread.fp_state.fpscr = buf[i];
> +
> +	return 0;
> +}
> +
> +unsigned long copy_vsx_to_user(void __user *to,
> +			       struct task_struct *task)
> +{
> +	u64 buf[ELF_NVSRHALFREG];
> +	int i;
> +
> +	/* save FPR copy to local buffer then write to the thread_struct */
> +	for (i = 0; i < ELF_NVSRHALFREG; i++)
> +		buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
> +	return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
> +}
> +
> +unsigned long copy_vsx_from_user(struct task_struct *task,
> +				 void __user *from)
> +{
> +	u64 buf[ELF_NVSRHALFREG];
> +	int i;
> +
> +	if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
> +		return 1;
> +	for (i = 0; i < ELF_NVSRHALFREG ; i++)
> +		task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> +unsigned long copy_ckfpr_to_user(void __user *to,
> +				  struct task_struct *task)
> +{
> +	u64 buf[ELF_NFPREG];
> +	int i;
> +
> +	/* save FPR copy to local buffer then write to the thread_struct */
> +	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
> +		buf[i] = task->thread.TS_CKFPR(i);
> +	buf[i] = task->thread.ckfp_state.fpscr;
> +	return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
> +}
> +
> +unsigned long copy_ckfpr_from_user(struct task_struct *task,
> +					  void __user *from)
> +{
> +	u64 buf[ELF_NFPREG];
> +	int i;
> +
> +	if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
> +		return 1;
> +	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
> +		task->thread.TS_CKFPR(i) = buf[i];
> +	task->thread.ckfp_state.fpscr = buf[i];
> +
> +	return 0;
> +}
> +
> +unsigned long copy_ckvsx_to_user(void __user *to,
> +				  struct task_struct *task)
> +{
> +	u64 buf[ELF_NVSRHALFREG];
> +	int i;
> +
> +	/* save FPR copy to local buffer then write to the thread_struct */
> +	for (i = 0; i < ELF_NVSRHALFREG; i++)
> +		buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
> +	return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
> +}
> +
> +unsigned long copy_ckvsx_from_user(struct task_struct *task,
> +					  void __user *from)
> +{
> +	u64 buf[ELF_NVSRHALFREG];
> +	int i;
> +
> +	if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
> +		return 1;
> +	for (i = 0; i < ELF_NVSRHALFREG ; i++)
> +		task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
> +	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
>    * through debug.exception-trace sysctl.
>    */
> diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
> index 98600b276f76..c93c937ea568 100644
> --- a/arch/powerpc/kernel/signal_32.c
> +++ b/arch/powerpc/kernel/signal_32.c
> @@ -235,146 +235,6 @@ struct rt_sigframe {
>   	int			abigap[56];
>   };
>   
> -#ifdef CONFIG_VSX
> -unsigned long copy_fpr_to_user(void __user *to,
> -			       struct task_struct *task)
> -{
> -	u64 buf[ELF_NFPREG];
> -	int i;
> -
> -	/* save FPR copy to local buffer then write to the thread_struct */
> -	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
> -		buf[i] = task->thread.TS_FPR(i);
> -	buf[i] = task->thread.fp_state.fpscr;
> -	return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
> -}
> -
> -unsigned long copy_fpr_from_user(struct task_struct *task,
> -				 void __user *from)
> -{
> -	u64 buf[ELF_NFPREG];
> -	int i;
> -
> -	if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
> -		return 1;
> -	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
> -		task->thread.TS_FPR(i) = buf[i];
> -	task->thread.fp_state.fpscr = buf[i];
> -
> -	return 0;
> -}
> -
> -unsigned long copy_vsx_to_user(void __user *to,
> -			       struct task_struct *task)
> -{
> -	u64 buf[ELF_NVSRHALFREG];
> -	int i;
> -
> -	/* save FPR copy to local buffer then write to the thread_struct */
> -	for (i = 0; i < ELF_NVSRHALFREG; i++)
> -		buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
> -	return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
> -}
> -
> -unsigned long copy_vsx_from_user(struct task_struct *task,
> -				 void __user *from)
> -{
> -	u64 buf[ELF_NVSRHALFREG];
> -	int i;
> -
> -	if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
> -		return 1;
> -	for (i = 0; i < ELF_NVSRHALFREG ; i++)
> -		task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
> -	return 0;
> -}
> -
> -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> -unsigned long copy_ckfpr_to_user(void __user *to,
> -				  struct task_struct *task)
> -{
> -	u64 buf[ELF_NFPREG];
> -	int i;
> -
> -	/* save FPR copy to local buffer then write to the thread_struct */
> -	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
> -		buf[i] = task->thread.TS_CKFPR(i);
> -	buf[i] = task->thread.ckfp_state.fpscr;
> -	return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
> -}
> -
> -unsigned long copy_ckfpr_from_user(struct task_struct *task,
> -					  void __user *from)
> -{
> -	u64 buf[ELF_NFPREG];
> -	int i;
> -
> -	if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
> -		return 1;
> -	for (i = 0; i < (ELF_NFPREG - 1) ; i++)
> -		task->thread.TS_CKFPR(i) = buf[i];
> -	task->thread.ckfp_state.fpscr = buf[i];
> -
> -	return 0;
> -}
> -
> -unsigned long copy_ckvsx_to_user(void __user *to,
> -				  struct task_struct *task)
> -{
> -	u64 buf[ELF_NVSRHALFREG];
> -	int i;
> -
> -	/* save FPR copy to local buffer then write to the thread_struct */
> -	for (i = 0; i < ELF_NVSRHALFREG; i++)
> -		buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
> -	return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
> -}
> -
> -unsigned long copy_ckvsx_from_user(struct task_struct *task,
> -					  void __user *from)
> -{
> -	u64 buf[ELF_NVSRHALFREG];
> -	int i;
> -
> -	if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
> -		return 1;
> -	for (i = 0; i < ELF_NVSRHALFREG ; i++)
> -		task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
> -	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
> -
>   /*
>    * Save the current user registers on the user stack.
>    * We only save the altivec/spe registers if the process has used
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 5/6] powerpc/64: Make COMPAT user-selectable disabled on littleendian by default.
  2019-08-30 18:57 ` [PATCH v6 5/6] powerpc/64: Make COMPAT user-selectable disabled on littleendian by default Michal Suchanek
@ 2019-08-30 20:23   ` Christophe Leroy
  0 siblings, 0 replies; 41+ messages in thread
From: Christophe Leroy @ 2019-08-30 20:23 UTC (permalink / raw)
  To: Michal Suchanek, linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange,
	Geert Uytterhoeven, Allison Randal, Firoz Khan, Joel Stanley,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini



Le 30/08/2019 à 20:57, Michal Suchanek a écrit :
> On bigendian ppc64 it is common to have 32bit legacy binaries but much
> less so on littleendian.
> 
> Signed-off-by: Michal Suchanek <msuchanek@suse.de>

Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>


> ---
> v3: make configurable
> ---
>   arch/powerpc/Kconfig | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 5bab0bb6b833..b0339e892329 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -264,8 +264,9 @@ config PANIC_TIMEOUT
>   	default 180
>   
>   config COMPAT
> -	bool
> -	default y if PPC64
> +	bool "Enable support for 32bit binaries"
> +	depends on PPC64
> +	default y if !CPU_LITTLE_ENDIAN
>   	select COMPAT_BINFMT_ELF
>   	select ARCH_WANT_OLD_COMPAT_IPC
>   	select COMPAT_OLD_SIGACTION
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness
  2019-08-30 18:57 ` [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness Michal Suchanek
  2019-08-30 19:06   ` Michal Suchánek
@ 2019-08-30 20:28   ` Christophe Leroy
  1 sibling, 0 replies; 41+ messages in thread
From: Christophe Leroy @ 2019-08-30 20:28 UTC (permalink / raw)
  To: Michal Suchanek, linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange,
	Geert Uytterhoeven, Allison Randal, Firoz Khan, Joel Stanley,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini



Le 30/08/2019 à 20:57, Michal Suchanek a écrit :
> Building callchain.c with !COMPAT proved quite ugly with all the
> defines. Splitting out the 32bit and 64bit parts looks better.
> 
> No code change intended.
> 
> Signed-off-by: Michal Suchanek <msuchanek@suse.de>

Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>

> ---
> v6:
>   - move current_is_64bit consolidetaion to earlier patch
>   - move defines to the top of callchain_32.c
>   - Makefile cleanup
> ---
>   arch/powerpc/perf/Makefile       |   5 +-
>   arch/powerpc/perf/callchain.c    | 371 +------------------------------
>   arch/powerpc/perf/callchain.h    |  11 +
>   arch/powerpc/perf/callchain_32.c | 204 +++++++++++++++++
>   arch/powerpc/perf/callchain_64.c | 185 +++++++++++++++
>   5 files changed, 405 insertions(+), 371 deletions(-)
>   create mode 100644 arch/powerpc/perf/callchain.h
>   create mode 100644 arch/powerpc/perf/callchain_32.c
>   create mode 100644 arch/powerpc/perf/callchain_64.c
> 
> diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
> index c155dcbb8691..53d614e98537 100644
> --- a/arch/powerpc/perf/Makefile
> +++ b/arch/powerpc/perf/Makefile
> @@ -1,6 +1,9 @@
>   # SPDX-License-Identifier: GPL-2.0
>   
> -obj-$(CONFIG_PERF_EVENTS)	+= callchain.o perf_regs.o
> +obj-$(CONFIG_PERF_EVENTS)	+= callchain.o callchain_$(BITS).o perf_regs.o
> +ifdef CONFIG_COMPAT
> +obj-$(CONFIG_PERF_EVENTS)	+= callchain_32.o
> +endif
>   
>   obj-$(CONFIG_PPC_PERF_CTRS)	+= core-book3s.o bhrb.o
>   obj64-$(CONFIG_PPC_PERF_CTRS)	+= ppc970-pmu.o power5-pmu.o \
> diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
> index 788ad2c63f18..8f30f1b47c78 100644
> --- a/arch/powerpc/perf/callchain.c
> +++ b/arch/powerpc/perf/callchain.c
> @@ -15,11 +15,9 @@
>   #include <asm/sigcontext.h>
>   #include <asm/ucontext.h>
>   #include <asm/vdso.h>
> -#ifdef CONFIG_COMPAT
> -#include "../kernel/ppc32.h"
> -#endif
>   #include <asm/pte-walk.h>
>   
> +#include "callchain.h"
>   
>   /*
>    * Is sp valid as the address of the next kernel stack frame after prev_sp?
> @@ -102,373 +100,6 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
>   	}
>   }
>   
> -#ifdef CONFIG_PPC64
> -/*
> - * On 64-bit we don't want to invoke hash_page on user addresses from
> - * interrupt context, so if the access faults, we read the page tables
> - * to find which page (if any) is mapped and access it directly.
> - */
> -static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
> -{
> -	int ret = -EFAULT;
> -	pgd_t *pgdir;
> -	pte_t *ptep, pte;
> -	unsigned shift;
> -	unsigned long addr = (unsigned long) ptr;
> -	unsigned long offset;
> -	unsigned long pfn, flags;
> -	void *kaddr;
> -
> -	pgdir = current->mm->pgd;
> -	if (!pgdir)
> -		return -EFAULT;
> -
> -	local_irq_save(flags);
> -	ptep = find_current_mm_pte(pgdir, addr, NULL, &shift);
> -	if (!ptep)
> -		goto err_out;
> -	if (!shift)
> -		shift = PAGE_SHIFT;
> -
> -	/* align address to page boundary */
> -	offset = addr & ((1UL << shift) - 1);
> -
> -	pte = READ_ONCE(*ptep);
> -	if (!pte_present(pte) || !pte_user(pte))
> -		goto err_out;
> -	pfn = pte_pfn(pte);
> -	if (!page_is_ram(pfn))
> -		goto err_out;
> -
> -	/* no highmem to worry about here */
> -	kaddr = pfn_to_kaddr(pfn);
> -	memcpy(buf, kaddr + offset, nb);
> -	ret = 0;
> -err_out:
> -	local_irq_restore(flags);
> -	return ret;
> -}
> -
> -static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
> -{
> -	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) ||
> -	    ((unsigned long)ptr & 7))
> -		return -EFAULT;
> -
> -	pagefault_disable();
> -	if (!__get_user_inatomic(*ret, ptr)) {
> -		pagefault_enable();
> -		return 0;
> -	}
> -	pagefault_enable();
> -
> -	return read_user_stack_slow(ptr, ret, 8);
> -}
> -
> -static inline int valid_user_sp(unsigned long sp, int is_64)
> -{
> -	if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32)
> -		return 0;
> -	return 1;
> -}
> -
> -/*
> - * 64-bit user processes use the same stack frame for RT and non-RT signals.
> - */
> -struct signal_frame_64 {
> -	char		dummy[__SIGNAL_FRAMESIZE];
> -	struct ucontext	uc;
> -	unsigned long	unused[2];
> -	unsigned int	tramp[6];
> -	struct siginfo	*pinfo;
> -	void		*puc;
> -	struct siginfo	info;
> -	char		abigap[288];
> -};
> -
> -static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
> -{
> -	if (nip == fp + offsetof(struct signal_frame_64, tramp))
> -		return 1;
> -	if (vdso64_rt_sigtramp && current->mm->context.vdso_base &&
> -	    nip == current->mm->context.vdso_base + vdso64_rt_sigtramp)
> -		return 1;
> -	return 0;
> -}
> -
> -/*
> - * Do some sanity checking on the signal frame pointed to by sp.
> - * We check the pinfo and puc pointers in the frame.
> - */
> -static int sane_signal_64_frame(unsigned long sp)
> -{
> -	struct signal_frame_64 __user *sf;
> -	unsigned long pinfo, puc;
> -
> -	sf = (struct signal_frame_64 __user *) sp;
> -	if (read_user_stack_64((unsigned long __user *) &sf->pinfo, &pinfo) ||
> -	    read_user_stack_64((unsigned long __user *) &sf->puc, &puc))
> -		return 0;
> -	return pinfo == (unsigned long) &sf->info &&
> -		puc == (unsigned long) &sf->uc;
> -}
> -
> -static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
> -				   struct pt_regs *regs)
> -{
> -	unsigned long sp, next_sp;
> -	unsigned long next_ip;
> -	unsigned long lr;
> -	long level = 0;
> -	struct signal_frame_64 __user *sigframe;
> -	unsigned long __user *fp, *uregs;
> -
> -	next_ip = perf_instruction_pointer(regs);
> -	lr = regs->link;
> -	sp = regs->gpr[1];
> -	perf_callchain_store(entry, next_ip);
> -
> -	while (entry->nr < entry->max_stack) {
> -		fp = (unsigned long __user *) sp;
> -		if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp))
> -			return;
> -		if (level > 0 && read_user_stack_64(&fp[2], &next_ip))
> -			return;
> -
> -		/*
> -		 * Note: the next_sp - sp >= signal frame size check
> -		 * is true when next_sp < sp, which can happen when
> -		 * transitioning from an alternate signal stack to the
> -		 * normal stack.
> -		 */
> -		if (next_sp - sp >= sizeof(struct signal_frame_64) &&
> -		    (is_sigreturn_64_address(next_ip, sp) ||
> -		     (level <= 1 && is_sigreturn_64_address(lr, sp))) &&
> -		    sane_signal_64_frame(sp)) {
> -			/*
> -			 * This looks like an signal frame
> -			 */
> -			sigframe = (struct signal_frame_64 __user *) sp;
> -			uregs = sigframe->uc.uc_mcontext.gp_regs;
> -			if (read_user_stack_64(&uregs[PT_NIP], &next_ip) ||
> -			    read_user_stack_64(&uregs[PT_LNK], &lr) ||
> -			    read_user_stack_64(&uregs[PT_R1], &sp))
> -				return;
> -			level = 0;
> -			perf_callchain_store_context(entry, PERF_CONTEXT_USER);
> -			perf_callchain_store(entry, next_ip);
> -			continue;
> -		}
> -
> -		if (level == 0)
> -			next_ip = lr;
> -		perf_callchain_store(entry, next_ip);
> -		++level;
> -		sp = next_sp;
> -	}
> -}
> -
> -#else  /* CONFIG_PPC64 */
> -static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
> -{
> -	return 0;
> -}
> -#endif /* CONFIG_PPC64 */
> -
> -/*
> - * On 32-bit we just access the address and let hash_page create a
> - * HPTE if necessary, so there is no need to fall back to reading
> - * the page tables.  Since this is called at interrupt level,
> - * do_page_fault() won't treat a DSI as a page fault.
> - */
> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> -{
> -	int rc;
> -
> -	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> -	    ((unsigned long)ptr & 3))
> -		return -EFAULT;
> -
> -	pagefault_disable();
> -	rc = __get_user_inatomic(*ret, ptr);
> -	pagefault_enable();
> -
> -	if (IS_ENABLED(CONFIG_PPC64) && rc)
> -		return read_user_stack_slow(ptr, ret, 4);
> -	return rc;
> -}
> -
> -#ifndef CONFIG_PPC64
> -static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
> -					  struct pt_regs *regs)
> -{
> -}
> -
> -static inline int valid_user_sp(unsigned long sp, int is_64)
> -{
> -	if (!sp || (sp & 7) || sp > TASK_SIZE - 32)
> -		return 0;
> -	return 1;
> -}
> -
> -#define __SIGNAL_FRAMESIZE32	__SIGNAL_FRAMESIZE
> -#define sigcontext32		sigcontext
> -#define mcontext32		mcontext
> -#define ucontext32		ucontext
> -#define compat_siginfo_t	struct siginfo
> -
> -#endif /* CONFIG_PPC64 */
> -
> -#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
> -/*
> - * Layout for non-RT signal frames
> - */
> -struct signal_frame_32 {
> -	char			dummy[__SIGNAL_FRAMESIZE32];
> -	struct sigcontext32	sctx;
> -	struct mcontext32	mctx;
> -	int			abigap[56];
> -};
> -
> -/*
> - * Layout for RT signal frames
> - */
> -struct rt_signal_frame_32 {
> -	char			dummy[__SIGNAL_FRAMESIZE32 + 16];
> -	compat_siginfo_t	info;
> -	struct ucontext32	uc;
> -	int			abigap[56];
> -};
> -
> -static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
> -{
> -	if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
> -		return 1;
> -	if (vdso32_sigtramp && current->mm->context.vdso_base &&
> -	    nip == current->mm->context.vdso_base + vdso32_sigtramp)
> -		return 1;
> -	return 0;
> -}
> -
> -static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp)
> -{
> -	if (nip == fp + offsetof(struct rt_signal_frame_32,
> -				 uc.uc_mcontext.mc_pad))
> -		return 1;
> -	if (vdso32_rt_sigtramp && current->mm->context.vdso_base &&
> -	    nip == current->mm->context.vdso_base + vdso32_rt_sigtramp)
> -		return 1;
> -	return 0;
> -}
> -
> -static int sane_signal_32_frame(unsigned int sp)
> -{
> -	struct signal_frame_32 __user *sf;
> -	unsigned int regs;
> -
> -	sf = (struct signal_frame_32 __user *) (unsigned long) sp;
> -	if (read_user_stack_32((unsigned int __user *) &sf->sctx.regs, &regs))
> -		return 0;
> -	return regs == (unsigned long) &sf->mctx;
> -}
> -
> -static int sane_rt_signal_32_frame(unsigned int sp)
> -{
> -	struct rt_signal_frame_32 __user *sf;
> -	unsigned int regs;
> -
> -	sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
> -	if (read_user_stack_32((unsigned int __user *) &sf->uc.uc_regs, &regs))
> -		return 0;
> -	return regs == (unsigned long) &sf->uc.uc_mcontext;
> -}
> -
> -static unsigned int __user *signal_frame_32_regs(unsigned int sp,
> -				unsigned int next_sp, unsigned int next_ip)
> -{
> -	struct mcontext32 __user *mctx = NULL;
> -	struct signal_frame_32 __user *sf;
> -	struct rt_signal_frame_32 __user *rt_sf;
> -
> -	/*
> -	 * Note: the next_sp - sp >= signal frame size check
> -	 * is true when next_sp < sp, for example, when
> -	 * transitioning from an alternate signal stack to the
> -	 * normal stack.
> -	 */
> -	if (next_sp - sp >= sizeof(struct signal_frame_32) &&
> -	    is_sigreturn_32_address(next_ip, sp) &&
> -	    sane_signal_32_frame(sp)) {
> -		sf = (struct signal_frame_32 __user *) (unsigned long) sp;
> -		mctx = &sf->mctx;
> -	}
> -
> -	if (!mctx && next_sp - sp >= sizeof(struct rt_signal_frame_32) &&
> -	    is_rt_sigreturn_32_address(next_ip, sp) &&
> -	    sane_rt_signal_32_frame(sp)) {
> -		rt_sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
> -		mctx = &rt_sf->uc.uc_mcontext;
> -	}
> -
> -	if (!mctx)
> -		return NULL;
> -	return mctx->mc_gregs;
> -}
> -
> -static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> -				   struct pt_regs *regs)
> -{
> -	unsigned int sp, next_sp;
> -	unsigned int next_ip;
> -	unsigned int lr;
> -	long level = 0;
> -	unsigned int __user *fp, *uregs;
> -
> -	next_ip = perf_instruction_pointer(regs);
> -	lr = regs->link;
> -	sp = regs->gpr[1];
> -	perf_callchain_store(entry, next_ip);
> -
> -	while (entry->nr < entry->max_stack) {
> -		fp = (unsigned int __user *) (unsigned long) sp;
> -		if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp))
> -			return;
> -		if (level > 0 && read_user_stack_32(&fp[1], &next_ip))
> -			return;
> -
> -		uregs = signal_frame_32_regs(sp, next_sp, next_ip);
> -		if (!uregs && level <= 1)
> -			uregs = signal_frame_32_regs(sp, next_sp, lr);
> -		if (uregs) {
> -			/*
> -			 * This looks like an signal frame, so restart
> -			 * the stack trace with the values in it.
> -			 */
> -			if (read_user_stack_32(&uregs[PT_NIP], &next_ip) ||
> -			    read_user_stack_32(&uregs[PT_LNK], &lr) ||
> -			    read_user_stack_32(&uregs[PT_R1], &sp))
> -				return;
> -			level = 0;
> -			perf_callchain_store_context(entry, PERF_CONTEXT_USER);
> -			perf_callchain_store(entry, next_ip);
> -			continue;
> -		}
> -
> -		if (level == 0)
> -			next_ip = lr;
> -		perf_callchain_store(entry, next_ip);
> -		++level;
> -		sp = next_sp;
> -	}
> -}
> -#else /* 32bit */
> -static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> -				   struct pt_regs *regs)
> -{
> -	(void)&read_user_stack_32; /* unused if !COMPAT */
> -}
> -#endif /* 32bit */
> -
>   static inline int current_is_64bit(void)
>   {
>   	if (!IS_ENABLED(CONFIG_COMPAT))
> diff --git a/arch/powerpc/perf/callchain.h b/arch/powerpc/perf/callchain.h
> new file mode 100644
> index 000000000000..63ffb43f3668
> --- /dev/null
> +++ b/arch/powerpc/perf/callchain.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +#ifndef _POWERPC_PERF_CALLCHAIN_H
> +#define _POWERPC_PERF_CALLCHAIN_H
> +
> +int read_user_stack_slow(void __user *ptr, void *buf, int nb);
> +void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
> +			    struct pt_regs *regs);
> +void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> +			    struct pt_regs *regs);
> +
> +#endif /* _POWERPC_PERF_CALLCHAIN_H */
> diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c
> new file mode 100644
> index 000000000000..01a38d929078
> --- /dev/null
> +++ b/arch/powerpc/perf/callchain_32.c
> @@ -0,0 +1,204 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Performance counter callchain support - powerpc architecture code
> + *
> + * Copyright © 2009 Paul Mackerras, IBM Corporation.
> + */
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/perf_event.h>
> +#include <linux/percpu.h>
> +#include <linux/uaccess.h>
> +#include <linux/mm.h>
> +#include <asm/ptrace.h>
> +#include <asm/pgtable.h>
> +#include <asm/sigcontext.h>
> +#include <asm/ucontext.h>
> +#include <asm/vdso.h>
> +#include <asm/pte-walk.h>
> +
> +#include "callchain.h"
> +
> +#ifdef CONFIG_PPC64
> +#include "../kernel/ppc32.h"
> +#else  /* CONFIG_PPC64 */
> +
> +#define __SIGNAL_FRAMESIZE32	__SIGNAL_FRAMESIZE
> +#define sigcontext32		sigcontext
> +#define mcontext32		mcontext
> +#define ucontext32		ucontext
> +#define compat_siginfo_t	struct siginfo
> +
> +#endif /* CONFIG_PPC64 */
> +
> +/*
> + * On 32-bit we just access the address and let hash_page create a
> + * HPTE if necessary, so there is no need to fall back to reading
> + * the page tables.  Since this is called at interrupt level,
> + * do_page_fault() won't treat a DSI as a page fault.
> + */
> +static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> +{
> +	int rc;
> +
> +	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> +	    ((unsigned long)ptr & 3))
> +		return -EFAULT;
> +
> +	pagefault_disable();
> +	rc = __get_user_inatomic(*ret, ptr);
> +	pagefault_enable();
> +
> +	if (IS_ENABLED(CONFIG_PPC64) && rc)
> +		return read_user_stack_slow(ptr, ret, 4);
> +	return rc;
> +}
> +
> +static inline int valid_user_sp(unsigned long sp, int is_64)
> +{
> +	if (!sp || (sp & 7) || sp > TASK_SIZE - 32)
> +		return 0;
> +	return 1;
> +}
> +
> +/*
> + * Layout for non-RT signal frames
> + */
> +struct signal_frame_32 {
> +	char			dummy[__SIGNAL_FRAMESIZE32];
> +	struct sigcontext32	sctx;
> +	struct mcontext32	mctx;
> +	int			abigap[56];
> +};
> +
> +/*
> + * Layout for RT signal frames
> + */
> +struct rt_signal_frame_32 {
> +	char			dummy[__SIGNAL_FRAMESIZE32 + 16];
> +	compat_siginfo_t	info;
> +	struct ucontext32	uc;
> +	int			abigap[56];
> +};
> +
> +static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
> +{
> +	if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
> +		return 1;
> +	if (vdso32_sigtramp && current->mm->context.vdso_base &&
> +	    nip == current->mm->context.vdso_base + vdso32_sigtramp)
> +		return 1;
> +	return 0;
> +}
> +
> +static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp)
> +{
> +	if (nip == fp + offsetof(struct rt_signal_frame_32,
> +				 uc.uc_mcontext.mc_pad))
> +		return 1;
> +	if (vdso32_rt_sigtramp && current->mm->context.vdso_base &&
> +	    nip == current->mm->context.vdso_base + vdso32_rt_sigtramp)
> +		return 1;
> +	return 0;
> +}
> +
> +static int sane_signal_32_frame(unsigned int sp)
> +{
> +	struct signal_frame_32 __user *sf;
> +	unsigned int regs;
> +
> +	sf = (struct signal_frame_32 __user *) (unsigned long) sp;
> +	if (read_user_stack_32((unsigned int __user *) &sf->sctx.regs, &regs))
> +		return 0;
> +	return regs == (unsigned long) &sf->mctx;
> +}
> +
> +static int sane_rt_signal_32_frame(unsigned int sp)
> +{
> +	struct rt_signal_frame_32 __user *sf;
> +	unsigned int regs;
> +
> +	sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
> +	if (read_user_stack_32((unsigned int __user *) &sf->uc.uc_regs, &regs))
> +		return 0;
> +	return regs == (unsigned long) &sf->uc.uc_mcontext;
> +}
> +
> +static unsigned int __user *signal_frame_32_regs(unsigned int sp,
> +				unsigned int next_sp, unsigned int next_ip)
> +{
> +	struct mcontext32 __user *mctx = NULL;
> +	struct signal_frame_32 __user *sf;
> +	struct rt_signal_frame_32 __user *rt_sf;
> +
> +	/*
> +	 * Note: the next_sp - sp >= signal frame size check
> +	 * is true when next_sp < sp, for example, when
> +	 * transitioning from an alternate signal stack to the
> +	 * normal stack.
> +	 */
> +	if (next_sp - sp >= sizeof(struct signal_frame_32) &&
> +	    is_sigreturn_32_address(next_ip, sp) &&
> +	    sane_signal_32_frame(sp)) {
> +		sf = (struct signal_frame_32 __user *) (unsigned long) sp;
> +		mctx = &sf->mctx;
> +	}
> +
> +	if (!mctx && next_sp - sp >= sizeof(struct rt_signal_frame_32) &&
> +	    is_rt_sigreturn_32_address(next_ip, sp) &&
> +	    sane_rt_signal_32_frame(sp)) {
> +		rt_sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
> +		mctx = &rt_sf->uc.uc_mcontext;
> +	}
> +
> +	if (!mctx)
> +		return NULL;
> +	return mctx->mc_gregs;
> +}
> +
> +void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> +			    struct pt_regs *regs)
> +{
> +	unsigned int sp, next_sp;
> +	unsigned int next_ip;
> +	unsigned int lr;
> +	long level = 0;
> +	unsigned int __user *fp, *uregs;
> +
> +	next_ip = perf_instruction_pointer(regs);
> +	lr = regs->link;
> +	sp = regs->gpr[1];
> +	perf_callchain_store(entry, next_ip);
> +
> +	while (entry->nr < entry->max_stack) {
> +		fp = (unsigned int __user *) (unsigned long) sp;
> +		if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp))
> +			return;
> +		if (level > 0 && read_user_stack_32(&fp[1], &next_ip))
> +			return;
> +
> +		uregs = signal_frame_32_regs(sp, next_sp, next_ip);
> +		if (!uregs && level <= 1)
> +			uregs = signal_frame_32_regs(sp, next_sp, lr);
> +		if (uregs) {
> +			/*
> +			 * This looks like an signal frame, so restart
> +			 * the stack trace with the values in it.
> +			 */
> +			if (read_user_stack_32(&uregs[PT_NIP], &next_ip) ||
> +			    read_user_stack_32(&uregs[PT_LNK], &lr) ||
> +			    read_user_stack_32(&uregs[PT_R1], &sp))
> +				return;
> +			level = 0;
> +			perf_callchain_store_context(entry, PERF_CONTEXT_USER);
> +			perf_callchain_store(entry, next_ip);
> +			continue;
> +		}
> +
> +		if (level == 0)
> +			next_ip = lr;
> +		perf_callchain_store(entry, next_ip);
> +		++level;
> +		sp = next_sp;
> +	}
> +}
> diff --git a/arch/powerpc/perf/callchain_64.c b/arch/powerpc/perf/callchain_64.c
> new file mode 100644
> index 000000000000..60308c2221a8
> --- /dev/null
> +++ b/arch/powerpc/perf/callchain_64.c
> @@ -0,0 +1,185 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Performance counter callchain support - powerpc architecture code
> + *
> + * Copyright © 2009 Paul Mackerras, IBM Corporation.
> + */
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/perf_event.h>
> +#include <linux/percpu.h>
> +#include <linux/uaccess.h>
> +#include <linux/mm.h>
> +#include <asm/ptrace.h>
> +#include <asm/pgtable.h>
> +#include <asm/sigcontext.h>
> +#include <asm/ucontext.h>
> +#include <asm/vdso.h>
> +#include <asm/pte-walk.h>
> +
> +#include "callchain.h"
> +
> +/*
> + * On 64-bit we don't want to invoke hash_page on user addresses from
> + * interrupt context, so if the access faults, we read the page tables
> + * to find which page (if any) is mapped and access it directly.
> + */
> +int read_user_stack_slow(void __user *ptr, void *buf, int nb)
> +{
> +	int ret = -EFAULT;
> +	pgd_t *pgdir;
> +	pte_t *ptep, pte;
> +	unsigned int shift;
> +	unsigned long addr = (unsigned long) ptr;
> +	unsigned long offset;
> +	unsigned long pfn, flags;
> +	void *kaddr;
> +
> +	pgdir = current->mm->pgd;
> +	if (!pgdir)
> +		return -EFAULT;
> +
> +	local_irq_save(flags);
> +	ptep = find_current_mm_pte(pgdir, addr, NULL, &shift);
> +	if (!ptep)
> +		goto err_out;
> +	if (!shift)
> +		shift = PAGE_SHIFT;
> +
> +	/* align address to page boundary */
> +	offset = addr & ((1UL << shift) - 1);
> +
> +	pte = READ_ONCE(*ptep);
> +	if (!pte_present(pte) || !pte_user(pte))
> +		goto err_out;
> +	pfn = pte_pfn(pte);
> +	if (!page_is_ram(pfn))
> +		goto err_out;
> +
> +	/* no highmem to worry about here */
> +	kaddr = pfn_to_kaddr(pfn);
> +	memcpy(buf, kaddr + offset, nb);
> +	ret = 0;
> +err_out:
> +	local_irq_restore(flags);
> +	return ret;
> +}
> +
> +static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
> +{
> +	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) ||
> +	    ((unsigned long)ptr & 7))
> +		return -EFAULT;
> +
> +	pagefault_disable();
> +	if (!__get_user_inatomic(*ret, ptr)) {
> +		pagefault_enable();
> +		return 0;
> +	}
> +	pagefault_enable();
> +
> +	return read_user_stack_slow(ptr, ret, 8);
> +}
> +
> +static inline int valid_user_sp(unsigned long sp, int is_64)
> +{
> +	if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32)
> +		return 0;
> +	return 1;
> +}
> +
> +/*
> + * 64-bit user processes use the same stack frame for RT and non-RT signals.
> + */
> +struct signal_frame_64 {
> +	char		dummy[__SIGNAL_FRAMESIZE];
> +	struct ucontext	uc;
> +	unsigned long	unused[2];
> +	unsigned int	tramp[6];
> +	struct siginfo	*pinfo;
> +	void		*puc;
> +	struct siginfo	info;
> +	char		abigap[288];
> +};
> +
> +static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
> +{
> +	if (nip == fp + offsetof(struct signal_frame_64, tramp))
> +		return 1;
> +	if (vdso64_rt_sigtramp && current->mm->context.vdso_base &&
> +	    nip == current->mm->context.vdso_base + vdso64_rt_sigtramp)
> +		return 1;
> +	return 0;
> +}
> +
> +/*
> + * Do some sanity checking on the signal frame pointed to by sp.
> + * We check the pinfo and puc pointers in the frame.
> + */
> +static int sane_signal_64_frame(unsigned long sp)
> +{
> +	struct signal_frame_64 __user *sf;
> +	unsigned long pinfo, puc;
> +
> +	sf = (struct signal_frame_64 __user *) sp;
> +	if (read_user_stack_64((unsigned long __user *) &sf->pinfo, &pinfo) ||
> +	    read_user_stack_64((unsigned long __user *) &sf->puc, &puc))
> +		return 0;
> +	return pinfo == (unsigned long) &sf->info &&
> +		puc == (unsigned long) &sf->uc;
> +}
> +
> +void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
> +			    struct pt_regs *regs)
> +{
> +	unsigned long sp, next_sp;
> +	unsigned long next_ip;
> +	unsigned long lr;
> +	long level = 0;
> +	struct signal_frame_64 __user *sigframe;
> +	unsigned long __user *fp, *uregs;
> +
> +	next_ip = perf_instruction_pointer(regs);
> +	lr = regs->link;
> +	sp = regs->gpr[1];
> +	perf_callchain_store(entry, next_ip);
> +
> +	while (entry->nr < entry->max_stack) {
> +		fp = (unsigned long __user *) sp;
> +		if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp))
> +			return;
> +		if (level > 0 && read_user_stack_64(&fp[2], &next_ip))
> +			return;
> +
> +		/*
> +		 * Note: the next_sp - sp >= signal frame size check
> +		 * is true when next_sp < sp, which can happen when
> +		 * transitioning from an alternate signal stack to the
> +		 * normal stack.
> +		 */
> +		if (next_sp - sp >= sizeof(struct signal_frame_64) &&
> +		    (is_sigreturn_64_address(next_ip, sp) ||
> +		     (level <= 1 && is_sigreturn_64_address(lr, sp))) &&
> +		    sane_signal_64_frame(sp)) {
> +			/*
> +			 * This looks like an signal frame
> +			 */
> +			sigframe = (struct signal_frame_64 __user *) sp;
> +			uregs = sigframe->uc.uc_mcontext.gp_regs;
> +			if (read_user_stack_64(&uregs[PT_NIP], &next_ip) ||
> +			    read_user_stack_64(&uregs[PT_LNK], &lr) ||
> +			    read_user_stack_64(&uregs[PT_R1], &sp))
> +				return;
> +			level = 0;
> +			perf_callchain_store_context(entry, PERF_CONTEXT_USER);
> +			perf_callchain_store(entry, next_ip);
> +			continue;
> +		}
> +
> +		if (level == 0)
> +			next_ip = lr;
> +		perf_callchain_store(entry, next_ip);
> +		++level;
> +		sp = next_sp;
> +	}
> +}
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
       [not found]       ` <20190830202959.3539-1-msuchanek@suse.de>
@ 2019-08-30 20:32         ` Arnd Bergmann
  0 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2019-08-30 20:32 UTC (permalink / raw)
  To: Michal Suchanek
  Cc: Heiko Carstens, Allison Randal, Linux Kernel Mailing List,
	Paul Mackerras, Alexander Viro, Greg Kroah-Hartman,
	Linux FS-devel Mailing List, Firoz Khan, Thomas Gleixner,
	linuxppc-dev, Christian Brauner

On Fri, Aug 30, 2019 at 10:30 PM Michal Suchanek <msuchanek@suse.de> wrote:
>
> Subject: [PATCH] powerpc: Add back __ARCH_WANT_SYS_LLSEEK macro
>
> This partially reverts commit caf6f9c8a326 ("asm-generic: Remove
> unneeded __ARCH_WANT_SYS_LLSEEK macro")
>
> When CONFIG_COMPAT is disabled on ppc64 the kernel does not build.
>
> There is resistance to both removing the llseek syscall from the 64bit
> syscall tables and building the llseek interface unconditionally.
>
> Link: https://lore.kernel.org/lkml/20190828151552.GA16855@infradead.org/
> Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/
>
> Signed-off-by: Michal Suchanek <msuchanek@suse.de>

Reviewed-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 4/6] powerpc/64: make buildable without CONFIG_COMPAT
  2019-08-30 20:21   ` Christophe Leroy
@ 2019-08-30 20:35     ` Michal Suchánek
  0 siblings, 0 replies; 41+ messages in thread
From: Michal Suchánek @ 2019-08-30 20:35 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Michael Neuling, Arnd Bergmann, Nicolai Stange,
	David Hildenbrand, Greg Kroah-Hartman, Andrew Donnellan,
	Heiko Carstens, linux-kernel, Nicholas Piggin, David Howells,
	Hari Bathini, Paul Mackerras, Joel Stanley, Christian Brauner,
	Firoz Khan, Breno Leitao, Geert Uytterhoeven, Thomas Gleixner,
	linuxppc-dev, Allison Randal, Eric W. Biederman

On Fri, 30 Aug 2019 22:21:09 +0200
Christophe Leroy <christophe.leroy@c-s.fr> wrote:

> Le 30/08/2019 à 20:57, Michal Suchanek a écrit :
> > There are numerous references to 32bit functions in generic and 64bit
> > code so ifdef them out.
> > 
> > Signed-off-by: Michal Suchanek <msuchanek@suse.de>
> > ---
> > v2:
> > - fix 32bit ifdef condition in signal.c
> > - simplify the compat ifdef condition in vdso.c - 64bit is redundant
> > - simplify the compat ifdef condition in callchain.c - 64bit is redundant
> > v3:
> > - use IS_ENABLED and maybe_unused where possible
> > - do not ifdef declarations
> > - clean up Makefile
> > v4:
> > - further makefile cleanup
> > - simplify is_32bit_task conditions
> > - avoid ifdef in condition by using return
> > v5:
> > - avoid unreachable code on 32bit
> > - make is_current_64bit constant on !COMPAT
> > - add stub perf_callchain_user_32 to avoid some ifdefs
> > v6:
> > - consolidate current_is_64bit
> > ---
> >   arch/powerpc/include/asm/thread_info.h |  4 +--
> >   arch/powerpc/kernel/Makefile           |  7 +++--
> >   arch/powerpc/kernel/entry_64.S         |  2 ++
> >   arch/powerpc/kernel/signal.c           |  3 +--
> >   arch/powerpc/kernel/syscall_64.c       |  6 ++---
> >   arch/powerpc/kernel/vdso.c             |  5 ++--
> >   arch/powerpc/perf/callchain.c          | 37 +++++++++++++++-----------
> >   7 files changed, 33 insertions(+), 31 deletions(-)
> >   
> 
> [...]
> 
> > diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
> > index b7cdcce20280..788ad2c63f18 100644
> > --- a/arch/powerpc/perf/callchain.c
> > +++ b/arch/powerpc/perf/callchain.c
> > @@ -15,7 +15,7 @@
> >   #include <asm/sigcontext.h>
> >   #include <asm/ucontext.h>
> >   #include <asm/vdso.h>
> > -#ifdef CONFIG_PPC64
> > +#ifdef CONFIG_COMPAT
> >   #include "../kernel/ppc32.h"
> >   #endif
> >   #include <asm/pte-walk.h>
> > @@ -268,16 +268,6 @@ static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
> >   	}
> >   }
> >   
> > -static inline int current_is_64bit(void)
> > -{
> > -	/*
> > -	 * We can't use test_thread_flag() here because we may be on an
> > -	 * interrupt stack, and the thread flags don't get copied over
> > -	 * from the thread_info on the main stack to the interrupt stack.
> > -	 */
> > -	return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> > -}
> > -
> >   #else  /* CONFIG_PPC64 */
> >   static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
> >   {
> > @@ -314,11 +304,6 @@ static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry
> >   {
> >   }
> >   
> > -static inline int current_is_64bit(void)
> > -{
> > -	return 0;
> > -}
> > -
> >   static inline int valid_user_sp(unsigned long sp, int is_64)
> >   {
> >   	if (!sp || (sp & 7) || sp > TASK_SIZE - 32)
> > @@ -334,6 +319,7 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
> >   
> >   #endif /* CONFIG_PPC64 */
> >   
> > +#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
> >   /*
> >    * Layout for non-RT signal frames
> >    */
> > @@ -475,6 +461,25 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> >   		sp = next_sp;
> >   	}
> >   }
> > +#else /* 32bit */
> > +static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> > +				   struct pt_regs *regs)
> > +{
> > +	(void)&read_user_stack_32; /* unused if !COMPAT */  
> 
> You don't need that anymore do you ?

Yes, this part is not needed. It was removed later anyway but this
state is broken.

Thanks

Michal

> 
> Christophe
> 
> > +}
> > +#endif /* 32bit */
> > +
> > +static inline int current_is_64bit(void)
> > +{
> > +	if (!IS_ENABLED(CONFIG_COMPAT))
> > +		return IS_ENABLED(CONFIG_PPC64);
> > +	/*
> > +	 * We can't use test_thread_flag() here because we may be on an
> > +	 * interrupt stack, and the thread flags don't get copied over
> > +	 * from the thread_info on the main stack to the interrupt stack.
> > +	 */
> > +	return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> > +}
> >   
> >   void
> >   perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
> >   


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro"
  2019-08-30 20:13       ` Michal Suchánek
@ 2019-08-30 20:37         ` Arnd Bergmann
  0 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2019-08-30 20:37 UTC (permalink / raw)
  To: Michal Suchánek
  Cc: Rich Felker, Linux-sh list, Heiko Carstens, linux-mips,
	James E.J. Bottomley, Max Filippov, Guo Ren, H. Peter Anvin,
	sparclinux, Vincenzo Frascino, Will Deacon, linux-arch,
	linux-s390, Yoshinori Sato, Helge Deller,
	the arch/x86 maintainers, Russell King, Christian Borntraeger,
	Ingo Molnar, Geert Uytterhoeven, Linux ARM, Catalin Marinas,
	James Hogan, Firoz Khan, linux-xtensa, Vasily Gorbik, linux-m68k,
	Borislav Petkov, Alexander Viro, David Howells, Thomas Gleixner,
	Christian Brauner, Chris Zankel, Michal Simek, Parisc List,
	Greg Kroah-Hartman, Linux Kernel Mailing List, Ralf Baechle,
	Paul Burton, Linux FS-devel Mailing List, Paul Mackerras,
	linuxppc-dev, David S. Miller

On Fri, Aug 30, 2019 at 10:13 PM Michal Suchánek <msuchanek@suse.de> wrote:
> On Fri, 30 Aug 2019 21:54:43 +0200
> Arnd Bergmann <arnd@arndb.de> wrote:
> > > index 5bbf587f5bc1..2f3c4bb138c4 100644
> > > --- a/fs/read_write.c
> > > +++ b/fs/read_write.c
> > > @@ -331,7 +331,7 @@ COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, compat_off_t, offset, unsigned i
> > >  }
> > >  #endif
> > >
> > > -#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
> > > +#ifdef __ARCH_WANT_SYS_LLSEEK
> > >  SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
> > >                 unsigned long, offset_low, loff_t __user *, result,
> > >                 unsigned int, whence)
> >
> > However, only reverting the patch will now break all newly added
> > 32-bit architectures that don't define __ARCH_WANT_SYS_LLSEEK:
> > at least nds32 and riscv32 come to mind, not sure if there is another.
>
> AFAICT nds32 never had the syscall. Its headers were added without
> __ARCH_WANT_SYS_LLSEEK before the define was removed.

nds32 got it from include/asm-generic/unistd.h

        Arnd

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro"
  2019-08-30 19:54     ` Arnd Bergmann
  2019-08-30 20:13       ` Michal Suchánek
       [not found]       ` <20190830202959.3539-1-msuchanek@suse.de>
@ 2019-08-31  8:38       ` Christoph Hellwig
  2019-08-31 13:44         ` Arnd Bergmann
  2 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-08-31  8:38 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rich Felker, Linux-sh list, Heiko Carstens,
	Linux Kernel Mailing List, James E.J. Bottomley, Max Filippov,
	Guo Ren, H. Peter Anvin, sparclinux, Vincenzo Frascino,
	Will Deacon, linux-arch, linux-s390, Yoshinori Sato,
	Helge Deller, the arch/x86 maintainers, Russell King,
	Christian Borntraeger, Ingo Molnar, Geert Uytterhoeven,
	Christian Brauner, Catalin Marinas, James Hogan, Firoz Khan,
	Michal Suchanek, linux-xtensa, Vasily Gorbik, Chris Zankel,
	linux-m68k, Borislav Petkov, Alexander Viro, Thomas Gleixner,
	Linux ARM, David Howells, Michal Simek, Parisc List,
	Greg Kroah-Hartman, linux-mips, Ralf Baechle, Paul Burton,
	Linux FS-devel Mailing List, Paul Mackerras, linuxppc-dev,
	David S. Miller

On Fri, Aug 30, 2019 at 09:54:43PM +0200, Arnd Bergmann wrote:
> > -#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
> > +#ifdef __ARCH_WANT_SYS_LLSEEK
> >  SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
> >                 unsigned long, offset_low, loff_t __user *, result,
> >                 unsigned int, whence)
> 
> However, only reverting the patch will now break all newly added
> 32-bit architectures that don't define __ARCH_WANT_SYS_LLSEEK:
> at least nds32 and riscv32 come to mind, not sure if there is another.
> 
> I think the easiest way however would be to combine the two checks
> above and make it
> 
> #if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) ||
> defined(__ARCH_WANT_SYS_LLSEEK)
> 
> and then only set __ARCH_WANT_SYS_LLSEEK for powerpc.

I'd much rather introduce a CONFIG_SYS_LLSEEK Kconfig symbol, selected
by CONFIG_64BIT and CONFIG_COMPAT by default, plus manually by powerpc.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro"
  2019-08-31  8:38       ` [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro" Christoph Hellwig
@ 2019-08-31 13:44         ` Arnd Bergmann
  0 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2019-08-31 13:44 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Rich Felker, Linux-sh list, Heiko Carstens,
	Linux Kernel Mailing List, James E.J. Bottomley, Max Filippov,
	Guo Ren, H. Peter Anvin, sparclinux, Vincenzo Frascino,
	Will Deacon, linux-arch, linux-s390, Yoshinori Sato,
	Helge Deller, the arch/x86 maintainers, Russell King,
	Christian Borntraeger, Ingo Molnar, Geert Uytterhoeven,
	Christian Brauner, Catalin Marinas, James Hogan, Firoz Khan,
	Michal Suchanek, linux-xtensa, Vasily Gorbik, Chris Zankel,
	Nitesh Kataria, linux-m68k, Borislav Petkov, Alexander Viro,
	Thomas Gleixner, Linux ARM, David Howells, Michal Simek,
	Parisc List, Greg Kroah-Hartman, linux-mips, Ralf Baechle,
	Paul Burton, Linux FS-devel Mailing List, Paul Mackerras,
	linuxppc-dev, David S. Miller

On Sat, Aug 31, 2019 at 10:39 AM Christoph Hellwig <hch@infradead.org> wrote:
>
> On Fri, Aug 30, 2019 at 09:54:43PM +0200, Arnd Bergmann wrote:
> > > -#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
> > > +#ifdef __ARCH_WANT_SYS_LLSEEK
> > >  SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
> > >                 unsigned long, offset_low, loff_t __user *, result,
> > >                 unsigned int, whence)
> >
> > However, only reverting the patch will now break all newly added
> > 32-bit architectures that don't define __ARCH_WANT_SYS_LLSEEK:
> > at least nds32 and riscv32 come to mind, not sure if there is another.
> >
> > I think the easiest way however would be to combine the two checks
> > above and make it
> >
> > #if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) ||
> > defined(__ARCH_WANT_SYS_LLSEEK)
> >
> > and then only set __ARCH_WANT_SYS_LLSEEK for powerpc.
>
> I'd much rather introduce a CONFIG_SYS_LLSEEK Kconfig symbol, selected
> by CONFIG_64BIT and CONFIG_COMPAT by default, plus manually by powerpc.

The reason we currently use  __ARCH_WANT_SYS_* for all the other conditional
system calls is that these macros can be put into the uapi file for use by
include/uapi/asm/unistd.h, which is not possible with CONFIG_*
symbols.

This is not a problem for llseek, but it would be slightly inconsistent.

Nitesh is trying to convert include/uapi/asm/unistd.h into syscall.tbl format,
after that is done, we can probably change all the __ARCH_WANT_SYS_*
into config symbols.

       Arnd

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness
  2019-08-30 19:06   ` Michal Suchánek
@ 2019-09-02  2:51     ` Michael Ellerman
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Ellerman @ 2019-09-02  2:51 UTC (permalink / raw)
  To: Michal Suchánek, linuxppc-dev
  Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
	Breno Leitao, Michael Neuling, Nicolai Stange,
	Geert Uytterhoeven, Allison Randal, Firoz Khan, Joel Stanley,
	Arnd Bergmann, Nicholas Piggin, Thomas Gleixner,
	Christian Brauner, Greg Kroah-Hartman, linux-kernel,
	Eric W. Biederman, Andrew Donnellan, Hari Bathini

Michal Suchánek <msuchanek@suse.de> writes:
> On Fri, 30 Aug 2019 20:57:57 +0200
> Michal Suchanek <msuchanek@suse.de> wrote:
>
>> Building callchain.c with !COMPAT proved quite ugly with all the
>> defines. Splitting out the 32bit and 64bit parts looks better.
>> 
>
> BTW the powerpc callchain.c does not match any of the patterns of PERF
> CORE in MAINTAINERS (unlike callchain implementation on other
> platforms). Is that intentional?

No.

cheers

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2022-04-22 15:53           ` Thomas Gleixner
@ 2022-04-23  2:29             ` Nicholas Piggin
  0 siblings, 0 replies; 41+ messages in thread
From: Nicholas Piggin @ 2022-04-23  2:29 UTC (permalink / raw)
  To: Michael Ellerman, paulmck, Thomas Gleixner, Zhouyi Zhou
  Cc: Viresh
	 Kumar,
	Daniel
	 Lezcano, linux-kernel, rcu, Miguel Ojeda, linuxppc-dev

Excerpts from Thomas Gleixner's message of April 23, 2022 1:53 am:
> On Wed, Apr 13 2022 at 15:11, Nicholas Piggin wrote:
>> So we traced the problem down to possibly a misunderstanding between 
>> decrementer clock event device and core code.
>>
>> The decrementer is only oneshot*ish*. It actually needs to either be 
>> reprogrammed or shut down otherwise it just continues to cause 
>> interrupts.
> 
> I always thought that PPC had sane timers. That's really disillusioning.

My comment was probably a bit misleading explanation of the whole
situation. This weirdness is actually in software in the powerpc
clock event driver due to a recent change I made assuming the clock 
event goes to oneshot-stopped.

The hardware is relatively sane I think, global synchronized constant
rate high frequency clock distributed to the CPUs so reads don't
go off-core. And per-CPU "decrementer" event interrupt at the same
frequency as the clock -- program it to a +ve value and it decrements
until zero then creates basically a level triggered interrupt.

Before my change, the decrementer interrupt would always clear the
interrupt at entry. The event_handler usually programs another
timer in so I tried to avoid that first clear counting on the
oneshot_stopped callback to clear the interrupt if there was no
other timer.

>> Before commit 35de589cb879, it was sort of two-shot. The initial 
>> interrupt at the programmed time would set its internal next_tb variable 
>> to ~0 and call the ->event_handler(). If that did not set_next_event or 
>> stop the timer, the interrupt will fire again immediately, notice 
>> next_tb is ~0, and only then stop the decrementer interrupt.
>>
>> So that was already kind of ugly, this patch just turned it into a hang.
>>
>> The problem happens when the tick is stopped with an event still 
>> pending, then tick_nohz_handler() is called, but it bails out because 
>> tick_stopped == 1 so the device never gets programmed again, and so it 
>> keeps firing.
>>
>> How to fix it? Before commit a7cba02deced, powerpc's decrementer was 
>> really oneshot, but we would like to avoid doing that because it requires 
>> additional programming of the hardware on each timer interrupt. We have 
>> the ONESHOT_STOPPED state which seems to be just about what we want.
>>
>> Did the ONESHOT_STOPPED patch just miss this case, or is there a reason 
>> we don't stop it here? This patch seems to fix the hang (not heavily
>> tested though).
> 
> This was definitely overlooked, but it's arguable it is is not required
> for real oneshot clockevent devices. This should only handle the case
> where the interrupt was already pending.
> 
> The ONESHOT_STOPPED state was introduced to handle the case where the
> last timer gets canceled, so the already programmed event does not fire.
> 
> It was not necessarily meant to "fix" clockevent devices which are
> pretending to be ONESHOT, but keep firing over and over.
> 
> That, said. I'm fine with the change along with a big fat comment why
> this is required.

Thanks for taking a look and confirming. I just sent a patch with a
comment and what looks like another missed case. Hopefully it's okay.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2022-04-13  5:11         ` Nicholas Piggin
@ 2022-04-22 15:53           ` Thomas Gleixner
  2022-04-23  2:29             ` Re: Nicholas Piggin
  0 siblings, 1 reply; 41+ messages in thread
From: Thomas Gleixner @ 2022-04-22 15:53 UTC (permalink / raw)
  To: Nicholas Piggin, Michael Ellerman, paulmck, Zhouyi Zhou
  Cc: Viresh Kumar, Daniel Lezcano, linux-kernel, rcu, Miguel Ojeda,
	linuxppc-dev

On Wed, Apr 13 2022 at 15:11, Nicholas Piggin wrote:
> So we traced the problem down to possibly a misunderstanding between 
> decrementer clock event device and core code.
>
> The decrementer is only oneshot*ish*. It actually needs to either be 
> reprogrammed or shut down otherwise it just continues to cause 
> interrupts.

I always thought that PPC had sane timers. That's really disillusioning.

> Before commit 35de589cb879, it was sort of two-shot. The initial 
> interrupt at the programmed time would set its internal next_tb variable 
> to ~0 and call the ->event_handler(). If that did not set_next_event or 
> stop the timer, the interrupt will fire again immediately, notice 
> next_tb is ~0, and only then stop the decrementer interrupt.
>
> So that was already kind of ugly, this patch just turned it into a hang.
>
> The problem happens when the tick is stopped with an event still 
> pending, then tick_nohz_handler() is called, but it bails out because 
> tick_stopped == 1 so the device never gets programmed again, and so it 
> keeps firing.
>
> How to fix it? Before commit a7cba02deced, powerpc's decrementer was 
> really oneshot, but we would like to avoid doing that because it requires 
> additional programming of the hardware on each timer interrupt. We have 
> the ONESHOT_STOPPED state which seems to be just about what we want.
>
> Did the ONESHOT_STOPPED patch just miss this case, or is there a reason 
> we don't stop it here? This patch seems to fix the hang (not heavily
> tested though).

This was definitely overlooked, but it's arguable it is is not required
for real oneshot clockevent devices. This should only handle the case
where the interrupt was already pending.

The ONESHOT_STOPPED state was introduced to handle the case where the
last timer gets canceled, so the already programmed event does not fire.

It was not necessarily meant to "fix" clockevent devices which are
pretending to be ONESHOT, but keep firing over and over.

That, said. I'm fine with the change along with a big fat comment why
this is required.

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2010-10-18 17:26 ` [PATCH 1/7] microblaze: pci-common cleanup Nishanth Aravamudan
  2010-10-20  5:31   ` Michal Simek
@ 2010-11-01  6:29   ` Michal Simek
  1 sibling, 0 replies; 41+ messages in thread
From: Michal Simek @ 2010-11-01  6:29 UTC (permalink / raw)
  To: microblaze-uclinux; +Cc: nacc, linuxppc-dev, miltonm

Hi,

Nishanth Aravamudan wrote:
> Use set_dma_ops and remove now used-once oddly named temp pointer sd.
> 
> Signed-off-by: Milton Miller <miltonm@bga.com>
> Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
> Cc: benh@kernel.crashing.org
> Cc: linuxppc-dev@lists.ozlabs.org
> ---
>  arch/microblaze/pci/pci-common.c |    6 ++----
>  1 files changed, 2 insertions(+), 4 deletions(-)

Is there any reason why you are sending me this patch again and again?
Please STOP doing this!
This patch was added to the mainline last week.

Regards,
Michal

-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2010-10-18 17:26 ` [PATCH 1/7] microblaze: pci-common cleanup Nishanth Aravamudan
@ 2010-10-20  5:31   ` Michal Simek
  2010-11-01  6:29   ` Re: Michal Simek
  1 sibling, 0 replies; 41+ messages in thread
From: Michal Simek @ 2010-10-20  5:31 UTC (permalink / raw)
  To: microblaze-uclinux; +Cc: nacc, linuxppc-dev, miltonm

Nishanth Aravamudan wrote:
> Use set_dma_ops and remove now used-once oddly named temp pointer sd.
> 
> Signed-off-by: Milton Miller <miltonm@bga.com>
> Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
> Cc: benh@kernel.crashing.org
> Cc: linuxppc-dev@lists.ozlabs.org
> ---

Maybe I forget to write you that this patch is already applied.
http://git.monstr.eu/git/gitweb.cgi?p=linux-2.6-microblaze.git;a=commit;h=9a6df6cbfd903b6d9b4b1021f46d78601adfac77


Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE:
  2010-09-02  6:14 ` Re: Wolfgang Denk
  2010-09-02 14:51   ` Rupjyoti Sarmah
@ 2010-09-07  6:29   ` Rupjyoti Sarmah
  1 sibling, 0 replies; 41+ messages in thread
From: Rupjyoti Sarmah @ 2010-09-07  6:29 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: linuxppc-dev, Prodyut Hazarika, Mark Miesfeld

Hi Wolfgang,

The current mainline 2.6.36-rc3 does not report any error while building
the SATA driver.

Regards,
Rup


-----Original Message-----
From: Rupjyoti Sarmah [mailto:rsarmah@apm.com]
Sent: Thursday, September 02, 2010 8:22 PM
To: 'Wolfgang Denk'
Cc: 'linuxppc-dev@ozlabs.org'; 'Prodyut Hazarika'; 'Mark Miesfeld'
Subject: RE:

Hi Wolfgang,

Sorry that I did not have a chance to check it recently.

Regards,
Rup

-----Original Message-----
From: Wolfgang Denk [mailto:wd@denx.de]
Sent: Thursday, September 02, 2010 11:44 AM
To: Rupjyoti Sarmah; Prodyut Hazarika; Mark Miesfeld
Cc: linuxppc-dev@ozlabs.org
Subject: Re:

Dear Rupjyoti, Prodyut, Mark,

two weeks ago I wrote:

In message <20100818205646.57783157D71@gemini.denx.de> you wrote:
>
> drivers/ata/sata_dwc_460ex.c fails to build in current mainline:
...
> Do you have any hints how to fix that?

Any comments or ideas how to fix this?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Time is an illusion perpetrated by the manufacturers of space.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE:
  2010-09-02  6:14 ` Re: Wolfgang Denk
@ 2010-09-02 14:51   ` Rupjyoti Sarmah
  2010-09-07  6:29   ` RE: Rupjyoti Sarmah
  1 sibling, 0 replies; 41+ messages in thread
From: Rupjyoti Sarmah @ 2010-09-02 14:51 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: linuxppc-dev, Prodyut Hazarika, Mark Miesfeld

Hi Wolfgang,

Sorry that I did not have a chance to check it recently.

Regards,
Rup

-----Original Message-----
From: Wolfgang Denk [mailto:wd@denx.de]
Sent: Thursday, September 02, 2010 11:44 AM
To: Rupjyoti Sarmah; Prodyut Hazarika; Mark Miesfeld
Cc: linuxppc-dev@ozlabs.org
Subject: Re:

Dear Rupjyoti, Prodyut, Mark,

two weeks ago I wrote:

In message <20100818205646.57783157D71@gemini.denx.de> you wrote:
>
> drivers/ata/sata_dwc_460ex.c fails to build in current mainline:
...
> Do you have any hints how to fix that?

Any comments or ideas how to fix this?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Time is an illusion perpetrated by the manufacturers of space.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2010-08-18 20:56 Wolfgang Denk
  2010-08-19  1:04 ` Stephen Rothwell
@ 2010-09-02  6:14 ` Wolfgang Denk
  2010-09-02 14:51   ` Rupjyoti Sarmah
  2010-09-07  6:29   ` RE: Rupjyoti Sarmah
  1 sibling, 2 replies; 41+ messages in thread
From: Wolfgang Denk @ 2010-09-02  6:14 UTC (permalink / raw)
  To: Rupjyoti Sarmah, Prodyut Hazarika, Mark Miesfeld; +Cc: linuxppc-dev

Dear Rupjyoti, Prodyut, Mark,

two weeks ago I wrote:

In message <20100818205646.57783157D71@gemini.denx.de> you wrote:
> 
> drivers/ata/sata_dwc_460ex.c fails to build in current mainline:
...
> Do you have any hints how to fix that?

Any comments or ideas how to fix this?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Time is an illusion perpetrated by the manufacturers of space.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2010-08-18 20:56 Wolfgang Denk
@ 2010-08-19  1:04 ` Stephen Rothwell
  2010-09-02  6:14 ` Re: Wolfgang Denk
  1 sibling, 0 replies; 41+ messages in thread
From: Stephen Rothwell @ 2010-08-19  1:04 UTC (permalink / raw)
  To: Wolfgang Denk
  Cc: linuxppc-dev, Rupjyoti Sarmah, Prodyut Hazarika, Mark Miesfeld

[-- Attachment #1: Type: text/plain, Size: 2597 bytes --]

Hi Wolfgang,

On Wed, 18 Aug 2010 22:56:46 +0200 Wolfgang Denk <wd@denx.de> wrote:
>
> drivers/ata/sata_dwc_460ex.c: At top level:
> drivers/ata/sata_dwc_460ex.c:1592: warning: 'struct of_device' declared inside parameter list
> drivers/ata/sata_dwc_460ex.c:1592: warning: its scope is only this definition or declaration, which is probably not what you want
> drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_probe':
> drivers/ata/sata_dwc_460ex.c:1607: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1614: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1616: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1622: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1628: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1630: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1646: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1650: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1652: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1658: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1660: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1667: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1676: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1678: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1691: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1693: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c: At top level:
> drivers/ata/sata_dwc_460ex.c:1705: warning: 'struct of_device' declared inside parameter list
> drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_remove':
> drivers/ata/sata_dwc_460ex.c:1707: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c:1720: error: dereferencing pointer to incomplete type
> drivers/ata/sata_dwc_460ex.c: At top level:
> drivers/ata/sata_dwc_460ex.c:1736: warning: initialization from incompatible pointer type
> drivers/ata/sata_dwc_460ex.c:1737: warning: initialization from incompatible pointer type

I think most of these (if not all) are fixed in Linus' tree today.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2009-07-23 14:38 Solomon Peachy
@ 2009-07-26 23:38 ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 41+ messages in thread
From: Benjamin Herrenschmidt @ 2009-07-26 23:38 UTC (permalink / raw)
  To: Solomon Peachy; +Cc: linuxppc-dev

On Thu, 2009-07-23 at 10:38 -0400, Solomon Peachy wrote:
> This patch (against 2.6.30) adds support for the ESTeem 195E Hotfoot
> SBC.  We've been maintaining this out-of-tree for some time now for
> older kernels, but recently I ported it to the new unified powerpc tree
> with the intent of pushing it upstream.

Please always have a subject or it will end up in patchwork without
a link I can clock on :-)

Cheersm
Ben.

> The board uses an ancient version of u-boot and a slightly mangled
> verison of the oft-abused ppcboot header.
> 
> There are several variants of the SBC deployed, single/dual
> ethernet/serial, and also 4MB/8MB flash units.  In the interest of
> having a single kernel image boot on all boards, the cuboot shim detects
> the differences and mangles the DTS tree appropriately.
> 
> With the exception of the CF interface that was never populated on
> production boards, this code/DTS supports all boardpop options.
> 
> Signed-off-by:  Solomon Peachy <solomon@linux-wlan.com>
> 
> diff -Naur linux-2.6.30/arch/powerpc/boot/Makefile linux-2.6.30.hotfoot/arch/powerpc/boot/Makefile
> --- linux-2.6.30/arch/powerpc/boot/Makefile	2009-06-09 23:05:27.000000000 -0400
> +++ linux-2.6.30.hotfoot/arch/powerpc/boot/Makefile	2009-07-07 12:55:18.000000000 -0400
> @@ -39,6 +39,7 @@
>  
>  $(obj)/4xx.o: BOOTCFLAGS += -mcpu=405
>  $(obj)/ebony.o: BOOTCFLAGS += -mcpu=405
> +$(obj)/cuboot-hotfoot.o: BOOTCFLAGS += -mcpu=405
>  $(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
>  $(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
>  $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
> @@ -67,7 +68,7 @@
>  		cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \
>  		fsl-soc.c mpc8xx.c pq2.c
>  src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \
> -		cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
> +		cuboot-ebony.c cuboot-hotfoot.c treeboot-ebony.c prpmc2800.c \
>  		ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
>  		cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c \
>  		cuboot-bamboo.c cuboot-mpc7448hpc2.c cuboot-taishan.c \
> @@ -190,6 +191,7 @@
>  
>  # Board ports in arch/powerpc/platform/40x/Kconfig
>  image-$(CONFIG_EP405)			+= dtbImage.ep405
> +image-$(CONFIG_HOTFOOT)			+= cuImage.hotfoot
>  image-$(CONFIG_WALNUT)			+= treeImage.walnut
>  image-$(CONFIG_ACADIA)			+= cuImage.acadia
>  
> diff -Naur linux-2.6.30/arch/powerpc/boot/cuboot-hotfoot.c linux-2.6.30.hotfoot/arch/powerpc/boot/cuboot-hotfoot.c
> --- linux-2.6.30/arch/powerpc/boot/cuboot-hotfoot.c	1969-12-31 19:00:00.000000000 -0500
> +++ linux-2.6.30.hotfoot/arch/powerpc/boot/cuboot-hotfoot.c	2009-07-07 12:55:23.000000000 -0400
> @@ -0,0 +1,142 @@
> +/*
> + * Old U-boot compatibility for Esteem 195E Hotfoot CPU Board
> + *
> + * Author: Solomon Peachy <solomon@linux-wlan.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published
> + * by the Free Software Foundation.
> + */
> +
> +#include "ops.h"
> +#include "stdio.h"
> +#include "reg.h"
> +#include "dcr.h"
> +#include "4xx.h"
> +#include "cuboot.h"
> +
> +#define TARGET_4xx
> +#define TARGET_HOTFOOT
> +
> +#include "ppcboot.h"
> +
> +static bd_t bd;
> +
> +#define NUM_REGS 3
> +
> +static void hotfoot_fixups(void)
> +{
> +	u32 uart = mfdcr(DCRN_CPC0_UCR) & 0x7f;
> +
> +	dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); 
> +
> +	dt_fixup_cpu_clocks(bd.bi_procfreq, bd.bi_procfreq, 0);
> +	dt_fixup_clock("/plb", bd.bi_plb_busfreq);
> +	dt_fixup_clock("/plb/opb", bd.bi_opbfreq);
> +	dt_fixup_clock("/plb/ebc", bd.bi_pci_busfreq);
> +	dt_fixup_clock("/plb/opb/serial@ef600300", bd.bi_procfreq / uart); 
> +	dt_fixup_clock("/plb/opb/serial@ef600400", bd.bi_procfreq / uart); 
> +	
> +	dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
> +	dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
> +
> +	/* Is this a single eth/serial board? */
> +	if ((bd.bi_enet1addr[0] == 0) && 
> +	    (bd.bi_enet1addr[1] == 0) &&
> +	    (bd.bi_enet1addr[2] == 0) &&
> +	    (bd.bi_enet1addr[3] == 0) &&
> +	    (bd.bi_enet1addr[4] == 0) &&
> +	    (bd.bi_enet1addr[5] == 0)) {
> +		void *devp;
> +
> +		printf("Trimming devtree for single eth board\n");
> +
> +		devp = finddevice("/plb/opb/serial@ef600300");
> +		if (!devp)
> +			fatal("Can't find node for /plb/opb/serial@ef600300");
> +		del_node(devp);
> +
> +		devp = finddevice("/plb/opb/ethernet@ef600900");
> +		if (!devp)
> +			fatal("Can't find node for /plb/opb/ethernet@ef600900");
> +		del_node(devp);
> +	}
> +
> +	ibm4xx_quiesce_eth((u32 *)0xef600800, (u32 *)0xef600900);
> +
> +	/* Fix up flash size in fdt for 4M boards. */
> +	if (bd.bi_flashsize < 0x800000) {
> +		u32 regs[NUM_REGS];
> +		void *devp = finddevice("/plb/ebc/nor_flash@0");
> +		if (!devp)
> +			fatal("Can't find FDT node for nor_flash!??");
> +
> +		printf("Fixing devtree for 4M Flash\n");
> +		
> +		/* First fix up the base addresse */
> +		getprop(devp, "reg", regs, sizeof(regs));
> +		regs[0] = 0;
> +		regs[1] = 0xffc00000;
> +		regs[2] = 0x00400000;
> +		setprop(devp, "reg", regs, sizeof(regs));
> +		
> +		/* Then the offsets */
> +		devp = finddevice("/plb/ebc/nor_flash@0/partition@0");
> +		if (!devp)
> +			fatal("Can't find FDT node for partition@0");
> +		getprop(devp, "reg", regs, 2*sizeof(u32));
> +		regs[0] -= 0x400000;
> +		setprop(devp, "reg", regs,  2*sizeof(u32));
> +
> +		devp = finddevice("/plb/ebc/nor_flash@0/partition@1");
> +		if (!devp)
> +			fatal("Can't find FDT node for partition@1");
> +		getprop(devp, "reg", regs, 2*sizeof(u32));
> +		regs[0] -= 0x400000;
> +		setprop(devp, "reg", regs,  2*sizeof(u32));
> +
> +		devp = finddevice("/plb/ebc/nor_flash@0/partition@2");
> +		if (!devp)
> +			fatal("Can't find FDT node for partition@2");
> +		getprop(devp, "reg", regs, 2*sizeof(u32));
> +		regs[0] -= 0x400000;
> +		setprop(devp, "reg", regs,  2*sizeof(u32));
> +
> +		devp = finddevice("/plb/ebc/nor_flash@0/partition@3");
> +		if (!devp)
> +			fatal("Can't find FDT node for partition@3");
> +		getprop(devp, "reg", regs, 2*sizeof(u32));
> +		regs[0] -= 0x400000;
> +		setprop(devp, "reg", regs,  2*sizeof(u32));
> +
> +		devp = finddevice("/plb/ebc/nor_flash@0/partition@4");
> +		if (!devp)
> +			fatal("Can't find FDT node for partition@4");
> +		getprop(devp, "reg", regs, 2*sizeof(u32));
> +		regs[0] -= 0x400000;
> +		setprop(devp, "reg", regs,  2*sizeof(u32));
> +
> +		devp = finddevice("/plb/ebc/nor_flash@0/partition@6");
> +		if (!devp)
> +			fatal("Can't find FDT node for partition@6");
> +		getprop(devp, "reg", regs, 2*sizeof(u32));
> +		regs[0] -= 0x400000;
> +		setprop(devp, "reg", regs,  2*sizeof(u32));
> +
> +		/* Delete the FeatFS node */
> +		devp = finddevice("/plb/ebc/nor_flash@0/partition@5");
> +		if (!devp)
> +			fatal("Can't find FDT node for partition@5");
> +		del_node(devp);
> +	}
> +}
> +
> +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
> +		   unsigned long r6, unsigned long r7)
> +{
> +	CUBOOT_INIT();
> +	platform_ops.fixups = hotfoot_fixups;
> +        platform_ops.exit = ibm40x_dbcr_reset;
> +	fdt_init(_dtb_start);
> +	serial_console_init();
> +}
> diff -Naur linux-2.6.30/arch/powerpc/boot/dts/hotfoot.dts linux-2.6.30.hotfoot/arch/powerpc/boot/dts/hotfoot.dts
> --- linux-2.6.30/arch/powerpc/boot/dts/hotfoot.dts	1969-12-31 19:00:00.000000000 -0500
> +++ linux-2.6.30.hotfoot/arch/powerpc/boot/dts/hotfoot.dts	2009-07-07 12:55:23.000000000 -0400
> @@ -0,0 +1,299 @@
> +/*
> + * Device Tree Source for ESTeem 195E Hotfoot
> + *
> + * Copyright 2009 AbsoluteValue Systems <solomon@linux-wlan.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without
> + * any warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	model = "est,hotfoot";
> +	compatible = "est,hotfoot";
> +	dcr-parent = <&{/cpus/cpu@0}>;
> +
> +	aliases {
> +		ethernet0 = &EMAC0;
> +		ethernet1 = &EMAC1;
> +		serial0 = &UART0;
> +		serial1 = &UART1;
> +	};
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu@0 {
> +			device_type = "cpu";
> +			model = "PowerPC,405EP";
> +			reg = <0x00000000>;
> +			clock-frequency = <0>; /* Filled in by zImage */
> +			timebase-frequency = <0>; /* Filled in by zImage */
> +			i-cache-line-size = <0x20>;
> +			d-cache-line-size = <0x20>;
> +			i-cache-size = <0x4000>;
> +			d-cache-size = <0x4000>;
> +			dcr-controller;
> +			dcr-access-method = "native";
> +		};
> +	};
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x00000000>; /* Filled in by zImage */
> +	};
> +
> +	UIC0: interrupt-controller {
> +		compatible = "ibm,uic";
> +		interrupt-controller;
> +		cell-index = <0>;
> +		dcr-reg = <0x0c0 0x009>;
> +		#address-cells = <0>;
> +		#size-cells = <0>;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	plb {
> +		compatible = "ibm,plb3";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +		clock-frequency = <0>; /* Filled in by zImage */
> +
> +		SDRAM0: memory-controller {
> +			compatible = "ibm,sdram-405ep";
> +			dcr-reg = <0x010 0x002>;
> +		};
> +
> +		MAL: mcmal {
> +			compatible = "ibm,mcmal-405ep", "ibm,mcmal";
> +			dcr-reg = <0x180 0x062>;
> +			num-tx-chans = <4>;
> +			num-rx-chans = <2>;
> +			interrupt-parent = <&UIC0>;
> +			interrupts = <
> +				0xb 0x4 /* TXEOB */
> +				0xc 0x4 /* RXEOB */
> +				0xa 0x4 /* SERR */
> +				0xd 0x4 /* TXDE */
> +				0xe 0x4 /* RXDE */>;
> +		};
> +
> +		POB0: opb {
> +			compatible = "ibm,opb-405ep", "ibm,opb";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0xef600000 0xef600000 0x00a00000>;
> +			dcr-reg = <0x0a0 0x005>;
> +			clock-frequency = <0>; /* Filled in by zImage */
> +
> +			/* Hotfoot has UART0/UART1 swapped */
> +
> +			UART0: serial@ef600400 {
> +				device_type = "serial";
> +				compatible = "ns16550";
> +				reg = <0xef600400 0x00000008>;
> +				virtual-reg = <0xef600400>;
> +				clock-frequency = <0>; /* Filled in by zImage */
> +				current-speed = <0x9600>;
> +				interrupt-parent = <&UIC0>;
> +				interrupts = <0x1 0x4>;
> +			};
> +
> +			UART1: serial@ef600300 {
> +				device_type = "serial";
> +				compatible = "ns16550";
> +				reg = <0xef600300 0x00000008>;
> +				virtual-reg = <0xef600300>;
> +				clock-frequency = <0>; /* Filled in by zImage */
> +				current-speed = <0x9600>;
> +				interrupt-parent = <&UIC0>;
> +				interrupts = <0x0 0x4>;
> +			};
> +
> +
> +			IIC: i2c@ef600500 {
> +				compatible = "ibm,iic-405ep", "ibm,iic";
> +				reg = <0xef600500 0x00000011>;
> +				interrupt-parent = <&UIC0>;
> +				interrupts = <0x2 0x4>;
> +
> +				rtc@68 {
> +				      /* Actually a DS1339 */
> +				      compatible = "dallas,ds1307"; 
> +				      reg = <0x68>;
> +				};
> +
> +				temp@4a { 
> +				      /* Not present on all boards */
> +				      compatible = "national,lm75";
> +				      reg = <0x4a>;
> +				};				
> +			};
> +
> +			GPIO: gpio@ef600700 {
> +			        #gpio-cells = <2>;
> +				compatible = "ibm,ppc4xx-gpio";
> +				reg = <0xef600700 0x00000020>;
> +				gpio-controller;
> +			};
> +
> +			gpio-leds {
> +			     compatible = "gpio-leds";
> +			     status {
> +			     	    label = "Status";
> +			     	    gpios = <&GPIO 1 0>;
> +				    /* linux,default=trigger = ".."; */
> +			     };
> +			     radiorx {
> +			     	    label = "Rx";
> +			     	    gpios = <&GPIO 0xe 0>;
> +				    /* linux,default=trigger = ".."; */
> +			     };
> +			};
> +
> +
> +			EMAC0: ethernet@ef600800 {
> +				linux,network-index = <0x0>;
> +				device_type = "network";
> +				compatible = "ibm,emac-405ep", "ibm,emac";
> +				interrupt-parent = <&UIC0>;
> +				interrupts = <
> +					0xf 0x4 /* Ethernet */
> +					0x9 0x4 /* Ethernet Wake Up */>;
> +				local-mac-address = [000000000000]; /* Filled in by zImage */
> +				reg = <0xef600800 0x00000070>;
> +				mal-device = <&MAL>;
> +				mal-tx-channel = <0>;
> +				mal-rx-channel = <0>;
> +				cell-index = <0>;
> +				max-frame-size = <0x5dc>;
> +				rx-fifo-size = <0x1000>;
> +				tx-fifo-size = <0x800>;
> +				phy-mode = "mii";
> +				phy-map = <0x00000000>;
> +			};
> +
> +			EMAC1: ethernet@ef600900 {
> +				linux,network-index = <0x1>;
> +				device_type = "network";
> +				compatible = "ibm,emac-405ep", "ibm,emac";
> +				interrupt-parent = <&UIC0>;
> +				interrupts = <
> +					0x11 0x4 /* Ethernet */
> +					0x9 0x4 /* Ethernet Wake Up */>;
> +				local-mac-address = [000000000000]; /* Filled in by zImage */
> +				reg = <0xef600900 0x00000070>;
> +				mal-device = <&MAL>;
> +				mal-tx-channel = <2>;
> +				mal-rx-channel = <1>;
> +				cell-index = <1>;
> +				max-frame-size = <0x5dc>;
> +				rx-fifo-size = <0x1000>;
> +				tx-fifo-size = <0x800>;
> +                                mdio-device = <&EMAC0>;
> +				phy-mode = "mii";
> +				phy-map = <0x0000001>;
> +			};
> +		};
> +
> +		EBC0: ebc {
> +			compatible = "ibm,ebc-405ep", "ibm,ebc";
> +			dcr-reg = <0x012 0x002>;
> +			#address-cells = <2>;
> +			#size-cells = <1>;
> +
> +			/* The ranges property is supplied by the bootwrapper
> +			 * and is based on the firmware's configuration of the
> +			 * EBC bridge
> +			 */
> +			clock-frequency = <0>; /* Filled in by zImage */
> +
> +                        nor_flash@0 {
> +                                compatible = "cfi-flash";
> +                                bank-width = <2>;
> +                                reg = <0x0 0xff800000 0x00800000>;
> +                                #address-cells = <1>;
> +                                #size-cells = <1>;
> +
> +				/* This mapping is for the 8M flash
> +				   4M flash has all ofssets -= 4M,
> +				   and FeatFS partition is not present */
> +				
> +                                partition@0 {
> +                                        label = "Bootloader";
> +                                        reg = <0x7c0000 0x40000>;
> +                                        /* read-only; */
> +                                };
> +                                partition@1 {
> +                                        label = "Env_and_Config_Primary";
> +                                        reg = <0x400000 0x10000>;
> +                                };
> +                                partition@2 {
> +                                        label = "Kernel";
> +                                        reg = <0x420000 0x100000>;
> +                                };
> +                                partition@3 {
> +                                        label = "Filesystem";
> +                                        reg = <0x520000 0x2a0000>;
> +                                };
> +                                partition@4 {
> +                                        label = "Env_and_Config_Secondary";
> +                                        reg = <0x410000 0x10000>;
> +                                };
> +                                partition@5 {
> +                                        label = "FeatFS";
> +                                        reg = <0x000000 0x400000>;
> +                                };
> +                                partition@6 {
> +                                        label = "Bootloader_Env";
> +                                        reg = <0x7d0000 0x10000>;
> +                                };
> +			};
> +		};
> +
> +                PCI0: pci@ec000000 {
> +                        device_type = "pci";
> +                        #interrupt-cells = <1>;
> +                        #size-cells = <2>;
> +                        #address-cells = <3>;
> +                        compatible = "ibm,plb405ep-pci", "ibm,plb-pci";
> +                        primary;
> +                        reg = <0xeec00000 0x00000008    /* Config space access */
> +                               0xeed80000 0x00000004    /* IACK */
> +                               0xeed80000 0x00000004    /* Special cycle */
> +                               0xef480000 0x00000040>;  /* Internal registers */
> +
> +                        /* Outbound ranges, one memory and one IO,
> +                         * later cannot be changed. Chip supports a second
> +                         * IO range but we don't use it for now
> +                         */
> +                        ranges = <0x02000000 0x00000000 0x80000000 0x80000000 0x00000000 0x20000000
> +                                  0x01000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>;
> +
> +                        /* Inbound 2GB range starting at 0 */
> +                        dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>;
> +
> +			interrupt-parent = <&UIC0>;
> +                        interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
> +                        interrupt-map = <
> +                                /* IDSEL 3 -- slot1 (optional) 27/29 A/B IRQ2/4 */
> +                                0x1800 0x0 0x0 0x1 &UIC0 0x1b 0x8
> +                                0x1800 0x0 0x0 0x2 &UIC0 0x1d 0x8
> +
> +                                /* IDSEL 4 -- slot0, 26/28 A/B IRQ1/3 */
> +                                0x2000 0x0 0x0 0x1 &UIC0 0x1a 0x8
> +                                0x2000 0x0 0x0 0x2 &UIC0 0x1c 0x8
> +                        >;
> +                };
> +	};
> +
> +	chosen {
> +		linux,stdout-path = &UART0;
> +	};
> +};
> diff -Naur linux-2.6.30/arch/powerpc/boot/ppcboot.h linux-2.6.30.hotfoot/arch/powerpc/boot/ppcboot.h
> --- linux-2.6.30/arch/powerpc/boot/ppcboot.h	2009-06-09 23:05:27.000000000 -0400
> +++ linux-2.6.30.hotfoot/arch/powerpc/boot/ppcboot.h	2009-07-07 12:55:18.000000000 -0400
> @@ -52,6 +52,11 @@
>  	unsigned long	bi_bootflags;	/* boot / reboot flag (for LynxOS) */
>  	unsigned long	bi_ip_addr;	/* IP Address */
>  	unsigned char	bi_enetaddr[6];	/* Ethernet address */
> +#if defined(TARGET_HOTFOOT)
> +	/* second onboard ethernet port */
> +	unsigned char	bi_enet1addr[6];
> +#define HAVE_ENET1ADDR
> +#endif /* TARGET_HOOTFOOT */
>  	unsigned short	bi_ethspeed;	/* Ethernet speed in Mbps */
>  	unsigned long	bi_intfreq;	/* Internal Freq, in MHz */
>  	unsigned long	bi_busfreq;	/* Bus Freq, in MHz */
> @@ -74,6 +79,9 @@
>  	unsigned int	bi_pci_busfreq;	/* PCI Bus speed, in Hz */
>  	unsigned char	bi_pci_enetaddr[6];	/* PCI Ethernet MAC address */
>  #endif
> +#if defined(TARGET_HOTFOOT)
> +	unsigned int     bi_pllouta_freq;       /* PLL OUTA speed, in Hz */
> +#endif
>  #if defined(TARGET_HYMOD)
>  	hymod_conf_t	bi_hymod_conf;	/* hymod configuration information */
>  #endif
> @@ -94,6 +102,10 @@
>  	unsigned char	bi_enet3addr[6];
>  #define HAVE_ENET3ADDR
>  #endif
> +#if defined(TARGET_HOTFOOT)
> +        int             bi_phynum[2];           /* Determines phy mapping */
> +        int             bi_phymode[2];          /* Determines phy mode */
> +#endif
>  #if defined(TARGET_4xx)
>  	unsigned int	bi_opbfreq;		/* OB clock in Hz */
>  	int		bi_iic_fast[2];		/* Use fast i2c mode */
> diff -Naur linux-2.6.30/arch/powerpc/platforms/40x/Kconfig linux-2.6.30.hotfoot/arch/powerpc/platforms/40x/Kconfig
> --- linux-2.6.30/arch/powerpc/platforms/40x/Kconfig	2009-06-09 23:05:27.000000000 -0400
> +++ linux-2.6.30.hotfoot/arch/powerpc/platforms/40x/Kconfig	2009-07-07 12:55:18.000000000 -0400
> @@ -40,6 +40,16 @@
>  	help
>  	  This option enables support for the Nestal Maschinen HCU4 board.
>  
> +config HOTFOOT
> +        bool "Hotfoot"
> +	depends on 40x
> +	default n
> +	select 405EP
> +	select PPC40x_SIMPLE
> +	select PCI
> +        help
> +	 This option enables support for the ESTEEM 195E Hotfoot board.
> +
>  config KILAUEA
>  	bool "Kilauea"
>  	depends on 40x
> diff -Naur linux-2.6.30/arch/powerpc/platforms/40x/ppc40x_simple.c linux-2.6.30.hotfoot/arch/powerpc/platforms/40x/ppc40x_simple.c
> --- linux-2.6.30/arch/powerpc/platforms/40x/ppc40x_simple.c	2009-06-09 23:05:27.000000000 -0400
> +++ linux-2.6.30.hotfoot/arch/powerpc/platforms/40x/ppc40x_simple.c	2009-07-07 12:55:18.000000000 -0400
> @@ -51,7 +51,8 @@
>   * board.c file for it rather than adding it to this list.
>   */
>  static char *board[] __initdata = {
> -	"amcc,acadia"
> +	"amcc,acadia",
> +	"est,hotfoot"
>  };
>  
>  static int __init ppc40x_probe(void)
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2008-08-21  6:21 Schmid Alexander
@ 2008-08-21  9:48 ` Wolfgang Denk
  0 siblings, 0 replies; 41+ messages in thread
From: Wolfgang Denk @ 2008-08-21  9:48 UTC (permalink / raw)
  To: a.schmid; +Cc: linuxppc-embedded

Dear Alexander,

In message <FCELKENEBBOLLHKPHCCBEECMCDAA.a.schmid@systeme-steuerungen.de> you wrote:
> 
> I use U-Boot 1.2.0 on MPC5200B. Console over serial works fine. I have a

U-Boot related questions are off topic here. Please post such
questions on the U-Boot mailing list, see
http://lists.denx.de/mailman/listinfo/u-boot

Second, U-Boot 1.2.0 is *very* old, please use recent code (1.3.4 or
later).

> Grafic controller at LPB Bus and U-Boot shows his console output at VGa too.
> But I would need a keyboard. I compiled U-Boot with USB and if i type "usb
> reset" the ohci controller scans the USB devices and finds a keyboard. But
> nothing happens if i push the buttons on the keyboard!

There is no USB keyboard driver in U-Boot yet. Please let me know if
you need help to develop one.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Time is fluid ... like a river with currents, eddies, backwash.
	-- Spock, "The City on the Edge of Forever", stardate 3134.0

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
@ 2008-01-02 18:16 rsa
  0 siblings, 0 replies; 41+ messages in thread
From: rsa @ 2008-01-02 18:16 UTC (permalink / raw)
  To: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 6 bytes --]

What?

[-- Attachment #2: Original Message.B64 --]
[-- Type: application/x-msdownload, Size: 134041 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE:
  2007-11-01 18:18 Mead, Joseph
  2007-11-01 19:07 ` Grant Likely
@ 2007-11-02  9:35 ` MingLiu
  1 sibling, 0 replies; 41+ messages in thread
From: MingLiu @ 2007-11-02  9:35 UTC (permalink / raw)
  To: Mead, Joseph, linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 743 bytes --]


Hi Joe,
I don't think you can do 64 bit transfer at once because ppc405 is a 32-bit CPU. So we have to the transfer in twice. 
 
BR
Ming


Date: Thu, 1 Nov 2007 14:18:07 -0400From: mead@bnl.govTo: linuxppc-embedded@ozlabs.orgSubject: 




I am using a Xilinx ML403 board and created a custom IP that connects to the PLB bus.   The PLB bus is 64 bits wide.   To communicate with the custom IP I have been using iowrite32() and ioread32() function calls to grab 32 bits at a time.  Is it possible to grab the full 64 bits in one transfer?   I don’t see an iowrite64() or ioread64() function…
 
Thanks,Joe 
 
 
_________________________________________________________________
用 Live Search 搜尽天下资讯!
http://www.live.com/?searchOnly=true

[-- Attachment #2: Type: text/html, Size: 2235 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2007-11-01 18:18 Mead, Joseph
@ 2007-11-01 19:07 ` Grant Likely
  2007-11-02  9:35 ` MingLiu
  1 sibling, 0 replies; 41+ messages in thread
From: Grant Likely @ 2007-11-01 19:07 UTC (permalink / raw)
  To: Mead, Joseph; +Cc: linuxppc-embedded

On 11/1/07, Mead, Joseph <mead@bnl.gov> wrote:
>
>
>
>
> I am using a Xilinx ML403 board and created a custom IP that connects to =
the
> PLB bus.   The PLB bus is 64 bits wide.   To communicate with the custom =
IP
> I have been using iowrite32() and ioread32() function calls to grab 32 bi=
ts
> at a time.  Is it possible to grab the full 64 bits in one transfer?   I
> don't see an iowrite64() or ioread64() function=85

Not really, at least not for non-cachable regions.  The ppc405 is a 32
bit machine and if it is doing non-cached reads then it will do
individual 32 bit transactions.  You could enable cache on the region,
but if it is accessing device registers then that is probably not what
you want (because there is no cache coherency between your device and
the 405).

Cheers,
g.

--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE:
  2007-04-27 19:15 Mead, Joseph
@ 2007-04-27 20:30 ` Scott Coulter
  0 siblings, 0 replies; 41+ messages in thread
From: Scott Coulter @ 2007-04-27 20:30 UTC (permalink / raw)
  To: Mead, Joseph; +Cc: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 4340 bytes --]

Check your UART  interrupt setup

 






___________________________________________________________________ 

  Scott N. Coulter 
  Senior Software Engineer 
  
  Cyclone Microsystems          
  370 James Street              Phone:  203.786.5536 ext. 118 
  New Haven, CT 06513-3051      Email:  scott.coulter@cyclone.com 
  U.S.A.                        Web:    http://www.cyclone.com 
___________________________________________________________________ 

________________________________

From: linuxppc-embedded-bounces+scott.coulter=cyclone.com@ozlabs.org
[mailto:linuxppc-embedded-bounces+scott.coulter=cyclone.com@ozlabs.org]
On Behalf Of Mead, Joseph
Sent: Friday, April 27, 2007 3:16 PM
To: linuxppc-embedded@ozlabs.org
Subject: 

 

Hi, 

I'm trying to use initramfs on an ML403 system but don't understand why
I can't see any console output after the line: 

[    1.034361] Freeing unused kernel memory: 1172k init  

 

my filesystem is built from the following: 

dir /dev 755 0 0 
nod /dev/console 644 0 0 c 5 1 
dir /proc 755 0 0 
dir /sys 755 0 0 
file /init usr/busybox 755 0 0 

 

Busybox was built statically, with init functionality so I think I can
just rename it to init and it should run the init process.   It seems to
find /dev/console because if I delete that node I get an error message
that it can't find /dev/console.   Also I think it is finding the
busybox init because I don't get a kernel panic like I do when I don't
include it.

Any help would be great. 

Thanks,
Joe 

 

Kernel boot-up messages. 

loaded at:     00400000 005E613C                                
board data at: 005E4124 005E413C                                
relocated to:  004050D0 004050E8                                
zimage at:     004057E9 005E3869                                
avail ram:     005E7000 04000000                                

Linux/PPC load: console=ttyS0,9600                                  
Uncompressing Linux...done.                           
Now booting the kernel                      
[    0.000000] Linux version 2.6.17.1 (root@ansto1) (gcc version 3.4.5)
#29 Thu Apr 27 11:13:26 EDT 2007                        

[    0.000000] Xilinx ML403 Reference System (Virtex-4 FX)

[    0.000000] Built 1 zonelists                                
[    0.000000] Kernel command line: console=ttyS0,9600

[    0.000000] Xilinx INTC #0 at 0x41200000 mapped to 0xFDFFE000


[    0.000000] PID hash table entries: 512 (order: 9, 2048 bytes)


[    0.000105] Console: colour dummy device 80x25

[    0.000394] Dentry cache hash table entries: 8192 (order: 3, 32768
bytes)


[    0.000887] Inode-cache hash table entries: 4096 (order: 2, 16384
bytes)


[    0.009214] Memory: 61964k available (1292k kernel code, 468k data,
1172k init, 0k highmem)              
[    0.096238] Mount-cache hash table entries: 512

[    0.435539] NET: Registered protocol family 16

[    0.440315] NET: Registered protocol family 2

[    0.480121] IP route cache hash table entries: 512 (order: -1, 2048
bytes)


[    0.480636] TCP established hash table entries: 2048 (order: 1, 8192
bytes)


[    0.480755] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)


[    0.480821] TCP: Hash tables configure

[    0.480843] TCP reno registered                                  
[    0.484696] io scheduler noop registered

[    0.484754] io scheduler anticipatory registered (default)


[    0.484799] io scheduler deadline registered

[    0.484890] io scheduler cfq registered

[    0.510230] Serial: 8250/16550 driver $Revision: 1.90 $ 1 ports, IRQ
sharing disabled        
[    0.511764] serial8250.0: ttyS0 at MMIO 0x40401003 (irq = 9) is a
16550A


[    0.924578] RAMDISK driver initialized: 16 RAM disks of 65536K size
1024 blocksize     
[    0.948301] tun: Universal TUN                                
[    0.963483] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>


[    0.982713] mice: PS/2 mouse device common for all mice

[    0.998445] TCP bic registered                                 
[    1.007702] NET: Registered protocol family 1

[    1.020827] NET: Registered protocol family 17

[    1.034361] Freeing unused kernel memory: 1172k init  


[-- Attachment #2: Type: text/html, Size: 25869 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Re:
  2007-04-13 18:59     ` Re: Sergei Shtylyov
@ 2007-04-13 19:10       ` Segher Boessenkool
  0 siblings, 0 replies; 41+ messages in thread
From: Segher Boessenkool @ 2007-04-13 19:10 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: ppcdev, Olaf Hering, Alan Cox, Milton Miller

>>> I think the proper test is ((cb & 5) == 5) but I can't remember for
>>> sure..
>> That is correct if you know for sure the controller
>> actually supports native mode, and doesn't have that
>> support turned off by some configuration setting;
>> otherwise, the test should be ((cb & 0xf) == 0xf).
>
>   "I protest your honor". :-)
>   Bits 1 and 3 only indicate that bits 0 and 2 are writeable.

Darn you're right.  Sorry for the confusion.


Segher

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2007-04-13 18:45   ` Re: Segher Boessenkool
@ 2007-04-13 18:59     ` Sergei Shtylyov
  2007-04-13 19:10       ` Re: Segher Boessenkool
  0 siblings, 1 reply; 41+ messages in thread
From: Sergei Shtylyov @ 2007-04-13 18:59 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Olaf Hering, Milton Miller, Alan Cox, ppcdev

Hello.

Segher Boessenkool wrote:
>>>+               if (cb & 0x5) { /* if controller is configured for
>>>pci-native mode for both channels */

>>>The above expression allows 1, 4, or 5 for the masked bits.  I'm
>>>guessing you
>>>wanted to test that equal to either 5 or 0.

>>I think the proper test is ((cb & 5) == 5) but I can't remember for
>>sure..
 
> That is correct if you know for sure the controller
> actually supports native mode, and doesn't have that
> support turned off by some configuration setting;
> otherwise, the test should be ((cb & 0xf) == 0xf).

   "I protest your honor". :-)
   Bits 1 and 3 only indicate that bits 0 and 2 are writeable.
 
MBR, Sergei

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Re:
  2007-04-13  2:23 ` Benjamin Herrenschmidt
@ 2007-04-13 18:45   ` Segher Boessenkool
  2007-04-13 18:59     ` Re: Sergei Shtylyov
  0 siblings, 1 reply; 41+ messages in thread
From: Segher Boessenkool @ 2007-04-13 18:45 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: ppcdev, Olaf Hering, Alan Cox, Milton Miller

>> +               if (cb & 0x5) { /* if controller is configured for
>> pci-native mode for both channels */
>>
>> The above expression allows 1, 4, or 5 for the masked bits.  I'm
>> guessing you
>> wanted to test that equal to either 5 or 0.
>
> I think the proper test is ((cb & 5) == 5) but I can't remember for
> sure..

That is correct if you know for sure the controller
actually supports native mode, and doesn't have that
support turned off by some configuration setting;
otherwise, the test should be ((cb & 0xf) == 0xf).


Segher

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  2007-04-12 15:44 Milton Miller
@ 2007-04-13  2:23 ` Benjamin Herrenschmidt
  2007-04-13 18:45   ` Re: Segher Boessenkool
  0 siblings, 1 reply; 41+ messages in thread
From: Benjamin Herrenschmidt @ 2007-04-13  2:23 UTC (permalink / raw)
  To: Milton Miller; +Cc: Olaf Hering, Alan Cox, ppcdev

On Thu, 2007-04-12 at 10:44 -0500, Milton Miller wrote:
> Matt sealey wrote:
> 
> +               if (cb & 0x5) { /* if controller is configured for 
> pci-native mode for both channels */
> 
> The above expression allows 1, 4, or 5 for the masked bits.  I'm 
> guessing you
> wanted to test that equal to either 5 or 0.

I think the proper test is ((cb & 5) == 5) but I can't remember for
sure.. 

Ben.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re:
  1999-05-18  7:26 nicolas.boussekeyt
@ 1999-05-18 18:03 ` Alex Vallens
  0 siblings, 0 replies; 41+ messages in thread
From: Alex Vallens @ 1999-05-18 18:03 UTC (permalink / raw)
  To: nicolas.boussekeyt; +Cc: linuxppc-dev


If you have a PowerBook G3 Series (Wallstreet), simply hold the
cmd-opt-o-f keys on startup (before the chime) and the computer will
automatically boot into OF.

Alex


[[ This message was sent via the linuxppc-dev mailing list.  Replies are ]]
[[ not  forced  back  to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting.   ]]

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2022-04-23  2:30 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-30 18:57 [PATCH v6 0/6] Disable compat cruft on ppc64le v6 Michal Suchanek
2019-08-30 18:57 ` [PATCH v6 1/6] powerpc: make llseek 32bit-only Michal Suchanek
2019-08-30 19:46   ` [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro" Michal Suchanek
2019-08-30 19:54     ` Arnd Bergmann
2019-08-30 20:13       ` Michal Suchánek
2019-08-30 20:37         ` Arnd Bergmann
     [not found]       ` <20190830202959.3539-1-msuchanek@suse.de>
2019-08-30 20:32         ` Arnd Bergmann
2019-08-31  8:38       ` [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro" Christoph Hellwig
2019-08-31 13:44         ` Arnd Bergmann
2019-08-30 18:57 ` [PATCH v6 2/6] powerpc: move common register copy functions from signal_32.c to signal.c Michal Suchanek
2019-08-30 20:22   ` Christophe Leroy
2019-08-30 18:57 ` [PATCH v6 3/6] powerpc/perf: consolidate read_user_stack_32 Michal Suchanek
2019-08-30 20:21   ` Christophe Leroy
2019-08-30 18:57 ` [PATCH v6 4/6] powerpc/64: make buildable without CONFIG_COMPAT Michal Suchanek
2019-08-30 20:21   ` Christophe Leroy
2019-08-30 20:35     ` Michal Suchánek
2019-08-30 18:57 ` [PATCH v6 5/6] powerpc/64: Make COMPAT user-selectable disabled on littleendian by default Michal Suchanek
2019-08-30 20:23   ` Christophe Leroy
2019-08-30 18:57 ` [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness Michal Suchanek
2019-08-30 19:06   ` Michal Suchánek
2019-09-02  2:51     ` Michael Ellerman
2019-08-30 20:28   ` Christophe Leroy
  -- strict thread matches above, loose matches on Subject: below --
2022-04-05 21:41 rcu_sched self-detected stall on CPU Miguel Ojeda
2022-04-06  9:31 ` Zhouyi Zhou
2022-04-06 17:00   ` Paul E. McKenney
2022-04-08  7:23     ` Michael Ellerman
2022-04-08 14:42       ` Michael Ellerman
2022-04-13  5:11         ` Nicholas Piggin
2022-04-22 15:53           ` Thomas Gleixner
2022-04-23  2:29             ` Re: Nicholas Piggin
     [not found] <1287422825-14999-1-git-send-email-nacc@us.ibm.com>
2010-10-18 17:26 ` [PATCH 1/7] microblaze: pci-common cleanup Nishanth Aravamudan
2010-10-20  5:31   ` Michal Simek
2010-11-01  6:29   ` Re: Michal Simek
2010-08-18 20:56 Wolfgang Denk
2010-08-19  1:04 ` Stephen Rothwell
2010-09-02  6:14 ` Re: Wolfgang Denk
2010-09-02 14:51   ` Rupjyoti Sarmah
2010-09-07  6:29   ` RE: Rupjyoti Sarmah
2009-07-23 14:38 Solomon Peachy
2009-07-26 23:38 ` Benjamin Herrenschmidt
2008-08-21  6:21 Schmid Alexander
2008-08-21  9:48 ` Wolfgang Denk
2008-01-02 18:16 Re: rsa
2007-11-01 18:18 Mead, Joseph
2007-11-01 19:07 ` Grant Likely
2007-11-02  9:35 ` MingLiu
2007-04-27 19:15 Mead, Joseph
2007-04-27 20:30 ` Scott Coulter
2007-04-12 15:44 Milton Miller
2007-04-13  2:23 ` Benjamin Herrenschmidt
2007-04-13 18:45   ` Re: Segher Boessenkool
2007-04-13 18:59     ` Re: Sergei Shtylyov
2007-04-13 19:10       ` Re: Segher Boessenkool
1999-05-18  7:26 nicolas.boussekeyt
1999-05-18 18:03 ` Alex Vallens

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).