linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jens Remus <jremus@linux.ibm.com>
To: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	bpf@vger.kernel.org, x86@kernel.org,
	Steven Rostedt <rostedt@kernel.org>,
	Heiko Carstens <hca@linux.ibm.com>,
	Vasily Gorbik <gor@linux.ibm.com>,
	Ilya Leoshkevich <iii@linux.ibm.com>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@kernel.org>, Jiri Olsa <jolsa@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Andrii Nakryiko <andrii@kernel.org>,
	Indu Bhagat <indu.bhagat@oracle.com>,
	"Jose E. Marchesi" <jemarch@gnu.org>,
	Beau Belgrave <beaub@linux.microsoft.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Jens Axboe <axboe@kernel.dk>, Florian Weimer <fweimer@redhat.com>,
	Sam James <sam@gentoo.org>
Subject: Re: [RFC PATCH v1 08/16] unwind_user: Enable archs that save RA/FP in other registers
Date: Thu, 17 Jul 2025 14:07:05 +0200	[thread overview]
Message-ID: <94e27f70-58f6-431d-9623-9c349a5977ff@linux.ibm.com> (raw)
In-Reply-To: <3he7rlcdchkwjtpbdt5khqflg4dipuvkneydhju2jjgs2ujqoh@2rpb6dutdogx>

On 17.07.2025 04:50, Josh Poimboeuf wrote:
> On Wed, Jul 16, 2025 at 07:01:09PM -0700, Josh Poimboeuf wrote:
>>>  	state->ip = ra;
>>>  	state->sp = sp;
>>> -	if (frame->fp_off)
>>> +	if (frame->fp.loc != UNWIND_USER_LOC_NONE)
>>>  		state->fp = fp;
>>
>> Instead of the extra conditional here, can fp be initialized to zero?
>> Either at the top of the function or in the RA switch statement?

No, but fp could be initialized to state->fp, so that it retains its
value.

> So it's been a while since I looked at the original code, but I actually
> think there's a bug here.
> 
> There's a subtlety in the original code:
> 
> 	if (frame->fp_off && unwind_get_user_long(fp, cfa + frame->fp_off, state))
> 		goto done;
> 
> 	state->ip = ra;
> 	state->sp = cfa;
> 	if (frame->fp_off)
> 		state->fp = fp;
> 
> 	arch_unwind_user_next(state);
> 
> Note that unlike !frame->ra_off, !frame->fp_off does NOT end the unwind.
> That only means the FP offset is unknown for the current frame.  Which
> is a perfectly valid condition, e.g. if the function doesn't have frame
> pointers or if it's before the prologue.
> 
> In that case, the unwind should continue, and state->fp's existing value
> should be preserved, as it might already have a valid value from a
> previous frame.

I fully agree with all of the above.

> So the following is wrong:
> 
> 	case UNWIND_USER_LOC_STACK:
> 		if (!frame->fp.frame_off)
> 			goto done;
> 		if (unwind_get_user_long(fp, cfa + frame->fp.frame_off, state))
> 			goto done;
> 		break;
> 
> Instead of having !fp.frame_off stopping the unwind, it should just
> break out of the switch statement and keep going.

If frame->fp.loc is UNWIND_USER_LOC_STACK then frame->fp.frame_off must
have a value != 0.  At least if we keep the original semantic.

We can omit this check, if we assume all producers of frame behave
correctly.  For instance user unwind sframe would not produce that
(see below).  Could it somehow be made a debug-config-only check?

> And that means the following is also wrong:
> 
> 	state->ip = ra;
> 	state->sp = sp;
> 	if (frame->fp.loc != UNWIND_USER_LOC_NONE)
> 		state->fp = fp;
> 
> because state->fp needs to preserved for the STACK+!fp.frame_off case.

unwind user sframe will not produce that:

static inline void
sframe_init_reginfo(struct unwind_user_reginfo *reginfo, s32 offset)
{
	if (offset) {
		reginfo->loc = UNWIND_USER_LOC_STACK;
		reginfo->frame_off = offset;
	} else {
		reginfo->loc = UNWIND_USER_LOC_NONE;
	}
}

