Hi Qais, On 3/23/2021 3:22 PM, Qais Yousef wrote: > Hi Alexander > > On 03/22/21 18:02, Alexander Sverdlin wrote: >> Hi Qais, >> >> On 22/03/2021 17:32, Qais Yousef wrote: >>> Yes you're right. I was a bit optimistic on CONFIG_DYNAMIC_FTRACE will imply >>> CONFIG_ARM_MODULE_PLTS is enabled too. >>> >>> It only has an impact on reducing ifdefery when calling >>> >>> ftrace_call_replace_mod(rec->arch.mod, ...) >>> >>> Should be easy to wrap rec->arch.mod with its own accessor that will return >>> NULL if !CONFIG_ARM_MODULE_PLTS or just ifdef the functions. >>> >>> Up to Alexander to pick what he prefers :-) >> >> well, I of course prefer v7 as-is, because this review is running longer >> than two >> years and I actually hope these patches to be finally merged at some point. >> But you are welcome to optimize them with follow up patches :) > > I appreciate that and thanks a lot for your effort. My attempt to review and > test here is to help in getting this merged. > > FWIW my main concern is about duplicating the range check in > ftrace_call_replace() and using magic values that already exist in > __arm_gen_branch_{arm, thumb2}() and better remain encapsulated there.
Your patch in addition to Alexander's patch work for me as well, so feel free to add a: Tested-by: Florian Fainelli <f.faine...@gmail.com> FWIW, what is nice about Alexander's original patch is that it applies relatively cleanly to older kernels as well where this is equally needed. There is not currently any Fixes: tag being provided but maybe we should amend the second patch with one? Thanks! > > Thanks > > -- > Qais Yousef > > ----->8------ > > > diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h > index a4dbac07e4ef..8545b3ff8317 100644 > --- a/arch/arm/include/asm/ftrace.h > +++ b/arch/arm/include/asm/ftrace.h > @@ -25,6 +25,27 @@ static inline unsigned long ftrace_call_adjust(unsigned > long addr) > /* With Thumb-2, the recorded addresses have the lsb set */ > return addr & ~1; > } > + > +#ifdef CONFIG_ARM_MODULE_PLTS > +static inline void ftrace_set_mod(struct dyn_arch_ftrace *arch, struct > module *mod) > +{ > + arch->mod = mod; > +} > + > +static inline struct module *ftrace_get_mod(struct dyn_arch_ftrace *arch) > +{ > + return arch->mod; > +} > +#else > +static inline void ftrace_set_mod(struct dyn_arch_ftrace *arch, struct > module *mod) > +{ > +} > + > +static inline struct module *ftrace_get_mod(struct dyn_arch_ftrace *arch) > +{ > + return NULL; > +} > +#endif > #endif > > #endif > diff --git a/arch/arm/include/asm/insn.h b/arch/arm/include/asm/insn.h > index f20e08ac85ae..71c3edefe629 100644 > --- a/arch/arm/include/asm/insn.h > +++ b/arch/arm/include/asm/insn.h > @@ -13,18 +13,24 @@ arm_gen_nop(void) > } > > unsigned long > -__arm_gen_branch(unsigned long pc, unsigned long addr, bool link); > +__arm_gen_branch(unsigned long pc, unsigned long addr, bool link, bool > check); > > static inline unsigned long > arm_gen_branch(unsigned long pc, unsigned long addr) > { > - return __arm_gen_branch(pc, addr, false); > + return __arm_gen_branch(pc, addr, false, true); > } > > static inline unsigned long > arm_gen_branch_link(unsigned long pc, unsigned long addr) > { > - return __arm_gen_branch(pc, addr, true); > + return __arm_gen_branch(pc, addr, true, true); > +} > + > +static inline unsigned long > +arm_gen_branch_link_nocheck(unsigned long pc, unsigned long addr) > +{ > + return __arm_gen_branch(pc, addr, true, false); > } > > #endif > diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c > index fa867a57100f..63ea34edd222 100644 > --- a/arch/arm/kernel/ftrace.c > +++ b/arch/arm/kernel/ftrace.c > @@ -70,20 +70,28 @@ int ftrace_arch_code_modify_post_process(void) > > static unsigned long ftrace_call_replace(unsigned long pc, unsigned long > addr) > { > - s32 offset = addr - pc; > - s32 blim = 0xfe000008; > - s32 flim = 0x02000004; > + return arm_gen_branch_link(pc, addr); > +} > > - if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) { > - blim = 0xff000004; > - flim = 0x01000002; > - } > +static unsigned long > +ftrace_call_replace_mod(struct module *mod, unsigned long pc, unsigned long > addr) > +{ > +#ifdef CONFIG_ARM_MODULE_PLTS > + unsigned long new; > > - if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS) && > - (offset < blim || offset > flim)) > - return 0; > + if (likely(!mod)) > + return arm_gen_branch_link(pc, addr); > > + new = arm_gen_branch_link_nocheck(pc, addr); > + if (!new) { > + addr = get_module_plt(mod, pc, addr); > + new = arm_gen_branch_link(pc, addr); > + } > + > + return new; > +#else > return arm_gen_branch_link(pc, addr); > +#endif > } > > static int ftrace_modify_code(unsigned long pc, unsigned long old, > @@ -141,18 +149,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned > long addr) > > old = ftrace_nop_replace(rec); > > - new = ftrace_call_replace(ip, aaddr); > - > -#ifdef CONFIG_ARM_MODULE_PLTS > - if (!new) { > - struct module *mod = rec->arch.mod; > - > - if (mod) { > - aaddr = get_module_plt(mod, ip, aaddr); > - new = ftrace_call_replace(ip, aaddr); > - } > - } > -#endif > + new = ftrace_call_replace_mod(ftrace_get_mod(&rec->arch), ip, aaddr); > > return ftrace_modify_code(rec->ip, old, new, true); > } > @@ -183,23 +180,11 @@ int ftrace_make_nop(struct module *mod, > unsigned long new; > int ret; > > -#ifdef CONFIG_ARM_MODULE_PLTS > /* mod is only supplied during module loading */ > - if (!mod) > - mod = rec->arch.mod; > - else > - rec->arch.mod = mod; > -#endif > - > - old = ftrace_call_replace(ip, aaddr); > - > -#ifdef CONFIG_ARM_MODULE_PLTS > - if (!old && mod) { > - aaddr = get_module_plt(mod, ip, aaddr); > - old = ftrace_call_replace(ip, aaddr); > - } > -#endif > + if (mod) > + ftrace_set_mod(&rec->arch, mod); > > + old = ftrace_call_replace_mod(ftrace_get_mod(&rec->arch), ip, aaddr); > new = ftrace_nop_replace(rec); > ret = ftrace_modify_code(ip, old, new, true); > > diff --git a/arch/arm/kernel/insn.c b/arch/arm/kernel/insn.c > index 2e844b70386b..37ec5734309e 100644 > --- a/arch/arm/kernel/insn.c > +++ b/arch/arm/kernel/insn.c > @@ -4,7 +4,7 @@ > #include <asm/opcodes.h> > > static unsigned long > -__arm_gen_branch_thumb2(unsigned long pc, unsigned long addr, bool link) > +__arm_gen_branch_thumb2(unsigned long pc, unsigned long addr, bool link, > bool check) > { > unsigned long s, j1, j2, i1, i2, imm10, imm11; > unsigned long first, second; > @@ -12,7 +12,7 @@ __arm_gen_branch_thumb2(unsigned long pc, unsigned long > addr, bool link) > > offset = (long)addr - (long)(pc + 4); > if (offset < -16777216 || offset > 16777214) { > - WARN_ON_ONCE(1); > + WARN_ON_ONCE(check); > return 0; > } > > @@ -34,7 +34,7 @@ __arm_gen_branch_thumb2(unsigned long pc, unsigned long > addr, bool link) > } > > static unsigned long > -__arm_gen_branch_arm(unsigned long pc, unsigned long addr, bool link) > +__arm_gen_branch_arm(unsigned long pc, unsigned long addr, bool link, bool > check) > { > unsigned long opcode = 0xea000000; > long offset; > @@ -44,7 +44,7 @@ __arm_gen_branch_arm(unsigned long pc, unsigned long addr, > bool link) > > offset = (long)addr - (long)(pc + 8); > if (unlikely(offset < -33554432 || offset > 33554428)) { > - WARN_ON_ONCE(1); > + WARN_ON_ONCE(check); > return 0; > } > > @@ -54,10 +54,10 @@ __arm_gen_branch_arm(unsigned long pc, unsigned long > addr, bool link) > } > > unsigned long > -__arm_gen_branch(unsigned long pc, unsigned long addr, bool link) > +__arm_gen_branch(unsigned long pc, unsigned long addr, bool link, bool check) > { > if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) > - return __arm_gen_branch_thumb2(pc, addr, link); > + return __arm_gen_branch_thumb2(pc, addr, link, check); > else > - return __arm_gen_branch_arm(pc, addr, link); > + return __arm_gen_branch_arm(pc, addr, link, check); > } > -- Florian