diff mbox series

[V6,16/20] riscv: compat: vdso: Add rv32 VDSO base code implementation

Message ID 20220224085410.399351-17-guoren@kernel.org
State New
Headers show
Series riscv: compat: Add COMPAT mode support for rv64 | expand

Commit Message

Guo Ren Feb. 24, 2022, 8:54 a.m. UTC
From: Guo Ren <guoren@linux.alibaba.com>

There is no vgettimeofday supported in rv32 that makes simple to
generate rv32 vdso code which only needs riscv64 compiler. Other
architectures need change compiler or -m (machine parameter) to
support vdso32 compiling. If rv32 support vgettimeofday (which
cause C compile) in future, we would add CROSS_COMPILE to support
that makes more requirement on compiler enviornment.

linux-rv64/arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg:
file format elf64-littleriscv

Disassembly of section .text:

0000000000000800 <__vdso_rt_sigreturn>:
 800:   08b00893                li      a7,139
 804:   00000073                ecall
 808:   0000                    unimp
        ...

000000000000080c <__vdso_getcpu>:
 80c:   0a800893                li      a7,168
 810:   00000073                ecall
 814:   8082                    ret
        ...

0000000000000818 <__vdso_flush_icache>:
 818:   10300893                li      a7,259
 81c:   00000073                ecall
 820:   8082                    ret

linux-rv32/arch/riscv/kernel/vdso/vdso.so.dbg:
file format elf32-littleriscv

Disassembly of section .text:

00000800 <__vdso_rt_sigreturn>:
 800:   08b00893                li      a7,139
 804:   00000073                ecall
 808:   0000                    unimp
        ...

0000080c <__vdso_getcpu>:
 80c:   0a800893                li      a7,168
 810:   00000073                ecall
 814:   8082                    ret
        ...

00000818 <__vdso_flush_icache>:
 818:   10300893                li      a7,259
 81c:   00000073                ecall
 820:   8082                    ret

Finally, reuse all *.S from vdso in compat_vdso that makes
implementation clear and readable.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
---
 arch/riscv/Makefile                           |  5 ++
 arch/riscv/include/asm/vdso.h                 |  9 +++
 arch/riscv/kernel/Makefile                    |  1 +
 arch/riscv/kernel/compat_vdso/.gitignore      |  2 +
 arch/riscv/kernel/compat_vdso/Makefile        | 68 +++++++++++++++++++
 arch/riscv/kernel/compat_vdso/compat_vdso.S   |  8 +++
 .../kernel/compat_vdso/compat_vdso.lds.S      |  3 +
 arch/riscv/kernel/compat_vdso/flush_icache.S  |  3 +
 .../compat_vdso/gen_compat_vdso_offsets.sh    |  5 ++
 arch/riscv/kernel/compat_vdso/getcpu.S        |  3 +
 arch/riscv/kernel/compat_vdso/note.S          |  3 +
 arch/riscv/kernel/compat_vdso/rt_sigreturn.S  |  3 +
 arch/riscv/kernel/vdso/vdso.S                 |  6 +-
 13 files changed, 118 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
 create mode 100644 arch/riscv/kernel/compat_vdso/Makefile
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
 create mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
 create mode 100755 arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
 create mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
 create mode 100644 arch/riscv/kernel/compat_vdso/note.S
 create mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S

Comments

Arnd Bergmann Feb. 24, 2022, 9:13 a.m. UTC | #1
On Thu, Feb 24, 2022 at 9:54 AM <guoren@kernel.org> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> There is no vgettimeofday supported in rv32 that makes simple to
> generate rv32 vdso code which only needs riscv64 compiler. Other
> architectures need change compiler or -m (machine parameter) to
> support vdso32 compiling. If rv32 support vgettimeofday (which
> cause C compile) in future, we would add CROSS_COMPILE to support
> that makes more requirement on compiler enviornment.

