[PATCH 8/9] LoongArch: ftrace: Add CALLER_ADDRx macros

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Kernel]     [Kernel Newbies]     [x86 Platform Driver]     [Netdev]     [Linux Wireless]     [Netfilter]     [Bugtraq]     [Linux Filesystems]     [Yosemite Discussion]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux