Hello Dylan and Weinan! On 4/6/2026 8:49 PM, Dylan Hatch wrote: > From: Weinan Liu <[email protected]> > > DWARF CFI (Call Frame Information) specifies how to recover the return > address and callee-saved registers at each PC in a given function. > Compilers are able to generate the CFI annotations when they compile > the code to assembly language. For handcrafted assembly, we need to > annotate them by hand. > > Annotate CFI unwind info for assembly for interrupt and exception > handlers.
It took me a while to figure, why CFI annotations are uncommonly only added to selected instruction (ranges) and not the whole functions. I guess you only want to enable stacktracing using SFrame through el1*_64_*() (from el1*_64_*_handler()) and call_on_irq_stack(), that is why the added CFI annotations start after the bl/blr instructions, so that whenever an unwound return address points after those bl/blr SFrame can recover the stack pointer, frame pointer, and return address. Wouldn't that be worth to be documented in the commit message? > Signed-off-by: Weinan Liu <[email protected]> > Signed-off-by: Dylan Hatch <[email protected]> > diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S > @@ -575,7 +575,12 @@ SYM_CODE_START_LOCAL(el\el\ht\()_\regsize\()_\label) > .if \el == 0 > b ret_to_user > .else /* Minimal DWARF CFI for unwinding across call above. */ > + .cfi_startproc > + .cfi_def_cfa_offset PT_REGS_SIZE > + .cfi_offset 29, S_FP - PT_REGS_SIZE > + .cfi_offset 30, S_LR - PT_REGS_SIZE > b ret_to_kernel > + .cfi_endproc > .endif > SYM_CODE_END(el\el\ht\()_\regsize\()_\label) > .endm > @@ -889,6 +894,10 @@ SYM_FUNC_START(call_on_irq_stack) > add sp, x16, #IRQ_STACK_SIZE > restore_irq x9 > blr x1 /* Minimal DWARF CFI for unwinding across indirect call above. */ > + .cfi_startproc > + .cfi_def_cfa 29, 16 > + .cfi_offset 29, -16 > + .cfi_offset 30, -8 > > save_and_disable_daif x9 > /* > @@ -900,6 +909,7 @@ SYM_FUNC_START(call_on_irq_stack) > scs_load_current > restore_irq x9 > ret > + .cfi_endproc > SYM_FUNC_END(call_on_irq_stack) > NOKPROBE(call_on_irq_stack) While above minimal DWARF CFI works for your use case, the following minor issue should probably be better corrected (excerpt from call_on_irq_stack with your patch applied): blr x1 .cfi_startproc .cfi_def_cfa 29, 16 <-- CFA is defined as FP + 16 .cfi_offset 29, -16 .cfi_offset 30, -8 save_and_disable_daif x9 /* * Restore the SP from the FP, and restore the FP and LR from the frame * record. */ mov sp, x29 ldp x29, x30, [sp], #16 <-- FP is restored, so that the CFA definition is no longer valid [CORRECTION] .cfi_restore 29 .cfi_restore 30 .cfi_def_cfa 31, 0 [/CORRECTION] scs_load_current restore_irq x9 ret .cfi_endproc SYM_FUNC_END(call_on_irq_stack) Would it alternatively make sense to add complete DWARF CFI annotations to call_on_irq_stack()? I think the following would do: SYM_FUNC_START(call_on_irq_stack) .cfi_startproc ... /* Create a frame record to save our LR and SP (implicit in FP) */ stp x29, x30, [sp, #-16]! mov x29, sp .cfi_def_cfa 29, 16 .cfi_offset 29, -16 .cfi_offset 30, -8 ... /* * Restore the SP from the FP, and restore the FP and LR from the frame * record. */ mov sp, x29 ldp x29, x30, [sp], #16 .cfi_restore 29 .cfi_restore 30 .cfi_def_cfa 31, 0 ... ret .cfi_endproc SYM_FUNC_END(call_on_irq_stack) Thanks and regards, Jens -- Jens Remus Linux on Z Development (D3303) [email protected] / [email protected] IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294 IBM Data Privacy Statement: https://www.ibm.com/privacy/

