From 07b9bacf7faaedc8d86b7b2a7fcea19cbfbee9df Mon Sep 17 00:00:00 2001
From: ZhangPeng <zhangpeng362@huawei.com>
Date: Thu, 6 Mar 2025 10:01:49 +0800
Subject: [PATCH 2/2] Revert "perf,x86: avoid missing caller address in stack
 traces captured in uprobe"

This reverts commit 0429117191082a7a5f0ff2c420f1d8f64d506d90.

Signed-off-by: ZhangPeng <zhangpeng362@huawei.com>
---
 arch/x86/events/core.c  | 63 -----------------------------------------
 include/linux/uprobes.h |  2 --
 kernel/events/uprobes.c |  2 --
 3 files changed, 67 deletions(-)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index ad0932f84094..1eb4b68d2a49 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -41,8 +41,6 @@
 #include <asm/desc.h>
 #include <asm/ldt.h>
 #include <asm/unwind.h>
-#include <asm/uprobes.h>
-#include <asm/ibt.h>
 
 #include "perf_event.h"
 
@@ -2820,46 +2818,6 @@ static unsigned long get_segment_base(unsigned int segment)
 	return get_desc_base(desc);
 }
 
-#ifdef CONFIG_UPROBES
-/*
- * Heuristic-based check if uprobe is installed at the function entry.
- *
- * Under assumption of user code being compiled with frame pointers,
- * `push %rbp/%ebp` is a good indicator that we indeed are.
- *
- * Similarly, `endbr64` (assuming 64-bit mode) is also a common pattern.
- * If we get this wrong, captured stack trace might have one extra bogus
- * entry, but the rest of stack trace will still be meaningful.
- */
-static bool is_uprobe_at_func_entry(struct pt_regs *regs)
-{
-	struct arch_uprobe *auprobe;
-
-	if (!current->utask)
-		return false;
-
-	auprobe = current->utask->auprobe;
-	if (!auprobe)
-		return false;
-
-	/* push %rbp/%ebp */
-	if (auprobe->insn[0] == 0x55)
-		return true;
-
-	/* endbr64 (64-bit only) */
-	if (user_64bit_mode(regs) && is_endbr(*(u32 *)auprobe->insn))
-		return true;
-
-	return false;
-}
-
-#else
-static bool is_uprobe_at_func_entry(struct pt_regs *regs)
-{
-	return false;
-}
-#endif /* CONFIG_UPROBES */
-
 #ifdef CONFIG_IA32_EMULATION
 
 #include <linux/compat.h>
@@ -2871,7 +2829,6 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
 	unsigned long ss_base, cs_base;
 	struct stack_frame_ia32 frame;
 	const struct stack_frame_ia32 __user *fp;
-	u32 ret_addr;
 
 	if (user_64bit_mode(regs))
 		return 0;
@@ -2881,12 +2838,6 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
 
 	fp = compat_ptr(ss_base + regs->bp);
 	pagefault_disable();
-
-	/* see perf_callchain_user() below for why we do this */
-	if (is_uprobe_at_func_entry(regs) &&
-	    !get_user(ret_addr, (const u32 __user *)regs->sp))
-		perf_callchain_store(entry, ret_addr);
-
 	while (entry->nr < entry->max_stack) {
 		if (!valid_user_frame(fp, sizeof(frame)))
 			break;
@@ -2915,7 +2866,6 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
 {
 	struct stack_frame frame;
 	const struct stack_frame __user *fp;
-	unsigned long ret_addr;
 
 	if (perf_guest_state()) {
 		/* TODO: We don't support guest os callchain now */
@@ -2939,19 +2889,6 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
 		return;
 
 	pagefault_disable();
-
-	/*
-	 * If we are called from uprobe handler, and we are indeed at the very
-	 * entry to user function (which is normally a `push %rbp` instruction,
-	 * under assumption of application being compiled with frame pointers),
-	 * we should read return address from *regs->sp before proceeding
-	 * to follow frame pointers, otherwise we'll skip immediate caller
-	 * as %rbp is not yet setup.
-	 */
-	if (is_uprobe_at_func_entry(regs) &&
-	    !get_user(ret_addr, (const unsigned long __user *)regs->sp))
-		perf_callchain_store(entry, ret_addr);
-
 	while (entry->nr < entry->max_stack) {
 		if (!valid_user_frame(fp, sizeof(frame)))
 			break;
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index c4ff1159cb81..86d0868b584a 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -77,8 +77,6 @@ struct uprobe_task {
 	struct uprobe			*active_uprobe;
 	unsigned long			xol_vaddr;
 
-	struct arch_uprobe              *auprobe;
-
 	struct return_instance		*return_instances;
 	unsigned int			depth;
 	KABI_RESERVE(1)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index a14b0059f177..69c9f0d33f0a 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -2073,7 +2073,6 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
 	bool need_prep = false; /* prepare return uprobe, when needed */
 
 	down_read(&uprobe->register_rwsem);
-	current->utask->auprobe = &uprobe->arch;
 	for (uc = uprobe->consumers; uc; uc = uc->next) {
 		int rc = 0;
 
@@ -2088,7 +2087,6 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
 
 		remove &= rc;
 	}
-	current->utask->auprobe = NULL;
 
 	if (need_prep && !remove)
 		prepare_uretprobe(uprobe, regs); /* put bp at return */
-- 
2.25.1

