ftrace with regs + live patching for ppc64 LE (ABI v2)
Subsystems (4)
v3 cover ftrace with regs + live patching for ppc64 LE (ABI v2)
Hi all,
here is the current status of ftrace with regs, trace ops and live patching for ppc64le. It seems I broke the ftrace graph caller and I spent most of last week trying to fix it; Steven, maybe you could have a look? I startet out with -mprofile-kernel and now found that the ordinary -pg is very different. -mprofile-kernel only does the very bare minimal prologue (set TOC, save LR) and then calls _mcount, which poses some problems. I managed to get them resolved up to the point of the graph return ...
I tested intensively with the ftrace self tests, and, without the graph caller, this set passes all of them on ppc64le. I tried not to break BE, but may have missed an ifdef or two.
patch 2 (ftrace_modify_all_code default) is an independent prerequisite, I would even call it a fix -- please consider applying it even if you don't like the rest.
patch 5 has proven to be very useful during development; as mentioned earlier, many of these functions may get called during a recoverable fault. The whole recursion will probably terminate if all goes well, but I'd rather be defensive here.
Torsten Duwe (8):
ppc64le FTRACE_WITH_REGS implementation
ppc use ftrace_modify_all_code default
ppc64 ftrace_with_regs configuration variables
ppc64 ftrace_with_regs: spare early boot and low level ppc64 ftrace: disable profiling for some functions
ppc64 ftrace: disable profiling for some files
Implement kernel live patching for ppc64le (ABIv2)
Enable LIVEPATCH to be configured on ppc64le and add livepatch.o if it
is selected.
arch/powerpc/Kconfig | 7 ++ arch/powerpc/Makefile | 7 ++ arch/powerpc/include/asm/ftrace.h | 5 ++ arch/powerpc/include/asm/livepatch.h | 27 +++++++ arch/powerpc/kernel/Makefile | 13 +-- arch/powerpc/kernel/entry_64.S | 153 ++++++++++++++++++++++++++++++++++- arch/powerpc/kernel/ftrace.c | 88 +++++++++++++++----- arch/powerpc/kernel/livepatch.c | 20 +++++ arch/powerpc/kernel/module_64.c | 39 ++++++++- arch/powerpc/kernel/process.c | 2 +- arch/powerpc/lib/Makefile | 4 +- arch/powerpc/mm/fault.c | 2 +- arch/powerpc/mm/hash_utils_64.c | 18 ++--- arch/powerpc/mm/hugetlbpage-hash64.c | 2 +- arch/powerpc/mm/hugetlbpage.c | 4 +- arch/powerpc/mm/mem.c | 2 +- arch/powerpc/mm/pgtable_64.c | 2 +- arch/powerpc/mm/slb.c | 6 +- arch/powerpc/mm/slice.c | 8 +- kernel/trace/Kconfig | 5 ++ 20 files changed, 359 insertions(+), 55 deletions(-) create mode 100644 arch/powerpc/include/asm/livepatch.h create mode 100644 arch/powerpc/kernel/livepatch.c
Signature · 1 line
1.8.5.6
PATCH v3 1/8 ppc64le FTRACE_WITH_REGS implementation
Implement FTRACE_WITH_REGS for powerpc64, on ELF ABI v2. Initial work started by Vojtech Pavlik, used with permission.
* arch/powerpc/kernel/entry_64.S:
- enhance _mcount with a stub to support call sites generated by -mprofile-kernel. This is backward-compatible.
- Implement an effective ftrace_caller that works from within the kernel binary as well as from modules.
* arch/powerpc/kernel/ftrace.c:
- be prepared to deal with ppc64 ELF ABI v2, especially calls to _mcount that result from gcc -mprofile-kernel
- a little more error verbosity
* arch/powerpc/kernel/module_64.c:
- do not save the TOC pointer on the trampoline when the destination is ftrace_caller. This trampoline jump happens from a function prologue before a new stack frame is set up, so bad things may happen otherwise...
- relax is_module_trampoline() to recognise the modified trampoline.
--- arch/powerpc/include/asm/ftrace.h | 5 ++ arch/powerpc/kernel/entry_64.S | 113 +++++++++++++++++++++++++++++++++++++- arch/powerpc/kernel/ftrace.c | 72 +++++++++++++++++++++--- arch/powerpc/kernel/module_64.c | 39 ++++++++++++- 4 files changed, 217 insertions(+), 12 deletions(-)
arch/powerpc/include/asm/ftrace.h +5 -0
@@ -46,6 +46,8 @@extern void _mcount (void );#ifdef CONFIG_DYNAMIC_FTRACE +# define FTRACE_ADDR ((unsigned long)ftrace_caller) +# define FTRACE_REGS_ADDR FTRACE_ADDRstatic inline unsigned long ftrace_call_adjust (unsigned long addr) {/* reloction of mcount call site is the same as the address */
@@ -58,6 +60,9 @@ struct dyn_arch_ftrace {#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* __ASSEMBLY__ */ +#ifdef CONFIG_DYNAMIC_FTRACE +#define ARCH_SUPPORTS_FTRACE_OPS 1 +#endif #endif #if defined(CONFIG_FTRACE_SYSCALLS ) && defined(CONFIG_PPC64 ) && !defined(__ASSEMBLY__)
arch/powerpc/kernel/entry_64.S +112 -1
142 lines not on this page · raw message
arch/powerpc/kernel/ftrace.c +64 -8
120 lines not on this page · raw message
arch/powerpc/kernel/module_64.c +36 -3
@@ -138,12 +138,21 @@ static u32 ppc64_stub_insns[] = {0x4e800420 /* bctr */ }; +/* In case of _mcount calls or dynamic ftracing, Do not save the +* current callee's TOC (in R2) again into the original caller's stack +* frame during this trampoline hop. The stack frame already holds +* that of the original caller. _mcount and ftrace_caller will take +* care of this TOC value themselves. +*/ +#define SQUASH_TOC_SAVE_INSN (trampoline_addr) \ + (((struct ppc64_stub_entry *)(trampoline_addr))->jump[2] = PPC_INST_NOP) +#ifdef CONFIG_DYNAMIC_FTRACE static u32 ppc64_stub_mask[] = {0xffff0000 ,0xffff0000 , -0xffffffff , +0x00000000 ,0xffffffff , #if !defined(_CALL_ELF) || _CALL_ELF != 2 0xffffffff,
@@ -170,6 +179,9 @@ bool is_module_trampoline(u32 *p)if ((insna & mask) != (insnb & mask))return false; } +if (insns[2 ] != ppc64_stub_insns[2 ] && + insns[2 ] !=PPC_INST_NOP ) +return false;return true; }
@@ -475,6 +487,19 @@ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,static int restore_r2 (u32 *instruction,struct module *me) {if (*instruction !=PPC_INST_NOP ) { + +/* -mprofile_kernel sequence starting with +* mflr r0; std r0, LRSAVE(r1) +*/ +if (instruction[-3 ] ==0x7c0802a6 && + instruction[-2 ] ==0xf8010010 ) { +/* Nothing to be done here, it's an _mcount +* call location and r2 will have to be +* restored in the _mcount function. +*/ +return 2 ; + }; +pr_err ("%s: Expect noop after relocate, got %08x\n" , me->name, *instruction);return 0 ;
@@ -490,7 +515,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,unsigned int relsec, struct module *me) { - unsigned int i; + unsigned int i, r2;Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr;Elf64_Sym *sym;unsigned long *location;
@@ -603,8 +628,12 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, value =stub_for_addr (sechdrs, value, me);if (!value)return -ENOENT ; -if (!restore_r2 ((u32 *)location +1 , me)) + r2 =restore_r2 ((u32 *)location +1 , me); +if (!r2)return -ENOEXEC ; +/* Squash the TOC saver for profiler calls */ +if (!strcmp ("_mcount" , strtab+sym->st_name)) +SQUASH_TOC_SAVE_INSN (value); }else value +=local_entry_offset (sym);
@@ -665,6 +694,10 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, me->arch.tramp =stub_for_addr (sechdrs, (unsigned long )ftrace_caller, me); +/* ftrace_caller will take care of the TOC; +* do not clobber original caller's value. +*/ +SQUASH_TOC_SAVE_INSN (me->arch.tramp);#endif return 0 ;
Signature · 1 line
1.8.5.6
* Makefile:
- globally use -mprofile-kernel in case it's configured.
* arch/powerpc/Kconfig / kernel/trace/Kconfig:
- declare that ppc64 HAVE_MPROFILE_KERNEL and HAVE_DYNAMIC_FTRACE_WITH_REGS, and use it.
--- arch/powerpc/Kconfig | 2 ++ arch/powerpc/Makefile | 7 +++++++ kernel/trace/Kconfig | 5 +++++ 3 files changed, 14 insertions(+)
arch/powerpc/Kconfig +2 -0
@@ -97,8 +97,10 @@ config PPC select OF_RESERVED_MEM select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE + select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER + select HAVE_MPROFILE_KERNEL select SYSCTL_EXCEPTION_TRACE select ARCH_WANT_OPTIONAL_GPIOLIB select VIRT_TO_BUS if !PPC64
arch/powerpc/Makefile +7 -0
@@ -133,6 +133,13 @@ else CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 endif +ifeq ($(CONFIG_PPC64),y) +ifdef CONFIG_HAVE_MPROFILE_KERNEL +CC_FLAGS_FTRACE := -pg $(call cc-option,-mprofile-kernel) +KBUILD_CPPFLAGS += -DCC_USING_MPROFILE_KERNEL +endif +endif + CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell) CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4) CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5)
kernel/trace/Kconfig +5 -0
@@ -52,6 +52,11 @@ config HAVE_FENTRY help Arch supports the gcc options -pg with -mfentry +config HAVE_MPROFILE_KERNEL + bool + help + Arch supports the gcc options -pg with -mprofile-kernel + config HAVE_C_RECORDMCOUNT bool help
Signature · 1 line
1.8.5.6
kbuild test robot
build botreproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree…
Hi Torsten,
[auto build test ERROR on powerpc/next -- if it's inappropriate base, please suggest rules for selecting the more suitable base]
url: https://github.com/0day-ci/linux/commits/Torsten-Duwe/Re-PATCH-v3-0-8-ftrace-with-regs-live-patching-for-ppc64-LE-ABI-v2/20151027-020058 config: powerpc-ppc6xx_defconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=powerpc
All errors (new ones prefixed by >>):
kernel/built-in.o: In function `ftrace_get_addr_curr':
>> kernel/trace/ftrace.c:2286: undefined reference to `ftrace_regs_caller' >> kernel/trace/ftrace.c:2286: undefined reference to `ftrace_regs_caller' kernel/built-in.o: In function `ftrace_get_addr_new': kernel/trace/ftrace.c:2254: undefined reference to `ftrace_regs_caller' kernel/trace/ftrace.c:2254: undefined reference to `ftrace_regs_caller' kernel/built-in.o: In function `__ftrace_replace_code': >> kernel/trace/ftrace.c:2316: undefined reference to `ftrace_modify_call' kernel/built-in.o: In function `ftrace_get_addr_curr': >> kernel/trace/ftrace.c:2286: undefined reference to `ftrace_regs_caller' >> kernel/trace/ftrace.c:2286: undefined reference to `ftrace_regs_caller' kernel/built-in.o: In function `ftrace_get_addr_new': kernel/trace/ftrace.c:2254: undefined reference to `ftrace_regs_caller' kernel/trace/ftrace.c:2254: undefined reference to `ftrace_regs_caller' kernel/built-in.o: In function `ftrace_get_addr_curr': >> kernel/trace/ftrace.c:2286: undefined reference to `ftrace_regs_caller'
kernel/built-in.o:kernel/trace/ftrace.c:2286: more undefined references to `ftrace_regs_caller' follow
vim +2286 kernel/trace/ftrace.c
79922b80 Steven Rostedt (Red Hat 2014-05-06 2280) return (unsigned long)FTRACE_ADDR;
79922b80 Steven Rostedt (Red Hat 2014-05-06 2281) }
79922b80 Steven Rostedt (Red Hat 2014-05-06 2282) return ops->trampoline;
79922b80 Steven Rostedt (Red Hat 2014-05-06 2283) }
79922b80 Steven Rostedt (Red Hat 2014-05-06 2284)
7413af1f Steven Rostedt (Red Hat 2014-05-06 2285) if (rec->flags & FTRACE_FL_REGS_EN)
7413af1f Steven Rostedt (Red Hat 2014-05-06 @2286) return (unsigned long)FTRACE_REGS_ADDR;
7413af1f Steven Rostedt (Red Hat 2014-05-06 2287) else
7413af1f Steven Rostedt (Red Hat 2014-05-06 2288) return (unsigned long)FTRACE_ADDR;
7413af1f Steven Rostedt (Red Hat 2014-05-06 2289) }
7413af1f Steven Rostedt (Red Hat 2014-05-06 2290)
c88fd863 Steven Rostedt 2011-08-16 2291 static int
c88fd863 Steven Rostedt 2011-08-16 2292 __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
c88fd863 Steven Rostedt 2011-08-16 2293 {
08f6fba5 Steven Rostedt 2012-04-30 2294 unsigned long ftrace_old_addr;
c88fd863 Steven Rostedt 2011-08-16 2295 unsigned long ftrace_addr;
c88fd863 Steven Rostedt 2011-08-16 2296 int ret;
c88fd863 Steven Rostedt 2011-08-16 2297
7c0868e0 Steven Rostedt (Red Hat 2014-05-08 2298) ftrace_addr = ftrace_get_addr_new(rec);
c88fd863 Steven Rostedt 2011-08-16 2299
7c0868e0 Steven Rostedt (Red Hat 2014-05-08 2300) /* This needs to be done before we call ftrace_update_record */
7c0868e0 Steven Rostedt (Red Hat 2014-05-08 2301) ftrace_old_addr = ftrace_get_addr_curr(rec);
7c0868e0 Steven Rostedt (Red Hat 2014-05-08 2302)
7c0868e0 Steven Rostedt (Red Hat 2014-05-08 2303) ret = ftrace_update_record(rec, enable);
08f6fba5 Steven Rostedt 2012-04-30 2304
c88fd863 Steven Rostedt 2011-08-16 2305 switch (ret) {
c88fd863 Steven Rostedt 2011-08-16 2306 case FTRACE_UPDATE_IGNORE:
c88fd863 Steven Rostedt 2011-08-16 2307 return 0;
c88fd863 Steven Rostedt 2011-08-16 2308
c88fd863 Steven Rostedt 2011-08-16 2309 case FTRACE_UPDATE_MAKE_CALL:
c88fd863 Steven Rostedt 2011-08-16 2310 return ftrace_make_call(rec, ftrace_addr);
c88fd863 Steven Rostedt 2011-08-16 2311
c88fd863 Steven Rostedt 2011-08-16 2312 case FTRACE_UPDATE_MAKE_NOP:
39b5552c Steven Rostedt (Red Hat 2014-08-17 2313) return ftrace_make_nop(NULL, rec, ftrace_old_addr);
08f6fba5 Steven Rostedt 2012-04-30 2314
08f6fba5 Steven Rostedt 2012-04-30 2315 case FTRACE_UPDATE_MODIFY_CALL:
08f6fba5 Steven Rostedt 2012-04-30 @2316 return ftrace_modify_call(rec, ftrace_old_addr, ftrace_addr);
5072c59f Steven Rostedt 2008-05-12 2317 }
5072c59f Steven Rostedt 2008-05-12 2318
c88fd863 Steven Rostedt 2011-08-16 2319 return -1; /* unknow ftrace bug */:::::: The code at line 2286 was first introduced by commit
:::::: 7413af1fb70e7efa6dbc7f27663e7a5126b3aa33 ftrace: Make get_ftrace_addr() and get_ftrace_addr_old() global
:::::: TO: Steven Rostedt (Red Hat) <[email protected]> :::::: CC: Steven Rostedt <[email protected]>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
PATCH v3 2/8 ppc use ftrace_modify_all_code default
In reply to Torsten DuweConvert ppc's arch_ftrace_update_code from its own function copy to use the generic default functionality (without stop_machine -- our instructions are properly aligned and the replacements atomic ;)
With this we gain error checking and the much-needed function_trace_op handling.
--- arch/powerpc/kernel/ftrace.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-)
arch/powerpc/kernel/ftrace.c +4 -12
@@ -511,20 +511,12 @@ void ftrace_replace_code(int enable) } } +/* Use the default ftrace_modify_all_code, but without +* stop_machine(). +*/ void arch_ftrace_update_code (int command) { -if (command &FTRACE_UPDATE_CALLS ) -ftrace_replace_code (1 ); -else if (command &FTRACE_DISABLE_CALLS ) -ftrace_replace_code (0 ); - -if (command &FTRACE_UPDATE_TRACE_FUNC ) -ftrace_update_ftrace_func (ftrace_trace_function); - -if (command &FTRACE_START_FUNC_RET ) -ftrace_enable_ftrace_graph_caller (); -else if (command &FTRACE_STOP_FUNC_RET ) -ftrace_disable_ftrace_graph_caller (); +ftrace_modify_all_code (command); }int __init ftrace_dyn_arch_init (void )
Signature · 1 line
1.8.5.6
PATCH v3 3/8 ppc64 ftrace_with_regs configuration variables
In reply to Torsten Duwe * Makefile:
- globally use -mprofile-kernel in case it's configured.
* arch/powerpc/Kconfig / kernel/trace/Kconfig:
- declare that ppc64 HAVE_MPROFILE_KERNEL and HAVE_DYNAMIC_FTRACE_WITH_REGS, and use it.
--- arch/powerpc/Kconfig | 2 ++ arch/powerpc/Makefile | 7 +++++++ kernel/trace/Kconfig | 5 +++++ 3 files changed, 14 insertions(+)
arch/powerpc/Kconfig +2 -0
@@ -97,8 +97,10 @@ config PPC select OF_RESERVED_MEM select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE + select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER + select HAVE_MPROFILE_KERNEL select SYSCTL_EXCEPTION_TRACE select ARCH_WANT_OPTIONAL_GPIOLIB select VIRT_TO_BUS if !PPC64
arch/powerpc/Makefile +7 -0
@@ -133,6 +133,13 @@ else CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 endif +ifeq ($(CONFIG_PPC64),y) +ifdef CONFIG_HAVE_MPROFILE_KERNEL +CC_FLAGS_FTRACE := -pg $(call cc-option,-mprofile-kernel) +KBUILD_CPPFLAGS += -DCC_USING_MPROFILE_KERNEL +endif +endif + CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell) CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4) CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5)
kernel/trace/Kconfig +5 -0
@@ -52,6 +52,11 @@ config HAVE_FENTRY help Arch supports the gcc options -pg with -mfentry +config HAVE_MPROFILE_KERNEL + bool + help + Arch supports the gcc options -pg with -mprofile-kernel + config HAVE_C_RECORDMCOUNT bool help
Signature · 1 line
1.8.5.6
PATCH v3 4/8 ppc64 ftrace_with_regs: spare early boot and low level
In reply to Torsten DuweUsing -mprofile-kernel on early boot code not only confuses the checker but is also useless, as the infrastructure is not yet in place. Proceed like with -pg (remove it from CFLAGS), equally with time.o and ftrace itself.
* arch/powerpc/kernel/Makefile:
- remove -mprofile-kernel from low level and boot code objects' CFLAGS for FUNCTION_TRACER configurations.
--- arch/powerpc/kernel/Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
arch/powerpc/kernel/Makefile +6 -6
@@ -16,14 +16,14 @@ endif ifdef CONFIG_FUNCTION_TRACER # Do not trace early boot code -CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog -CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog -CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog -CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog +CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog -mprofile-kernel +CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog -mprofile-kernel +CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog -mprofile-kernel +CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog -mprofile-kernel # do not trace tracer code -CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog +CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog -mprofile-kernel # timers used by tracing -CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog +CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog -mprofile-kernel endif obj-y := cputable.o ptrace.o syscalls.o \
Signature · 1 line
1.8.5.6
PATCH v3 5/8 ppc64 ftrace: disable profiling for some functions
In reply to Torsten DuweAt least POWER7/8 have MMUs that don't completely autoload; a normal, recoverable memory fault might pass through these functions. If a dynamic tracer function causes such a fault, any of these functions being traced with -mprofile-kernel may cause an endless recursion.
--- arch/powerpc/kernel/process.c | 2 +- arch/powerpc/mm/fault.c | 2 +- arch/powerpc/mm/hash_utils_64.c | 18 +++++++++--------- arch/powerpc/mm/hugetlbpage-hash64.c | 2 +- arch/powerpc/mm/hugetlbpage.c | 4 ++-- arch/powerpc/mm/mem.c | 2 +- arch/powerpc/mm/pgtable_64.c | 2 +- arch/powerpc/mm/slb.c | 6 +++--- arch/powerpc/mm/slice.c | 8 ++++---- 9 files changed, 23 insertions(+), 23 deletions(-)
arch/powerpc/kernel/process.c +1 -1
@@ -715,7 +715,7 @@ static inline void __switch_to_tm(struct task_struct *prev)* don't know which of the checkpointed state and the transactional * state to use. */ -void restore_tm_state (struct pt_regs *regs) +notrace void restore_tm_state(struct pt_regs *regs) {unsigned long msr_diff;
arch/powerpc/mm/fault.c +1 -1
@@ -205,7 +205,7 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault)* The return value is 0 if the fault was handled, or the signal * number if this is a kernel fault that can't be handled here. */ -int __kprobes do_page_fault (struct pt_regs *regs,unsigned long address, +notrace int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,unsigned long error_code) {enum ctx_state prev_state =exception_enter ();
arch/powerpc/mm/hash_utils_64.c +9 -9
@@ -849,7 +849,7 @@ void early_init_mmu_secondary(void)/* * Called by asm hashtable.S for doing lazy icache flush */ -unsigned int hash_page_do_lazy_icache (unsigned int pp,pte_t pte,int trap) +notrace unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap) {struct page *page;
@@ -870,7 +870,7 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap) }#ifdef CONFIG_PPC_MM_SLICES -static unsigned int get_paca_psize (unsigned long addr) +static notrace unsigned int get_paca_psize(unsigned long addr) {u64 lpsizes;unsigned char *hpsizes;
@@ -899,7 +899,7 @@ unsigned int get_paca_psize(unsigned long addr)* For now this makes the whole process use 4k pages. */ #ifdef CONFIG_PPC_64K_PAGES -void demote_segment_4k (struct mm_struct *mm,unsigned long addr) +notrace void demote_segment_4k(struct mm_struct *mm, unsigned long addr) {if (get_slice_psize (mm, addr) ==MMU_PAGE_4K )return ;
@@ -920,7 +920,7 @@ void demote_segment_4k(struct mm_struct *mm, unsigned long addr)* Result is 0: full permissions, _PAGE_RW: read-only, * _PAGE_USER or _PAGE_USER|_PAGE_RW: no access. */ -static int subpage_protection (struct mm_struct *mm,unsigned long ea) +static notrace int subpage_protection(struct mm_struct *mm, unsigned long ea) {struct subpage_prot_table *spt = &mm->context.spt;u32 spp =0 ;
@@ -968,7 +968,7 @@ void hash_failure_debug(unsigned long ea, unsigned long access, trap, vsid, ssize, psize, lpsize, pte); } -static void check_paca_psize (unsigned long ea,struct mm_struct *mm, +static notrace void check_paca_psize(unsigned long ea, struct mm_struct *mm,int psize,bool user_region) {if (user_region) {
@@ -990,7 +990,7 @@ static void check_paca_psize(unsigned long ea, struct mm_struct *mm,* -1 - critical hash insertion error * -2 - access not permitted by subpage protection mechanism */ -int hash_page_mm (struct mm_struct *mm,unsigned long ea, +notrace int hash_page_mm(struct mm_struct *mm, unsigned long ea,unsigned long access,unsigned long trap,unsigned long flags) {
@@ -1186,7 +1186,7 @@ bail: }EXPORT_SYMBOL_GPL (hash_page_mm); -int hash_page (unsigned long ea,unsigned long access,unsigned long trap, +notrace int hash_page(unsigned long ea, unsigned long access, unsigned long trap,unsigned long dsisr) {unsigned long flags =0 ;
@@ -1288,7 +1288,7 @@ out_exit:/* WARNING: This is called from hash_low_64.S, if you change this prototype, * do not forget to update the assembly call site ! */ -void flush_hash_page (unsigned long vpn,real_pte_t pte,int psize,int ssize, +notrace void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, int ssize,unsigned long flags) {unsigned long hash, index, shift, hidx, slot;
@@ -1436,7 +1436,7 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc)exception_exit (prev_state); } -long hpte_insert_repeating (unsigned long hash,unsigned long vpn, +notrace long hpte_insert_repeating (unsigned long hash,unsigned long vpn,unsigned long pa,unsigned long rflags,unsigned long vflags,int psize,int ssize) {
arch/powerpc/mm/hugetlbpage-hash64.c +1 -1
@@ -18,7 +18,7 @@ extern long hpte_insert_repeating(unsigned long hash, unsigned long vpn, unsigned long pa, unsigned long rlags, unsigned long vflags, int psize, int ssize); -int __hash_page_huge (unsigned long ea,unsigned long access,unsigned long vsid, +notrace int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,pte_t *ptep,unsigned long trap,unsigned long flags,int ssize,unsigned int shift,unsigned int mmu_psize) {
arch/powerpc/mm/hugetlbpage.c +2 -2
@@ -922,7 +922,7 @@ static int __init hugetlbpage_init(void)#endif arch_initcall (hugetlbpage_init); -void flush_dcache_icache_hugepage (struct page *page) +notrace void flush_dcache_icache_hugepage(struct page *page) {int i;void *start;
@@ -955,7 +955,7 @@ void flush_dcache_icache_hugepage(struct page *page)* when we have MSR[EE] = 0 but the paca->soft_enabled = 1 */ -pte_t *__find_linux_pte_or_hugepte (pgd_t *pgdir,unsigned long ea, +notrace pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,unsigned *shift) {pgd_t pgd, *pgdp;
arch/powerpc/mm/mem.c +1 -1
@@ -406,7 +406,7 @@ void flush_dcache_page(struct page *page) }EXPORT_SYMBOL (flush_dcache_page); -void flush_dcache_icache_page (struct page *page) +notrace void flush_dcache_icache_page(struct page *page) {#ifdef CONFIG_HUGETLB_PAGE if (PageCompound (page)) {
arch/powerpc/mm/pgtable_64.c +1 -1
@@ -442,7 +442,7 @@ static void page_table_free_rcu(void *table) } } -void pgtable_free_tlb (struct mmu_gather *tlb,void *table,int shift) +notrace void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift) {unsigned long pgf = (unsigned long )table;
arch/powerpc/mm/slb.c +3 -3
@@ -91,7 +91,7 @@ static inline void create_shadowed_slbe(unsigned long ea, int ssize, : "memory" ); } -static void __slb_flush_and_rebolt (void ) +static notrace void __slb_flush_and_rebolt(void) {/* If you change this make sure you change SLB_NUM_BOLTED * and PR KVM appropriately too. */
@@ -131,7 +131,7 @@ static void __slb_flush_and_rebolt(void) : "memory"); } -void slb_flush_and_rebolt (void ) +notrace void slb_flush_and_rebolt(void) {WARN_ON (!irqs_disabled ());
@@ -146,7 +146,7 @@ void slb_flush_and_rebolt(void)get_paca ()->slb_cache_ptr =0 ; } -void slb_vmalloc_update (void ) +notrace void slb_vmalloc_update(void) {unsigned long vflags;
arch/powerpc/mm/slice.c +4 -4
@@ -76,8 +76,8 @@ static void slice_print_mask(const char *label, struct slice_mask mask) {}#endif -static struct slice_mask slice_range_to_mask (unsigned long start, -unsigned long len) +static notrace struct slice_mask slice_range_to_mask(unsigned long start, +unsigned long len) {unsigned long end = start + len -1 ;struct slice_mask ret = {0 ,0 };
@@ -564,7 +564,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, current->mm->context.user_psize, 1); } -unsigned int get_slice_psize (struct mm_struct *mm,unsigned long addr) +notrace unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr) {unsigned char *hpsizes;int index, mask_index;
@@ -645,7 +645,7 @@ void slice_set_user_psize(struct mm_struct *mm, unsigned int psize)spin_unlock_irqrestore (&slice_convert_lock, flags); } -void slice_set_range_psize (struct mm_struct *mm,unsigned long start, +notrace void slice_set_range_psize(struct mm_struct *mm, unsigned long start,unsigned long len,unsigned int psize) {struct slice_mask mask =slice_range_to_mask (start, len);
Signature · 1 line
1.8.5.6
PATCH v3 6/8 ppc64 ftrace: disable profiling for some files
In reply to Torsten DuweThis adds -mprofile-kernel to the cc flags to be stripped from the command line for code-patching.o and feature-fixups.o, in addition to "-pg"
--- arch/powerpc/lib/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/lib/Makefile +2 -2
@@ -6,8 +6,8 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) -CFLAGS_REMOVE_code-patching.o = -pg -CFLAGS_REMOVE_feature-fixups.o = -pg +CFLAGS_REMOVE_code-patching.o = -pg -mprofile-kernel +CFLAGS_REMOVE_feature-fixups.o = -pg -mprofile-kernel obj-y += string.o alloc.o crtsavres.o ppc_ksyms.o code-patching.o \ feature-fixups.o
Signature · 1 line
1.8.5.6
PATCH v3 7/8 Implement kernel live patching for ppc64le (ABIv2)
In reply to Torsten Duwe * create the appropriate files+functions arch/powerpc/include/asm/livepatch.h klp_check_compiler_support,
klp_arch_set_pc
arch/powerpc/kernel/livepatch.c with a stub for
klp_write_module_reloc
This is architecture-independent work in progress.
* introduce a fixup in arch/powerpc/kernel/entry_64.S for local calls that are becoming global due to live patching. And of course do the main KLP thing: return to a maybe different address, possibly altered by the live patching ftrace op.
--- arch/powerpc/include/asm/livepatch.h | 27 ++++++++++++++++++++ arch/powerpc/kernel/entry_64.S | 48 +++++++++++++++++++++++++++++++++--- arch/powerpc/kernel/livepatch.c | 20 +++++++++++++++ 3 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/include/asm/livepatch.h create mode 100644 arch/powerpc/kernel/livepatch.c
arch/powerpc/include/asm/livepatch.h new file +27 -0
@@ -0,0 +1,27 @@ +#ifndef _ASM_POWERPC64_LIVEPATCH_H +#define _ASM_POWERPC64_LIVEPATCH_H + +#include <linux/module.h> +#include <linux/ftrace.h> + +#ifdef CONFIG_LIVEPATCH +static inline int klp_check_compiler_support (void ) +{ +#if !defined(_CALL_ELF) || _CALL_ELF !=2 +return 1 ; +#endif +return 0 ; +} + +extern int klp_write_module_reloc (struct module *mod,unsigned long type, +unsigned long loc,unsigned long value); + +static inline void klp_arch_set_pc (struct pt_regs *regs,unsigned long ip) +{ + regs->nip = ip; +} +#else +#error Live patching support is disabled; check CONFIG_LIVEPATCH +#endif + +#endif /* _ASM_POWERPC64_LIVEPATCH_H */
arch/powerpc/kernel/entry_64.S +44 -4
78 lines not on this page · raw message
arch/powerpc/kernel/livepatch.c new file +20 -0
@@ -0,0 +1,20 @@ +#include <linux/module.h> +#include <asm/livepatch.h> + +/** +* klp_write_module_reloc() - write a relocation in a module +* @mod: module in which the section to be modified is found +* @type: ELF relocation type (see asm/elf.h) +* @loc: address that the relocation should be written to +* @value: relocation value (sym address + addend) +* +* This function writes a relocation to the specified location for +* a particular module. +*/ +int klp_write_module_reloc (struct module *mod,unsigned long type, +unsigned long loc,unsigned long value) +{ +/* This requires infrastructure changes; we need the loadinfos. */ +pr_err ("lpc_write_module_reloc not yet supported\n" ); +return -ENOSYS ; +}
Signature · 1 line
1.8.5.6
PATCH v3 8/8 Enable LIVEPATCH to be configured on ppc64le and add livepatch.o if it is selected.
In reply to Torsten Duwe--- arch/powerpc/Kconfig | 5 +++++ arch/powerpc/kernel/Makefile | 1 + 2 files changed, 6 insertions(+)
arch/powerpc/Kconfig +5 -0
@@ -163,6 +163,9 @@ config PPC select ARCH_HAS_DMA_SET_COHERENT_MASK select HAVE_ARCH_SECCOMP_FILTER +config HAVE_LIVEPATCH + def_bool PPC64 && CPU_LITTLE_ENDIAN + config GENERIC_CSUM def_bool CPU_LITTLE_ENDIAN
@@ -1095,3 +1098,5 @@ config PPC_LIB_RHEAP bool source "arch/powerpc/kvm/Kconfig" + +source "kernel/livepatch/Kconfig"
arch/powerpc/kernel/Makefile +1 -0
@@ -119,6 +119,7 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o obj-$(CONFIG_TRACING) += trace_clock.o +obj-$(CONFIG_LIVEPATCH) += livepatch.o ifneq ($(CONFIG_PPC_INDIRECT_PIO),y) obj-y += iomap.o
Signature · 1 line
1.8.5.6