summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2017-11-20 11:46:13 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-12-13 10:51:36 +0100
commit7bceec4e58ee23be653c0dd366479d6cb64ae686 (patch)
treecd285499f296c534522f812c6d4af6febd7aa8a2 /arch
parentbc3703f21cec8a2ac6a64f6fb3686fbcb1ba1513 (diff)
downloadlinux-7bceec4e58ee23be653c0dd366479d6cb64ae686.tar.bz2
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')
-rw-r--r--arch/s390/Makefile7
-rw-r--r--arch/s390/include/asm/dwarf.h12
-rw-r--r--arch/s390/kernel/vdso32/clock_getres.S4
-rw-r--r--arch/s390/kernel/vdso32/clock_gettime.S16
-rw-r--r--arch/s390/kernel/vdso32/getcpu.S4
-rw-r--r--arch/s390/kernel/vdso32/gettimeofday.S8
-rw-r--r--arch/s390/kernel/vdso64/clock_getres.S4
-rw-r--r--arch/s390/kernel/vdso64/clock_gettime.S20
-rw-r--r--arch/s390/kernel/vdso64/getcpu.S4
-rw-r--r--arch/s390/kernel/vdso64/gettimeofday.S8
10 files changed, 69 insertions, 18 deletions
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 494bb9ad5edf..aa37ba79c762 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -88,10 +88,13 @@ KBUILD_CFLAGS += -DCC_USING_HOTPATCH
endif
endif
+# Test CFI features of binutils
+cfi := $(call as-instr,.cfi_startproc\n.cfi_val_offset 15$(comma)-160\n.cfi_endproc,-DCONFIG_AS_CFI_VAL_OFFSET=1)
+
KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y)
KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare
-KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
-KBUILD_AFLAGS += $(aflags-y)
+KBUILD_CFLAGS += -fno-asynchronous-unwind-tables $(cfi)
+KBUILD_AFLAGS += $(aflags-y) $(cfi)
OBJCOPYFLAGS := -O binary
diff --git a/arch/s390/include/asm/dwarf.h b/arch/s390/include/asm/dwarf.h
index dffdb81e534f..4f21ae561e4d 100644
--- a/arch/s390/include/asm/dwarf.h
+++ b/arch/s390/include/asm/dwarf.h
@@ -4,6 +4,18 @@
#ifdef __ASSEMBLY__
+#define CFI_STARTPROC .cfi_startproc
+#define CFI_ENDPROC .cfi_endproc
+#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
+#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
+#define CFI_RESTORE .cfi_restore
+
+#ifdef CONFIG_AS_CFI_VAL_OFFSET
+#define CFI_VAL_OFFSET .cfi_val_offset
+#else
+#define CFI_VAL_OFFSET #
+#endif
+
#ifndef BUILD_VDSO
/*
* Emit CFI data in .debug_frame sections and not in .eh_frame
diff --git a/arch/s390/kernel/vdso32/clock_getres.S b/arch/s390/kernel/vdso32/clock_getres.S
index 6aeddf8e4bc7..eaf9cf1417f6 100644
--- a/arch/s390/kernel/vdso32/clock_getres.S
+++ b/arch/s390/kernel/vdso32/clock_getres.S
@@ -16,7 +16,7 @@
.globl __kernel_clock_getres
.type __kernel_clock_getres,@function
__kernel_clock_getres:
- .cfi_startproc
+ CFI_STARTPROC
basr %r1,0
la %r1,4f-.(%r1)
chi %r2,__CLOCK_REALTIME
@@ -38,7 +38,7 @@ __kernel_clock_getres:
3: lhi %r1,__NR_clock_getres /* fallback to svc */
svc 0
br %r14
+ CFI_ENDPROC
4: .long __CLOCK_REALTIME_RES
5: .long __CLOCK_COARSE_RES
- .cfi_endproc
.size __kernel_clock_getres,.-__kernel_clock_getres
diff --git a/arch/s390/kernel/vdso32/clock_gettime.S b/arch/s390/kernel/vdso32/clock_gettime.S
index d0ac32c413e2..a9418bf975db 100644
--- a/arch/s390/kernel/vdso32/clock_gettime.S
+++ b/arch/s390/kernel/vdso32/clock_gettime.S
@@ -16,8 +16,10 @@
.globl __kernel_clock_gettime
.type __kernel_clock_gettime,@function
__kernel_clock_gettime:
- .cfi_startproc
+ CFI_STARTPROC
ahi %r15,-16
+ CFI_DEF_CFA_OFFSET 176
+ CFI_VAL_OFFSET 15, -160
basr %r5,0
0: al %r5,21f-0b(%r5) /* get &_vdso_data */
chi %r2,__CLOCK_REALTIME_COARSE
@@ -70,9 +72,13 @@ __kernel_clock_gettime:
st %r1,4(%r3) /* store tp->tv_nsec */
lhi %r2,0
ahi %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
9: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
tml %r4,0x0001 /* pending update ? loop */
jnz 9b
@@ -152,15 +158,21 @@ __kernel_clock_gettime:
st %r1,4(%r3) /* store tp->tv_nsec */
lhi %r2,0
ahi %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
19: lhi %r1,__NR_clock_gettime
svc 0
ahi %r15,16
+ CFI_DEF_CFA_OFFSET 160
+ CFI_RESTORE 15
br %r14
+ CFI_ENDPROC
20: .long 1000000000
21: .long _vdso_data - 0b
- .cfi_endproc
.size __kernel_clock_gettime,.-__kernel_clock_gettime
diff --git a/arch/s390/kernel/vdso32/getcpu.S b/arch/s390/kernel/vdso32/getcpu.S
index 539d92a2c61b..25515f3fbcea 100644
--- a/arch/s390/kernel/vdso32/getcpu.S
+++ b/arch/s390/kernel/vdso32/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: lhi %r2,0
br %r14
- .cfi_endproc
+ CFI_ENDPROC
.size __kernel_getcpu,.-__kernel_getcpu
diff --git a/arch/s390/kernel/vdso32/gettimeofday.S b/arch/s390/kernel/vdso32/gettimeofday.S
index 435f819c3e65..3c0db0fa6ad9 100644
--- a/arch/s390/kernel/vdso32/gettimeofday.S
+++ b/arch/s390/kernel/vdso32/gettimeofday.S
@@ -16,8 +16,10 @@
.globl __kernel_gettimeofday
.type __kernel_gettimeofday,@function
__kernel_gettimeofday:
- .cfi_startproc
+ CFI_STARTPROC
ahi %r15,-16
+ CFI_ADJUST_CFA_OFFSET 16
+ CFI_VAL_OFFSET 15, -160
basr %r5,0
0: al %r5,13f-0b(%r5) /* get &_vdso_data */
1: ltr %r3,%r3 /* check if tz is NULL */
@@ -90,9 +92,11 @@ __kernel_gettimeofday:
st %r0,4(%r2) /* store tv->tv_usec */
10: slr %r2,%r2
ahi %r15,16
+ CFI_ADJUST_CFA_OFFSET -16
+ CFI_RESTORE 15
br %r14
+ CFI_ENDPROC
11: .long 1000000000
12: .long 274877907
13: .long _vdso_data - 0b
- .cfi_endproc
.size __kernel_gettimeofday,.-__kernel_gettimeofday
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