linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] riscv: explicitly use symbol offsets for VDSO v2
@ 2021-08-02 21:00 Saleem Abdulrasool
  2021-08-02 23:14 ` kernel test robot
  2021-08-04  3:54 ` Palmer Dabbelt
  0 siblings, 2 replies; 4+ messages in thread
From: Saleem Abdulrasool @ 2021-08-02 21:00 UTC (permalink / raw)
  To: linux-riscv, linux-kernel
  Cc: Palmer Dabbelt, Nathan Chancellor, Nick Desaulniers,
	Bill Wendling, clang-built-linux, Saleem Abdulrasool

The current implementation of the `__rt_sigaction` reference computed an
absolute offset relative to the mapped base of the VDSO.  While this can
be handled in the medlow model, the medany model cannot handle this as
it is meant to be position independent.  The current implementation
relied on the BFD linker relaxing the PC-relative relocation into an
absolute relocation as it was a near-zero address allowing it to be
referenced relative to `zero`.

We now extract the offsets and create a generated header allowing the
build with LLVM and lld to succeed as we no longer depend on the linker
rewriting address references near zero.  This change was largely
modelled after the ARM64 target which does something similar.

Signed-off-by: Saleem Abdulrasool <abdulras@google.com>
---
 arch/riscv/Makefile                        |  4 ++++
 arch/riscv/include/asm/vdso.h              | 11 ++--------
 arch/riscv/kernel/vdso/Makefile            | 25 ++++++++++------------
 arch/riscv/kernel/vdso/gen_vdso_offsets.sh |  5 +++++
 arch/riscv/kernel/vdso/so2s.sh             |  6 ------
 5 files changed, 22 insertions(+), 29 deletions(-)
 create mode 100755 arch/riscv/kernel/vdso/gen_vdso_offsets.sh
 delete mode 100755 arch/riscv/kernel/vdso/so2s.sh

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..098795262b92 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -9,24 +9,17 @@
 #define _ASM_RISCV_VDSO_H
 
 #include <linux/types.h>
+#include <generated/vdso-offsets.h>
 
 #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 24d936c147cd..f8cb9144a284 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
@@ -43,20 +43,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.
@@ -65,11 +67,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 <palmerdabbelt@google.com>
-
-sed 's!\([0-9a-f]*\) T \([a-z0-9_]*\)\(@@LINUX_4.15\)*!.global \2\n.set \2,0x\1!' \
-| grep '^\.'
-- 
2.32.0.554.ge1b32706d8-goog


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] riscv: explicitly use symbol offsets for VDSO v2
  2021-08-02 21:00 [PATCH] riscv: explicitly use symbol offsets for VDSO v2 Saleem Abdulrasool
@ 2021-08-02 23:14 ` kernel test robot
  2021-08-04  3:54 ` Palmer Dabbelt
  1 sibling, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-08-02 23:14 UTC (permalink / raw)
  To: Saleem Abdulrasool, linux-riscv, linux-kernel
  Cc: kbuild-all, Palmer Dabbelt, Nathan Chancellor, Nick Desaulniers,
	Bill Wendling, clang-built-linux, Saleem Abdulrasool

[-- Attachment #1: Type: text/plain, Size: 6061 bytes --]

Hi Saleem,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linux/master]
[also build test ERROR on linus/master v5.14-rc3 next-20210730]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Saleem-Abdulrasool/riscv-explicitly-use-symbol-offsets-for-VDSO-v2/20210803-050150
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 349a2d52ffe59b7a0c5876fa7ee9f3eaf188b830
config: riscv-nommu_k210_defconfig (attached as .config)
compiler: riscv64-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/82dd1f24fc79924938e3633ecf573c7973d938f6
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Saleem-Abdulrasool/riscv-explicitly-use-symbol-offsets-for-VDSO-v2/20210803-050150
        git checkout 82dd1f24fc79924938e3633ecf573c7973d938f6
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross ARCH=riscv 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/riscv/kernel/vdso/vgettimeofday.c: In function '__vdso_clock_gettime':
>> arch/riscv/kernel/vdso/vgettimeofday.c:16:9: error: implicit declaration of function '__cvdso_clock_gettime'; did you mean '__vdso_clock_gettime'? [-Werror=implicit-function-declaration]
      16 |  return __cvdso_clock_gettime(clock, ts);
         |         ^~~~~~~~~~~~~~~~~~~~~
         |         __vdso_clock_gettime
   arch/riscv/kernel/vdso/vgettimeofday.c: In function '__vdso_gettimeofday':
