aboutsummaryrefslogtreecommitdiff
path: root/arch/loongarch/kernel/inst.c
diff options
context:
space:
mode:
authorGravatar Qing Zhang <zhangqing@loongson.cn> 2022-12-10 22:40:15 +0800
committerGravatar Huacai Chen <chenhuacai@loongson.cn> 2022-12-14 08:41:53 +0800
commit5fcfad3d41cc70f39fb31e7ee314989cc4c5f02c (patch)
treef28299e0707c961a823c59fba914afb5da7534af /arch/loongarch/kernel/inst.c
parentLoongArch/ftrace: Add dynamic function tracer support (diff)
downloadlinux-5fcfad3d41cc70f39fb31e7ee314989cc4c5f02c.tar.gz
linux-5fcfad3d41cc70f39fb31e7ee314989cc4c5f02c.tar.bz2
linux-5fcfad3d41cc70f39fb31e7ee314989cc4c5f02c.zip
LoongArch/ftrace: Add dynamic function graph tracer support
Once the function_graph tracer is enabled, a filtered function has the following call sequence: 1) ftracer_caller ==> on/off by ftrace_make_call/ftrace_make_nop 2) ftrace_graph_caller 3) ftrace_graph_call ==> on/off by ftrace_en/disable_ftrace_graph_caller 4) prepare_ftrace_return Considering the following DYNAMIC_FTRACE_WITH_REGS feature, it would be more extendable to have a ftrace_graph_caller function, instead of calling prepare_ftrace_return directly in ftrace_caller. Co-developed-by: Jinyang He <hejinyang@loongson.cn> Signed-off-by: Jinyang He <hejinyang@loongson.cn> Signed-off-by: Qing Zhang <zhangqing@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Diffstat (limited to 'arch/loongarch/kernel/inst.c')
-rw-r--r--arch/loongarch/kernel/inst.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c
index 4fd22b4413d0..39671e87e31c 100644
--- a/arch/loongarch/kernel/inst.c
+++ b/arch/loongarch/kernel/inst.c
@@ -55,6 +55,30 @@ u32 larch_insn_gen_nop(void)
return INSN_NOP;
}
+u32 larch_insn_gen_b(unsigned long pc, unsigned long dest)
+{
+ long offset = dest - pc;
+ unsigned int immediate_l, immediate_h;
+ union loongarch_instruction insn;
+
+ if ((offset & 3) || offset < -SZ_128M || offset >= SZ_128M) {
+ pr_warn("The generated b instruction is out of range.\n");
+ return INSN_BREAK;
+ }
+
+ offset >>= 2;
+
+ immediate_l = offset & 0xffff;
+ offset >>= 16;
+ immediate_h = offset & 0x3ff;
+
+ insn.reg0i26_format.opcode = b_op;
+ insn.reg0i26_format.immediate_l = immediate_l;
+ insn.reg0i26_format.immediate_h = immediate_h;
+
+ return insn.word;
+}
+
u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest)
{
long offset = dest - pc;