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:

committed by
Paul Burton

parent
c2aeaaea17
commit
24640f233b
@@ -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 \
|
||||
|
17
arch/mips/vdso/config-n32-o32-env.c
Normal file
17
arch/mips/vdso/config-n32-o32-env.c
Normal 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
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* Author: Alex Smith <alex.smith@imgtec.com>
|
||||
*/
|
||||
|
||||
#include "vdso.h"
|
||||
#include <asm/vdso/vdso.h>
|
||||
|
||||
#include <asm/isa-rev.h>
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* Author: Alex Smith <alex.smith@imgtec.com>
|
||||
*/
|
||||
|
||||
#include "vdso.h"
|
||||
#include <asm/vdso/vdso.h>
|
||||
|
||||
#include <uapi/asm/unistd.h>
|
||||
|
||||
|
@@ -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__ */
|
40
arch/mips/vdso/vgettimeofday.c
Normal file
40
arch/mips/vdso/vgettimeofday.c
Normal 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
|
Reference in New Issue
Block a user