mips: Add support for generic vDSO

The mips vDSO library requires some adaptations to take advantage of the
newly introduced generic vDSO library.

Introduce the following changes:
 - Modification of vdso.c to be compliant with the common vdso datapage
 - Use of lib/vdso for gettimeofday

Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
[paul.burton@mips.com: Prepend $(src) to config-n32-o32-env.c path.]
Signed-off-by: Paul Burton <paul.burton@mips.com>
This commit is contained in:
Vincenzo Frascino
2019-06-21 10:52:46 +01:00
committed by Paul Burton
parent c2aeaaea17
commit 24640f233b
11 changed files with 296 additions and 115 deletions

View File

@@ -1,6 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
# Objects to go into the VDSO.
obj-vdso-y := elf.o gettimeofday.o sigreturn.o
# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
# the inclusion of generic Makefile.
ARCH_REL_TYPE_ABS := R_MIPS_JUMP_SLOT|R_MIPS_GLOB_DAT
include $(srctree)/lib/vdso/Makefile
obj-vdso-y := elf.o vgettimeofday.o sigreturn.o
# Common compiler flags between ABIs.
ccflags-vdso := \
@@ -15,15 +21,31 @@ ifdef CONFIG_CC_IS_CLANG
ccflags-vdso += $(filter --target=%,$(KBUILD_CFLAGS))
endif
#
# The -fno-jump-tables flag only prevents the compiler from generating
# jump tables but does not prevent the compiler from emitting absolute
# offsets.
cflags-vdso := $(ccflags-vdso) \
$(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
-O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
-DDISABLE_BRANCH_PROFILING \
-O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
-fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \
$(call cc-option, -fno-asynchronous-unwind-tables) \
$(call cc-option, -fno-stack-protector)
aflags-vdso := $(ccflags-vdso) \
-D__ASSEMBLY__ -Wa,-gdwarf-2
ifneq ($(c-gettimeofday-y),)
CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y)
# config-n32-o32-env.c prepares the environment to build a 32bit vDSO
# library on a 64bit kernel.
# Note: Needs to be included before than the generic library.
CFLAGS_vgettimeofday-o32.o = -include $(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
CFLAGS_vgettimeofday-n32.o = -include $(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
endif
CFLAGS_REMOVE_vgettimeofday.o = -pg
#
# For the pre-R6 code in arch/mips/vdso/vdso.h for locating
# the base address of VDSO, the linker will emit a R_MIPS_PC32
@@ -48,6 +70,8 @@ VDSO_LDFLAGS := \
$(addprefix -Wl$(comma),$(filter -E%,$(KBUILD_CFLAGS))) \
-nostdlib -shared -Wl,--hash-style=sysv -Wl,--build-id
CFLAGS_REMOVE_vdso.o = -pg
GCOV_PROFILE := n
UBSAN_SANITIZE := n
@@ -96,6 +120,7 @@ $(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi)
$(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE
$(call if_changed,vdsold)
$(call if_changed,vdso_check)
$(obj)/vdso-image.c: $(obj)/vdso.so.dbg.raw $(obj)/vdso.so.raw \
$(obj)/genvdso FORCE
@@ -134,6 +159,7 @@ $(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE
$(obj)/vdso-o32.so.dbg.raw: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE
$(call if_changed,vdsold)
$(call if_changed,vdso_check)
$(obj)/vdso-o32-image.c: VDSO_NAME := o32
$(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg.raw $(obj)/vdso-o32.so.raw \
@@ -174,6 +200,7 @@ $(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE
$(obj)/vdso-n32.so.dbg.raw: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE
$(call if_changed,vdsold)
$(call if_changed,vdso_check)
$(obj)/vdso-n32-image.c: VDSO_NAME := n32
$(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg.raw $(obj)/vdso-n32.so.raw \

View File

@@ -0,0 +1,17 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Configuration file for O32 and N32 binaries.
* Note: To be included before lib/vdso/gettimeofday.c
*/
#if defined(CONFIG_MIPS32_O32) || defined(CONFIG_MIPS32_N32)
/*
* In case of a 32 bit VDSO for a 64 bit kernel fake a 32 bit kernel
* configuration.
*/
#undef CONFIG_64BIT
#define CONFIG_32BIT 1
#define CONFIG_GENERIC_ATOMIC64 1
#endif

View File

@@ -4,7 +4,7 @@
* Author: Alex Smith <alex.smith@imgtec.com>
*/
#include "vdso.h"
#include <asm/vdso/vdso.h>
#include <asm/isa-rev.h>

View File

@@ -4,7 +4,7 @@
* Author: Alex Smith <alex.smith@imgtec.com>
*/
#include "vdso.h"
#include <asm/vdso/vdso.h>
#include <uapi/asm/unistd.h>

View File

@@ -1,85 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2015 Imagination Technologies
* Author: Alex Smith <alex.smith@imgtec.com>
*/
#include <asm/sgidefs.h>
#if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT)
/* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */
#undef CONFIG_64BIT
#define CONFIG_32BIT 1
#ifndef __ASSEMBLY__
#include <asm-generic/atomic64.h>
#endif
#endif
#ifndef __ASSEMBLY__
#include <asm/asm.h>
#include <asm/page.h>
#include <asm/vdso.h>
static inline unsigned long get_vdso_base(void)
{
unsigned long addr;
/*
* We can't use cpu_has_mips_r6 since it needs the cpu_data[]
* kernel symbol.
*/
#ifdef CONFIG_CPU_MIPSR6
/*
* lapc <symbol> is an alias to addiupc reg, <symbol> - .
*
* We can't use addiupc because there is no label-label
* support for the addiupc reloc
*/
__asm__("lapc %0, _start \n"
: "=r" (addr) : :);
#else
/*
* Get the base load address of the VDSO. We have to avoid generating
* relocations and references to the GOT because ld.so does not peform
* relocations on the VDSO. We use the current offset from the VDSO base
* and perform a PC-relative branch which gives the absolute address in
* ra, and take the difference. The assembler chokes on
* "li %0, _start - .", so embed the offset as a word and branch over
* it.
*
*/
__asm__(
" .set push \n"
" .set noreorder \n"
" bal 1f \n"
" nop \n"
" .word _start - . \n"
"1: lw %0, 0($31) \n"
" " STR(PTR_ADDU) " %0, $31, %0 \n"
" .set pop \n"
: "=r" (addr)
:
: "$31");
#endif /* CONFIG_CPU_MIPSR6 */
return addr;
}
static inline const union mips_vdso_data *get_vdso_data(void)
{
return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE);
}
#ifdef CONFIG_CLKSRC_MIPS_GIC
static inline void __iomem *get_gic(const union mips_vdso_data *data)
{
return (void __iomem *)data - PAGE_SIZE;
}
#endif /* CONFIG_CLKSRC_MIPS_GIC */
#endif /* __ASSEMBLY__ */

View File

@@ -0,0 +1,40 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* MIPS64 and compat userspace implementations of gettimeofday()
* and similar.
*
* Copyright (C) 2015 Imagination Technologies
* Copyright (C) 2018 ARM Limited
*
*/
#include <linux/time.h>
#include <linux/types.h>
#if _MIPS_SIM != _MIPS_SIM_ABI64
int __vdso_clock_gettime(clockid_t clock,
struct old_timespec32 *ts)
{
return __cvdso_clock_gettime32(clock, ts);
}
int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
struct timezone *tz)
{
return __cvdso_gettimeofday(tv, tz);
}
#else
int __vdso_clock_gettime(clockid_t clock,
struct __kernel_timespec *ts)
{
return __cvdso_clock_gettime(clock, ts);
}
int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
struct timezone *tz)
{
return __cvdso_gettimeofday(tv, tz);
}
#endif