I think it's just a bug that rv32 doesn't have the vdso version of the
time syscalls. Fixing that is of course independent of the compat support,
but I think you need that anyway, and it would be better to start
out by building the compat vdso with the correct
architecture level.

At least this should be a lot easier than on arch/arm64 because you
can assume that an rv64 compiler is able to also build rv32 output.

        Arnd
Guo Ren Feb. 25, 2022, 3:42 p.m. UTC | #2
Hi Arnd & Palmer,

Here is the new modified compat_vdso/Makefile, please have a look,
first. Then I would update it to v7:
===========================================
# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for compat_vdso
#

# Symbols present in the compat_vdso
compat_vdso-syms  = rt_sigreturn
compat_vdso-syms += getcpu
compat_vdso-syms += flush_icache

ifdef CROSS_COMPILE_COMPAT
        COMPAT_CC := $(CROSS_COMPILE_COMPAT)gcc
        COMPAT_LD := $(CROSS_COMPILE_COMPAT)ld
else
        COMPAT_CC := $(CC)
        COMPAT_LD := $(LD)
endif

COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32
COMPAT_LD_FLAGS := -melf32lriscv

# Files to link into the compat_vdso
obj-compat_vdso = $(patsubst %, %.o, $(compat_vdso-syms)) note.o

# Build rules
targets := $(obj-compat_vdso) compat_vdso.so compat_vdso.so.dbg compat_vdso.lds
obj-compat_vdso := $(addprefix $(obj)/, $(obj-compat_vdso))

obj-y += compat_vdso.o
CPPFLAGS_compat_vdso.lds += -P -C -U$(ARCH)

# Disable profiling and instrumentation for VDSO code
GCOV_PROFILE := n
KCOV_INSTRUMENT := n
KASAN_SANITIZE := n
UBSAN_SANITIZE := n

# Force dependency
$(obj)/compat_vdso.o: $(obj)/compat_vdso.so

# link rule for the .so file, .lds has to be first
$(obj)/compat_vdso.so.dbg: $(obj)/compat_vdso.lds $(obj-compat_vdso) FORCE
        $(call if_changed,compat_vdsold)
LDFLAGS_compat_vdso.so.dbg = -shared -S -soname=linux-compat_vdso.so.1 \
        --build-id=sha1 --hash-style=both --eh-frame-hdr

$(obj-compat_vdso): %.o: %.S FORCE
        $(call if_changed_dep,compat_vdsoas)

# 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-compat_vdsosym := $(srctree)/$(src)/gen_compat_vdso_offsets.sh
quiet_cmd_compat_vdsosym = VDSOSYM $@
        cmd_compat_vdsosym = $(NM) $< | $(gen-compat_vdsosym) |
LC_ALL=C sort > $@

include/generated/compat_vdso-offsets.h: $(obj)/compat_vdso.so.dbg FORCE
        $(call if_changed,compat_vdsosym)

# actual build commands
# The DSO images are built using a special linker script
# Make sure only to export the intended __compat_vdso_xxx symbol offsets.
quiet_cmd_compat_vdsold = VDSOLD  $@
      cmd_compat_vdsold = $(COMPAT_LD) $(ld_flags) $(COMPAT_LD_FLAGS)
-T $(filter-out FORCE,$^) -o $@.tmp && \
                   $(OBJCOPY) $(patsubst %, -G __compat_vdso_%,
$(compat_vdso-syms)) $@.tmp $@ && \
                   rm $@.tmp

# actual build commands
quiet_cmd_compat_vdsoas = VDSOAS $@
      cmd_compat_vdsoas = $(COMPAT_CC) $(a_flags) $(COMPAT_CC_FLAGS) -c -o $@ $<

# install commands for the unstripped file
quiet_cmd_compat_vdso_install = INSTALL $@
      cmd_compat_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/compat_vdso/$@

compat_vdso.so: $(obj)/compat_vdso.so.dbg
        @mkdir -p $(MODLIB)/compat_vdso
        $(call cmd,compat_vdso_install)

