Skip to content

Commit dded31e

Browse files
committed
powerpc/vdso: Fix incorrect CFI in gettimeofday.S
jira LE-1907 Rebuild_History Non-Buildable kernel-5.14.0-284.30.1.el9_2 commit-author Michael Ellerman <[email protected]> commit 6d65028 As reported by Alan, the CFI (Call Frame Information) in the VDSO time routines is incorrect since commit ce7d805 ("powerpc/vdso: Prepare for switching VDSO to generic C implementation."). DWARF has a concept called the CFA (Canonical Frame Address), which on powerpc is calculated as an offset from the stack pointer (r1). That means when the stack pointer is changed there must be a corresponding CFI directive to update the calculation of the CFA. The current code is missing those directives for the changes to r1, which prevents gdb from being able to generate a backtrace from inside VDSO functions, eg: Breakpoint 1, 0x00007ffff7f804dc in __kernel_clock_gettime () (gdb) bt #0 0x00007ffff7f804dc in __kernel_clock_gettime () #1 0x00007ffff7d8872c in clock_gettime@@GLIBC_2.17 () from /lib64/libc.so.6 #2 0x00007fffffffd960 in ?? () #3 0x00007ffff7d8872c in clock_gettime@@GLIBC_2.17 () from /lib64/libc.so.6 Backtrace stopped: frame did not save the PC Alan helpfully describes some rules for correctly maintaining the CFI information: 1) Every adjustment to the current frame address reg (ie. r1) must be described, and exactly at the instruction where r1 changes. Why? Because stack unwinding might want to access previous frames. 2) If a function changes LR or any non-volatile register, the save location for those regs must be given. The CFI can be at any instruction after the saves up to the point that the reg is changed. (Exception: LR save should be described before a bl. not after) 3) If asychronous unwind info is needed then restores of LR and non-volatile regs must also be described. The CFI can be at any instruction after the reg is restored up to the point where the save location is (potentially) trashed. Fix the inability to backtrace by adding CFI directives describing the changes to r1, ie. satisfying rule 1. Also change the information for LR to point to the copy saved on the stack, not the value in r0 that will be overwritten by the function call. Finally, add CFI directives describing the save/restore of r2. With the fix gdb can correctly back trace and navigate up and down the stack: Breakpoint 1, 0x00007ffff7f804dc in __kernel_clock_gettime () (gdb) bt #0 0x00007ffff7f804dc in __kernel_clock_gettime () #1 0x00007ffff7d8872c in clock_gettime@@GLIBC_2.17 () from /lib64/libc.so.6 #2 0x0000000100015b60 in gettime () #3 0x000000010000c8bc in print_long_format () ctrliq#4 0x000000010000d180 in print_current_files () ctrliq#5 0x00000001000054ac in main () (gdb) up #1 0x00007ffff7d8872c in clock_gettime@@GLIBC_2.17 () from /lib64/libc.so.6 (gdb) #2 0x0000000100015b60 in gettime () (gdb) #3 0x000000010000c8bc in print_long_format () (gdb) ctrliq#4 0x000000010000d180 in print_current_files () (gdb) ctrliq#5 0x00000001000054ac in main () (gdb) Initial frame selected; you cannot go up. (gdb) down ctrliq#4 0x000000010000d180 in print_current_files () (gdb) #3 0x000000010000c8bc in print_long_format () (gdb) #2 0x0000000100015b60 in gettime () (gdb) #1 0x00007ffff7d8872c in clock_gettime@@GLIBC_2.17 () from /lib64/libc.so.6 (gdb) #0 0x00007ffff7f804dc in __kernel_clock_gettime () (gdb) Fixes: ce7d805 ("powerpc/vdso: Prepare for switching VDSO to generic C implementation.") Cc: [email protected] # v5.11+ Reported-by: Alan Modra <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Reviewed-by: Segher Boessenkool <[email protected]> Link: https://lore.kernel.org/r/[email protected] (cherry picked from commit 6d65028) Signed-off-by: Jonathan Maple <[email protected]>
1 parent 045f600 commit dded31e

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

arch/powerpc/kernel/vdso32/gettimeofday.S

+7-2
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@
2222
.macro cvdso_call funct call_time=0
2323
.cfi_startproc
2424
PPC_STLU r1, -PPC_MIN_STKFRM(r1)
25+
.cfi_adjust_cfa_offset PPC_MIN_STKFRM
2526
mflr r0
26-
.cfi_register lr, r0
2727
PPC_STLU r1, -PPC_MIN_STKFRM(r1)
28+
.cfi_adjust_cfa_offset PPC_MIN_STKFRM
2829
PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
30+
.cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF
2931
#ifdef __powerpc64__
3032
PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1)
33+
.cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
3134
#endif
3235
get_datapage r5
3336
.ifeq \call_time
@@ -39,13 +42,15 @@
3942
PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
4043
#ifdef __powerpc64__
4144
PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1)
45+
.cfi_restore r2
4246
#endif
4347
.ifeq \call_time
4448
cmpwi r3, 0
4549
.endif
4650
mtlr r0
47-
.cfi_restore lr
4851
addi r1, r1, 2 * PPC_MIN_STKFRM
52+
.cfi_restore lr
53+
.cfi_def_cfa_offset 0
4954
crclr so
5055
.ifeq \call_time
5156
beqlr+

0 commit comments

Comments
 (0)