From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F0264407CFE; Thu, 21 May 2026 14:26:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779373607; cv=none; b=a/Fet3zvK9m5fQxIqY+J6BAhHd5IqNBR/K1JnGjJAosPRFUyqL4McCCkeNgWlF3AzbTbCl73lGjVNHpq/GzR0yun1bZ0oUf/SxnwymHqn7NfrmLIlN75N+cKSz/GZOrdzv4hB5E5oFgnIS2ddyIYLozDpL46J2ovrfvdD4VX97Q= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779373607; c=relaxed/simple; bh=kGNjjC6C+f+uGmlVEj/aSeixIT/e1bSybpI13YtquDc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gXj/NPuzwOFCbGBmt3amnZI+1zfDX46Wo9mzGatuEQqZnByX7D1XdfTeFtkwUUnGwXApS86dFgHBim8wuQ873g/72iQSXaT5Ein5hc61Id/O4EC9HasP/JfWeyJw2eDbys9UoqaBf6jtPimqYEU0Kj+NadFM92915pM6csGxu/c= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=pUdm0lBP; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="pUdm0lBP" Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64L5K7gl3386862; Thu, 21 May 2026 14:25:59 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=tXpNIe7iOtik2FWOA aKIlzFM00E3KzCJxJoD0NRH//s=; b=pUdm0lBPLgSHbq0mC/1gqs3dP72iRCvTL KaUXSrsywK5Wj62x7TVnnWXnklmZ8CjBWXn6EHeR23PDoYMAD6fkwG51ms2ee/xn pvZ6BTZFLK6TH1GoATaPXtc3ijsaUQTeORkz8RUacrq7GVNizlJ8Zxq2Ny10z77o 0KJ861PXsednjzFlzip+r5JFWy1hnBP1SwgJgKsBZh4WOcNpCJLOjvew0VXNQ1is zUw8CQK5PQJ3nbzaot0RSx+JNCw5KcS7kV5rsb5ACQ6GpvRptS2CH/Y8v3lgUVI7 EmDv/MkJI5SXW9Yk/NKq9UYUxNik0SVuI1Pc/1XTEuzpfwg21GMjw== Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4e6h757dqm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 21 May 2026 14:25:58 +0000 (GMT) Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64LEODZ1001765; Thu, 21 May 2026 14:25:57 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4e72wqcst5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 21 May 2026 14:25:57 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64LEPsdj13959518 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 21 May 2026 14:25:54 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 400DF20040; Thu, 21 May 2026 14:25:54 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DED2F2004B; Thu, 21 May 2026 14:25:53 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Thu, 21 May 2026 14:25:53 +0000 (GMT) From: Jens Remus To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, x86@kernel.org, Steven Rostedt , Josh Poimboeuf , Indu Bhagat , Peter Zijlstra , Dylan Hatch , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Mathieu Desnoyers , Kees Cook , Sam James Cc: Jens Remus , bpf@vger.kernel.org, linux-mm@kvack.org, Namhyung Kim , Andrii Nakryiko , "Jose E. Marchesi" , Beau Belgrave , Florian Weimer , "Carlos O'Donell" , Masami Hiramatsu , Jiri Olsa , Arnaldo Carvalho de Melo , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Heiko Carstens , Vasily Gorbik , Ilya Leoshkevich Subject: [PATCH v16 13/20] unwind_user: Enable archs that pass RA in a register Date: Thu, 21 May 2026 16:25:39 +0200 Message-ID: <20260521142546.3908498-14-jremus@linux.ibm.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260521142546.3908498-1-jremus@linux.ibm.com> References: <20260521142546.3908498-1-jremus@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-trace-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-Reinject: loops=2 maxloops=12 X-Authority-Analysis: v=2.4 cv=ffCdDUQF c=1 sm=1 tr=0 ts=6a0f15f7 cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=pGLkceISAAAA:8 a=VnNF1IyMAAAA:8 a=c48flIb4C_QYATK_dV0A:9 X-Proofpoint-ORIG-GUID: TsRj1JK-9_NOcNAOrQ63hcnC1LYaBrQq X-Proofpoint-GUID: Gdy2mtPuOEojV51mMXhNIPimxaNVlX4F X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTIxMDE0MiBTYWx0ZWRfX3yjef41rB6Zq R5QuYeXLnQXPv5yOZJtgEzPNqCZoGljYuGOY2ZTi/xxP8a872DH9BJyBNOI46C81IrXvgyioPci +UgEhseJ/1XimuVL7sBjRH/fTUFCvRKjvlFGNF8nYFKJ/GSfkWEUsH4bOlgXtuxw+Ebp2KGgtUS McY1qXokwYq8O1P8MRbvvsUoxPjkA7rrQVGbcsZm7UveHaG6/9epJvFlA2xolz07Mg0XIsSi90M ojW51J/m1bNLhqB/gG6u5p0CmrCfTHWl1bgvgscjFKHeCq4mCOfFFjDo68cZj7WowXQ2Yi1buOv sDiNrk4R0mtK+wwujhdkOHuzm1EKG52ZStG1YByTEbvvhNfED1M2g3llRi3D+f0E6wWnywGZUFg j86oOUVHV+6/TnWjN0nbwnIS7PP8LPlKquYErnPn6f/VYMyoi5azRjus8cDXg9v0JDWZG9JN1Md yBMjriBPfVegPwClbQw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-21_02,2026-05-18_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 spamscore=0 phishscore=0 suspectscore=0 adultscore=0 clxscore=1015 impostorscore=0 lowpriorityscore=0 bulkscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605130000 definitions=main-2605210142 Not all architectures/ABIs pass the return address (RA) on the stack on function entry, like x86-64 does due to its CALL instruction pushing the RA onto the stack. Architectures/ABIs, such as s390, also do not require the RA to be saved on the stack in the function prologue. In particular, the RA may never be saved to the stack at all, such as in leaf functions. Unwinding must therefore not assume the presence of a RA saved on stack for the topmost frame. Treat a RA offset from CFA of zero as indication that the RA is not saved (on the stack). For the topmost frame treat it as indication that the RA is in the link/RA register, such as on arm64 and s390, and obtain it from there. For non-topmost frames treat it as error, as the RA must be saved. Additionally allow the SP to be unchanged in the topmost frame, for architectures where SP at function entry == SP at call site, such as arm64 and s390. Note that treating a RA offset from CFA of zero as indication that the RA is not saved on the stack additionally allows for architectures, such as s390, where the frame pointer (FP) may be saved without the RA being saved as well. Provided that such architectures represent this in SFrame by encoding the "missing" RA offset using a padding RA offset with a value of zero. Reviewed-by: Indu Bhagat Signed-off-by: Jens Remus --- Notes (jremus): Changes in v15: - Define pr_fmt(). - unwind_user_get_ra_reg(): Use pr_debug_once() instead of WARN_ON_ONCE() to prevent user-triggered warning/panic. (Sashiko AI) - Reworded commit message. (Indu) include/linux/unwind_user.h | 10 ++++++++++ kernel/unwind/sframe.c | 6 ++---- kernel/unwind/user.c | 20 ++++++++++++++++---- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/include/linux/unwind_user.h b/include/linux/unwind_user.h index 64618618febd..7bf58f23aa64 100644 --- a/include/linux/unwind_user.h +++ b/include/linux/unwind_user.h @@ -23,6 +23,16 @@ static inline bool unwind_user_at_function_start(struct pt_regs *regs) #define unwind_user_at_function_start unwind_user_at_function_start #endif +#ifndef unwind_user_get_ra_reg +static inline int unwind_user_get_ra_reg(unsigned long *val) +{ + pr_debug_once("%s (%d): unwind_user_get_ra_reg() not implemented\n", + current->comm, current->pid); + return -EINVAL; +} +#define unwind_user_get_ra_reg unwind_user_get_ra_reg +#endif + int unwind_user(struct unwind_stacktrace *trace, unsigned int max_entries); #endif /* _LINUX_UNWIND_USER_H */ diff --git a/kernel/unwind/sframe.c b/kernel/unwind/sframe.c index e6d66ae8e7ac..d573c2529926 100644 --- a/kernel/unwind/sframe.c +++ b/kernel/unwind/sframe.c @@ -257,10 +257,8 @@ static __always_inline int __read_fre(struct sframe_section *sec, dataword_count--; ra_off = sec->ra_off; - if (!ra_off) { - if (!dataword_count--) - return -EINVAL; - + if (!ra_off && dataword_count) { + dataword_count--; UNSAFE_GET_USER_INC(ra_off, cur, dataword_size, Efault); } diff --git a/kernel/unwind/user.c b/kernel/unwind/user.c index fdb1001e3750..afa7c6f6d9b4 100644 --- a/kernel/unwind/user.c +++ b/kernel/unwind/user.c @@ -2,6 +2,9 @@ /* * Generic interfaces for unwinding user space */ + +#define pr_fmt(fmt) "unwind_user: " fmt + #include #include #include @@ -48,8 +51,12 @@ static int unwind_user_next_common(struct unwind_user_state *state, } cfa += frame->cfa_off; - /* Make sure that stack is not going in wrong direction */ - if (cfa <= state->sp) + /* + * Make sure that stack is not going in wrong direction. Allow SP + * to be unchanged for the topmost frame, by subtracting topmost, + * which is either 0 or 1. + */ + if (cfa <= state->sp - state->topmost) return -EINVAL; /* Make sure that the address is word aligned */ @@ -57,8 +64,13 @@ static int unwind_user_next_common(struct unwind_user_state *state, return -EINVAL; /* Get the Return Address (RA) */ - if (get_user_word(&ra, cfa, frame->ra_off, state->ws)) - return -EINVAL; + if (frame->ra_off) { + if (get_user_word(&ra, cfa, frame->ra_off, state->ws)) + return -EINVAL; + } else { + if (!state->topmost || unwind_user_get_ra_reg(&ra)) + return -EINVAL; + } /* Get the Frame Pointer (FP) */ if (frame->fp_off && get_user_word(&fp, cfa, frame->fp_off, state->ws)) -- 2.51.0