From 3473f26592c1c365d376aee29433d7db75f14d1e Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 17 Jul 2015 21:40:28 +0100 Subject: ARM: 8405/1: VDSO: fix regression with toolchains lacking ld.bfd executable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Sourcery CodeBench Lite 2014.05 toolchain (gcc 4.8.3, binutils 2.24.51) has a GCC which implements -fuse-ld, and it doesn't include the gold linker, but it lacks an ld.bfd executable in its installation. This means that passing -fuse-ld=bfd fails with: VDSO arch/arm/vdso/vdso.so.raw collect2: fatal error: cannot find 'ld' Arguably this is a deficiency in the toolchain, but I suspect it's commonly used enough that it's worth accommodating: just use cc-ldoption (to cause a link attempt) instead of cc-option to test whether we can use -fuse-ld. So -fuse-ld=bfd won't be used with this toolchain, but the build will rightly succeed, just as it does for toolchains which don't implement -fuse-ld (and don't use gold as the default linker). Note: this will change the failure mode for a corner case I was trying to handle in d2b30cd4b722, where the toolchain defaults to the gold linker and the BFD linker is not found in PATH, from: VDSO arch/arm/vdso/vdso.so.raw collect2: fatal error: cannot find 'ld' i.e. the BFD linker is not found, to: OBJCOPY arch/arm/vdso/vdso.so BFD: arch/arm/vdso/vdso.so: Not enough room for program headers, try linking with -N that is, we fail to prevent gold from being used as the linker, and it produces an object that objcopy can't digest. Reported-by: Baruch Siach Tested-by: Baruch Siach Tested-by: Raphaƫl Poggi Fixes: d2b30cd4b722 ("ARM: 8384/1: VDSO: force use of BFD linker") Cc: stable@vger.kernel.org Signed-off-by: Nathan Lynch Signed-off-by: Russell King --- arch/arm/vdso/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index 9d259d94e429..1160434eece0 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -14,7 +14,7 @@ VDSO_LDFLAGS += -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 VDSO_LDFLAGS += -nostdlib -shared VDSO_LDFLAGS += $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) VDSO_LDFLAGS += $(call cc-ldoption, -Wl$(comma)--build-id) -VDSO_LDFLAGS += $(call cc-option, -fuse-ld=bfd) +VDSO_LDFLAGS += $(call cc-ldoption, -fuse-ld=bfd) obj-$(CONFIG_VDSO) += vdso.o extra-$(CONFIG_VDSO) += vdso.lds -- cgit v1.2.3 From 998ef5d81c74c752d74c7925bc370909b84adb9d Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 6 Aug 2015 15:07:04 +0100 Subject: ARM: 8408/1: Fix the secondary_startup function in Big Endian case Since the commit "b2c3e38a5471 ARM: redo TTBR setup code for LPAE", the setup code had been reworked. As a result the secondary CPUs failed to come online in Big Endian. As explained by Russell, the new code expected the value in r4/r5 to be the least significant 32bits in r4 and the most significant 32bits in r5. However, in the secondary code, we load this using ldrd, which on BE reverses that. This patch swap r4/r5 after the ldrd. It is done using the xor instructions in order to not use a temporary register. Signed-off-by: Gregory CLEMENT Signed-off-by: Russell King --- arch/arm/kernel/head.S | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index bd755d97e459..29e2991465cb 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -399,6 +399,9 @@ ENTRY(secondary_startup) sub lr, r4, r5 @ mmu has been enabled add r3, r7, lr ldrd r4, [r3, #0] @ get secondary_data.pgdir +ARM_BE8(eor r4, r4, r5) @ Swap r5 and r4 in BE: +ARM_BE8(eor r5, r4, r5) @ it can be done in 3 steps +ARM_BE8(eor r4, r4, r5) @ without using a temp reg. ldr r8, [r3, #8] @ get secondary_data.swapper_pg_dir badr lr, __enable_mmu @ return address mov r13, r12 @ __secondary_switched address -- cgit v1.2.3 From e83dd3770021910293edea6fb2dc2fa306b1bf34 Mon Sep 17 00:00:00 2001 From: Drew Richardson Date: Thu, 6 Aug 2015 18:50:27 +0100 Subject: ARM: 8409/1: Mark ret_fast_syscall as a function ret_fast_syscall runs when user space makes a syscall. However it needs to be marked as such so the ELF information is correct. Before it was: 101: 8000f300 0 NOTYPE LOCAL DEFAULT 2 ret_fast_syscall But with this change it correctly shows as: 101: 8000f300 96 FUNC LOCAL DEFAULT 2 ret_fast_syscall I see this function when using perf to unwind call stacks from kernel space to user space. Without this change I would need to add some special case logic when using the vmlinux ELF information. Signed-off-by: Drew Richardson Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/entry-common.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 92828a1dec80..b48dd4f37f80 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -61,6 +61,7 @@ work_pending: movlt scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE) ldmia sp, {r0 - r6} @ have to reload r0 - r6 b local_restart @ ... and off we go +ENDPROC(ret_fast_syscall) /* * "slow" syscall return path. "why" tells us if this was a real syscall. -- cgit v1.2.3 From 09edea4f8fdeb4e292b80d493296070f5ec64e6e Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Mon, 10 Aug 2015 17:36:06 +0100 Subject: ARM: 8410/1: VDSO: fix coarse clock monotonicity regression Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the real timekeeper last") it has become possible on ARM to: - Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp via syscall. - Subsequently obtain a timestamp for the same clock ID via VDSO which predates the first timestamp (by one jiffy). This is because ARM's update_vsyscall is deriving the coarse time using the __current_kernel_time interface, when it should really be using the timekeeper object provided to it by the timekeeping core. It happened to work before only because __current_kernel_time would access the same timekeeper object which had been passed to update_vsyscall. This is no longer the case. Cc: stable@vger.kernel.org Fixes: 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the real timekeeper last") Signed-off-by: Nathan Lynch Acked-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/vdso.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c index efe17dd9b921..54a5aeab988d 100644 --- a/arch/arm/kernel/vdso.c +++ b/arch/arm/kernel/vdso.c @@ -296,7 +296,6 @@ static bool tk_is_cntvct(const struct timekeeper *tk) */ void update_vsyscall(struct timekeeper *tk) { - struct timespec xtime_coarse; struct timespec64 *wtm = &tk->wall_to_monotonic; if (!cntvct_ok) { @@ -308,10 +307,10 @@ void update_vsyscall(struct timekeeper *tk) vdso_write_begin(vdso_data); - xtime_coarse = __current_kernel_time(); vdso_data->tk_is_cntvct = tk_is_cntvct(tk); - vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec; - vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec; + vdso_data->xtime_coarse_sec = tk->xtime_sec; + vdso_data->xtime_coarse_nsec = (u32)(tk->tkr_mono.xtime_nsec >> + tk->tkr_mono.shift); vdso_data->wtm_clock_sec = wtm->tv_sec; vdso_data->wtm_clock_nsec = wtm->tv_nsec; -- cgit v1.2.3