On 08/29/2019 10:28 PM, Michal Suchanek wrote: > Building callchain.c with !COMPAT proved quite ugly with all the > defines. Splitting out the 32bit and 64bit parts looks better. > > Also rewrite current_is_64bit as common function. No other code change > intended.
Nice result. Could look even better by merging both read_user_stack_32(), see below. Also a possible cosmetic change to Makefile. --- arch/powerpc/perf/Makefile | 7 ++--- arch/powerpc/perf/callchain_32.c | 65 ++++++++++++++++------------------------ 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index e9f3202251d0..53d614e98537 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile @@ -1,9 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o -ifdef CONFIG_PERF_EVENTS -obj-y += callchain_$(BITS).o -obj-$(CONFIG_COMPAT) += callchain_32.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 diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c index 0bd4484eddaa..17c43ae03084 100644 --- a/arch/powerpc/perf/callchain_32.c +++ b/arch/powerpc/perf/callchain_32.c @@ -15,50 +15,13 @@ #include <asm/sigcontext.h> #include <asm/ucontext.h> #include <asm/vdso.h> -#ifdef CONFIG_PPC64 -#include "../kernel/ppc32.h" -#endif #include <asm/pte-walk.h> #include "callchain.h" #ifdef CONFIG_PPC64 -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); -} -#else /* 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(); - - return rc; -} +#include "../kernel/ppc32.h" +#else #define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE #define sigcontext32 sigcontext @@ -95,6 +58,30 @@ struct rt_signal_frame_32 { int abigap[56]; }; +/* + * 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_PPC32) || !rc) + return rc; + + return read_user_stack_slow(ptr, ret, 4); +} + static int is_sigreturn_32_address(unsigned int nip, unsigned int fp) { if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad)) -- 2.13.3