arm64: add livepatch support
cover arm64: add livepatch support
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
Please note that I tested the feature only with livepatch-sample, and the code for DYNAMIC_TRACE_WITH_REGS is still rough-edged.
To: Steven Rostedt <[email protected]>
To: Ingo Molnar <[email protected]>
To: Josh Poimboeuf <[email protected]>
To: Seth Jennings <[email protected]>
To: Jiri Kosina <[email protected]>
To: Vojtech Pavlik <[email protected]>
To: Catalin Marinas <[email protected]>
To: Will Deacon <[email protected]>
AKASHI Takahiro (4):
ftrace: add a helper function for livepatch
livepatch: adjust a patched function's address
arm64: ftrace: add DYNAMIC_TRACE_WITH_REGS version
arm64: add livepatch support
arch/arm64/Kconfig | 4 ++ arch/arm64/include/asm/ftrace.h | 4 ++ arch/arm64/include/asm/livepatch.h | 38 +++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/entry-ftrace.S | 124 ++++++++++++++++++++++++++++++++++++ arch/arm64/kernel/ftrace.c | 24 ++++++- arch/arm64/kernel/livepatch.c | 68 ++++++++++++++++++++ arch/x86/include/asm/livepatch.h | 5 ++ include/linux/ftrace.h | 2 + include/linux/livepatch.h | 2 + kernel/livepatch/core.c | 16 +++-- kernel/trace/ftrace.c | 26 ++++++++ 12 files changed, 309 insertions(+), 5 deletions(-) create mode 100644 arch/arm64/include/asm/livepatch.h create mode 100644 arch/arm64/kernel/livepatch.c
Signature · 1 line
1.7.9.5
RFC 1/4 ftrace: add a helper function for livepatch
ftrace_lookup_mcount() will return an address of mcount call in a function.
--- include/linux/ftrace.h | 2 ++ kernel/trace/ftrace.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+)
include/linux/ftrace.h +2 -0
@@ -699,6 +699,8 @@ static inline void __ftrace_enabled_restore(int enabled)# define trace_preempt_off (a0, a1) do { } while (0)#endif +extern unsigned long ftrace_lookup_mcount (unsigned long addr); +#ifdef CONFIG_FTRACE_MCOUNT_RECORD extern void ftrace_init (void );#else
kernel/trace/ftrace.c +26 -0
@@ -4857,6 +4857,32 @@ static int ftrace_process_locs(struct module *mod,return ret; } +unsigned long ftrace_lookup_mcount (unsigned long addr) +{ +struct ftrace_page *pg; +struct dyn_ftrace *rec; +char str[KSYM_SYMBOL_LEN ]; +char *modname; +const char *name; +unsigned long mcount =0 ; +unsigned long offset; + +mutex_lock (&ftrace_lock); + +do_for_each_ftrace_rec (pg, rec) { + name =kallsyms_lookup (rec->ip,NULL , &offset, &modname, str); +if (name && rec->ip == (addr + offset)) { + mcount = rec->ip; + goto out_unlock; + } + }while_for_each_ftrace_rec (); + + out_unlock: +mutex_unlock (&ftrace_lock); + +return mcount; +} +#ifdef CONFIG_MODULES #define next_to_ftrace_page (p) container_of(p, struct ftrace_page, next)
Signature · 1 line
1.7.9.5
RFC 2/4 livepatch: adjust a patched function's address
In reply to AKASHI TakahiroThe existing livepatch code assumes that a fentry call is inserted before a function prolog by -mfentry option of gcc. But the location of mcount() can be identified by using ftrace_lookup_mcount(), and which eventually allows arch's which don't support -mfentry option, like arm64, to support livepatch.
This patch modifies core and x86 code before adding livepatch support for arm64.
--- arch/x86/include/asm/livepatch.h | 5 +++++ include/linux/livepatch.h | 2 ++ kernel/livepatch/core.c | 16 ++++++++++++---- 3 files changed, 19 insertions(+), 4 deletions(-)
arch/x86/include/asm/livepatch.h +5 -0
@@ -39,6 +39,11 @@ static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip) { regs->ip = ip; } + +static inline unsigned long klp_arch_lookup_mcount (unsigned long addr) +{ +return addr; +}#else #error Live patching support is disabled; check CONFIG_LIVEPATCH#endif
include/linux/livepatch.h +2 -0
@@ -47,6 +47,7 @@ struct klp_func {/* external */ const char *old_name;void *new_func; +unsigned long new_func_mcount;/* * The old_addr field is optional and can be used to resolve * duplicate symbol names in the vmlinux object. If this
@@ -56,6 +57,7 @@ struct klp_func {* way to resolve the ambiguity. */ unsigned long old_addr; +unsigned long old_addr_mcount;/* internal */ struct kobject kobj;
kernel/livepatch/core.c +12 -4
@@ -245,6 +245,9 @@ static int klp_find_verify_func_addr(struct klp_object *obj, ret =klp_verify_vmlinux_symbol (func->old_name, func->old_addr); +if (func->old_addr && !ret) + func->old_addr_mcount =klp_arch_lookup_mcount (func->old_addr); +return ret; }
@@ -330,7 +333,7 @@ static void notrace klp_ftrace_handler(unsigned long ip,if (WARN_ON_ONCE (!func)) goto unlock; -klp_arch_set_pc (regs, (unsigned long )func->new_func); +klp_arch_set_pc (regs, func->new_func_mcount); unlock:rcu_read_unlock (); }
@@ -358,7 +361,8 @@ static int klp_disable_func(struct klp_func *func)return ret; } - ret =ftrace_set_filter_ip (&ops->fops, func->old_addr,1 ,0 ); + ret =ftrace_set_filter_ip (&ops->fops, + func->old_addr_mcount,1 ,0 );if (ret)pr_warn ("function unregister succeeded but failed to clear the filter\n" );
@@ -401,7 +405,8 @@ static int klp_enable_func(struct klp_func *func)INIT_LIST_HEAD (&ops->func_stack);list_add_rcu (&func->stack_node, &ops->func_stack); - ret =ftrace_set_filter_ip (&ops->fops, func->old_addr,0 ,0 ); + ret =ftrace_set_filter_ip (&ops->fops, + func->old_addr_mcount,0 ,0 );if (ret) {pr_err ("failed to set ftrace filter for function '%s' (%d)\n" , func->old_name, ret);
@@ -412,7 +417,8 @@ static int klp_enable_func(struct klp_func *func)if (ret) {pr_err ("failed to register ftrace handler for function '%s' (%d)\n" , func->old_name, ret); -ftrace_set_filter_ip (&ops->fops, func->old_addr,1 ,0 ); +ftrace_set_filter_ip (&ops->fops, + func->old_addr_mcount,1 ,0 ); goto err; }
@@ -742,6 +748,8 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func) {INIT_LIST_HEAD (&func->stack_node); func->state =KLP_DISABLED ; + func->new_func_mcount = +klp_arch_lookup_mcount ((unsigned long )func->new_func);return kobject_init_and_add (&func->kobj, &klp_ktype_func, obj->kobj,"%s" , func->old_name);
Signature · 1 line
1.7.9.5
RFC 3/4 arm64: ftrace: add DYNAMIC_TRACE_WITH_REGS version
In reply to AKASHI TakahiroCONFIG_DYNAMIC_TRACE_WITH_REGS is a prerequisite for ftrace-based kprobes as well as livepatch.
This patch adds ftrace_regs_caller(), which will pass pt_regs info to ftrace handlers, to enable this config.
--- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/ftrace.h | 4 ++ arch/arm64/kernel/entry-ftrace.S | 124 ++++++++++++++++++++++++++++++++++++++ arch/arm64/kernel/ftrace.c | 24 +++++++- 4 files changed, 152 insertions(+), 1 deletion(-)
arch/arm64/Kconfig +1 -0
@@ -54,6 +54,7 @@ config ARM64 select HAVE_DMA_ATTRS select HAVE_DMA_CONTIGUOUS select HAVE_DYNAMIC_FTRACE + select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_EFFICIENT_UNALIGNED_ACCESS select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_TRACER
arch/arm64/include/asm/ftrace.h +4 -0
@@ -16,6 +16,10 @@#define MCOUNT_ADDR ((unsigned long)_mcount)#define MCOUNT_INSN_SIZE AARCH64_INSN_SIZE +#ifdef CONFIG_DYNAMIC_FTRACE +#define ARCH_SUPPORTS_FTRACE_OPS 1 +#endif +#ifndef __ASSEMBLY__#include <linux/compat.h>
arch/arm64/kernel/entry-ftrace.S +124 -0
148 lines not on this page · raw message
arch/arm64/kernel/ftrace.c +23 -1
@@ -56,12 +56,21 @@ int ftrace_update_ftrace_func(ftrace_func_t func) {unsigned long pc;u32 new; +int ret; pc = (unsigned long )&ftrace_call; new =aarch64_insn_gen_branch_imm (pc, (unsigned long )func,AARCH64_INSN_BRANCH_LINK ); + ret =ftrace_modify_code (pc,0 , new, false); -return ftrace_modify_code (pc,0 , new, false); +if (!ret) { + pc = (unsigned long )&ftrace_regs_call; + new =aarch64_insn_gen_branch_imm (pc, (unsigned long )func, +AARCH64_INSN_BRANCH_LINK ); + ret =ftrace_modify_code (pc,0 , new, false); + } + +return ret; }/*
@@ -97,6 +106,19 @@ int __init ftrace_dyn_arch_init(void) {return 0 ; } + +int ftrace_modify_call (struct dyn_ftrace *rec,unsigned long old_addr, +unsigned long addr) +{ +unsigned long pc = rec->ip; +u32 old, new; + + old =aarch64_insn_gen_branch_imm (pc, old_addr, +AARCH64_INSN_BRANCH_LINK ); + new =aarch64_insn_gen_branch_imm (pc, addr,AARCH64_INSN_BRANCH_LINK ); + +return ftrace_modify_code (pc, old, new, true); +}#endif /* CONFIG_DYNAMIC_FTRACE */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
Signature · 1 line
1.7.9.5
RFC 4/4 arm64: add livepatch support
In reply to AKASHI Takahiro--- arch/arm64/Kconfig | 3 ++ arch/arm64/include/asm/livepatch.h | 38 ++++++++++++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/livepatch.c | 68 ++++++++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+) create mode 100644 arch/arm64/include/asm/livepatch.h create mode 100644 arch/arm64/kernel/livepatch.c
arch/arm64/Kconfig +3 -0
@@ -61,6 +61,7 @@ config ARM64 select HAVE_FUNCTION_GRAPH_TRACER select HAVE_GENERIC_DMA_COHERENT select HAVE_HW_BREAKPOINT if PERF_EVENTS + select HAVE_LIVEPATCH select HAVE_MEMBLOCK select HAVE_PATA_PLATFORM select HAVE_PERF_EVENTS
@@ -612,6 +613,8 @@ config SETEND_EMULATION If unsure, say Y endif +source "kernel/livepatch/Kconfig" + endmenu menu "Boot options"
arch/arm64/include/asm/livepatch.h new file +38 -0
@@ -0,0 +1,38 @@ +/* +* Copyright (C) 2015 Linaro Limited +* Author: AKASHI Takahiro <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ +#ifndef __ASM_LIVEPATCH_H +#define __ASM_LIVEPATCH_H + +#include <linux/module.h> +#include <linux/ftrace.h> + +#ifdef CONFIG_LIVEPATCH +static inline int klp_check_compiler_support (void ) +{ +return 0 ; +} +extern int klp_write_module_reloc (struct module *mod,unsigned long type, +unsigned long loc,unsigned long value); + +extern unsigned long ftrace_lookup_mcount (unsigned long addr); + +static inline void klp_arch_set_pc (struct pt_regs *regs,unsigned long ip) +{ + regs->regs[30 ] = ip; +} + +static inline unsigned long klp_arch_lookup_mcount (unsigned long addr) +{ +return ftrace_lookup_mcount (addr); +} +#else +#error Live patching support is disabled; check CONFIG_LIVEPATCH +#endif + +#endif /* __ASM_LIVEPATCH_H */
arch/arm64/kernel/Makefile +1 -0
@@ -35,6 +35,7 @@ arm64-obj-$(CONFIG_KGDB) += kgdb.o arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o arm64-obj-$(CONFIG_PCI) += pci.o arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o +arm64-obj-$(CONFIG_LIVEPATCH) += livepatch.o obj-y += $(arm64-obj-y) vdso/ obj-m += $(arm64-obj-m)
arch/arm64/kernel/livepatch.c new file +68 -0
68 lines not on this page · raw message
Signature · 1 line
1.7.9.5
Steven Rostedt
maintainerQuoted 10 lines · On Fri, 24 Apr 2015 11:44:05 +0900 AKASHI Takahiro…
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
You need to be extremely careful about this. I don't know what arm does with mcount but on x86 without -fentry, it sets up the stack frame before calling mcount. That is, if mcount returns to a different function, it doesn't mean that the registers will match the parameters.
I have to look at what arm64 does when compiled with -pg. Because, if it moves registers around before the mcount, you will have a disaster on your hands if it returns to a different function that moved the registers around differently.
Also, you need to be careful about how link registers are handled.
-- Steve
Quoted 35 lines
Please note that I tested the feature only with livepatch-sample, and the code for
DYNAMIC_TRACE_WITH_REGSis still rough-edged.To: Steven Rostedt <[email protected]>
To: Ingo Molnar <[email protected]>
To: Josh Poimboeuf <[email protected]>
To: Seth Jennings <[email protected]>
To: Jiri Kosina <[email protected]>
To: Vojtech Pavlik <[email protected]>
To: Catalin Marinas <[email protected]>
To: Will Deacon <[email protected]>AKASHI Takahiro (4):
ftrace: add a helper function for livepatch
livepatch: adjust a patched function's address
arm64: ftrace: addDYNAMIC_TRACE_WITH_REGSversion
arm64: add livepatch supportarch/arm64/Kconfig | 4 ++ arch/arm64/include/asm/ftrace.h | 4 ++ arch/arm64/include/asm/livepatch.h | 38 +++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/entry-ftrace.S | 124 ++++++++++++++++++++++++++++++++++++ arch/arm64/kernel/ftrace.c | 24 ++++++- arch/arm64/kernel/livepatch.c | 68 ++++++++++++++++++++ arch/x86/include/asm/livepatch.h | 5 ++ include/linux/ftrace.h | 2 + include/linux/livepatch.h | 2 + kernel/livepatch/core.c | 16 +++-- kernel/trace/ftrace.c | 26 ++++++++ 12 files changed, 309 insertions(+), 5 deletions(-) create mode 100644 arch/arm64/include/asm/livepatch.h create mode 100644 arch/arm64/kernel/livepatch.c
Quoted 8 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
This is not correct for the case that the prologue of the old and new function is different.
Thanks,
Li Bin
Quoted 37 lines
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
Please note that I tested the feature only with livepatch-sample, and the code for
DYNAMIC_TRACE_WITH_REGSis still rough-edged.To: Steven Rostedt <[email protected]>
To: Ingo Molnar <[email protected]>
To: Josh Poimboeuf <[email protected]>
To: Seth Jennings <[email protected]>
To: Jiri Kosina <[email protected]>
To: Vojtech Pavlik <[email protected]>
To: Catalin Marinas <[email protected]>
To: Will Deacon <[email protected]>AKASHI Takahiro (4):
ftrace: add a helper function for livepatch
livepatch: adjust a patched function's address
arm64: ftrace: addDYNAMIC_TRACE_WITH_REGSversion
arm64: add livepatch supportarch/arm64/Kconfig | 4 ++ arch/arm64/include/asm/ftrace.h | 4 ++ arch/arm64/include/asm/livepatch.h | 38 +++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/entry-ftrace.S | 124 ++++++++++++++++++++++++++++++++++++ arch/arm64/kernel/ftrace.c | 24 ++++++- arch/arm64/kernel/livepatch.c | 68 ++++++++++++++++++++ arch/x86/include/asm/livepatch.h | 5 ++ include/linux/ftrace.h | 2 + include/linux/livepatch.h | 2 + kernel/livepatch/core.c | 16 +++-- kernel/trace/ftrace.c | 26 ++++++++ 12 files changed, 309 insertions(+), 5 deletions(-) create mode 100644 arch/arm64/include/asm/livepatch.h create mode 100644 arch/arm64/kernel/livepatch.c
Quoted 10 lines · Li Bin
Quoted 8 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
Quoted 2 lines
This is not correct for the case that the prologue of the old and new function is different.
Hmm, is that possible to support -mfentry on arm64?
Of course we can not call a function directly at the first instruction of functions on arm, because it can overwrite link register which stores caller address. However, we can do "store link register to stack and branch with link" on arm. That is actually almost same as -mfentry does :), and that may not depend on the prologue.
Thank you,
Quoted 43 lines
Thanks,
Li BinQuoted 37 lines
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
Please note that I tested the feature only with livepatch-sample, and the code for
DYNAMIC_TRACE_WITH_REGSis still rough-edged.To: Steven Rostedt <[email protected]>
To: Ingo Molnar <[email protected]>
To: Josh Poimboeuf <[email protected]>
To: Seth Jennings <[email protected]>
To: Jiri Kosina <[email protected]>
To: Vojtech Pavlik <[email protected]>
To: Catalin Marinas <[email protected]>
To: Will Deacon <[email protected]>AKASHI Takahiro (4):
ftrace: add a helper function for livepatch
livepatch: adjust a patched function's address
arm64: ftrace: addDYNAMIC_TRACE_WITH_REGSversion
arm64: add livepatch supportarch/arm64/Kconfig | 4 ++ arch/arm64/include/asm/ftrace.h | 4 ++ arch/arm64/include/asm/livepatch.h | 38 +++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/entry-ftrace.S | 124 ++++++++++++++++++++++++++++++++++++ arch/arm64/kernel/ftrace.c | 24 ++++++- arch/arm64/kernel/livepatch.c | 68 ++++++++++++++++++++ arch/x86/include/asm/livepatch.h | 5 ++ include/linux/ftrace.h | 2 + include/linux/livepatch.h | 2 + kernel/livepatch/core.c | 16 +++-- kernel/trace/ftrace.c | 26 ++++++++ 12 files changed, 309 insertions(+), 5 deletions(-) create mode 100644 arch/arm64/include/asm/livepatch.h create mode 100644 arch/arm64/kernel/livepatch.c
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: masami.hiramatsu.pt at hitachi.com
Steve, Li and Masami,
Thank you for all your comments. You pointed out the cases that I didn't think of. Let me think how I can manage the issues for a while.
Probably I will talk to gcc guys.
-Takahiro AKASHI
Quoted 71 lines · Masami Hiramatsu
Quoted 10 lines · Li Bin
Quoted 8 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
Quoted 2 lines
This is not correct for the case that the prologue of the old and new function is different.
Hmm, is that possible to support -mfentry on arm64?
Of course we can not call a function directly at the first instruction of functions on arm, because it can overwrite link register which stores caller address. However, we can do "store link register to stack and branch with link" on arm. That is actually almost same as -mfentry does :), and that may not depend on the prologue.
Thank you,
Quoted 43 lines
Thanks,
Li BinQuoted 37 lines
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
Please note that I tested the feature only with livepatch-sample, and the code for
DYNAMIC_TRACE_WITH_REGSis still rough-edged.To: Steven Rostedt <[email protected]>
To: Ingo Molnar <[email protected]>
To: Josh Poimboeuf <[email protected]>
To: Seth Jennings <[email protected]>
To: Jiri Kosina <[email protected]>
To: Vojtech Pavlik <[email protected]>
To: Catalin Marinas <[email protected]>
To: Will Deacon <[email protected]>AKASHI Takahiro (4):
ftrace: add a helper function for livepatch
livepatch: adjust a patched function's address
arm64: ftrace: addDYNAMIC_TRACE_WITH_REGSversion
arm64: add livepatch supportarch/arm64/Kconfig | 4 ++ arch/arm64/include/asm/ftrace.h | 4 ++ arch/arm64/include/asm/livepatch.h | 38 +++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/entry-ftrace.S | 124 ++++++++++++++++++++++++++++++++++++ arch/arm64/kernel/ftrace.c | 24 ++++++- arch/arm64/kernel/livepatch.c | 68 ++++++++++++++++++++ arch/x86/include/asm/livepatch.h | 5 ++ include/linux/ftrace.h | 2 + include/linux/livepatch.h | 2 + kernel/livepatch/core.c | 16 +++-- kernel/trace/ftrace.c | 26 ++++++++ 12 files changed, 309 insertions(+), 5 deletions(-)create mode 100644
arch/arm64/include/asm/livepatch.hcreate mode 100644arch/arm64/kernel/livepatch.c
Quoted 14 lines · Masami Hiramatsu
Quoted 10 lines · Li Bin
Quoted 8 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
Quoted 2 lines
This is not correct for the case that the prologue of the old and new function is different.
Quoted 9 lines
Hmm, is that possible to support -mfentry on arm64?
Of course we can not call a function directly at the first instruction of functions on arm, because it can overwrite link register which stores caller address. However, we can do "store link register to stack and branch with link" on arm. That is actually almost same as -mfentry does :), and that may not depend on the prologue.
Yes, but the method "store link register to stack" will break the arm64 ABI rules, and memory operations may bring performance cost.
We have a gcc -mfentry implementation strategy for arm64, and based on this we implement the livepatch for arm64.
I will post the patchset for review soon.
Thank you,
Li Bin
Quoted 48 lines
Thank you,
Quoted 43 lines
Thanks,
Li BinQuoted 37 lines
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
Please note that I tested the feature only with livepatch-sample, and the code for
DYNAMIC_TRACE_WITH_REGSis still rough-edged.To: Steven Rostedt <[email protected]>
To: Ingo Molnar <[email protected]>
To: Josh Poimboeuf <[email protected]>
To: Seth Jennings <[email protected]>
To: Jiri Kosina <[email protected]>
To: Vojtech Pavlik <[email protected]>
To: Catalin Marinas <[email protected]>
To: Will Deacon <[email protected]>AKASHI Takahiro (4):
ftrace: add a helper function for livepatch
livepatch: adjust a patched function's address
arm64: ftrace: addDYNAMIC_TRACE_WITH_REGSversion
arm64: add livepatch supportarch/arm64/Kconfig | 4 ++ arch/arm64/include/asm/ftrace.h | 4 ++ arch/arm64/include/asm/livepatch.h | 38 +++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/entry-ftrace.S | 124 ++++++++++++++++++++++++++++++++++++ arch/arm64/kernel/ftrace.c | 24 ++++++- arch/arm64/kernel/livepatch.c | 68 ++++++++++++++++++++ arch/x86/include/asm/livepatch.h | 5 ++ include/linux/ftrace.h | 2 + include/linux/livepatch.h | 2 + kernel/livepatch/core.c | 16 +++-- kernel/trace/ftrace.c | 26 ++++++++ 12 files changed, 309 insertions(+), 5 deletions(-) create mode 100644 arch/arm64/include/asm/livepatch.h create mode 100644 arch/arm64/kernel/livepatch.c
Quoted 10 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
I don't have arm64 cross-compiler handy, could you please copy/paste how does function prologue, generated by gcc -pg on arm64 look like?
Thanks,
Signature · 2 lines
Jiri Kosina SUSE Labs
Sorry for not replying soon.
Quoted 10 lines · Jiri Kosina
Quoted 8 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
Quoted 5 lines
Quoted 2 lines
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
I don't have arm64 cross-compiler handy, could you please copy/paste how does function prologue, generated by gcc -pg on arm64 look like?
As other people said, my current patch has some drawbacks and was far from perfect. I talked to a toolchain guy in Linaro, and he suggested that, instead of x86 specific -mfentry option, we should add a new generic option, -fprolog-pad=N.
It works as if "-pg -mfentry -mrecord-mcount -mnop-mcount" were specified on a command line, but actually puts N nop instructions at the very beginning of a function.
(Please note that -mrecord-mcount and -mnop-mcount options have been added in x86 gcc to make it easier to implement ftrace and others.)
While it is not clear that this new option will be implemented soon (in gcc-6), once it is supported on aarch64, I will update and re-post my livepatch patch as well as DYNAMIC_TRACE_WITH_REGS ftrace.
Thanks,
-Takahiro AKASHI
Quoted 2 lines
Thanks,
Quoted 17 lines · AKASHI Takahiro
Quoted 11 lines
Quoted 8 lines
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
I don't have arm64 cross-compiler handy, could you please copy/paste how does function prologue, generated by gcc -pg on arm64 look like?
As other people said, my current patch has some drawbacks and was far from perfect. I talked to a toolchain guy in Linaro, and he suggested that, instead of x86 specific -mfentry option, we should add a new generic option, -fprolog-pad=N.
Quoted 5 lines
It works as if "-pg -mfentry -mrecord-mcount -mnop-mcount" were specified on a command line, but actually puts N nop instructions at the very beginning of a function. (Please note that -mrecord-mcount and -mnop-mcount options have been added in x86 gcc to make it easier to implement ftrace and others.)
This is BTW implemented in gcc for various architectures already (see -mhotpatch for s390 or -mprofile-kernel for ppc64). Would be nice to at least try the semantics and format unified in some sense.
Thanks,
Signature · 2 lines
Jiri Kosina SUSE Labs
Quoted 23 lines · AKASHI Takahiro
Sorry for not replying soon.
Quoted 10 lines · Jiri Kosina
Quoted 8 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
Quoted 5 lines
Quoted 2 lines
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
I don't have arm64 cross-compiler handy, could you please copy/paste how does function prologue, generated by gcc -pg on arm64 look like?
As other people said, my current patch has some drawbacks and was far from perfect. I talked to a toolchain guy in Linaro, and he suggested that, instead of x86 specific -mfentry option, we should add a new generic option, -fprolog-pad=N.
Quoted 5 lines
It works as if "-pg -mfentry -mrecord-mcount -mnop-mcount" were specified on a command line, but actually puts N nop instructions at the very beginning of a function.
(Please note that -mrecord-mcount and -mnop-mcount options have been added in x86 gcc to make it easier to implement ftrace and others.)
Ah, that's a cool idea :) Note that it also will need to take care of debuginfo. Previously -mfentry had broken the debuginfo about function prologue.
Quoted 3 lines
While it is not clear that this new option will be implemented soon (in gcc-6), once it is supported on aarch64, I will update and re-post my livepatch patch as well as
DYNAMIC_TRACE_WITH_REGSftrace.
Thank you!
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: masami.hiramatsu.pt at hitachi.com
cover arm64: add livepatch support
In reply to Jiri KosinaQuoted 10 lines · Jiri Kosina
Quoted 8 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
Quoted 6 lines
Quoted 2 lines
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
I don't have arm64 cross-compiler handy, could you please copy/paste how does function prologue, generated by gcc -pg on arm64 look like?
The function prologue on arm64 with gcc -pg look like as following:
func:
stp x29, x30, [sp, -48]!
add x29, sp, 0
mov x1, x30
str w0, [x29,28]
mov x0, x1
bl _mcount
...Thanks,
Li Bin
Quoted 2 lines
Thanks,
Quoted 10 lines · Jiri Kosina
Quoted 8 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
Quoted 6 lines
Quoted 2 lines
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
I don't have arm64 cross-compiler handy, could you please copy/paste how does function prologue, generated by gcc -pg on arm64 look like?
The function prologue on arm64 with gcc -pg look like as following:
func:
stp x29, x30, [sp, -48]!
add x29, sp, 0
mov x1, x30
str w0, [x29,28]
mov x0, x1
bl _mcount
...Thanks,
Li Bin
Quoted 2 lines
Thanks,
Quoted 18 lines · Li Bin
Quoted 10 lines · Jiri Kosina
Quoted 8 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
Quoted 6 lines
Quoted 2 lines
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
I don't have arm64 cross-compiler handy, could you please copy/paste how does function prologue, generated by gcc -pg on arm64 look like?
Quoted 8 lines
The function prologue on arm64 with gcc -pg look like as following:
func:stp x29, x30, [sp, -48]! add x29, sp, 0 mov x1, x30 str w0, [x29,28] mov x0, x1 bl _mcount
Just for the avoidance of confusion, this looks like a function with a live parameter in x0, which explains the str to the stack and the juggling of x30 into x0. I don't think there's necessarily a golden template for the prologue code.
Will
Quoted 28 lines · Will Deacon
Quoted 18 lines · Li Bin
Quoted 10 lines · Jiri Kosina
Quoted 8 lines · AKASHI Takahiro
This patchset enables livepatch support on arm64.
Livepatch was merged in v4.0, and allows replacying a function dynamically based on ftrace framework, but it also requires -mfentry option of gcc. Currently arm64 gcc doesn't support it, but by adding a helper function to ftrace, we will be able to support livepatch on arch's which don't support this option.
Quoted 6 lines
Quoted 2 lines
I submit this patchset as RFC since I'm not quite sure that I'm doing in the right way, or we should definitely support -fentry instead.
I don't have arm64 cross-compiler handy, could you please copy/paste how does function prologue, generated by gcc -pg on arm64 look like?
Quoted 8 lines
The function prologue on arm64 with gcc -pg look like as following:
func:stp x29, x30, [sp, -48]! add x29, sp, 0 mov x1, x30 str w0, [x29,28] mov x0, x1 bl _mcount
Quoted 4 lines
Just for the avoidance of confusion, this looks like a function with a live parameter in x0, which explains the str to the stack and the juggling of x30 into x0. I don't think there's necessarily a golden template for the prologue code.
We just started the discussion about gcc, -mfentry vs. a more generic option that I mentioned in:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-May/346632.html
on gcc's devel ML.
-Takahiro AKASHI
Quoted 2 lines
Will