>> arch/riscv/kernel/vdso/vgettimeofday.c:23:9: error: implicit declaration of function '__cvdso_gettimeofday'; did you mean '__vdso_gettimeofday'? [-Werror=implicit-function-declaration]
      23 |  return __cvdso_gettimeofday(tv, tz);
         |         ^~~~~~~~~~~~~~~~~~~~
         |         __vdso_gettimeofday
   arch/riscv/kernel/vdso/vgettimeofday.c: In function '__vdso_clock_getres':
>> arch/riscv/kernel/vdso/vgettimeofday.c:30:9: error: implicit declaration of function '__cvdso_clock_getres'; did you mean '__vdso_clock_getres'? [-Werror=implicit-function-declaration]
      30 |  return __cvdso_clock_getres(clock_id, res);
         |         ^~~~~~~~~~~~~~~~~~~~
         |         __vdso_clock_getres
   cc1: some warnings being treated as errors
--
   arch/riscv/kernel/vdso/vgettimeofday.c: In function '__vdso_clock_gettime':
>> arch/riscv/kernel/vdso/vgettimeofday.c:16:9: error: implicit declaration of function '__cvdso_clock_gettime'; did you mean '__vdso_clock_gettime'? [-Werror=implicit-function-declaration]
      16 |  return __cvdso_clock_gettime(clock, ts);
         |         ^~~~~~~~~~~~~~~~~~~~~
         |         __vdso_clock_gettime
   arch/riscv/kernel/vdso/vgettimeofday.c: In function '__vdso_gettimeofday':
>> arch/riscv/kernel/vdso/vgettimeofday.c:23:9: error: implicit declaration of function '__cvdso_gettimeofday'; did you mean '__vdso_gettimeofday'? [-Werror=implicit-function-declaration]
      23 |  return __cvdso_gettimeofday(tv, tz);
         |         ^~~~~~~~~~~~~~~~~~~~
         |         __vdso_gettimeofday
   arch/riscv/kernel/vdso/vgettimeofday.c: In function '__vdso_clock_getres':
>> arch/riscv/kernel/vdso/vgettimeofday.c:30:9: error: implicit declaration of function '__cvdso_clock_getres'; did you mean '__vdso_clock_getres'? [-Werror=implicit-function-declaration]
      30 |  return __cvdso_clock_getres(clock_id, res);
         |         ^~~~~~~~~~~~~~~~~~~~
         |         __vdso_clock_getres
   cc1: some warnings being treated as errors
   make[2]: *** [scripts/Makefile.build:273: arch/riscv/kernel/vdso/vgettimeofday.o] Error 1
   make[2]: Target 'include/generated/vdso-offsets.h' not remade because of errors.
   make[1]: *** [arch/riscv/Makefile:114: vdso_prepare] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [Makefile:215: __sub-make] Error 2
   make: Target 'prepare' not remade because of errors.


vim +16 arch/riscv/kernel/vdso/vgettimeofday.c

