diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index bc74afdbf31e..e026b2d0a5a4 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -108,6 +108,10 @@ PHONY += vdso_install vdso_install: $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@ +prepare: vdso_prepare +vdso_prepare: prepare0 + $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h + ifneq ($(CONFIG_XIP_KERNEL),y) ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN),yy) KBUILD_IMAGE := $(boot)/loader.bin diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h index 1453a2f563bc..d8d003c2b5a3 100644 --- a/arch/riscv/include/asm/vdso.h +++ b/arch/riscv/include/asm/vdso.h @@ -9,25 +9,15 @@ #define _ASM_RISCV_VDSO_H #include +#include #ifndef CONFIG_GENERIC_TIME_VSYSCALL struct vdso_data { }; #endif -/* - * The VDSO symbols are mapped into Linux so we can just use regular symbol - * addressing to get their offsets in userspace. The symbols are mapped at an - * offset of 0, but since the linker must support setting weak undefined - * symbols to the absolute address 0 it also happens to support other low - * addresses even when the code model suggests those low addresses would not - * otherwise be availiable. - */ #define VDSO_SYMBOL(base, name) \ -({ \ - extern const char __vdso_##name[]; \ - (void __user *)((unsigned long)(base) + __vdso_##name); \ -}) + (void __user *)((unsigned long)(base) + __vdso_##name##_offset) asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t); diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile index 30a5335bd317..f2e065671e4d 100644 --- a/arch/riscv/kernel/vdso/Makefile +++ b/arch/riscv/kernel/vdso/Makefile @@ -23,10 +23,10 @@ ifneq ($(c-gettimeofday-y),) endif # Build rules -targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds vdso-syms.S +targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) -obj-y += vdso.o vdso-syms.o +obj-y += vdso.o CPPFLAGS_vdso.lds += -P -C -U$(ARCH) # Disable -pg to prevent insert call site @@ -44,20 +44,22 @@ $(obj)/vdso.o: $(obj)/vdso.so # link rule for the .so file, .lds has to be first $(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE $(call if_changed,vdsold) -LDFLAGS_vdso.so.dbg = -shared -s -soname=linux-vdso.so.1 \ +LDFLAGS_vdso.so.dbg = -shared -S -soname=linux-vdso.so.1 \ --build-id=sha1 --hash-style=both --eh-frame-hdr -# We also create a special relocatable object that should mirror the symbol -# table and layout of the linked DSO. With ld --just-symbols we can then -# refer to these symbols in the kernel code rather than hand-coded addresses. -$(obj)/vdso-syms.S: $(obj)/vdso.so FORCE - $(call if_changed,so2s) - # strip rule for the .so file $(obj)/%.so: OBJCOPYFLAGS := -S $(obj)/%.so: $(obj)/%.so.dbg FORCE $(call if_changed,objcopy) +# Generate VDSO offsets using helper script +gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh +quiet_cmd_vdsosym = VDSOSYM $@ + cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ + +include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE + $(call if_changed,vdsosym) + # actual build commands # The DSO images are built using a special linker script # Make sure only to export the intended __vdso_xxx symbol offsets. @@ -66,11 +68,6 @@ quiet_cmd_vdsold = VDSOLD $@ $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \ rm $@.tmp -# Extracts symbol offsets from the VDSO, converting them into an assembly file -# that contains the same symbols at the same offsets. -quiet_cmd_so2s = SO2S $@ - cmd_so2s = $(NM) -D $< | $(srctree)/$(src)/so2s.sh > $@ - # install commands for the unstripped file quiet_cmd_vdso_install = INSTALL $@ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ diff --git a/arch/riscv/kernel/vdso/gen_vdso_offsets.sh b/arch/riscv/kernel/vdso/gen_vdso_offsets.sh new file mode 100755 index 000000000000..c2e5613f3495 --- /dev/null +++ b/arch/riscv/kernel/vdso/gen_vdso_offsets.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +LC_ALL=C +sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define \2_offset\t0x\1/p' diff --git a/arch/riscv/kernel/vdso/so2s.sh b/arch/riscv/kernel/vdso/so2s.sh deleted file mode 100755 index e64cb6d9440e..000000000000 --- a/arch/riscv/kernel/vdso/so2s.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0+ -# Copyright 2020 Palmer Dabbelt - -sed 's!\([0-9a-f]*\) T \([a-z0-9_]*\)\(@@LINUX_4.15\)*!.global \2\n.set \2,0x\1!' \ -| grep '^\.'