Dynamic FTRACE for PA-RISC
Subsystems (3)
v2 cover Dynamic FTRACE for PA-RISC
Hi List,
this series adds support for dynamic ftrace. See the commit message of the patch for a explanation how it works. For testing, you need a patched version of gcc because the current version has a bug which misplaces the function label. John David Anglin can provide a patch which fixes this issue. This issue is tracked here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90751
Changes to v1:
- replace a few hardcoded size by sizeof()
- change len parameter of patch_text_multiple() to unsigned
- add link to gcc bugtracker
Sven Schnelle (6):
parisc: add support for patching multiple words
parisc: add spinlock to patch function
parisc: add WARN_ON() to clear_fixmap
parisc: use pr_debug() in kernel/module.c compiler.h: add CC_USING_PATCHABLE_FUNCTION_ENTRY
parisc: add dynamic ftrace
arch/parisc/Kconfig | 2 + arch/parisc/Makefile | 18 +++++ arch/parisc/include/asm/ftrace.h | 15 +++- arch/parisc/include/asm/patch.h | 4 +- arch/parisc/kernel/Makefile | 9 ++- arch/parisc/kernel/entry.S | 64 +++++++++++++++ arch/parisc/kernel/ftrace.c | 129 +++++++++++++++++++++++++++--- arch/parisc/kernel/module.c | 64 +++++++++------ arch/parisc/kernel/module.lds | 7 ++ arch/parisc/kernel/patch.c | 88 ++++++++++++++++---- arch/parisc/kernel/vmlinux.lds.S | 2 + arch/parisc/mm/fixmap.c | 7 +- include/asm-generic/vmlinux.lds.h | 7 ++ include/linux/compiler_types.h | 2 + 14 files changed, 358 insertions(+), 60 deletions(-) create mode 100644 arch/parisc/kernel/module.lds
Signature · 1 line
2.20.1
PATCH v2 1/6 parisc: add support for patching multiple words
add patch_text_multiple() which allows to patch multiple text words in memory. This can be used to copy functions.
--- arch/parisc/include/asm/patch.h | 4 +- arch/parisc/kernel/patch.c | 75 ++++++++++++++++++++++++++------- 2 files changed, 62 insertions(+), 17 deletions(-)
arch/parisc/include/asm/patch.h +3 -1
@@ -4,8 +4,10 @@/* stop machine and patch kernel text */ void patch_text (void *addr,unsigned int insn); +void patch_text_multiple (void *addr,u32 *insn,unsigned int len);/* patch kernel text with machine already stopped (e.g. in kgdb) */ -void __patch_text (void *addr,unsigned int insn); +void __patch_text (void *addr,u32 insn); +void __patch_text_multiple (void *addr,u32 *insn,unsigned int len);#endif
arch/parisc/kernel/patch.c +59 -16
114 lines not on this page · raw message
Signature · 1 line
2.20.1
Re: [PATCH v2 1/6] parisc: add support for patching multiple words
arch/parisc/kernel/patch.c static void __kprobes patch_unmap(int fixmap) · line 67
Quoted 5 lines · Sven Schnelle
arch/parisc/kernel/patch.c +5
-0+while (len >=4 ) { + *p++ = *insn++; + addr +=sizeof (u32); + len -=sizeof (u32); +if (len && !((unsigned long )addr & ~PAGE_MASK )) {
if (len && offset_in_page(addr) == 0)
This is a bit more obvious to me. YMMV.
Eike
Re: [PATCH v2 1/6] parisc: add support for patching multiple words
Hi,
Quoted 10 lines · Rolf Eike Beer
arch/parisc/kernel/patch.c static void __kprobes patch_unmap(int fixmap) · line 67
Quoted 5 lines · Sven Schnelle
arch/parisc/kernel/patch.c +5
-0+while (len >=4 ) { + *p++ = *insn++; + addr +=sizeof (u32); + len -=sizeof (u32); +if (len && !((unsigned long )addr & ~PAGE_MASK )) {if (len &&
offset_in_page(addr)== 0)This is a bit more obvious to me. YMMV.
It is. I'll update the patch and send a v3. Thanks!
Sven
PATCH v2 2/6 parisc: add spinlock to patch function
In reply to Sven SchnelleIf multiple CPUs are patching code we need the spinlock to protect against parallel fixmap maps/unmap calls.
--- arch/parisc/kernel/patch.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)
arch/parisc/kernel/patch.c +19 -6
@@ -23,7 +23,9 @@ struct patch {static DEFINE_RAW_SPINLOCK (patch_lock); -static void __kprobes *patch_map (void *addr,int fixmap,int *need_unmap) +static void __kprobes *patch_map (void *addr,int fixmap,unsigned long *flags, +int *need_unmap) +{unsigned long uintaddr = (uintptr_t ) addr;bool module = !core_kernel_text (uintaddr);struct page *page;
@@ -38,19 +40,29 @@ static void __kprobes *patch_map(void *addr, int fixmap, int *need_unmap) *need_unmap =1 ;set_fixmap (fixmap,page_to_phys (page)); +if (flags) +raw_spin_lock_irqsave (&patch_lock, *flags); +else +__acquire (&patch_lock);return (void *) (__fix_to_virt (fixmap) + (uintaddr & ~PAGE_MASK )); } -static void __kprobes patch_unmap (int fixmap) +static void __kprobes patch_unmap (int fixmap,unsigned long *flags) {clear_fixmap (fixmap); + +if (flags) +raw_spin_unlock_irqrestore (&patch_lock, *flags); +else +__release (&patch_lock); }void __kprobes __patch_text_multiple (void *addr,u32 *insn,unsigned int len) {unsigned long start = (unsigned long )addr;unsigned long end = (unsigned long )addr + len; +unsigned long flags;u32 *p, *fixmap;int mapped;
@@ -58,7 +70,7 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)flush_kernel_vmap_range (addr, len);flush_icache_range (start, end); - p = fixmap =patch_map (addr,FIX_TEXT_POKE0 , &mapped); + p = fixmap =patch_map (addr,FIX_TEXT_POKE0 , &flags, &mapped);while (len >=4 ) { *p++ = *insn++;
@@ -72,14 +84,15 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)flush_kernel_vmap_range ((void *)fixmap, (p-fixmap) *sizeof (*p));if (mapped) -patch_unmap (FIX_TEXT_POKE0 ); - p = fixmap =patch_map (addr,FIX_TEXT_POKE0 , &mapped); +patch_unmap (FIX_TEXT_POKE0 , &flags); + p = fixmap =patch_map (addr,FIX_TEXT_POKE0 , &flags, + &mapped); } }flush_kernel_vmap_range ((void *)fixmap, (p-fixmap) *sizeof (*p));if (mapped) -patch_unmap (FIX_TEXT_POKE0 ); +patch_unmap (FIX_TEXT_POKE0 , &flags);flush_icache_range (start, end); }
Signature · 1 line
2.20.1
PATCH v2 3/6 parisc: add WARN_ON() to clear_fixmap
In reply to Sven SchnelleCalling clear_fixmap() on an already cleared fixed mapping is a bad thing to do. Add a WARN_ON() to catch such issues.
--- arch/parisc/mm/fixmap.c | 3 +++ 1 file changed, 3 insertions(+)
arch/parisc/mm/fixmap.c +3 -0
@@ -35,6 +35,9 @@ void clear_fixmap(enum fixed_addresses idx)pmd_t *pmd =pmd_offset (pgd, vaddr);pte_t *pte =pte_offset_kernel (pmd, vaddr); +if (WARN_ON (pte_none (*pte))) +return ; +pte_clear (&init_mm, vaddr, pte);flush_tlb_kernel_range (vaddr, vaddr +PAGE_SIZE );
Signature · 1 line
2.20.1
PATCH v2 4/6 parisc: use pr_debug() in kernel/module.c
In reply to Sven SchnelleInstead of using our own version, switch to the generic pr_() calls.
--- arch/parisc/kernel/module.c | 44 ++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 25 deletions(-)
arch/parisc/kernel/module.c +19 -25
@@ -48,9 +48,9 @@* However, SEGREL32 is used only for PARISC unwind entries, and we want * those entries to have an absolute address, and not just an offset. * -* The unwind table mechanism has the ability to specify an offset for +* The unwind table mechanism has the ability to specify an offset for * the unwind table; however, because we split off the init functions into -* a different piece of memory, it is not possible to do this using a +* a different piece of memory, it is not possible to do this using a * single offset. Instead, we use the above hack for now. */
@@ -68,12 +68,6 @@#include <asm/unwind.h> #include <asm/sections.h> -#if 0 -#define DEBUGP printk -#else -#define DEBUGP(fmt...) -#endif -#define RELOC_REACHABLE (val, bits) \ (( ( !((val) & (1<<((bits)-1))) && ((val)>>(bits)) != 0 ) || \ ( ((val) & (1<<((bits)-1))) && ((val)>>(bits)) != (((__typeof__(val))(~0))>>((bits)+2)))) ? \
@@ -315,7 +309,7 @@ unsigned int arch_mod_section_prepend(struct module *mod, *sizeof (struct stub_entry ); } -#define CONST +#define CONST int module_frob_arch_sections(CONST Elf_Ehdr *hdr, CONST Elf_Shdr *sechdrs, CONST char *secstrings,
@@ -401,7 +395,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend) got[i].addr = value; out: -DEBUGP ("GOT ENTRY %d[%x] val %lx\n" , i, i*sizeof (struct got_entry ), +pr_debug ("GOT ENTRY %d[%lx] val %lx\n" , i, i*sizeof (struct got_entry ), value);return i *sizeof (struct got_entry ); }
@@ -554,7 +548,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,//unsigned long dp = (unsigned long)$global$; registerunsigned long dp asm ("r27" ); -DEBUGP ("Applying relocate section %u to %u\n" , relsec, +pr_debug ("Applying relocate section %u to %u\n" , relsec, targetsec);for (i =0 ; i < sechdrs[relsec].sh_size /sizeof (*rel); i++) {/* This is where to make the change */
@@ -578,7 +572,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,#if 0 #define r (t) ELF32_R_TYPE(rel[i].r_info)==t ? #t : -DEBUGP ("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n" , +pr_debug ("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n" , strtab + sym->st_name, (uint32_t )loc, val, addend, r(R_PARISC_PLABEL32)
@@ -619,7 +613,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,/* See note about special handling of SEGREL32 at * the beginning of this file. */ - *loc =fsel (val, addend); + *loc =fsel (val, addend);break ;case R_PARISC_SECREL32 :/* 32-bit section relative address. */
@@ -698,7 +692,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,Elf_Addr loc0;unsigned int targetsec = sechdrs[relsec].sh_info; -DEBUGP ("Applying relocate section %u to %u\n" , relsec, +pr_debug ("Applying relocate section %u to %u\n" , relsec, targetsec);for (i =0 ; i < sechdrs[relsec].sh_size /sizeof (*rel); i++) {/* This is where to make the change */
@@ -740,7 +734,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,case R_PARISC_LTOFF21L :/* LT-relative; left 21 bits */ val =get_got (me, val, addend); -DEBUGP ("LTOFF21L Symbol %s loc %p val %lx\n" , +pr_debug ("LTOFF21L Symbol %s loc %p val %llx\n" , strtab + sym->st_name, loc, val); val =lrsel (val,0 );
@@ -751,14 +745,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs,/* LT-relative; right 14 bits */ val =get_got (me, val, addend); val =rrsel (val,0 ); -DEBUGP ("LTOFF14R Symbol %s loc %p val %lx\n" , +pr_debug ("LTOFF14R Symbol %s loc %p val %llx\n" , strtab + sym->st_name, loc, val); *loc =mask (*loc,14 ) |reassemble_14 (val);break ;case R_PARISC_PCREL22F :/* PC-relative; 22 bits */ -DEBUGP ("PCREL22F Symbol %s loc %p val %lx\n" , +pr_debug ("PCREL22F Symbol %s loc %p val %llx\n" , strtab + sym->st_name, loc, val); val += addend;
@@ -790,7 +784,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, val =get_stub (me, val, addend,ELF_STUB_GOT , loc0, targetsec); } -DEBUGP ("STUB FOR %s loc %lx, val %lx+%lx at %lx\n" , +pr_debug ("STUB FOR %s loc %px, val %llx+%llx at %llx\n" , strtab + sym->st_name, loc, sym->st_value, addend, val); val = (val - dot -8 )/4 ;
@@ -810,7 +804,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,/* See note about special handling of SEGREL32 at * the beginning of this file. */ - *loc =fsel (val, addend); + *loc =fsel (val, addend);break ;case R_PARISC_SECREL32 :/* 32-bit section relative address. */
@@ -820,14 +814,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs,/* 64-bit function address */ if (in_local (me, (void *)(val + addend))) { *loc64 =get_fdesc (me, val+addend); -DEBUGP ("FDESC for %s at %p points to %lx\n" , +pr_debug ("FDESC for %s at %llx points to %llx\n" , strtab + sym->st_name, *loc64, ((Elf_Fdesc *)*loc64)->addr); }else {/* if the symbol is not local to this * module then val+addend is a pointer * to the function descriptor */ -DEBUGP ("Non local FPTR64 Symbol %s loc %p val %lx\n" , +pr_debug ("Non local FPTR64 Symbol %s loc %p val %llx\n" , strtab + sym->st_name, loc, val); *loc64 = val + addend;
@@ -858,7 +852,7 @@ register_unwind_table(struct module *me, end = table + sechdrs[me->arch.unwind_section].sh_size; gp = (Elf_Addr )me->core_layout.base + me->arch.got_offset; -DEBUGP ("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n" , +pr_debug ("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n" , me->arch.unwind_section, table, end, gp); me->arch.unwind =unwind_table_add (me->name,0 , gp, table, end); }
@@ -914,7 +908,7 @@ int module_finalize(const Elf_Ehdr *hdr, } } -DEBUGP ("module %s: strtab %p, symhdr %p\n" , +pr_debug ("module %s: strtab %p, symhdr %p\n" , me->name, strtab, symhdr);if (me->arch.got_count >MAX_GOTS ) {
@@ -933,7 +927,7 @@ int module_finalize(const Elf_Ehdr *hdr, oldptr = (void *)symhdr->sh_addr; newptr = oldptr +1 ;/* we start counting at 1 */ nsyms = symhdr->sh_size /sizeof (Elf_Sym); -DEBUGP ("OLD num_symtab %lu\n" , nsyms); +pr_debug ("OLD num_symtab %lu\n" , nsyms);for (i =1 ; i < nsyms; i++) { oldptr++;/* note, count starts at 1 so preincrement */
@@ -948,7 +942,7 @@ int module_finalize(const Elf_Ehdr *hdr, } nsyms = newptr - (Elf_Sym *)symhdr->sh_addr; -DEBUGP ("NEW num_symtab %lu\n" , nsyms); +pr_debug ("NEW num_symtab %lu\n" , nsyms); symhdr->sh_size = nsyms *sizeof (Elf_Sym);/* find .altinstructions section */
Signature · 1 line
2.20.1
PATCH v2 5/6 compiler.h: add CC_USING_PATCHABLE_FUNCTION_ENTRY
In reply to Sven SchnelleThis can be used for architectures implementing dynamic ftrace via -fpatchable-function-entry.
--- include/linux/compiler_types.h | 2 ++ 1 file changed, 2 insertions(+)
include/linux/compiler_types.h +2 -0
@@ -112,6 +112,8 @@ struct ftrace_likely_data {#if defined(CC_USING_HOTPATCH )#define notrace __attribute__((hotpatch(0, 0))) +#elif defined(CC_USING_PATCHABLE_FUNCTION_ENTRY ) +#define notrace __attribute__((patchable_function_entry(0, 0)))#else #define notrace __attribute__((__no_instrument_function__))#endif
Signature · 1 line
2.20.1
PATCH v2 6/6 parisc: add dynamic ftrace
In reply to Sven SchnelleThis patch implements dynamic ftrace for PA-RISC. The required mcount call sequences can get pretty long, so instead of patching the whole call sequence out of the functions, we are using -fpatchable-function-entry from gcc. This puts a configurable amount of NOPS before/at the start of the function. Taking do_sys_open() as example, which would look like this when the call is patched out:
1036b248: 08 00 02 40 nop 1036b24c: 08 00 02 40 nop 1036b250: 08 00 02 40 nop 1036b254: 08 00 02 40 nop
1036b258 <do_sys_open>:
1036b258: 08 00 02 40 nop 1036b25c: 08 03 02 41 copy r3,r1 1036b260: 6b c2 3f d9 stw rp,-14(sp) 1036b264: 08 1e 02 43 copy sp,r3 1036b268: 6f c1 01 00 stw,ma r1,80(sp)
When ftrace gets enabled for this function the kernel will patch these NOPs to:
1036b248: 10 19 57 20 <address of ftrace> 1036b24c: 6f c1 00 80 stw,ma r1,40(sp) 1036b250: 48 21 3f d1 ldw -18(r1),r1 1036b254: e8 20 c0 02 bv,n r0(r1)
1036b258 <do_sys_open>:
1036b258: e8 3f 1f df b,l,n .-c,r1 1036b25c: 08 03 02 41 copy r3,r1 1036b260: 6b c2 3f d9 stw rp,-14(sp) 1036b264: 08 1e 02 43 copy sp,r3 1036b268: 6f c1 01 00 stw,ma r1,80(sp)
So the first NOP in do_sys_open() will be patched to jump backwards into some minimal trampoline code which pushes a stackframe, saves r1 which holds the return address, loads the address of the real ftrace function, and branches to that location. For 64 Bit things are getting a bit more complicated (and longer) because we must make sure that the address of ftrace location is 8 byte aligned, and the offset passed to ldd for fetching the address is 8 byte aligned as well.
Note that gcc has a bug which misplaces the function label, and needs a patch to make dynamic ftrace work. See
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90751 for details.
--- arch/parisc/Kconfig | 2 + arch/parisc/Makefile | 18 +++++ arch/parisc/include/asm/ftrace.h | 15 +++- arch/parisc/kernel/Makefile | 9 ++- arch/parisc/kernel/entry.S | 64 +++++++++++++++ arch/parisc/kernel/ftrace.c | 129 +++++++++++++++++++++++++++--- arch/parisc/kernel/module.c | 20 ++++- arch/parisc/kernel/module.lds | 7 ++ arch/parisc/kernel/vmlinux.lds.S | 2 + arch/parisc/mm/fixmap.c | 4 +- include/asm-generic/vmlinux.lds.h | 7 ++ 11 files changed, 259 insertions(+), 18 deletions(-) create mode 100644 arch/parisc/kernel/module.lds
arch/parisc/Kconfig +2 -0
@@ -59,6 +59,8 @@ config PARISC select HAVE_ARCH_KGDB select HAVE_KPROBES select HAVE_KRETPROBES + select HAVE_DYNAMIC_FTRACE if $(cc-option,-fpatchable-function-entry=1,1) + select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE help The PA-RISC microprocessor is designed by Hewlett-Packard and used
arch/parisc/Makefile +18 -0
@@ -47,6 +47,24 @@ ifneq ($(SUBARCH),$(UTS_MACHINE)) endif endif +ifdef CONFIG_DYNAMIC_FTRACE +ifdef CONFIG_64BIT +NOP_COUNT := 8 +else +NOP_COUNT := 5 +endif + +export CC_USING_RECORD_MCOUNT:=1 +export CC_USING_PATCHABLE_FUNCTION_ENTRY:=1 + +KBUILD_AFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY=1 +KBUILD_CFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY=1 \ + -DFTRACE_PATCHABLE_FUNCTION_SIZE=$(NOP_COUNT) + +CC_FLAGS_FTRACE := -fpatchable-function-entry=$(NOP_COUNT),$(shell echo $$(($(NOP_COUNT)-1))) +KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/parisc/kernel/module.lds +endif + OBJCOPY_FLAGS =-O binary -R .note -R .comment -S cflags-y := -pipe
arch/parisc/include/asm/ftrace.h +13 -2
@@ -5,12 +5,23 @@#ifndef __ASSEMBLY__extern void mcount (void ); -#define MCOUNT_INSN_SIZE 4 - +#define MCOUNT_ADDR ((unsigned long)mcount) +#define MCOUNT_INSN_SIZE 4 +#define CC_USING_NOP_MCOUNT extern unsigned long sys_call_table[];extern unsigned long return_address (unsigned int ); +#ifdef CONFIG_DYNAMIC_FTRACE +extern void ftrace_caller (void ); + +struct dyn_arch_ftrace { +}; + +unsigned long ftrace_call_adjust (unsigned long addr); + +#endif +#define ftrace_return_address (n) return_address(n)#endif /* __ASSEMBLY__ */
arch/parisc/kernel/Makefile +5 -4
@@ -14,10 +14,11 @@ obj-y := cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \ ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities -CFLAGS_REMOVE_ftrace.o = -pg -CFLAGS_REMOVE_cache.o = -pg -CFLAGS_REMOVE_perf.o = -pg -CFLAGS_REMOVE_unwind.o = -pg +CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_cache.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_perf.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_unwind.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_patch.o = $(CC_FLAGS_FTRACE) endif obj-$(CONFIG_SMP) += smp.o
arch/parisc/kernel/entry.S +64 -0
70 lines not on this page · raw message
arch/parisc/kernel/ftrace.c +120 -9
153 lines not on this page · raw message
arch/parisc/kernel/module.c +19 -1
@@ -873,6 +873,7 @@ int module_finalize(const Elf_Ehdr *hdr,const char *strtab =NULL ;const Elf_Shdr *s;char *secstrings; +int err, symindex =-1 ;Elf_Sym *newptr, *oldptr;Elf_Shdr *symhdr =NULL ;#ifdef DEBUG
@@ -899,6 +900,7 @@ int module_finalize(const Elf_Ehdr *hdr,if (sechdrs[i].sh_type ==SHT_SYMTAB && (sechdrs[i].sh_flags &SHF_ALLOC )) {int strindex = sechdrs[i].sh_link; + symindex = i;/* FIXME: AWFUL HACK * The cast is to drop the const from * the sechdrs pointer */
@@ -954,8 +956,24 @@ int module_finalize(const Elf_Ehdr *hdr,if (!strcmp (".altinstructions" , secname))/* patch .altinstructions */ apply_alternatives (aseg, aseg + s->sh_size, me->name); - } +/* For 32 bit kernels we're compiling modules with +* -ffunction-sections so we must relocate the addresses in the +*__mcount_loc section. +*/ +if (symindex !=-1 && !strcmp (secname,"__mcount_loc" )) { +if (s->sh_type ==SHT_REL ) + err =apply_relocate ((Elf_Shdr *)sechdrs, + strtab, symindex, + s - sechdrs, me); +else if (s->sh_type ==SHT_RELA ) + err =apply_relocate_add ((Elf_Shdr *)sechdrs, + strtab, symindex, + s - sechdrs, me); +if (err) +return err; + } + }return 0 ; }
arch/parisc/kernel/module.lds new file +7 -0
@@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +SECTIONS { + __mcount_loc : { + *(__patchable_function_entries) + } +}
arch/parisc/kernel/vmlinux.lds.S +2 -0
@@ -18,6 +18,8 @@ *(.data..vm0.pgd) \ *(.data..vm0.pte) +#define CC_USING_PATCHABLE_FUNCTION_ENTRY + #include <asm-generic/vmlinux.lds.h> /* needed for the processor specific cache alignment size */
arch/parisc/mm/fixmap.c +2 -2
@@ -10,7 +10,7 @@#include <asm/cacheflush.h> #include <asm/fixmap.h> -void set_fixmap (enum fixed_addresses idx,phys_addr_t phys) +void notrace set_fixmap(enum fixed_addresses idx, phys_addr_t phys) {unsigned long vaddr =__fix_to_virt (idx);pgd_t *pgd =pgd_offset_k (vaddr);
@@ -28,7 +28,7 @@ void set_fixmap(enum fixed_addresses idx, phys_addr_t phys)flush_tlb_kernel_range (vaddr, vaddr +PAGE_SIZE ); } -void clear_fixmap (enum fixed_addresses idx) +void notrace clear_fixmap(enum fixed_addresses idx) {unsigned long vaddr =__fix_to_virt (idx);pgd_t *pgd =pgd_offset_k (vaddr);
include/asm-generic/vmlinux.lds.h +7 -0
@@ -110,10 +110,17 @@#endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD +#ifdef CC_USING_PATCHABLE_FUNCTION_ENTRY +#define MCOUNT_REC () . = ALIGN(8); \ + __start_mcount_loc = .; \ + KEEP(*(__patchable_function_entries)) \ + __stop_mcount_loc = .; +#else #define MCOUNT_REC () . = ALIGN(8); \ __start_mcount_loc = .; \ KEEP(*(__mcount_loc)) \ __stop_mcount_loc = .; +#endif #else #define MCOUNT_REC ()#endif
Signature · 1 line
2.20.1