ad5d1122b82fbd Vincent Chen 2020-06-09  11  
e93b327dbf3d37 Vincent Chen 2020-06-23  12  extern
e93b327dbf3d37 Vincent Chen 2020-06-23  13  int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts);
ad5d1122b82fbd Vincent Chen 2020-06-09  14  int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
ad5d1122b82fbd Vincent Chen 2020-06-09  15  {
ad5d1122b82fbd Vincent Chen 2020-06-09 @16  	return __cvdso_clock_gettime(clock, ts);
ad5d1122b82fbd Vincent Chen 2020-06-09  17  }
ad5d1122b82fbd Vincent Chen 2020-06-09  18  
e93b327dbf3d37 Vincent Chen 2020-06-23  19  extern
e93b327dbf3d37 Vincent Chen 2020-06-23  20  int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz);
ad5d1122b82fbd Vincent Chen 2020-06-09  21  int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
ad5d1122b82fbd Vincent Chen 2020-06-09  22  {
ad5d1122b82fbd Vincent Chen 2020-06-09 @23  	return __cvdso_gettimeofday(tv, tz);
ad5d1122b82fbd Vincent Chen 2020-06-09  24  }
ad5d1122b82fbd Vincent Chen 2020-06-09  25  
e93b327dbf3d37 Vincent Chen 2020-06-23  26  extern
e93b327dbf3d37 Vincent Chen 2020-06-23  27  int __vdso_clock_getres(clockid_t clock_id, struct __kernel_timespec *res);
ad5d1122b82fbd Vincent Chen 2020-06-09  28  int __vdso_clock_getres(clockid_t clock_id, struct __kernel_timespec *res)
ad5d1122b82fbd Vincent Chen 2020-06-09  29  {
ad5d1122b82fbd Vincent Chen 2020-06-09 @30  	return __cvdso_clock_getres(clock_id, res);

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 8522 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] riscv: explicitly use symbol offsets for VDSO v2
  2021-08-02 21:00 [PATCH] riscv: explicitly use symbol offsets for VDSO v2 Saleem Abdulrasool
  2021-08-02 23:14 ` kernel test robot
@ 2021-08-04  3:54 ` Palmer Dabbelt
  2021-08-04 17:35   ` Saleem Abdulrasool
  1 sibling, 1 reply; 4+ messages in thread
From: Palmer Dabbelt @ 2021-08-04  3:54 UTC (permalink / raw)
  To: abdulras
  Cc: linux-riscv, linux-kernel, nathan, ndesaulniers, morbo,
	clang-built-linux, abdulras

On Mon, 02 Aug 2021 14:00:17 PDT (-0700), abdulras@google.com wrote:
> The current implementation of the `__rt_sigaction` reference computed an
> absolute offset relative to the mapped base of the VDSO.  While this can
> be handled in the medlow model, the medany model cannot handle this as
> it is meant to be position independent.  The current implementation
> relied on the BFD linker relaxing the PC-relative relocation into an
> absolute relocation as it was a near-zero address allowing it to be
> referenced relative to `zero`.
>
> We now extract the offsets and create a generated header allowing the
> build with LLVM and lld to succeed as we no longer depend on the linker
> rewriting address references near zero.  This change was largely
> modelled after the ARM64 target which does something similar.
>
> Signed-off-by: Saleem Abdulrasool <abdulras@google.com>
> ---
>  arch/riscv/Makefile                        |  4 ++++
>  arch/riscv/include/asm/vdso.h              | 11 ++--------
>  arch/riscv/kernel/vdso/Makefile            | 25 ++++++++++------------
>  arch/riscv/kernel/vdso/gen_vdso_offsets.sh |  5 +++++
>  arch/riscv/kernel/vdso/so2s.sh             |  6 ------
>  5 files changed, 22 insertions(+), 29 deletions(-)
>  create mode 100755 arch/riscv/kernel/vdso/gen_vdso_offsets.sh
>  delete mode 100755 arch/riscv/kernel/vdso/so2s.sh
>
> 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..098795262b92 100644
> --- a/arch/riscv/include/asm/vdso.h
> +++ b/arch/riscv/include/asm/vdso.h
> @@ -9,24 +9,17 @@
>  #define _ASM_RISCV_VDSO_H
>
>  #include <linux/types.h>
> +#include <generated/vdso-offsets.h>
>
>  #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 24d936c147cd..f8cb9144a284 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
> @@ -43,20 +43,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.
> @@ -65,11 +67,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 <palmerdabbelt@google.com>
> -
> -sed 's!\([0-9a-f]*\) T \([a-z0-9_]*\)\(@@LINUX_4.15\)*!.global \2\n.set \2,0x\1!' \
> -| grep '^\.'

This is giving me some unused variable warnings:

In file included from arch/riscv/kernel/signal.c:16:
arch/riscv/kernel/signal.c: In function ‘setup_rt_frame’:
./arch/riscv/include/asm/vdso.h:21:20: warning: unused variable ‘__vdso_rt_sigreturn’ [-Wunused-variable]
   21 |  extern const char __vdso_##name[];     \
      |                    ^~~~~~~
arch/riscv/kernel/signal.c:197:28: note: in expansion of macro ‘VDSO_SYMBOL’
  197 |  regs->ra = (unsigned long)VDSO_SYMBOL(
      |                            ^~~~~~~~~~~

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] riscv: explicitly use symbol offsets for VDSO v2
  2021-08-04  3:54 ` Palmer Dabbelt
