On Fri, 30 Aug 2019 06:35:11 +0000 (UTC) Christophe Leroy <christophe.le...@c-s.fr> wrote:
> 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 > That looks good. > 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)) I will leave consolidating this function to somebody who knows what the desired semantic is. With a short ifdef section at the top of the file it is a low-hanging fruit. Thanks Michal