linux/arch/riscv/kernel/vdso/Makefile
Deepak Gupta ccad8c1336 arch/riscv: add dual vdso creation logic and select vdso based on hw
Shadow stack instructions are taken from the Zimop ISA extension,
which is mandated on RVA23. Any userspace with shadow stack
instructions in it will fault on hardware that doesn't have support
for Zimop.  Thus, a shadow stack-enabled userspace can't be run on
hardware that doesn't support Zimop.

It's not known how Linux userspace providers will respond to this kind
of binary fragmentation.  In order to keep kernel portable across
different hardware, 'arch/riscv/kernel/vdso_cfi' is created which has
Makefile logic to compile 'arch/riscv/kernel/vdso' sources with CFI
flags, and 'arch/riscv/kernel/vdso.c' is modified to select the
appropriate vdso depending on whether the underlying CPU implements
the Zimop extension. Since the offset of vdso symbols will change due
to having two different vdso binaries, there is added logic to include
a new generated vdso offset header and dynamically select the offset
(like for rt_sigreturn).

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
Acked-by: Charles Mirabile <cmirabil@redhat.com>
Tested-by: Andreas Korb <andreas.korb@aisec.fraunhofer.de> # QEMU, custom CVA6
Tested-by: Valentin Haudiquet <valentin.haudiquet@canonical.com>
Link: https://patch.msgid.link/20251112-v5_user_cfi_series-v23-24-b55691eacf4f@rivosinc.com
[pjw@kernel.org: cleaned up patch description]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2026-01-29 02:38:40 -07:00

106 lines
3.1 KiB
Makefile

# SPDX-License-Identifier: GPL-2.0-only
# Copied from arch/tile/kernel/vdso/Makefile
# Include the generic Makefile to check the built vdso.
include $(srctree)/lib/vdso/Makefile.include
# Symbols present in the vdso
vdso-syms = rt_sigreturn
ifdef CONFIG_64BIT
vdso-syms += vgettimeofday
endif
vdso-syms += getcpu
vdso-syms += flush_icache
vdso-syms += hwprobe
vdso-syms += sys_hwprobe
ifdef CONFIG_VDSO_GETRANDOM
vdso-syms += getrandom
endif
ifdef VDSO_CFI_BUILD
CFI_MARCH = _zicfilp_zicfiss
CFI_FULL = -fcf-protection=full
CFI_SUFFIX = -cfi
OFFSET_SUFFIX = _cfi
ccflags-y += -DVDSO_CFI=1
asflags-y += -DVDSO_CFI=1
endif
# Files to link into the vdso
obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o
ifdef CONFIG_VDSO_GETRANDOM
obj-vdso += vgetrandom-chacha.o
endif
ccflags-y := -fno-stack-protector
ccflags-y += -DDISABLE_BRANCH_PROFILING
ccflags-y += -fno-builtin
ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
ccflags-y += $(CFI_FULL)
asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
asflags-y += $(CFI_FULL)
ifneq ($(c-gettimeofday-y),)
CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
endif
ifneq ($(c-getrandom-y),)
CFLAGS_getrandom.o += -fPIC -include $(c-getrandom-y)
endif
CFLAGS_hwprobe.o += -fPIC
# Build rules
vdso_offsets := vdso$(if $(VDSO_CFI_BUILD),$(CFI_SUFFIX),)-offsets.h
vdso_o := vdso$(if $(VDSO_CFI_BUILD),$(CFI_SUFFIX),).o
vdso_so := vdso$(if $(VDSO_CFI_BUILD),$(CFI_SUFFIX),).so
vdso_so_dbg := vdso$(if $(VDSO_CFI_BUILD),$(CFI_SUFFIX),).so.dbg
vdso_lds := vdso.lds
targets := $(obj-vdso) $(vdso_so) $(vdso_so_dbg) $(vdso_lds)
obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
obj-y += vdso$(if $(VDSO_CFI_BUILD),$(CFI_SUFFIX),).o
CPPFLAGS_$(vdso_lds) += -P -C -U$(ARCH)
ifneq ($(filter vgettimeofday, $(vdso-syms)),)
CPPFLAGS_$(vdso_lds) += -DHAS_VGETTIMEOFDAY
endif
# Disable -pg to prevent insert call site
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS)
CFLAGS_REMOVE_getrandom.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS)
CFLAGS_REMOVE_hwprobe.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS)
# Force dependency
$(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_and_check)
LDFLAGS_$(vdso_so_dbg) = -shared -soname=linux-vdso.so.1 \
--build-id=sha1 --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-vdsosym := $(src)/gen_vdso_offsets.sh
quiet_cmd_vdsosym = VDSOSYM $@
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) $(OFFSET_SUFFIX) | LC_ALL=C sort > $@
include/generated/$(vdso_offsets): $(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.
quiet_cmd_vdsold_and_check = VDSOLD $@
cmd_vdsold_and_check = $(LD) $(CFI_FULL) $(ld_flags) -T $(filter-out FORCE,$^) -o $@.tmp && \
$(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \
rm $@.tmp && \
$(cmd_vdso_check)