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 ED5683EFD22; Wed, 20 May 2026 15:40:53 +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=1779291655; cv=none; b=X045mmrIn05c/hH+rh4EqV8momwdKIyA88LcK2dniopBMLCo/UyCbAYuhsj2h+18OciAMN3ji5MB5URzNEV0N11qqMjNdUfWBaFSn6OfjjbrNq2qr1mKX57dPPqVHaS1I9YNcRJgxj25oS4unvgEeImN5HOpA/8A1BoEESYfB3A= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779291655; c=relaxed/simple; bh=1nwEvzyjn78+bpot1nWJXP7nJecX1W5XHQO3KfJtGJs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KTt7DOeKoeNNf8aLkVrpQqvcwnL5cqT638l/rJHTmn9DtveCcDSSaTZEgZGjXvgjaCRn80eYQTENdn/N8eaii28MIt3dXgwG5poXLHTuttcBioN6jMxo/Uyj7m+1eKZU6XtZ3gSMMIY2VLJaB3UPq8tOlubYOOePXywM2CgjSj8= 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=KYLcYfxc; 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="KYLcYfxc" Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64KDqNrc4104744; Wed, 20 May 2026 15:40:20 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=yu9YEn7cMwbNDaErb gC10vKCiE7zCGLCJox7Eg4hlxw=; b=KYLcYfxcO3nqtmX//Y6eVNl3yMEZ1eXSr qDi0jZT9nG6g4n4zLeFP8hjIZoO1t+JHunUUOfMQ111LIxAN1Vc618Zt5OkINVMW fquemVt2MlIJiyI9GF9EOXrB6X7zf/tWJ5Po7vbgdsZ75mHD+nsiMMSi/SN3il5E HQkhJj+Kk3DLo/enrA90VBDyEK4wX7wX0Bqg/TPaGPazk8wkPemzqaQfoF4tkeES CKOppDxk+iSNYneBT7iylzPqnWkJlREk5jGyrAp5EMe6u9z8dKklXugew5RADaaX omTG1hzv6Dm5f8nE+X0+Vli6eitpWTxZpPBQiVZbfBWHCqCSGQkJA== Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4e6h9y2vn4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 20 May 2026 15:40:19 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64KFd9on008388; Wed, 20 May 2026 15:40:18 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4e739w03bb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 20 May 2026 15:40:18 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (smtpav04.fra02v.mail.ibm.com [10.20.54.103]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64KFeElH44237218 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 20 May 2026 15:40:15 GMT Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D1F1420040; Wed, 20 May 2026 15:40:14 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 52D0B2004E; Wed, 20 May 2026 15:40:14 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav04.fra02v.mail.ibm.com (Postfix) with ESMTP; Wed, 20 May 2026 15:40:14 +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 v15 13/20] unwind_user: Enable archs that pass RA in a register Date: Wed, 20 May 2026 17:39:57 +0200 Message-ID: <20260520154004.3845823-14-jremus@linux.ibm.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260520154004.3845823-1-jremus@linux.ibm.com> References: <20260520154004.3845823-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-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTIwMDE1MSBTYWx0ZWRfX+ZJ+3qEpulp9 BPO8NYhXZzH0Ny3YLbhLv8U9s/DDBqHpZ1G2HzppTO2GEySYMNtom0KBol1DYSgNmEEJ/9TZIzE t/MKr0wyZVdq5HZD4HgwRj6irE66q0X9OOlPIb0J71I9MUJn/s6KXssb9DE0nbg4KrkRqZ5dTnl Qvop6V9bEx33jm1DRKnjeJCkQkBPkm32hdmY4+3XIrTHS5r5BcVVh4jx6jt2zeEIZvQUE9gzslX OVZLTyVrlksaoecaS23DoE5V7E3D9qRdgfEdIeed5cwMm6pebyZcOxaCE2Nx2GXGNT5oYUW3ZyY B6tR/EKDHvLQc3QmOI+tS/3qJFEsz6e9Vt30QJZkFZA/kRtiJAwLfnS8wji6l1b9nN+1RD7rYEV EVctAemmYp6SZb9GY1LyoGMNUdtZE9ZB//Kz6m5UTpHITxeGSEI6xE0jIP/Cxybj3GNAJYeiWq6 YwGyLK/iMXwireapCRA== X-Authority-Analysis: v=2.4 cv=BNuDalQG c=1 sm=1 tr=0 ts=6a0dd5e4 cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=pGLkceISAAAA:8 a=VnNF1IyMAAAA:8 a=c48flIb4C_QYATK_dV0A:9 X-Proofpoint-ORIG-GUID: dtAPcJIj4_HKjvCpdMenCV1ryW5p_1td X-Proofpoint-GUID: CcKY7XMm1KJQsZb35JSoWVF1glEn73FC 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-20_03,2026-05-18_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 priorityscore=1501 malwarescore=0 impostorscore=0 suspectscore=0 lowpriorityscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605130000 definitions=main-2605200151 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 b5f984fb2df2..4af533e9f980 100644 --- a/kernel/unwind/sframe.c +++ b/kernel/unwind/sframe.c @@ -255,10 +255,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