@ 2021-08-04 17:35   ` Saleem Abdulrasool
  0 siblings, 0 replies; 4+ messages in thread
From: Saleem Abdulrasool @ 2021-08-04 17:35 UTC (permalink / raw)
  To: Palmer Dabbelt
  Cc: linux-riscv, linux-kernel, nathan, Nick Desaulniers,
	Bill Wendling, clang-built-linux

On Tue, Aug 3, 2021 at 8:55 PM Palmer Dabbelt <palmer@dabbelt.com> wrote:
>
> On Mon, 02 Aug 2021 14:00:17 PDT (-0700), abdulras@google.com wrote:
> > The current implementation of the `__rt_sigaction` reference computed an
> > absolute offset relative to the mapped base of the VDSO.  While this can
> > be handled in the medlow model, the medany model cannot handle this as
> > it is meant to be position independent.  The current implementation
> > relied on the BFD linker relaxing the PC-relative relocation into an
> > absolute relocation as it was a near-zero address allowing it to be
> > referenced relative to `zero`.
> >
> > We now extract the offsets and create a generated header allowing the
> > build with LLVM and lld to succeed as we no longer depend on the linker
> > rewriting address references near zero.  This change was largely
> > modelled after the ARM64 target which does something similar.
> >
> > Signed-off-by: Saleem Abdulrasool <abdulras@google.com>
> > ---
> >  arch/riscv/Makefile                        |  4 ++++
> >  arch/riscv/include/asm/vdso.h              | 11 ++--------
> >  arch/riscv/kernel/vdso/Makefile            | 25 ++++++++++------------
> >  arch/riscv/kernel/vdso/gen_vdso_offsets.sh |  5 +++++
> >  arch/riscv/kernel/vdso/so2s.sh             |  6 ------
> >  5 files changed, 22 insertions(+), 29 deletions(-)
> >  create mode 100755 arch/riscv/kernel/vdso/gen_vdso_offsets.sh
> >  delete mode 100755 arch/riscv/kernel/vdso/so2s.sh
> >
> > 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..098795262b92 100644
> > --- a/arch/riscv/include/asm/vdso.h
> > +++ b/arch/riscv/include/asm/vdso.h
> > @@ -9,24 +9,17 @@
> >  #define _ASM_RISCV_VDSO_H
> >
> >  #include <linux/types.h>
> > +#include <generated/vdso-offsets.h>
> >
> >  #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 24d936c147cd..f8cb9144a284 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
> > @@ -43,20 +43,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.
> > @@ -65,11 +67,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 <palmerdabbelt@google.com>
> > -
> > -sed 's!\([0-9a-f]*\) T \([a-z0-9_]*\)\(@@LINUX_4.15\)*!.global \2\n.set \2,0x\1!' \
> > -| grep '^\.'
>
> This is giving me some unused variable warnings:
>
> In file included from arch/riscv/kernel/signal.c:16:
> arch/riscv/kernel/signal.c: In function ‘setup_rt_frame’:
> ./arch/riscv/include/asm/vdso.h:21:20: warning: unused variable ‘__vdso_rt_sigreturn’ [-Wunused-variable]
>    21 |  extern const char __vdso_##name[];     \
>       |                    ^~~~~~~
> arch/riscv/kernel/signal.c:197:28: note: in expansion of macro ‘VDSO_SYMBOL’
>   197 |  regs->ra = (unsigned long)VDSO_SYMBOL(
>       |                            ^~~~~~~~~~~

Thanks Palmer,

It seems that there was a difference in diagnostics between gcc and
clang.  The diagnostic indicated that I didn't scrub hard enough
during the cleanups.  I've sent out an updated version.  Thank you for
informing me of this missed cleanup!

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-08-04 17:35 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-02 21:00 [PATCH] riscv: explicitly use symbol offsets for VDSO v2 Saleem Abdulrasool
2021-08-02 23:14 ` kernel test robot
2021-08-04  3:54 ` Palmer Dabbelt
2021-08-04 17:35   ` Saleem Abdulrasool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).