Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/lib: Use patch_site to patch copy_32 functions once cache is enabled

The symbol memcpy_nocache_branch defined in order to allow patching
of memset function once cache is enabled leads to confusing reports
by perf tool.

Using the new patch_site functionality solves this issue.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

Christophe Leroy and committed by
Michael Ellerman
fa54a981 cd813e1c

+10 -7
+1
arch/powerpc/include/asm/asm-prototypes.h
··· 146 146 /* Patch sites */ 147 147 extern s32 patch__call_flush_count_cache; 148 148 extern s32 patch__flush_count_cache_return; 149 + extern s32 patch__memset_nocache, patch__memcpy_nocache; 149 150 150 151 extern long flush_count_cache; 151 152
+3 -4
arch/powerpc/kernel/setup_32.c
··· 97 97 * We do the initial parsing of the flat device-tree and prepares 98 98 * for the MMU to be fully initialized. 99 99 */ 100 - extern unsigned int memset_nocache_branch; /* Insn to be replaced by NOP */ 101 - 102 100 notrace void __init machine_init(u64 dt_ptr) 103 101 { 104 - unsigned int *addr = &memset_nocache_branch; 102 + unsigned int *addr = (unsigned int *)((unsigned long)&patch__memset_nocache + 103 + patch__memset_nocache); 105 104 unsigned long insn; 106 105 107 106 /* Configure static keys first, now that we're relocated. */ ··· 109 110 /* Enable early debugging if any specified (see udbg.h) */ 110 111 udbg_early_init(); 111 112 112 - patch_instruction((unsigned int *)&memcpy, PPC_INST_NOP); 113 + patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP); 113 114 114 115 insn = create_cond_branch(addr, branch_target(addr), 0x820000); 115 116 patch_instruction(addr, insn); /* replace b by bne cr0 */
+6 -3
arch/powerpc/lib/copy_32.S
··· 13 13 #include <asm/errno.h> 14 14 #include <asm/ppc_asm.h> 15 15 #include <asm/export.h> 16 + #include <asm/code-patching-asm.h> 16 17 17 18 #define COPY_16_BYTES \ 18 19 lwz r7,4(r4); \ ··· 108 107 * Skip optimised bloc until cache is enabled. Will be replaced 109 108 * by 'bne' during boot to use normal procedure if r4 is not zero 110 109 */ 111 - _GLOBAL(memset_nocache_branch) 112 - b 2f 110 + 5: b 2f 111 + patch_site 5b, patch__memset_nocache 113 112 114 113 clrlwi r7,r6,32-LG_CACHELINE_BYTES 115 114 add r8,r7,r5 ··· 169 168 /* fall through */ 170 169 171 170 _GLOBAL(memcpy) 172 - b generic_memcpy 171 + 1: b generic_memcpy 172 + patch_site 1b, patch__memcpy_nocache 173 + 173 174 add r7,r3,r5 /* test if the src & dst overlap */ 174 175 add r8,r4,r5 175 176 cmplw 0,r4,r7