From nobody Sat Feb 7 09:59:19 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 3C4A635E541; Tue, 27 Jan 2026 15:06:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769526419; cv=none; b=HHQv8M6n7IN7yLaHAijMJWpJQL1y4t+O6eKWyJVYMeInMR+hq5ta5ACog5hvEkzc6pkPObVfN/WjDelhb9znUPQ/tBkTcE/4W8rAhvMtEn0KA8ak7LJ3SmQ4d3BF7Xg0d3kba4srkRucIBHmgJqPzI4smm3kBAaU4dBjOOgg6o8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769526419; c=relaxed/simple; bh=28Hs12xLRDSeQZJr6/eVUZu9HN7Lm9lUnh84mMvhEuY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SM5D2LhlNqT6hpzsQ/vFAXE+yboWb0jUFmYmHV/jHp9xy7wGijVioy6VYoN24WaCfL1y2NG4oCm1oo7666ocOSmhVJbLyL9GxkpSGQ1ZQu45qWgIgWyJOiudR+sKiJKyyn5044ISmHE1wnVzakmyY0PLUJe3aX/fJcaAtAAweNQ= 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=H6ap+SwL; arc=none smtp.client-ip=148.163.158.5 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="H6ap+SwL" Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 60RElpet031076; Tue, 27 Jan 2026 15:06:09 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=3oxrNqvT1rMVaA9XQ eLJXr2NbWh63PM2NKwSN0+VBoM=; b=H6ap+SwLdjS3mmSwFPbfzH2b01uoWZpF6 tM3fKMMLpQ/sylcarRsUqkOBy5pUSlt1qTsiETC6IX4orVieBgTQdv4NmLs7OjN3 SPF5oB4ELCmXOYeOOPI5ZHLzrjcUJjIKudV93L5p3AtnUJ0+yoWyTCB/HpCzO2Hx hyWDkXYLNi57QUEynV20qQ76LAetlTXKIh03bn6yMVQpVhvGkjIrARCazJMfq+ZX BjNz8NwS0sv7LqPhh3iYHWqCNYMDvYhKaDvbvmKx46r6h1D1G2BHkHwAHOGVeFrb z9KMdPSpSDbkokoOeR8cIv+hVC/k5UBLaJ5SfohZyZHb1cEY7vn5Q== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4bvmgfvdex-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 27 Jan 2026 15:06:08 +0000 (GMT) Received: from m0353725.ppops.net (m0353725.ppops.net [127.0.0.1]) by pps.reinject (8.18.1.12/8.18.0.8) with ESMTP id 60RF2vOH017959; Tue, 27 Jan 2026 15:06:07 GMT Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4bvmgfvdet-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 27 Jan 2026 15:06:07 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.2/8.18.1.2) with ESMTP id 60REptcY017960; Tue, 27 Jan 2026 15:06:06 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4bwb41ru44-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 27 Jan 2026 15:06:06 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 60RF636252822376 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 27 Jan 2026 15:06:03 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id F115A20040; Tue, 27 Jan 2026 15:06:02 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 926F92004E; Tue, 27 Jan 2026 15:06:02 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 27 Jan 2026 15:06:02 +0000 (GMT) From: Jens Remus To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org, x86@kernel.org, linux-mm@kvack.org, Steven Rostedt Cc: Jens Remus , Josh Poimboeuf , Masami Hiramatsu , Mathieu Desnoyers , Peter Zijlstra , Ingo Molnar , Jiri Olsa , Arnaldo Carvalho de Melo , Namhyung Kim , Thomas Gleixner , Andrii Nakryiko , Indu Bhagat , "Jose E. Marchesi" , Beau Belgrave , Linus Torvalds , Andrew Morton , Florian Weimer , Kees Cook , "Carlos O'Donell" , Sam James , Dylan Hatch , Borislav Petkov , Dave Hansen , David Hildenbrand , "H. Peter Anvin" , "Liam R. Howlett" , Lorenzo Stoakes , Michal Hocko , Mike Rapoport , Suren Baghdasaryan , Vlastimil Babka , Heiko Carstens , Vasily Gorbik Subject: [PATCH v13 15/18] unwind_user/sframe: Add support for SFrame V3 flexible FDEs Date: Tue, 27 Jan 2026 16:05:50 +0100 Message-ID: <20260127150554.2760964-16-jremus@linux.ibm.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260127150554.2760964-1-jremus@linux.ibm.com> References: <20260127150554.2760964-1-jremus@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=Z4vh3XRA c=1 sm=1 tr=0 ts=6978d460 cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=vUbySO9Y5rIA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VwQbUJbxAAAA:8 a=7d_E57ReAAAA:8 a=JfrnYn6hAAAA:8 a=yPCof4ZbAAAA:8 a=mDV3o1hIAAAA:8 a=yMhMjlubAAAA:8 a=VnNF1IyMAAAA:8 a=Z4Rwk6OoAAAA:8 a=20KFwNOVAAAA:8 a=7mOBRU54AAAA:8 a=2wkDFiw1nnRQRUo0YT0A:9 a=jhqOcbufqs7Y1TYCrUUU:22 a=1CNFftbPRP8L7MoqJWF3:22 a=HkZW87K1Qel5hWWM3VKY:22 a=wa9RWnbW_A1YIeRBVszw:22 X-Proofpoint-GUID: 0wGnHg8qCGjbx3-LIzoY5IImluPfJ43- X-Proofpoint-ORIG-GUID: k8VUmwsesU7Qjy_Zf5UhIY-OXQeeDB1b X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTI3MDEyMSBTYWx0ZWRfX08dPWt8WBYHQ Qe6yBycEBxR4QECgsvau9hp6oKPG3n7t0MOt2PU/gX5DvduWwnR6Un/Y7GcAjjqXma1zYE/JKys qi+9y/KTJr2CYMbTx0PEz719NvxHk/JDRoxyrLPIkEy+Yxn94H0vlBQBSKIVZFqHtxO3bhLMpb6 tCf0gkkHyiGWbi9rL/UjsH33aFfeLAAcg0qtZj011HRK42NUPbQYc8giE4wveUe3vv6O/aPeNop b38i+anwwyEH+vNdKaOqqr1vM5x3nDKhrR26etLJMhGMKpiKvEpBWdPiKd8ZK1VECPJBBcdvnj7 9Hqv5vEW2TSunWtlFcWgrhfh5qdLE39g0sxkfVCiSUeROnifeMeUJxZwOIT/1FwyhvPgPrwW+RA nJ9BczHL6jwAskMMUJBw1mcTclI4ip3cuAUWFrmaGDqleMKxs45eeMg3jVcMmQOgR1qI52pkg7+ cKE3ruR2olsKr5Qo9Dw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-01-27_03,2026-01-27_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 malwarescore=0 phishscore=0 priorityscore=1501 bulkscore=0 adultscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2601150000 definitions=main-2601270121 Content-Type: text/plain; charset="utf-8" SFrame V3 introduces flexible FDEs in addition to the regular FDEs. The key difference is that flexible FDEs encode the CFA, RA, and FP tracking information using two FRE data words, a control word and an offset, or a single padding data word of zero (e.g. to represent FP without RA tracking information). The control word contains the following information: - reg_p: Whether to use the register contents (reg_p=3D1) specified by regnum or the CFA (reg_p=3D0) as base. - deref_p: Whether to dereference. - regnum: A DWARF register number. The offset is added to the base (i.e. CFA or register contents). Then the resulting address may optionally be dereferenced. This enables the following flexible CFA and FP/RA recovery rules: - CFA =3D register + offset // reg_p=3D1, deref_p=3D0 - CFA =3D *(register + offset) // reg_p=3D1, deref_p=3D1 - FP/RA =3D *(CFA + offset) // reg_p=3D0, deref_p=3D0 - FP/RA =3D register + offset // reg_p=3D1, deref_p=3D0 - FP/RA =3D *(register + offset) // reg_p=3D1, deref_p=3D1 Note that for the CFA a rule with reg_p=3D0 is invalid, as the value of the CFA cannot be described using itself as base. For FP/RA a rule with reg_p=3D0 and deref_p=3D0 and regnum=3D0 is invalid, as it that is equal to the padding data word of zero. Cc: Steven Rostedt Cc: Josh Poimboeuf Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Namhyung Kim Cc: Thomas Gleixner Cc: Andrii Nakryiko Cc: Indu Bhagat Cc: "Jose E. Marchesi" Cc: Beau Belgrave Cc: Jens Remus Cc: Linus Torvalds Cc: Andrew Morton Cc: Florian Weimer Cc: Sam James Cc: Kees Cook Cc: "Carlos O'Donell" Signed-off-by: Jens Remus --- Notes (jremus): Changes in v13: - New patch. kernel/unwind/sframe.c | 249 ++++++++++++++++++++++++++++++++--------- kernel/unwind/sframe.h | 5 + 2 files changed, 204 insertions(+), 50 deletions(-) diff --git a/kernel/unwind/sframe.c b/kernel/unwind/sframe.c index 4dfc8cf2075e..ebf2a2905c5c 100644 --- a/kernel/unwind/sframe.c +++ b/kernel/unwind/sframe.c @@ -12,6 +12,7 @@ #include #include #include +#include #include =20 #include "sframe.h" @@ -31,8 +32,11 @@ struct sframe_fde_internal { struct sframe_fre_internal { unsigned int size; u32 ip_off; + u32 cfa_ctl; s32 cfa_off; + u32 ra_ctl; s32 ra_off; + u32 fp_ctl; s32 fp_off; u8 info; }; @@ -189,16 +193,147 @@ static __always_inline int __find_fde(struct sframe_= section *sec, s32 : UNSAFE_GET_USER_SIGNED_INC(to, from, size, label), \ s64 : UNSAFE_GET_USER_SIGNED_INC(to, from, size, label)) =20 +static __always_inline int +__read_regular_fre_datawords(struct sframe_section *sec, + struct sframe_fde_internal *fde, + unsigned long cur, + unsigned char dataword_count, + unsigned char dataword_size, + struct sframe_fre_internal *fre) +{ + s32 cfa_off, ra_off, fp_off; + unsigned int cfa_regnum; + + UNSAFE_GET_USER_INC(cfa_off, cur, dataword_size, Efault); + dataword_count--; + + ra_off =3D sec->ra_off; + if (!ra_off && dataword_count) { + dataword_count--; + UNSAFE_GET_USER_INC(ra_off, cur, dataword_size, Efault); + } + + fp_off =3D sec->fp_off; + if (!fp_off && dataword_count) { + dataword_count--; + UNSAFE_GET_USER_INC(fp_off, cur, dataword_size, Efault); + } + + if (dataword_count) + return -EFAULT; + + cfa_regnum =3D + (SFRAME_V3_FRE_CFA_BASE_REG_ID(fre->info) =3D=3D SFRAME_BASE_REG_FP) ? + SFRAME_REG_FP : SFRAME_REG_SP; + + fre->cfa_ctl =3D (cfa_regnum << 3) | 1; /* regnum, deref_p=3D0, reg_p=3D1= */ + fre->cfa_off =3D cfa_off; + fre->ra_ctl =3D ra_off ? 2 : 0; /* regnum=3D0, deref_p=3D(ra_off !=3D 0),= reg_p=3D0 */ + fre->ra_off =3D ra_off; + fre->fp_ctl =3D fp_off ? 2 : 0; /* regnum=3D0, deref_p=3D(fp_off !=3D 0),= reg_p=3D0 */ + fre->fp_off =3D fp_off; + + return 0; + +Efault: + return -EFAULT; +} + +static __always_inline int +__read_flex_fde_fre_datawords(struct sframe_section *sec, + struct sframe_fde_internal *fde, + unsigned long cur, + unsigned char dataword_count, + unsigned char dataword_size, + struct sframe_fre_internal *fre) +{ + u32 cfa_ctl, ra_ctl, fp_ctl; + s32 cfa_off, ra_off, fp_off; + + if (dataword_count < 2) + return -EFAULT; + UNSAFE_GET_USER_INC(cfa_ctl, cur, dataword_size, Efault); + UNSAFE_GET_USER_INC(cfa_off, cur, dataword_size, Efault); + dataword_count -=3D 2; + + ra_off =3D sec->ra_off; + ra_ctl =3D ra_off ? 2 : 0; /* regnum=3D0, deref_p=3D(ra_off !=3D 0), reg_= p=3D0 */ + if (dataword_count >=3D 2) { + UNSAFE_GET_USER_INC(ra_ctl, cur, dataword_size, Efault); + dataword_count--; + if (ra_ctl) { + UNSAFE_GET_USER_INC(ra_off, cur, dataword_size, Efault); + dataword_count--; + } else { + /* Padding RA location info */ + ra_ctl =3D ra_off ? 2 : 0; /* re-deduce (see above) */ + } + } + + fp_off =3D sec->fp_off; + fp_ctl =3D fp_off ? 2 : 0; /* regnum=3D0, deref_p=3D(fp_off !=3D 0), reg_= p=3D0 */ + if (dataword_count >=3D 2) { + UNSAFE_GET_USER_INC(fp_ctl, cur, dataword_size, Efault); + dataword_count--; + if (fp_ctl) { + UNSAFE_GET_USER_INC(fp_off, cur, dataword_size, Efault); + dataword_count--; + } else { + /* Padding FP location info */ + fp_ctl =3D fp_off ? 2 : 0; /* re-deduce (see above) */ + } + } + + if (dataword_count) + return -EFAULT; + + fre->cfa_ctl =3D cfa_ctl; + fre->cfa_off =3D cfa_off; + fre->ra_ctl =3D ra_ctl; + fre->ra_off =3D ra_off; + fre->fp_ctl =3D fp_ctl; + fre->fp_off =3D fp_off; + + return 0; + +Efault: + return -EFAULT; +} + +static __always_inline int +__read_fre_datawords(struct sframe_section *sec, + struct sframe_fde_internal *fde, + unsigned long cur, + unsigned char dataword_count, + unsigned char dataword_size, + struct sframe_fre_internal *fre) +{ + unsigned char fde_type =3D SFRAME_V3_FDE_TYPE(fde->info2); + + switch (fde_type) { + case SFRAME_FDE_TYPE_REGULAR: + return __read_regular_fre_datawords(sec, fde, cur, + dataword_count, + dataword_size, + fre); + case SFRAME_FDE_TYPE_FLEXIBLE: + return __read_flex_fde_fre_datawords(sec, fde, cur, + dataword_count, + dataword_size, + fre); + default: + return -EFAULT; + } +} + static __always_inline int __read_fre(struct sframe_section *sec, struct sframe_fde_internal *fde, unsigned long fre_addr, struct sframe_fre_internal *fre) { - unsigned char fde_type =3D SFRAME_V3_FDE_TYPE(fde->info2); unsigned char fde_pctype =3D SFRAME_V3_FDE_PCTYPE(fde->info); unsigned char fre_type =3D SFRAME_V3_FDE_FRE_TYPE(fde->info); unsigned char dataword_count, dataword_size; - s32 cfa_off, ra_off, fp_off; unsigned long cur =3D fre_addr; unsigned char addr_size; u32 ip_off; @@ -224,75 +359,88 @@ static __always_inline int __read_fre(struct sframe_s= ection *sec, if (cur + (dataword_count * dataword_size) > sec->fres_end) return -EFAULT; =20 - /* TODO: Support for flexible FDEs not implemented yet. */ - if (fde_type !=3D SFRAME_FDE_TYPE_REGULAR) - return -EFAULT; + fre->size =3D addr_size + 1 + (dataword_count * dataword_size); + fre->ip_off =3D ip_off; + fre->info =3D info; =20 if (!dataword_count) { /* * A FRE without data words indicates RA undefined / * outermost frame. */ - cfa_off =3D 0; - ra_off =3D 0; - fp_off =3D 0; - goto done; - } + fre->cfa_ctl =3D 0; + fre->cfa_off =3D 0; + fre->ra_ctl =3D 0; + fre->ra_off =3D 0; + fre->fp_ctl =3D 0; + fre->fp_off =3D 0; =20 - UNSAFE_GET_USER_INC(cfa_off, cur, dataword_size, Efault); - dataword_count--; - - ra_off =3D sec->ra_off; - if (!ra_off && dataword_count) { - dataword_count--; - UNSAFE_GET_USER_INC(ra_off, cur, dataword_size, Efault); - } - - fp_off =3D sec->fp_off; - if (!fp_off && dataword_count) { - dataword_count--; - UNSAFE_GET_USER_INC(fp_off, cur, dataword_size, Efault); + return 0; } =20 - if (dataword_count) - return -EFAULT; - -done: - fre->size =3D addr_size + 1 + (dataword_count * dataword_size); - fre->ip_off =3D ip_off; - fre->cfa_off =3D cfa_off; - fre->ra_off =3D ra_off; - fre->fp_off =3D fp_off; - fre->info =3D info; - - return 0; + return __read_fre_datawords(sec, fde, cur, dataword_count, dataword_size,= fre); =20 Efault: return -EFAULT; } =20 -static __always_inline void +static __always_inline int sframe_init_cfa_rule_data(struct unwind_user_cfa_rule_data *cfa_rule_data, - unsigned char fre_info, - s32 offset) + u32 ctlword, s32 offset) { - if (SFRAME_V3_FRE_CFA_BASE_REG_ID(fre_info) =3D=3D SFRAME_BASE_REG_FP) - cfa_rule_data->rule =3D UNWIND_USER_CFA_RULE_FP_OFFSET; - else - cfa_rule_data->rule =3D UNWIND_USER_CFA_RULE_SP_OFFSET; + bool deref_p =3D SFRAME_V3_FLEX_FDE_CTLWORD_DEREF_P(ctlword); + bool reg_p =3D SFRAME_V3_FLEX_FDE_CTLWORD_REG_P(ctlword); + + if (reg_p) { + unsigned int regnum =3D SFRAME_V3_FLEX_FDE_CTLWORD_REGNUM(ctlword); + + switch (regnum) { + case SFRAME_REG_SP: + cfa_rule_data->rule =3D UNWIND_USER_CFA_RULE_SP_OFFSET; + break; + case SFRAME_REG_FP: + cfa_rule_data->rule =3D UNWIND_USER_CFA_RULE_FP_OFFSET; + break; + default: + cfa_rule_data->rule =3D UNWIND_USER_CFA_RULE_REG_OFFSET; + cfa_rule_data->regnum =3D regnum; + } + } else { + return -EINVAL; + } + + if (deref_p) + cfa_rule_data->rule |=3D UNWIND_USER_RULE_DEREF; + cfa_rule_data->offset =3D offset; + + return 0; } =20 static __always_inline void sframe_init_rule_data(struct unwind_user_rule_data *rule_data, - s32 offset) + u32 ctlword, s32 offset) { - if (offset) { - rule_data->rule =3D UNWIND_USER_RULE_CFA_OFFSET_DEREF; - rule_data->offset =3D offset; - } else { + bool deref_p =3D SFRAME_V3_FLEX_FDE_CTLWORD_DEREF_P(ctlword); + bool reg_p =3D SFRAME_V3_FLEX_FDE_CTLWORD_REG_P(ctlword); + + if (!ctlword && !offset) { rule_data->rule =3D UNWIND_USER_RULE_RETAIN; + return; + } + if (reg_p) { + unsigned int regnum =3D SFRAME_V3_FLEX_FDE_CTLWORD_REGNUM(ctlword); + + rule_data->rule =3D UNWIND_USER_RULE_REG_OFFSET; + rule_data->regnum =3D regnum; + } else { + rule_data->rule =3D UNWIND_USER_RULE_CFA_OFFSET; } + + if (deref_p) + rule_data->rule |=3D UNWIND_USER_RULE_DEREF; + + rule_data->offset =3D offset; } =20 static __always_inline int __find_fre(struct sframe_section *sec, @@ -344,9 +492,10 @@ static __always_inline int __find_fre(struct sframe_se= ction *sec, return -EINVAL; fre =3D prev_fre; =20 - sframe_init_cfa_rule_data(&frame->cfa, fre->info, fre->cfa_off); - sframe_init_rule_data(&frame->ra, fre->ra_off); - sframe_init_rule_data(&frame->fp, fre->fp_off); + if (sframe_init_cfa_rule_data(&frame->cfa, fre->cfa_ctl, fre->cfa_off)) + return -EINVAL; + sframe_init_rule_data(&frame->ra, fre->ra_ctl, fre->ra_off); + sframe_init_rule_data(&frame->fp, fre->fp_ctl, fre->fp_off); frame->outermost =3D SFRAME_V3_FRE_RA_UNDEFINED_P(fre->info); =20 return 0; diff --git a/kernel/unwind/sframe.h b/kernel/unwind/sframe.h index 3fcc15534e5a..5b6112945b6c 100644 --- a/kernel/unwind/sframe.h +++ b/kernel/unwind/sframe.h @@ -66,6 +66,7 @@ struct sframe_fda_v3 { #define SFRAME_V3_AARCH64_FDE_PAUTH_KEY(info) (((info) >> 5) & 0x1) =20 #define SFRAME_FDE_TYPE_REGULAR 0 +#define SFRAME_FDE_TYPE_FLEXIBLE 1 =20 #define SFRAME_V3_FDE_TYPE_MASK 0x0f #define SFRAME_V3_FDE_TYPE(info2) ((info2) & SFRAME_V3_FDE_TYPE_MASK) @@ -79,4 +80,8 @@ struct sframe_fda_v3 { #define SFRAME_V3_AARCH64_FRE_MANGLED_RA_P(info) (((info) >> 7) & 0x1) #define SFRAME_V3_FRE_RA_UNDEFINED_P(info) (SFRAME_V3_FRE_DATAWORD_COUNT(= info) =3D=3D 0) =20 +#define SFRAME_V3_FLEX_FDE_CTLWORD_REGNUM(data) (((data) >> 3) & 0x1f) +#define SFRAME_V3_FLEX_FDE_CTLWORD_DEREF_P(data) (((data) >> 1) & 0x1) +#define SFRAME_V3_FLEX_FDE_CTLWORD_REG_P(data) ((data) & 0x1) + #endif /* _SFRAME_H */ --=20 2.51.0