diff options
author | Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 2017-11-20 11:46:13 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2017-12-13 10:51:36 +0100 |
commit | 7bceec4e58ee23be653c0dd366479d6cb64ae686 (patch) | |
tree | cd285499f296c534522f812c6d4af6febd7aa8a2 /arch/s390/kernel/vdso64 | |
parent | s390/kernel: emit CFI data in .debug_frame and discard .eh_frame sections (diff) | |
download | linux-7bceec4e58ee23be653c0dd366479d6cb64ae686.tar.xz linux-7bceec4e58ee23be653c0dd366479d6cb64ae686.zip |
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>
Diffstat (limited to 'arch/s390/kernel/vdso64')
-rw-r--r-- | arch/s390/kernel/vdso64/clock_getres.S | 4 | ||||
-rw-r--r-- | arch/s390/kernel/vdso64/clock_gettime.S | 20 | ||||
-rw-r--r-- | arch/s390/kernel/vdso64/getcpu.S | 4 | ||||
-rw-r--r-- | arch/s390/kernel/vdso64/gettimeofday.S | 8 |
4 files changed, 28 insertions, 8 deletions
diff --git a/arch/s390/kernel/vdso64/clock_getres.S b/arch/s390/kernel/vdso64/clock_getres.S index 5b0d9c380de2..081435398e0a 100644 --- a/arch/s390/kernel/vdso64/clock_getres.S +++ b/arch/s390/kernel/vdso64/clock_getres.S @@ -16,7 +16,7 @@ .globl __kernel_clock_getres .type __kernel_clock_getres,@function __kernel_clock_getres: - .cfi_startproc + CFI_STARTPROC larl %r1,4f cghi %r2,__CLOCK_REALTIME_COARSE je 0f @@ -44,7 +44,7 @@ __kernel_clock_getres: 2: lghi %r1,__NR_clock_getres /* fallback to svc */ svc 0 br %r14 + CFI_ENDPROC 3: .quad __CLOCK_REALTIME_RES 4: .quad __CLOCK_COARSE_RES - .cfi_endproc .size __kernel_clock_getres,.-__kernel_clock_getres diff --git a/arch/s390/kernel/vdso64/clock_gettime.S b/arch/s390/kernel/vdso64/clock_gettime.S index deccd793b279..fac3ab5ec83a 100644 --- a/arch/s390/kernel/vdso64/clock_gettime.S +++ b/arch/s390/kernel/vdso64/clock_gettime.S @@ -16,8 +16,10 @@ .globl __kernel_clock_gettime .type __kernel_clock_gettime,@function __kernel_clock_gettime: - .cfi_startproc + CFI_STARTPROC aghi %r15,-16 + CFI_DEF_CFA_OFFSET 176 + CFI_VAL_OFFSET 15, -160 larl %r5,_vdso_data cghi %r2,__CLOCK_REALTIME_COARSE je 4f @@ -54,9 +56,13 @@ __kernel_clock_gettime: stg %r1,8(%r3) /* store tp->tv_nsec */ lghi %r2,0 aghi %r15,16 + CFI_DEF_CFA_OFFSET 160 + CFI_RESTORE 15 br %r14 /* CLOCK_MONOTONIC_COARSE */ + CFI_DEF_CFA_OFFSET 176 + CFI_VAL_OFFSET 15, -160 3: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ tmll %r4,0x0001 /* pending update ? loop */ jnz 3b @@ -109,9 +115,13 @@ __kernel_clock_gettime: stg %r1,8(%r3) /* store tp->tv_nsec */ lghi %r2,0 aghi %r15,16 + CFI_DEF_CFA_OFFSET 160 + CFI_RESTORE 15 br %r14 /* CPUCLOCK_VIRT for this thread */ + CFI_DEF_CFA_OFFSET 176 + CFI_VAL_OFFSET 15, -160 9: lghi %r4,0 icm %r0,15,__VDSO_ECTG_OK(%r5) jz 12f @@ -132,15 +142,21 @@ __kernel_clock_gettime: stg %r4,8(%r3) lghi %r2,0 aghi %r15,16 + CFI_DEF_CFA_OFFSET 160 + CFI_RESTORE 15 br %r14 /* Fallback to system call */ + CFI_DEF_CFA_OFFSET 176 + CFI_VAL_OFFSET 15, -160 12: lghi %r1,__NR_clock_gettime svc 0 aghi %r15,16 + CFI_DEF_CFA_OFFSET 160 + CFI_RESTORE 15 br %r14 + CFI_ENDPROC 13: .quad 1000000000 14: .quad 19342813113834067 - .cfi_endproc .size __kernel_clock_gettime,.-__kernel_clock_gettime diff --git a/arch/s390/kernel/vdso64/getcpu.S b/arch/s390/kernel/vdso64/getcpu.S index 022acdecd5b9..2446e9dac8ab 100644 --- a/arch/s390/kernel/vdso64/getcpu.S +++ b/arch/s390/kernel/vdso64/getcpu.S @@ -15,7 +15,7 @@ .globl __kernel_getcpu .type __kernel_getcpu,@function __kernel_getcpu: - .cfi_startproc + CFI_STARTPROC la %r4,0 sacf 256 l %r5,__VDSO_CPU_NR(%r4) @@ -29,5 +29,5 @@ __kernel_getcpu: st %r4,0(%r3) 3: lghi %r2,0 br %r14 - .cfi_endproc + CFI_ENDPROC .size __kernel_getcpu,.-__kernel_getcpu diff --git a/arch/s390/kernel/vdso64/gettimeofday.S b/arch/s390/kernel/vdso64/gettimeofday.S index 964afb1de06d..6e1f0b421695 100644 --- a/arch/s390/kernel/vdso64/gettimeofday.S +++ b/arch/s390/kernel/vdso64/gettimeofday.S @@ -16,8 +16,10 @@ .globl __kernel_gettimeofday .type __kernel_gettimeofday,@function __kernel_gettimeofday: - .cfi_startproc + CFI_STARTPROC aghi %r15,-16 + CFI_ADJUST_CFA_OFFSET 16 + CFI_VAL_OFFSET 15, -160 larl %r5,_vdso_data 0: ltgr %r3,%r3 /* check if tz is NULL */ je 1f @@ -59,8 +61,10 @@ __kernel_gettimeofday: stg %r0,8(%r2) /* store tv->tv_usec */ 4: lghi %r2,0 aghi %r15,16 + CFI_ADJUST_CFA_OFFSET -16 + CFI_RESTORE 15 br %r14 + CFI_ENDPROC 5: .quad 1000000000 .long 274877907 - .cfi_endproc .size __kernel_gettimeofday,.-__kernel_gettimeofday |