diff mbox series

[v2,21/25] powerpc/ftrace: Don't use copy_from_kernel_nofault() in module_trampoline_target()

Message ID 921e8d60c847d42f7309feae1936fa0117b7f0d1.1651905939.git.christophe.leroy@csgroup.eu (mailing list archive)
State Superseded
Headers show
Series powerpc: ftrace optimisation and cleanup and more [v2] | expand

Commit Message

Christophe Leroy May 7, 2022, 6:46 a.m. UTC
module_trampoline_target() is quite a hot path used when
activating/deactivating function tracer.

Avoid the heavy copy_from_kernel_nofault() by doing four calls
to copy_inst_from_kernel_nofault().

Use __copy_inst_from_kernel_nofault() for the 3 last calls. First call
is done to copy_from_kernel_nofault() to check address is within
kernel space. No risk to wrap out the top of kernel space because the
last page is never mapped so if address is in last page the first copy
will fails and the other ones will never be performed.

And also make it notrace just like all functions that call it.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/kernel/module_32.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

Comments

kernel test robot May 7, 2022, 11:29 a.m. UTC | #1
Hi Christophe,

I love your patch! Perhaps something to improve:

[auto build test WARNING on powerpc/next]
[also build test WARNING on powerpc/topic/ppc-kvm v5.18-rc5 next-20220506]
[cannot apply to rostedt-trace/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Christophe-Leroy/powerpc-ftrace-optimisation-and-cleanup-and-more-v2/20220507-145034
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-randconfig-s031-20220506 (https://download.01.org/0day-ci/archive/20220507/202205071900.opHsWE8v-lkp@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 11.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/intel-lab-lkp/linux/commit/1c6a385ed330a6ed959cad02f89306fb84e4334c
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Christophe-Leroy/powerpc-ftrace-optimisation-and-cleanup-and-more-v2/20220507-145034
        git checkout 1c6a385ed330a6ed959cad02f89306fb84e4334c
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=powerpc SHELL=/bin/bash arch/powerpc/kernel/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> arch/powerpc/kernel/module_32.c:298:43: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected struct ppc_inst_t [usertype] *inst @@     got unsigned int * @@
   arch/powerpc/kernel/module_32.c:298:43: sparse:     expected struct ppc_inst_t [usertype] *inst
   arch/powerpc/kernel/module_32.c:298:43: sparse:     got unsigned int *
   arch/powerpc/kernel/module_32.c:300:49: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected struct ppc_inst_t [usertype] *inst @@     got unsigned int * @@
   arch/powerpc/kernel/module_32.c:300:49: sparse:     expected struct ppc_inst_t [usertype] *inst
   arch/powerpc/kernel/module_32.c:300:49: sparse:     got unsigned int *
   arch/powerpc/kernel/module_32.c:302:49: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected struct ppc_inst_t [usertype] *inst @@     got unsigned int * @@
   arch/powerpc/kernel/module_32.c:302:49: sparse:     expected struct ppc_inst_t [usertype] *inst
   arch/powerpc/kernel/module_32.c:302:49: sparse:     got unsigned int *
   arch/powerpc/kernel/module_32.c:304:49: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected struct ppc_inst_t [usertype] *inst @@     got unsigned int * @@
   arch/powerpc/kernel/module_32.c:304:49: sparse:     expected struct ppc_inst_t [usertype] *inst
   arch/powerpc/kernel/module_32.c:304:49: sparse:     got unsigned int *

vim +298 arch/powerpc/kernel/module_32.c

   290	
   291	#ifdef CONFIG_DYNAMIC_FTRACE
   292	notrace int module_trampoline_target(struct module *mod, unsigned long addr,
   293					     unsigned long *target)
   294	{
   295		unsigned int jmp[4];
   296	
   297		/* Find where the trampoline jumps to */
 > 298		if (copy_inst_from_kernel_nofault(jmp, (void *)addr))
   299			return -EFAULT;
   300		if (__copy_inst_from_kernel_nofault(jmp + 1, (void *)addr + 4))
   301			return -EFAULT;
   302		if (__copy_inst_from_kernel_nofault(jmp + 2, (void *)addr + 8))
   303			return -EFAULT;
   304		if (__copy_inst_from_kernel_nofault(jmp + 3, (void *)addr + 12))
   305			return -EFAULT;
   306	
   307		/* verify that this is what we expect it to be */
   308		if ((jmp[0] & 0xffff0000) != PPC_RAW_LIS(_R12, 0) ||
   309		    (jmp[1] & 0xffff0000) != PPC_RAW_ADDI(_R12, _R12, 0) ||
   310		    jmp[2] != PPC_RAW_MTCTR(_R12) ||
   311		    jmp[3] != PPC_RAW_BCTR())
   312			return -EINVAL;
   313	
   314		addr = (jmp[1] & 0xffff) | ((jmp[0] & 0xffff) << 16);
   315		if (addr & 0x8000)
   316			addr -= 0x10000;
   317	
   318		*target = addr;
   319	
   320		return 0;
   321	}
   322
diff mbox series

Patch

diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
index a0432ef46967..1b129d728e83 100644
--- a/arch/powerpc/kernel/module_32.c
+++ b/arch/powerpc/kernel/module_32.c
@@ -289,13 +289,19 @@  int apply_relocate_add(Elf32_Shdr *sechdrs,
 }
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-int module_trampoline_target(struct module *mod, unsigned long addr,
-			     unsigned long *target)
+notrace int module_trampoline_target(struct module *mod, unsigned long addr,
+				     unsigned long *target)
 {
 	unsigned int jmp[4];
 
 	/* Find where the trampoline jumps to */
-	if (copy_from_kernel_nofault(jmp, (void *)addr, sizeof(jmp)))
+	if (copy_inst_from_kernel_nofault(jmp, (void *)addr))
+		return -EFAULT;
+	if (__copy_inst_from_kernel_nofault(jmp + 1, (void *)addr + 4))
+		return -EFAULT;
+	if (__copy_inst_from_kernel_nofault(jmp + 2, (void *)addr + 8))
+		return -EFAULT;
+	if (__copy_inst_from_kernel_nofault(jmp + 3, (void *)addr + 12))
 		return -EFAULT;
 
 	/* verify that this is what we expect it to be */