compat_vdso_install: compat_vdso.so
===========================================

Here is the make V=1 output:

make -f /home/guoren/source/kernel/riscv-linux/scripts/Makefile.build
obj=arch/riscv/kernel/vdso include/generated/vdso-offsets.h
make -f /home/guoren/source/kernel/riscv-linux/scripts/Makefile.build
obj=arch/riscv/kernel/compat_vdso
include/generated/compat_vdso-offsets.h
  riscv64-unknown-linux-gnu-gcc -E
-Wp,-MMD,arch/riscv/kernel/compat_vdso/.compat_vdso.lds.d  -nostdinc
-I/home/guoren/source/kernel/riscv-linux/arch/riscv/include
-I./arch/riscv/include/generated
-I/home/guoren/source/kernel/riscv-linux/include -I./include
-I/home/guoren/source/kernel/riscv-linux/arch/riscv/include/uapi
-I./arch/riscv/include/generated/uapi
-I/home/guoren/source/kernel/riscv-linux/include/uapi -I./includ
e/generated/uapi -include
/home/guoren/source/kernel/riscv-linux/include/linux/compiler-version.h
-include /home/guoren/source/kernel/riscv-linux/include/linux/kconfig.h
-D__KERNEL__ -fmacro-prefix-map=/home/guoren/source/kernel/riscv-linux/=
   -P -C -Uriscv -I
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso
-I ./arch/riscv/kernel/compat_vdso -P -Uriscv -D__ASSEMBLY__
-DLINKER_SCRIPT -o arch/riscv/ke
rnel/compat_vdso/compat_vdso.lds
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
  riscv64-unknown-linux-gnu-gcc
-Wp,-MMD,arch/riscv/kernel/compat_vdso/.rt_sigreturn.o.d  -nostdinc
-I/home/guoren/source/kernel/riscv-linux/arch/riscv/include
-I./arch/riscv/include/generated
-I/home/guoren/source/kernel/riscv-linux/include -I./include
-I/home/guoren/source/kernel/riscv-linux/arch/riscv/include/uapi
-I./arch/riscv/include/generated/uapi
-I/home/guoren/source/kernel/riscv-linux/include/uapi -I./include/ge
nerated/uapi -include
/home/guoren/source/kernel/riscv-linux/include/linux/compiler-version.h
-include /home/guoren/source/kernel/riscv-linux/include/linux/kconfig.h
-D__KERNEL__ -fmacro-prefix-map=/home/guoren/source/kernel/riscv-linux/=
-D__ASSEMBLY__ -fno-PIE -mabi=lp64 -march=rv64imafdc -I
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso
-I ./arch/riscv/kernel/compat_vdso    -march=rv32g -mabi=ilp3
2 -c -o arch/riscv/kernel/compat_vdso/rt_sigreturn.o
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso/rt_sigreturn.S
  riscv64-unknown-linux-gnu-gcc
-Wp,-MMD,arch/riscv/kernel/compat_vdso/.getcpu.o.d  -nostdinc
-I/home/guoren/source/kernel/riscv-linux/arch/riscv/include
-I./arch/riscv/include/generated
-I/home/guoren/source/kernel/riscv-linux/include -I./include
-I/home/guoren/source/kernel/riscv-linux/arch/riscv/include/uapi
-I./arch/riscv/include/generated/uapi
-I/home/guoren/source/kernel/riscv-linux/include/uapi
-I./include/generate
d/uapi -include
/home/guoren/source/kernel/riscv-linux/include/linux/compiler-version.h
-include /home/guoren/source/kernel/riscv-linux/include/linux/kconfig.h
-D__KERNEL__ -fmacro-prefix-map=/home/guoren/source/kernel/riscv-linux/=
-D__ASSEMBLY__ -fno-PIE -mabi=lp64 -march=rv64imafdc -I
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso
-I ./arch/riscv/kernel/compat_vdso    -march=rv32g -mabi=ilp32 -c -
o arch/riscv/kernel/compat_vdso/getcpu.o
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso/getcpu.S
  riscv64-unknown-linux-gnu-gcc