> So, something like this?
> 
> 	bool preserve_fp = false;
> 	...
> 
> 	/* Get the Frame Pointer (FP) */
> 	switch (frame->fp.loc) {
> 	case UNWIND_USER_LOC_NONE:
> 		preserve_fp = true;
> 		break;
> 	case UNWIND_USER_LOC_STACK:
> 		if (!frame->fp.frame_off) {
> 			preserve_fp = true;
> 			break;
> 		}
> 	...
> 
> 	state->ip = ra;
> 	state->sp = sp;
> 	if (!preserve_fp)
> 		state->fp = fp;

I don't think all of this is necessary.

frame->fp.loc == UNWIND_USER_LOC_NONE already indicates the state->fp
retains it's previous value.

> BTW, I would suggest renaming "frame_off" to "offset",
> "frame->fp.offset" reads better and is more compact.

Makes sense.  I'll change that.

Regards,
Jens
-- 
Jens Remus
Linux on Z Development (D3303)
+49-7031-16-1128 Office
jremus@de.ibm.com

IBM

IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/


  reply	other threads:[~2025-07-17 12:07 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-10 16:35 [RFC PATCH v1 00/16] s390: SFrame user space unwinding Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 01/16] fixup! unwind_user: Add frame pointer support Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 02/16] s390: asm/dwarf.h should only be included in assembly files Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 03/16] s390/vdso: Avoid emitting DWARF CFI for non-vDSO Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 04/16] s390/vdso: Enable SFrame generation in vDSO Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 05/16] s390/vdso: Keep function symbols " Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 06/16] unwind_user: Enable archs that define CFA = SP_callsite + offset Jens Remus
2025-07-16 21:32   ` Josh Poimboeuf
2025-07-17  9:27     ` Jens Remus
2025-07-18  4:51       ` Josh Poimboeuf
2025-07-10 16:35 ` [RFC PATCH v1 07/16] unwind_user: Enable archs that do not necessarily save RA Jens Remus
2025-07-16 23:01   ` Josh Poimboeuf
2025-07-17 11:09     ` Jens Remus
2025-07-18  8:28       ` Jens Remus
2025-07-18 16:59         ` Josh Poimboeuf
2025-07-21 14:25           ` Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 08/16] unwind_user: Enable archs that save RA/FP in other registers Jens Remus
2025-07-17  2:01   ` Josh Poimboeuf
2025-07-17  2:50     ` Josh Poimboeuf
2025-07-17 12:07       ` Jens Remus [this message]
2025-07-18  4:52         ` Josh Poimboeuf
2025-07-17  3:57     ` Steven Rostedt
2025-07-17  7:24       ` Josh Poimboeuf
2025-07-17 12:05         ` Steven Rostedt
2025-07-17 11:28     ` Jens Remus
2025-07-17 12:10       ` Steven Rostedt
2025-07-18  4:51       ` Josh Poimboeuf
2025-07-10 16:35 ` [RFC PATCH v1 09/16] unwind_user/sframe: Enable archs with encoded SFrame CFA offsets Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 10/16] s390/ptrace: Enable HAVE_USER_RA_REG Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 11/16] s390/unwind_user/sframe: Enable HAVE_UNWIND_USER_SFRAME Jens Remus
2025-08-01 12:53   ` Heiko Carstens
2025-08-01 15:46     ` Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 12/16] unwind_user/backchain: Introduce back chain user space unwinding Jens Remus
2025-07-17  2:06   ` Josh Poimboeuf
2025-07-17 12:20     ` Jens Remus
2025-07-18  5:19       ` Josh Poimboeuf
2025-08-01 12:36         ` Heiko Carstens
2025-08-01 15:49           ` Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 13/16] s390/unwind_user/backchain: Enable HAVE_UNWIND_USER_BACKCHAIN Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 14/16] PREREQ: x86/asm: Avoid emitting DWARF CFI for non-VDSO Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 15/16] PREREQ: x86/vdso: Enable sframe generation in VDSO Jens Remus
2025-07-10 16:35 ` [RFC PATCH v1 16/16] WIP: fixup! s390/unwind_user/sframe: Enable HAVE_UNWIND_USER_SFRAME Jens Remus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=94e27f70-58f6-431d-9623-9c349a5977ff@linux.ibm.com \
    --to=jremus@linux.ibm.com \
    --cc=akpm@linux-foundation.org \
    --cc=andrii@kernel.org \
    --cc=axboe@kernel.dk \
    --cc=beaub@linux.microsoft.com \
    --cc=bpf@vger.kernel.org \
    --cc=fweimer@redhat.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=iii@linux.ibm.com \
    --cc=indu.bhagat@oracle.com \
    --cc=jemarch@gnu.org \
    --cc=jolsa@kernel.org \
    --cc=jpoimboe@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rostedt@kernel.org \
    --cc=sam@gentoo.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).