Skip to content
This repository has been archived by the owner on Nov 21, 2022. It is now read-only.

Commit

Permalink
riscv: compat: vdso: Add COMPAT_VDSO base code implementation
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Guo Ren <[email protected]>
Tested-by: Heiko Stuebner <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Palmer Dabbelt <[email protected]>
  • Loading branch information
guoren83 authored and palmer-dabbelt committed Apr 26, 2022
1 parent f4b395e commit 0715372
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 1 deletion.
5 changes: 5 additions & 0 deletions arch/riscv/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
9 changes: 9 additions & 0 deletions arch/riscv/include/asm/vdso.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
1 change: 1 addition & 0 deletions arch/riscv/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,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/
2 changes: 2 additions & 0 deletions arch/riscv/kernel/compat_vdso/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
compat_vdso.lds
78 changes: 78 additions & 0 deletions arch/riscv/kernel/compat_vdso/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# 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

COMPAT_CC := $(CC)
COMPAT_LD := $(LD)

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
8 changes: 8 additions & 0 deletions arch/riscv/kernel/compat_vdso/compat_vdso.S
Original file line number Diff line number Diff line change
@@ -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"
3 changes: 3 additions & 0 deletions arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include "../vdso/vdso.lds.S"
3 changes: 3 additions & 0 deletions arch/riscv/kernel/compat_vdso/flush_icache.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include "../vdso/flush_icache.S"
5 changes: 5 additions & 0 deletions arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
Original file line number Diff line number Diff line change
@@ -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'
3 changes: 3 additions & 0 deletions arch/riscv/kernel/compat_vdso/getcpu.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include "../vdso/getcpu.S"
3 changes: 3 additions & 0 deletions arch/riscv/kernel/compat_vdso/note.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include "../vdso/note.S"
3 changes: 3 additions & 0 deletions arch/riscv/kernel/compat_vdso/rt_sigreturn.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include "../vdso/rt_sigreturn.S"
6 changes: 5 additions & 1 deletion arch/riscv/kernel/vdso/vdso.S
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down

0 comments on commit 0715372

Please sign in to comment.