-Wp,-MMD,arch/riscv/kernel/compat_vdso/.flush_icache.o.d  -nostdinc
-I/home/guoren/source/kernel/riscv-linux/arch/riscv/include
-I./arch/riscv/include/generated
-I/home/guoren/source/kernel/riscv-linux/include -I./include
-I/home/guoren/source/kernel/riscv-linux/arch/riscv/include/uapi
-I./arch/riscv/include/generated/uapi
-I/home/guoren/source/kernel/riscv-linux/include/uapi -I./include/ge
nerated/uapi -include
/home/guoren/source/kernel/riscv-linux/include/linux/compiler-version.h
-include /home/guoren/source/kernel/riscv-linux/include/linux/kconfig.h
-D__KERNEL__ -fmacro-prefix-map=/home/guoren/source/kernel/riscv-linux/=
-D__ASSEMBLY__ -fno-PIE -mabi=lp64 -march=rv64imafdc -I
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso
-I ./arch/riscv/kernel/compat_vdso    -march=rv32g -mabi=ilp3
2 -c -o arch/riscv/kernel/compat_vdso/flush_icache.o
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso/flush_icache.S
  riscv64-unknown-linux-gnu-gcc
-Wp,-MMD,arch/riscv/kernel/compat_vdso/.note.o.d  -nostdinc
-I/home/guoren/source/kernel/riscv-linux/arch/riscv/include
-I./arch/riscv/include/generated
-I/home/guoren/source/kernel/riscv-linux/include -I./include
-I/home/guoren/source/kernel/riscv-linux/arch/riscv/include/uapi
-I./arch/riscv/include/generated/uapi
-I/home/guoren/source/kernel/riscv-linux/include/uapi
-I./include/generated/
uapi -include /home/guoren/source/kernel/riscv-linux/include/linux/compiler-version.h
-include /home/guoren/source/kernel/riscv-linux/include/linux/kconfig.h
-D__KERNEL__ -fmacro-prefix-map=/home/guoren/source/kernel/riscv-linux/=
-D__ASSEMBLY__ -fno-PIE -mabi=lp64 -march=rv64imafdc -I
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso
-I ./arch/riscv/kernel/compat_vdso    -march=rv32g -mabi=ilp32 -c -o
arch/riscv/kernel/compat_vdso/note.o
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso/note.S
  riscv64-unknown-linux-gnu-ld  -melf64lriscv   -shared -S
-soname=linux-compat_vdso.so.1 --build-id=sha1 --hash-style=both
--eh-frame-hdr -melf32lriscv -T
arch/riscv/kernel/compat_vdso/compat_vdso.lds
arch/riscv/kernel/compat_vdso/rt_sigreturn.o
arch/riscv/kernel/compat_vdso/getcpu.o
arch/riscv/kernel/compat_vdso/flush_icache.o
arch/riscv/kernel/compat_vdso/note.o -o
arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg.tmp &
& riscv64-unknown-linux-gnu-objcopy  -G __compat_vdso_rt_sigreturn  -G
__compat_vdso_getcpu  -G __compat_vdso_flush_icache
arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg.tmp
arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg && rm
arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg.tmp
  riscv64-unknown-linux-gnu-nm
arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg |
/home/guoren/source/kernel/riscv-linux/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
| LC_ALL=C sort > include/generated/compat_vdso-offsets.h


