[PATCH 8/9] LoongArch: ftrace: Add CALLER_ADDRx macros
From: Qing Zhang
Date: Fri Aug 19 2022 - 04:18:04 EST
CALLER_ADDRx returns caller's address at specified level in call stacks.
They are used for several tracers like irqsoff and preemptoff.
do_vint
irqentry_exit
trace_hardirqs_on
tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1)
Signed-off-by: Qing Zhang <zhangqing@xxxxxxxxxxx>
---
arch/loongarch/include/asm/ftrace.h | 2 ++
arch/loongarch/include/asm/processor.h | 2 --
arch/loongarch/kernel/Makefile | 4 +--
arch/loongarch/kernel/return_address.c | 45 ++++++++++++++++++++++++++
4 files changed, 49 insertions(+), 4 deletions(-)
create mode 100644 arch/loongarch/kernel/return_address.c
diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/asm/ftrace.h
index f96adef0e4a5..6afc9fc712f4 100644
--- a/arch/loongarch/include/asm/ftrace.h
+++ b/arch/loongarch/include/asm/ftrace.h
@@ -16,6 +16,8 @@
#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
#ifndef __ASSEMBLY__
+extern void *return_address(unsigned int);
+#define ftrace_return_address(n) return_address(n)
#ifndef CONFIG_DYNAMIC_FTRACE
extern void _mcount(void);
#define mcount _mcount
diff --git a/arch/loongarch/include/asm/processor.h b/arch/loongarch/include/asm/processor.h
index 1c4b4308378d..5eb45e55f3c7 100644
--- a/arch/loongarch/include/asm/processor.h
+++ b/arch/loongarch/include/asm/processor.h
@@ -201,8 +201,6 @@ unsigned long __get_wchan(struct task_struct *p);
#define KSTK_EUEN(tsk) (task_pt_regs(tsk)->csr_euen)
#define KSTK_ECFG(tsk) (task_pt_regs(tsk)->csr_ecfg)
-#define return_address() ({__asm__ __volatile__("":::"$1"); __builtin_return_address(0);})
-
#ifdef CONFIG_CPU_HAS_PREFETCH
#define ARCH_HAS_PREFETCH
diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
index a73599619466..9a3df7c1f6e8 100644
--- a/arch/loongarch/kernel/Makefile
+++ b/arch/loongarch/kernel/Makefile
@@ -6,8 +6,8 @@
extra-y := head.o vmlinux.lds
obj-y += cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \
- traps.o irq.o idle.o process.o dma.o mem.o io.o reset.o switch.o \
- elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o
+ traps.o irq.o idle.o process.o dma.o mem.o io.o reset.o return_address.o \
+ switch.o elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o
obj-$(CONFIG_ACPI) += acpi.o
obj-$(CONFIG_EFI) += efi.o
diff --git a/arch/loongarch/kernel/return_address.c b/arch/loongarch/kernel/return_address.c
new file mode 100644
index 000000000000..ed8121dd2b0f
--- /dev/null
+++ b/arch/loongarch/kernel/return_address.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Loongson Technology Corporation Limited
+ */
+
+#include <linux/export.h>
+#include <linux/ftrace.h>
+#include <linux/kprobes.h>
+#include <linux/stacktrace.h>
+
+struct return_address_data {
+ unsigned int level;
+ void *addr;
+};
+
+static bool save_return_addr(void *d, unsigned long pc)
+{
+ struct return_address_data *data = d;
+
+ if (!data->level) {
+ data->addr = (void *)pc;
+ return false;
+ } else {
+ --data->level;
+ return true;
+ }
+}
+NOKPROBE_SYMBOL(save_return_addr);
+
+void *return_address(unsigned int level)
+{
+ struct return_address_data data;
+
+ data.level = level + 2;
+ data.addr = NULL;
+
+ arch_stack_walk(save_return_addr, &data, current, NULL);
+
+ if (!data.level)
+ return data.addr;
+ else
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(return_address);
+NOKPROBE_SYMBOL(return_address);
--
2.36.1