Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/vdso: revise CFI annotations of vDSO functions

Revise and add CFI CFA and register rule annotations to the vDSO
functions for proper stack unwinding and debugging.

Because glibc might call the vDSO in special ways, the vDSO code
does not rely on a stack frame created by the caller. The TOD clock
value can be therefore not stored in the pre-allocated stack area
and additional stack space is required.
To correctly annotate these situations with CFI, the .cfi_val_offset
directive is required to create relative offsets on the value of the
stack register %r15. Because the .cfi_val_offset directive is
available with recent GNU assembler versions only, additional checks
are necessary.

Note that if the vDSO is assembled with an older assembler version,
stack unwinding and debugging from within the vDSO code might not
be possible.

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Hendrik Brueckner and committed by
Martin Schwidefsky
7bceec4e bc3703f2

+69 -18
+5 -2
arch/s390/Makefile
··· 88 88 endif 89 89 endif 90 90 91 + # Test CFI features of binutils 92 + cfi := $(call as-instr,.cfi_startproc\n.cfi_val_offset 15$(comma)-160\n.cfi_endproc,-DCONFIG_AS_CFI_VAL_OFFSET=1) 93 + 91 94 KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y) 92 95 KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare 93 - KBUILD_CFLAGS += -fno-asynchronous-unwind-tables 94 - KBUILD_AFLAGS += $(aflags-y) 96 + KBUILD_CFLAGS += -fno-asynchronous-unwind-tables $(cfi) 97 + KBUILD_AFLAGS += $(aflags-y) $(cfi) 95 98 96 99 OBJCOPYFLAGS := -O binary 97 100
+12
arch/s390/include/asm/dwarf.h
··· 4 4 5 5 #ifdef __ASSEMBLY__ 6 6 7 + #define CFI_STARTPROC .cfi_startproc 8 + #define CFI_ENDPROC .cfi_endproc 9 + #define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset 10 + #define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset 11 + #define CFI_RESTORE .cfi_restore 12 + 13 + #ifdef CONFIG_AS_CFI_VAL_OFFSET 14 + #define CFI_VAL_OFFSET .cfi_val_offset 15 + #else 16 + #define CFI_VAL_OFFSET # 17 + #endif 18 + 7 19 #ifndef BUILD_VDSO 8 20 /* 9 21 * Emit CFI data in .debug_frame sections and not in .eh_frame
+2 -2
arch/s390/kernel/vdso32/clock_getres.S
··· 16 16 .globl __kernel_clock_getres 17 17 .type __kernel_clock_getres,@function 18 18 __kernel_clock_getres: 19 - .cfi_startproc 19 + CFI_STARTPROC 20 20 basr %r1,0 21 21 la %r1,4f-.(%r1) 22 22 chi %r2,__CLOCK_REALTIME ··· 38 38 3: lhi %r1,__NR_clock_getres /* fallback to svc */ 39 39 svc 0 40 40 br %r14 41 + CFI_ENDPROC 41 42 4: .long __CLOCK_REALTIME_RES 42 43 5: .long __CLOCK_COARSE_RES 43 - .cfi_endproc 44 44 .size __kernel_clock_getres,.-__kernel_clock_getres
+14 -2
arch/s390/kernel/vdso32/clock_gettime.S
··· 16 16 .globl __kernel_clock_gettime 17 17 .type __kernel_clock_gettime,@function 18 18 __kernel_clock_gettime: 19 - .cfi_startproc 19 + CFI_STARTPROC 20 20 ahi %r15,-16 21 + CFI_DEF_CFA_OFFSET 176 22 + CFI_VAL_OFFSET 15, -160 21 23 basr %r5,0 22 24 0: al %r5,21f-0b(%r5) /* get &_vdso_data */ 23 25 chi %r2,__CLOCK_REALTIME_COARSE ··· 72 70 st %r1,4(%r3) /* store tp->tv_nsec */ 73 71 lhi %r2,0 74 72 ahi %r15,16 73 + CFI_DEF_CFA_OFFSET 160 74 + CFI_RESTORE 15 75 75 br %r14 76 76 77 77 /* CLOCK_MONOTONIC_COARSE */ 78 + CFI_DEF_CFA_OFFSET 176 79 + CFI_VAL_OFFSET 15, -160 78 80 9: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 79 81 tml %r4,0x0001 /* pending update ? loop */ 80 82 jnz 9b ··· 158 152 st %r1,4(%r3) /* store tp->tv_nsec */ 159 153 lhi %r2,0 160 154 ahi %r15,16 155 + CFI_DEF_CFA_OFFSET 160 156 + CFI_RESTORE 15 161 157 br %r14 162 158 163 159 /* Fallback to system call */ 160 + CFI_DEF_CFA_OFFSET 176 161 + CFI_VAL_OFFSET 15, -160 164 162 19: lhi %r1,__NR_clock_gettime 165 163 svc 0 166 164 ahi %r15,16 165 + CFI_DEF_CFA_OFFSET 160 166 + CFI_RESTORE 15 167 167 br %r14 168 + CFI_ENDPROC 168 169 169 170 20: .long 1000000000 170 171 21: .long _vdso_data - 0b 171 - .cfi_endproc 172 172 .size __kernel_clock_gettime,.-__kernel_clock_gettime
+2 -2
arch/s390/kernel/vdso32/getcpu.S
··· 15 15 .globl __kernel_getcpu 16 16 .type __kernel_getcpu,@function 17 17 __kernel_getcpu: 18 - .cfi_startproc 18 + CFI_STARTPROC 19 19 la %r4,0 20 20 sacf 256 21 21 l %r5,__VDSO_CPU_NR(%r4) ··· 29 29 st %r4,0(%r3) 30 30 3: lhi %r2,0 31 31 br %r14 32 - .cfi_endproc 32 + CFI_ENDPROC 33 33 .size __kernel_getcpu,.-__kernel_getcpu
+6 -2
arch/s390/kernel/vdso32/gettimeofday.S
··· 16 16 .globl __kernel_gettimeofday 17 17 .type __kernel_gettimeofday,@function 18 18 __kernel_gettimeofday: 19 - .cfi_startproc 19 + CFI_STARTPROC 20 20 ahi %r15,-16 21 + CFI_ADJUST_CFA_OFFSET 16 22 + CFI_VAL_OFFSET 15, -160 21 23 basr %r5,0 22 24 0: al %r5,13f-0b(%r5) /* get &_vdso_data */ 23 25 1: ltr %r3,%r3 /* check if tz is NULL */ ··· 92 90 st %r0,4(%r2) /* store tv->tv_usec */ 93 91 10: slr %r2,%r2 94 92 ahi %r15,16 93 + CFI_ADJUST_CFA_OFFSET -16 94 + CFI_RESTORE 15 95 95 br %r14 96 + CFI_ENDPROC 96 97 11: .long 1000000000 97 98 12: .long 274877907 98 99 13: .long _vdso_data - 0b 99 - .cfi_endproc 100 100 .size __kernel_gettimeofday,.-__kernel_gettimeofday
+2 -2
arch/s390/kernel/vdso64/clock_getres.S
··· 16 16 .globl __kernel_clock_getres 17 17 .type __kernel_clock_getres,@function 18 18 __kernel_clock_getres: 19 - .cfi_startproc 19 + CFI_STARTPROC 20 20 larl %r1,4f 21 21 cghi %r2,__CLOCK_REALTIME_COARSE 22 22 je 0f ··· 44 44 2: lghi %r1,__NR_clock_getres /* fallback to svc */ 45 45 svc 0 46 46 br %r14 47 + CFI_ENDPROC 47 48 3: .quad __CLOCK_REALTIME_RES 48 49 4: .quad __CLOCK_COARSE_RES 49 - .cfi_endproc 50 50 .size __kernel_clock_getres,.-__kernel_clock_getres
+18 -2
arch/s390/kernel/vdso64/clock_gettime.S
··· 16 16 .globl __kernel_clock_gettime 17 17 .type __kernel_clock_gettime,@function 18 18 __kernel_clock_gettime: 19 - .cfi_startproc 19 + CFI_STARTPROC 20 20 aghi %r15,-16 21 + CFI_DEF_CFA_OFFSET 176 22 + CFI_VAL_OFFSET 15, -160 21 23 larl %r5,_vdso_data 22 24 cghi %r2,__CLOCK_REALTIME_COARSE 23 25 je 4f ··· 56 54 stg %r1,8(%r3) /* store tp->tv_nsec */ 57 55 lghi %r2,0 58 56 aghi %r15,16 57 + CFI_DEF_CFA_OFFSET 160 58 + CFI_RESTORE 15 59 59 br %r14 60 60 61 61 /* CLOCK_MONOTONIC_COARSE */ 62 + CFI_DEF_CFA_OFFSET 176 63 + CFI_VAL_OFFSET 15, -160 62 64 3: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ 63 65 tmll %r4,0x0001 /* pending update ? loop */ 64 66 jnz 3b ··· 115 109 stg %r1,8(%r3) /* store tp->tv_nsec */ 116 110 lghi %r2,0 117 111 aghi %r15,16 112 + CFI_DEF_CFA_OFFSET 160 113 + CFI_RESTORE 15 118 114 br %r14 119 115 120 116 /* CPUCLOCK_VIRT for this thread */ 117 + CFI_DEF_CFA_OFFSET 176 118 + CFI_VAL_OFFSET 15, -160 121 119 9: lghi %r4,0 122 120 icm %r0,15,__VDSO_ECTG_OK(%r5) 123 121 jz 12f ··· 142 132 stg %r4,8(%r3) 143 133 lghi %r2,0 144 134 aghi %r15,16 135 + CFI_DEF_CFA_OFFSET 160 136 + CFI_RESTORE 15 145 137 br %r14 146 138 147 139 /* Fallback to system call */ 140 + CFI_DEF_CFA_OFFSET 176 141 + CFI_VAL_OFFSET 15, -160 148 142 12: lghi %r1,__NR_clock_gettime 149 143 svc 0 150 144 aghi %r15,16 145 + CFI_DEF_CFA_OFFSET 160 146 + CFI_RESTORE 15 151 147 br %r14 148 + CFI_ENDPROC 152 149 153 150 13: .quad 1000000000 154 151 14: .quad 19342813113834067 155 - .cfi_endproc 156 152 .size __kernel_clock_gettime,.-__kernel_clock_gettime
+2 -2
arch/s390/kernel/vdso64/getcpu.S
··· 15 15 .globl __kernel_getcpu 16 16 .type __kernel_getcpu,@function 17 17 __kernel_getcpu: 18 - .cfi_startproc 18 + CFI_STARTPROC 19 19 la %r4,0 20 20 sacf 256 21 21 l %r5,__VDSO_CPU_NR(%r4) ··· 29 29 st %r4,0(%r3) 30 30 3: lghi %r2,0 31 31 br %r14 32 - .cfi_endproc 32 + CFI_ENDPROC 33 33 .size __kernel_getcpu,.-__kernel_getcpu
+6 -2
arch/s390/kernel/vdso64/gettimeofday.S
··· 16 16 .globl __kernel_gettimeofday 17 17 .type __kernel_gettimeofday,@function 18 18 __kernel_gettimeofday: 19 - .cfi_startproc 19 + CFI_STARTPROC 20 20 aghi %r15,-16 21 + CFI_ADJUST_CFA_OFFSET 16 22 + CFI_VAL_OFFSET 15, -160 21 23 larl %r5,_vdso_data 22 24 0: ltgr %r3,%r3 /* check if tz is NULL */ 23 25 je 1f ··· 61 59 stg %r0,8(%r2) /* store tv->tv_usec */ 62 60 4: lghi %r2,0 63 61 aghi %r15,16 62 + CFI_ADJUST_CFA_OFFSET -16 63 + CFI_RESTORE 15 64 64 br %r14 65 + CFI_ENDPROC 65 66 5: .quad 1000000000 66 67 .long 274877907 67 - .cfi_endproc 68 68 .size __kernel_gettimeofday,.-__kernel_gettimeofday