On Thu, Feb 24, 2022 at 6:13 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Thu, Feb 24, 2022 at 9:54 AM <guoren@kernel.org> wrote:
> >
> > From: Guo Ren <guoren@linux.alibaba.com>
> >
> > There is no vgettimeofday supported in rv32 that makes simple to
> > generate rv32 vdso code which only needs riscv64 compiler. Other
> > architectures need change compiler or -m (machine parameter) to
> > support vdso32 compiling. If rv32 support vgettimeofday (which
> > cause C compile) in future, we would add CROSS_COMPILE to support
> > that makes more requirement on compiler enviornment.
>
> I think it's just a bug that rv32 doesn't have the vdso version of the
> time syscalls. Fixing that is of course independent of the compat support,
> but I think you need that anyway, and it would be better to start
> out by building the compat vdso with the correct
> architecture level.
>
> At least this should be a lot easier than on arch/arm64 because you
> can assume that an rv64 compiler is able to also build rv32 output.
>
>         Arnd
Arnd Bergmann Feb. 25, 2022, 3:49 p.m. UTC | #3
On Fri, Feb 25, 2022 at 4:42 PM Guo Ren <guoren@kernel.org> wrote:
>
> Hi Arnd & Palmer,
>
> Here is the new modified compat_vdso/Makefile, please have a look,
> first. Then I would update it to v7:
> ===========================================
> # SPDX-License-Identifier: GPL-2.0-only
> #
> # Makefile for compat_vdso
> #
>
> # Symbols present in the compat_vdso
> compat_vdso-syms  = rt_sigreturn
> compat_vdso-syms += getcpu
> compat_vdso-syms += flush_icache
>
> ifdef CROSS_COMPILE_COMPAT
>         COMPAT_CC := $(CROSS_COMPILE_COMPAT)gcc
>         COMPAT_LD := $(CROSS_COMPILE_COMPAT)ld
> else
>         COMPAT_CC := $(CC)
>         COMPAT_LD := $(LD)
> endif
>
> COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32
> COMPAT_LD_FLAGS := -melf32lriscv

Have you come across a case in which a separate cross toolchain
is required? If not, I would leave this out and just set the flags for the
normal toolchain.

I also think it would be a nicer split to build the two vdso variants
as vdso64/vdso32 rather than vdso/compat_vdso. That way,
the build procedure can be kept as close as possible to the
native 32-bit build.

        Arnd
Guo Ren Feb. 25, 2022, 4:07 p.m. UTC | #4
On Fri, Feb 25, 2022 at 11:50 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Fri, Feb 25, 2022 at 4:42 PM Guo Ren <guoren@kernel.org> wrote:
> >
> > Hi Arnd & Palmer,
> >
> > Here is the new modified compat_vdso/Makefile, please have a look,
> > first. Then I would update it to v7:
> > ===========================================
> > # SPDX-License-Identifier: GPL-2.0-only
> > #
> > # Makefile for compat_vdso
> > #
> >
> > # Symbols present in the compat_vdso
> > compat_vdso-syms  = rt_sigreturn
> > compat_vdso-syms += getcpu
> > compat_vdso-syms += flush_icache
> >
> > ifdef CROSS_COMPILE_COMPAT
> >         COMPAT_CC := $(CROSS_COMPILE_COMPAT)gcc
> >         COMPAT_LD := $(CROSS_COMPILE_COMPAT)ld
> > else
> >         COMPAT_CC := $(CC)
> >         COMPAT_LD := $(LD)
> > endif
> >
> > COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32
> > COMPAT_LD_FLAGS := -melf32lriscv
>
> Have you come across a case in which a separate cross toolchain
> is required? If not, I would leave this out and just set the flags for the
> normal toolchain.
Okay

>
> I also think it would be a nicer split to build the two vdso variants
> as vdso64/vdso32 rather than vdso/compat_vdso. That way,
> the build procedure can be kept as close as possible to the
> native 32-bit build.
Yes, current native 32-bit vdso & 64-bit vdso use the same
vdso/Makfile. So, I think it could be another patch for this cleanup.

>
>         Arnd
diff mbox series

Patch

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index c6ca1b9cbf71..6a494029b8bd 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -112,12 +112,17 @@  libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 PHONY += vdso_install
 vdso_install:
 	$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
+	$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
+		$(build)=arch/riscv/kernel/compat_vdso $@)
 
 ifeq ($(KBUILD_EXTMOD),)
 ifeq ($(CONFIG_MMU),y)
 prepare: vdso_prepare
 vdso_prepare: prepare0
 	$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h
+	$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
+		$(build)=arch/riscv/kernel/compat_vdso include/generated/compat_vdso-offsets.h)
+
 endif
 endif
 
diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
index bc6f75f3a199..af981426fe0f 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -21,6 +21,15 @@ 
 
 #define VDSO_SYMBOL(base, name)							\
 	(void __user *)((unsigned long)(base) + __vdso_##name##_offset)
+
+#ifdef CONFIG_COMPAT
+#include <generated/compat_vdso-offsets.h>
+
+#define COMPAT_VDSO_SYMBOL(base, name)						\
+	(void __user *)((unsigned long)(base) + compat__vdso_##name##_offset)
+
+#endif /* CONFIG_COMPAT */
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* CONFIG_MMU */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 954dc7043ad2..88e79f481c21 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -67,3 +67,4 @@  obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
 
 obj-$(CONFIG_EFI)		+= efi.o
 obj-$(CONFIG_COMPAT)		+= compat_syscall_table.o
+obj-$(CONFIG_COMPAT)		+= compat_vdso/
diff --git a/arch/riscv/kernel/compat_vdso/.gitignore b/arch/riscv/kernel/compat_vdso/.gitignore
new file mode 100644
index 000000000000..19d83d846c1e
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/.gitignore
@@ -0,0 +1,2 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+compat_vdso.lds
diff --git a/arch/riscv/kernel/compat_vdso/Makefile b/arch/riscv/kernel/compat_vdso/Makefile
new file mode 100644
index 000000000000..7bbbbf94307f
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/Makefile
@@ -0,0 +1,68 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
+# the inclusion of generic Makefile.
+ARCH_REL_TYPE_ABS := R_RISCV_32|R_RISCV_64|R_RISCV_JUMP_SLOT
+include $(srctree)/lib/vdso/Makefile
+# Symbols present in the compat_vdso
+compat_vdso-syms  = rt_sigreturn
+compat_vdso-syms += getcpu
+compat_vdso-syms += flush_icache
+
+# Files to link into the compat_vdso
+obj-compat_vdso = $(patsubst %, %.o, $(compat_vdso-syms)) note.o
+
+ccflags-y := -fno-stack-protector
+
+# Build rules
+targets := $(obj-compat_vdso) compat_vdso.so compat_vdso.so.dbg compat_vdso.lds
+obj-compat_vdso := $(addprefix $(obj)/, $(obj-compat_vdso))
+
+obj-y += compat_vdso.o
+CPPFLAGS_compat_vdso.lds += -P -C -U$(ARCH)
+
+# Disable profiling and instrumentation for VDSO code
+GCOV_PROFILE := n
+KCOV_INSTRUMENT := n
+KASAN_SANITIZE := n
+UBSAN_SANITIZE := n
+
+# Force dependency
+$(obj)/compat_vdso.o: $(obj)/compat_vdso.so
+
+# link rule for the .so file, .lds has to be first
+$(obj)/compat_vdso.so.dbg: $(obj)/compat_vdso.lds $(obj-compat_vdso) FORCE
+	$(call if_changed,compat_vdsold)
+LDFLAGS_compat_vdso.so.dbg = -shared -S -soname=linux-compat_vdso.so.1 \
+	--build-id=sha1 --hash-style=both --eh-frame-hdr
+
+# 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-compat_vdsosym := $(srctree)/$(src)/gen_compat_vdso_offsets.sh
+quiet_cmd_compat_vdsosym = VDSOSYM $@
+	cmd_compat_vdsosym = $(NM) $< | $(gen-compat_vdsosym) | LC_ALL=C sort > $@
+
+include/generated/compat_vdso-offsets.h: $(obj)/compat_vdso.so.dbg FORCE
+	$(call if_changed,compat_vdsosym)
+
+# actual build commands
+# The DSO images are built using a special linker script
+# Make sure only to export the intended __compat_vdso_xxx symbol offsets.
+quiet_cmd_compat_vdsold = VDSOLD  $@
+      cmd_compat_vdsold = $(LD) $(ld_flags) -T $(filter-out FORCE,$^) -o $@.tmp && \
+                   $(OBJCOPY) $(patsubst %, -G __compat_vdso_%, $(compat_vdso-syms)) $@.tmp $@ && \
+                   rm $@.tmp
+
+# install commands for the unstripped file
+quiet_cmd_compat_vdso_install = INSTALL $@
+      cmd_compat_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/compat_vdso/$@
+
+compat_vdso.so: $(obj)/compat_vdso.so.dbg
+	@mkdir -p $(MODLIB)/compat_vdso
+	$(call cmd,compat_vdso_install)
+
+compat_vdso_install: compat_vdso.so
diff --git a/arch/riscv/kernel/compat_vdso/compat_vdso.S b/arch/riscv/kernel/compat_vdso/compat_vdso.S
new file mode 100644
index 000000000000..fea4a8b0c45d
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/compat_vdso.S
@@ -0,0 +1,8 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#define	vdso_start	compat_vdso_start
+#define	vdso_end	compat_vdso_end
+
+#define	__VDSO_PATH	"arch/riscv/kernel/compat_vdso/compat_vdso.so"
+
+#include <../vdso/vdso.S>
diff --git a/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S b/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
new file mode 100644
index 000000000000..02a9ec5dc7f6
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
@@ -0,0 +1,3 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/vdso.lds.S>
diff --git a/arch/riscv/kernel/compat_vdso/flush_icache.S b/arch/riscv/kernel/compat_vdso/flush_icache.S
new file mode 100644
index 000000000000..88e21a84a974
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/flush_icache.S
@@ -0,0 +1,3 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/flush_icache.S>
diff --git a/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh b/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
new file mode 100755
index 000000000000..8ac070c783b3
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/gen_compat_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 compat\2_offset\t0x\1/p'
diff --git a/arch/riscv/kernel/compat_vdso/getcpu.S b/arch/riscv/kernel/compat_vdso/getcpu.S
new file mode 100644
index 000000000000..946449a15a94
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/getcpu.S
@@ -0,0 +1,3 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/getcpu.S>
diff --git a/arch/riscv/kernel/compat_vdso/note.S b/arch/riscv/kernel/compat_vdso/note.S
new file mode 100644
index 000000000000..67c50898b8e5
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/note.S
@@ -0,0 +1,3 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/note.S>
diff --git a/arch/riscv/kernel/compat_vdso/rt_sigreturn.S b/arch/riscv/kernel/compat_vdso/rt_sigreturn.S
new file mode 100644
index 000000000000..f4c98f18c053
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/rt_sigreturn.S
@@ -0,0 +1,3 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/rt_sigreturn.S>
diff --git a/arch/riscv/kernel/vdso/vdso.S b/arch/riscv/kernel/vdso/vdso.S
index df222245be05..83f1c899e8d8 100644
--- a/arch/riscv/kernel/vdso/vdso.S
+++ b/arch/riscv/kernel/vdso/vdso.S
@@ -7,12 +7,16 @@ 
 #include <linux/linkage.h>
 #include <asm/page.h>
 
+#ifndef __VDSO_PATH
+#define __VDSO_PATH "arch/riscv/kernel/vdso/vdso.so"
+#endif
+
 	__PAGE_ALIGNED_DATA
 
 	.globl vdso_start, vdso_end
 	.balign PAGE_SIZE
 vdso_start:
-	.incbin "arch/riscv/kernel/vdso/vdso.so"
+	.incbin __VDSO_PATH
 	.balign PAGE_SIZE
 vdso_end: