Merge tag 'x86_entry_for_7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 entry code updates from Dave Hansen:
 "This is entirely composed of a set of long overdue VDSO cleanups. They
  makes the VDSO build much more logical and zap quite a bit of old
  cruft.

  It also results in a coveted net-code-removal diffstat"

* tag 'x86_entry_for_7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/entry/vdso: Add vdso2c to .gitignore
  x86/entry/vdso32: Omit '.cfi_offset eflags' for LLVM < 16
  MAINTAINERS: Adjust vdso file entry in INTEL SGX
  x86/entry/vdso/selftest: Update location of vgetrandom-chacha.S
  x86/entry/vdso: Fix filtering of vdso compiler flags
  x86/entry/vdso: Update the object paths for "make vdso_install"
  x86/entry/vdso32: When using int $0x80, use it directly
  x86/cpufeature: Replace X86_FEATURE_SYSENTER32 with X86_FEATURE_SYSFAST32
  x86/vdso: Abstract out vdso system call internals
  x86/entry/vdso: Include GNU_PROPERTY and GNU_STACK PHDRs
  x86/entry/vdso32: Remove open-coded DWARF in sigreturn.S
  x86/entry/vdso32: Remove SYSCALL_ENTER_KERNEL macro in sigreturn.S
  x86/entry/vdso32: Don't rely on int80_landing_pad for adjusting ip
  x86/entry/vdso: Refactor the vdso build
  x86/entry/vdso: Move vdso2c to arch/x86/tools
  x86/entry/vdso: Rename vdso_image_* to vdso*_image
This commit is contained in:
Linus Torvalds
2026-02-10 19:34:26 -08:00
50 changed files with 458 additions and 493 deletions
+1 -1
View File
@@ -13032,7 +13032,7 @@ S: Supported
Q: https://patchwork.kernel.org/project/intel-sgx/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/sgx
F: Documentation/arch/x86/sgx.rst
F: arch/x86/entry/vdso/vsgx.S
F: arch/x86/entry/vdso/vdso64/vsgx.S
F: arch/x86/include/asm/sgx.h
F: arch/x86/include/uapi/asm/sgx.h
F: arch/x86/kernel/cpu/sgx/*
+8
View File
@@ -56,6 +56,10 @@ config X86_REQUIRED_FEATURE_MOVBE
def_bool y
depends on MATOM
config X86_REQUIRED_FEATURE_SYSFAST32
def_bool y
depends on X86_64 && !X86_FRED
config X86_REQUIRED_FEATURE_CPUID
def_bool y
depends on X86_64
@@ -120,6 +124,10 @@ config X86_DISABLED_FEATURE_CENTAUR_MCR
def_bool y
depends on X86_64
config X86_DISABLED_FEATURE_SYSCALL32
def_bool y
depends on !X86_64
config X86_DISABLED_FEATURE_PCID
def_bool y
depends on !X86_64
+4 -4
View File
@@ -252,7 +252,7 @@ endif
archscripts: scripts_basic
$(Q)$(MAKE) $(build)=arch/x86/tools relocs
$(Q)$(MAKE) $(build)=arch/x86/tools relocs vdso2c
###
# Syscall table generation
@@ -318,9 +318,9 @@ PHONY += install
install:
$(call cmd,install)
vdso-install-$(CONFIG_X86_64) += arch/x86/entry/vdso/vdso64.so.dbg
vdso-install-$(CONFIG_X86_X32_ABI) += arch/x86/entry/vdso/vdsox32.so.dbg
vdso-install-$(CONFIG_COMPAT_32) += arch/x86/entry/vdso/vdso32.so.dbg
vdso-install-$(CONFIG_X86_64) += arch/x86/entry/vdso/vdso64/vdso64.so.dbg
vdso-install-$(CONFIG_X86_X32_ABI) += arch/x86/entry/vdso/vdso64/vdsox32.so.dbg
vdso-install-$(CONFIG_COMPAT_32) += arch/x86/entry/vdso/vdso32/vdso32.so.dbg
archprepare: checkbin
checkbin:
+1 -1
View File
@@ -319,7 +319,7 @@ __visible noinstr bool do_fast_syscall_32(struct pt_regs *regs)
* convention. Adjust regs so it looks like we entered using int80.
*/
unsigned long landing_pad = (unsigned long)current->mm->context.vdso +
vdso_image_32.sym_int80_landing_pad;
vdso32_image.sym_int80_landing_pad;
/*
* SYSENTER loses EIP, and even SYSCALL32 needs us to skip forward
+4 -7
View File
@@ -1,8 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
vdso.lds
vdsox32.lds
vdso32-syscall-syms.lds
vdso32-sysenter-syms.lds
vdso32-int80-syms.lds
vdso-image-*.c
vdso2c
*.lds
*.so
*.so.dbg
vdso*-image.c
+6 -156
View File
@@ -3,160 +3,10 @@
# Building vDSO images for x86.
#
# Include the generic Makefile to check the built vDSO:
include $(srctree)/lib/vdso/Makefile.include
# Regular kernel objects
obj-y := vma.o extable.o
obj-$(CONFIG_COMPAT_32) += vdso32-setup.o
# Files to link into the vDSO:
vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vgetrandom.o vgetrandom-chacha.o
vobjs32-y := vdso32/note.o vdso32/system_call.o vdso32/sigreturn.o
vobjs32-y += vdso32/vclock_gettime.o vdso32/vgetcpu.o
vobjs-$(CONFIG_X86_SGX) += vsgx.o
# Files to link into the kernel:
obj-y += vma.o extable.o
# vDSO images to build:
obj-$(CONFIG_X86_64) += vdso-image-64.o
obj-$(CONFIG_X86_X32_ABI) += vdso-image-x32.o
obj-$(CONFIG_COMPAT_32) += vdso-image-32.o vdso32-setup.o
vobjs := $(addprefix $(obj)/, $(vobjs-y))
vobjs32 := $(addprefix $(obj)/, $(vobjs32-y))
$(obj)/vdso.o: $(obj)/vdso.so
targets += vdso.lds $(vobjs-y)
targets += vdso32/vdso32.lds $(vobjs32-y)
targets += $(foreach x, 64 x32 32, vdso-image-$(x).c vdso$(x).so vdso$(x).so.dbg)
CPPFLAGS_vdso.lds += -P -C
VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -soname linux-vdso.so.1 \
-z max-page-size=4096
$(obj)/vdso64.so.dbg: $(obj)/vdso.lds $(vobjs) FORCE
$(call if_changed,vdso_and_check)
HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi -I$(srctree)/arch/$(SUBARCH)/include/uapi
hostprogs += vdso2c
quiet_cmd_vdso2c = VDSO2C $@
cmd_vdso2c = $(obj)/vdso2c $< $(<:%.dbg=%) $@
$(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso%.so $(obj)/vdso2c FORCE
$(call if_changed,vdso2c)
#
# Don't omit frame pointers for ease of userspace debugging, but do
# optimize sibling calls.
#
CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
$(filter -g%,$(KBUILD_CFLAGS)) -fno-stack-protector \
-fno-omit-frame-pointer -foptimize-sibling-calls \
-DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
ifdef CONFIG_MITIGATION_RETPOLINE
ifneq ($(RETPOLINE_VDSO_CFLAGS),)
CFL += $(RETPOLINE_VDSO_CFLAGS)
endif
endif
$(vobjs): KBUILD_CFLAGS := $(filter-out $(PADDING_CFLAGS) $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) $(RANDSTRUCT_CFLAGS) $(KSTACK_ERASE_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
$(vobjs): KBUILD_AFLAGS += -DBUILD_VDSO
#
# vDSO code runs in userspace and -pg doesn't help with profiling anyway.
#
CFLAGS_REMOVE_vclock_gettime.o = -pg
CFLAGS_REMOVE_vdso32/vclock_gettime.o = -pg
CFLAGS_REMOVE_vgetcpu.o = -pg
CFLAGS_REMOVE_vdso32/vgetcpu.o = -pg
CFLAGS_REMOVE_vsgx.o = -pg
CFLAGS_REMOVE_vgetrandom.o = -pg
#
# X32 processes use x32 vDSO to access 64bit kernel data.
#
# Build x32 vDSO image:
# 1. Compile x32 vDSO as 64bit.
# 2. Convert object files to x32.
# 3. Build x32 VDSO image with x32 objects, which contains 64bit codes
# so that it can reach 64bit address space with 64bit pointers.
#
CPPFLAGS_vdsox32.lds = $(CPPFLAGS_vdso.lds)
VDSO_LDFLAGS_vdsox32.lds = -m elf32_x86_64 -soname linux-vdso.so.1 \
-z max-page-size=4096
# x32-rebranded versions
vobjx32s-y := $(vobjs-y:.o=-x32.o)
# same thing, but in the output directory
vobjx32s := $(addprefix $(obj)/, $(vobjx32s-y))
# Convert 64bit object file to x32 for x32 vDSO.
quiet_cmd_x32 = X32 $@
cmd_x32 = $(OBJCOPY) -O elf32-x86-64 $< $@
$(obj)/%-x32.o: $(obj)/%.o FORCE
$(call if_changed,x32)
targets += vdsox32.lds $(vobjx32s-y)
$(obj)/%.so: OBJCOPYFLAGS := -S --remove-section __ex_table
$(obj)/%.so: $(obj)/%.so.dbg FORCE
$(call if_changed,objcopy)
$(obj)/vdsox32.so.dbg: $(obj)/vdsox32.lds $(vobjx32s) FORCE
$(call if_changed,vdso_and_check)
CPPFLAGS_vdso32/vdso32.lds = $(CPPFLAGS_vdso.lds)
VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -soname linux-gate.so.1
KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS)) -DBUILD_VDSO
$(obj)/vdso32.so.dbg: KBUILD_AFLAGS = $(KBUILD_AFLAGS_32)
$(obj)/vdso32.so.dbg: asflags-$(CONFIG_X86_64) += -m32
KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(RANDSTRUCT_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(KSTACK_ERASE_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_CFI),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(PADDING_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
KBUILD_CFLAGS_32 += -fno-stack-protector
KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
KBUILD_CFLAGS_32 += -fno-omit-frame-pointer
KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING
KBUILD_CFLAGS_32 += -DBUILD_VDSO
ifdef CONFIG_MITIGATION_RETPOLINE
ifneq ($(RETPOLINE_VDSO_CFLAGS),)
KBUILD_CFLAGS_32 += $(RETPOLINE_VDSO_CFLAGS)
endif
endif
$(obj)/vdso32.so.dbg: KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
$(obj)/vdso32.so.dbg: $(obj)/vdso32/vdso32.lds $(vobjs32) FORCE
$(call if_changed,vdso_and_check)
#
# The DSO images are built using a special linker script.
#
quiet_cmd_vdso = VDSO $@
cmd_vdso = $(LD) -o $@ \
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
-T $(filter %.lds,$^) $(filter %.o,$^)
VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 --no-undefined \
$(call ld-option, --eh-frame-hdr) -Bsymbolic -z noexecstack
quiet_cmd_vdso_and_check = VDSO $@
cmd_vdso_and_check = $(cmd_vdso); $(cmd_vdso_check)
# vDSO directories
obj-$(CONFIG_X86_64) += vdso64/
obj-$(CONFIG_COMPAT_32) += vdso32/
@@ -0,0 +1,89 @@
# SPDX-License-Identifier: GPL-2.0
#
# Building vDSO images for x86.
#
# Include the generic Makefile to check the built vDSO:
include $(srctree)/lib/vdso/Makefile.include
obj-y += $(foreach x,$(vdsos-y),vdso$(x)-image.o)
targets += $(foreach x,$(vdsos-y),vdso$(x)-image.c vdso$(x).so vdso$(x).so.dbg vdso$(x).lds)
targets += $(vobjs-y)
# vobjs-y with $(obj)/ prepended
vobjs := $(addprefix $(obj)/,$(vobjs-y))
# Options for vdso*.lds
CPPFLAGS_VDSO_LDS := -P -C -I$(src)/..
$(obj)/%.lds : KBUILD_CPPFLAGS += $(CPPFLAGS_VDSO_LDS)
#
# Options from KBUILD_[AC]FLAGS that should *NOT* be kept
#
flags-remove-y += \
-D__KERNEL__ -mcmodel=kernel -mregparm=3 \
-fno-pic -fno-PIC -fno-pie -fno-PIE \
-mfentry -pg \
$(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(KSTACK_ERASE_CFLAGS) \
$(RETPOLINE_CFLAGS) $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
$(PADDING_CFLAGS)
#
# Don't omit frame pointers for ease of userspace debugging, but do
# optimize sibling calls.
#
flags-y += -D__DISABLE_EXPORTS
flags-y += -DDISABLE_BRANCH_PROFILING
flags-y += -DBUILD_VDSO
flags-y += -I$(src)/.. -I$(srctree)
flags-y += -O2 -fpic
flags-y += -fno-stack-protector
flags-y += -fno-omit-frame-pointer
flags-y += -foptimize-sibling-calls
flags-y += -fasynchronous-unwind-tables
# Reset cf protections enabled by compiler default
flags-y += $(call cc-option, -fcf-protection=none)
flags-$(X86_USER_SHADOW_STACK) += $(call cc-option, -fcf-protection=return)
# When user space IBT is supported, enable this.
# flags-$(CONFIG_USER_IBT) += $(call cc-option, -fcf-protection=branch)
flags-$(CONFIG_MITIGATION_RETPOLINE) += $(RETPOLINE_VDSO_CFLAGS)
# These need to be conditional on $(vobjs) as they do not apply to
# the output vdso*-image.o files which are standard kernel objects.
$(vobjs) : KBUILD_AFLAGS := \
$(filter-out $(flags-remove-y),$(KBUILD_AFLAGS)) $(flags-y)
$(vobjs) : KBUILD_CFLAGS := \
$(filter-out $(flags-remove-y),$(KBUILD_CFLAGS)) $(flags-y)
#
# The VDSO images are built using a special linker script.
#
VDSO_LDFLAGS := -shared --hash-style=both --build-id=sha1 --no-undefined \
$(call ld-option, --eh-frame-hdr) -Bsymbolic -z noexecstack
quiet_cmd_vdso = VDSO $@
cmd_vdso = $(LD) -o $@ \
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$*) \
-T $(filter %.lds,$^) $(filter %.o,$^)
quiet_cmd_vdso_and_check = VDSO $@
cmd_vdso_and_check = $(cmd_vdso); $(cmd_vdso_check)
$(obj)/vdso%.so.dbg: $(obj)/vdso%.lds FORCE
$(call if_changed,vdso_and_check)
$(obj)/%.so: OBJCOPYFLAGS := -S --remove-section __ex_table
$(obj)/%.so: $(obj)/%.so.dbg FORCE
$(call if_changed,objcopy)
VDSO2C = $(objtree)/arch/x86/tools/vdso2c
quiet_cmd_vdso2c = VDSO2C $@
cmd_vdso2c = $(VDSO2C) $< $(<:%.dbg=%) $@
$(obj)/%-image.c: $(obj)/%.so.dbg $(obj)/%.so $(VDSO2C) FORCE
$(call if_changed,vdso2c)
$(obj)/%-image.o: $(obj)/%-image.c
@@ -1,13 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
* Here we can supply some information useful to userland.
*/
#include <linux/build-salt.h>
#include <linux/uts.h>
#include <linux/version.h>
#include <linux/elfnote.h>
/* Ideally this would use UTS_NAME, but using a quoted string here
doesn't work. Remember to change this when changing the
kernel's name. */
ELFNOTE_START(Linux, 0, "a")
.long LINUX_VERSION_CODE
ELFNOTE_END
@@ -47,18 +47,18 @@ SECTIONS
*(.gnu.linkonce.b.*)
} :text
/*
* Discard .note.gnu.property sections which are unused and have
* different alignment requirement from vDSO note sections.
*/
/DISCARD/ : {
.note.gnu.property : {
*(.note.gnu.property)
}
.note : { *(.note.*) } :text :note
.eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
.eh_frame : { KEEP (*(.eh_frame)) } :text
} :text :note :gnu_property
.note : {
*(.note*)
} :text :note
.eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
.eh_frame : {
KEEP (*(.eh_frame))
*(.eh_frame.*)
} :text
/*
* Text is well-separated from actual data: there's plenty of
@@ -87,15 +87,23 @@ SECTIONS
* Very old versions of ld do not recognize this name token; use the constant.
*/
#define PT_GNU_EH_FRAME 0x6474e550
#define PT_GNU_STACK 0x6474e551
#define PT_GNU_PROPERTY 0x6474e553
/*
* We must supply the ELF program headers explicitly to get just one
* PT_LOAD segment, and set the flags explicitly to make segments read-only.
*/
*/
#define PF_R FLAGS(4)
#define PF_RW FLAGS(6)
#define PF_RX FLAGS(5)
PHDRS
{
text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
note PT_NOTE FLAGS(4); /* PF_R */
eh_frame_hdr PT_GNU_EH_FRAME;
text PT_LOAD PF_RX FILEHDR PHDRS;
dynamic PT_DYNAMIC PF_R;
note PT_NOTE PF_R;
eh_frame_hdr PT_GNU_EH_FRAME PF_R;
gnu_stack PT_GNU_STACK PF_RW;
gnu_property PT_GNU_PROPERTY PF_R;
}
+24
View File
@@ -0,0 +1,24 @@
# SPDX-License-Identifier: GPL-2.0
#
# 32-bit vDSO images for x86.
#
# The vDSOs built in this directory
vdsos-y := 32
# Files to link into the vDSO:
vobjs-y := note.o vclock_gettime.o vgetcpu.o
vobjs-y += system_call.o sigreturn.o
# Compilation flags
flags-y := -DBUILD_VDSO32 -m32 -mregparm=0
flags-$(CONFIG_X86_64) += -include $(src)/fake_32bit_build.h
flags-remove-y := -m64
# The location of this include matters!
include $(src)/../common/Makefile.include
# Linker options for the vdso
VDSO_LDFLAGS_32 := -m elf_i386 -soname linux-gate.so.1
$(obj)/vdso32.so.dbg: $(vobjs)
+1 -18
View File
@@ -1,18 +1 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
* Here we can supply some information useful to userland.
*/
#include <linux/build-salt.h>
#include <linux/version.h>
#include <linux/elfnote.h>
/* Ideally this would use UTS_NAME, but using a quoted string here
doesn't work. Remember to change this when changing the
kernel's name. */
ELFNOTE_START(Linux, 0, "a")
.long LINUX_VERSION_CODE
ELFNOTE_END
BUILD_SALT
#include "common/note.S"
+42 -118
View File
@@ -1,140 +1,64 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
#include <asm/unistd_32.h>
#include <asm/dwarf2.h>
#include <asm/asm-offsets.h>
#ifndef SYSCALL_ENTER_KERNEL
#define SYSCALL_ENTER_KERNEL int $0x80
.macro STARTPROC_SIGNAL_FRAME sc
CFI_STARTPROC simple
CFI_SIGNAL_FRAME
/* -4 as pretcode has already been popped */
CFI_DEF_CFA esp, \sc - 4
CFI_OFFSET eip, IA32_SIGCONTEXT_ip
CFI_OFFSET eax, IA32_SIGCONTEXT_ax
CFI_OFFSET ebx, IA32_SIGCONTEXT_bx
CFI_OFFSET ecx, IA32_SIGCONTEXT_cx
CFI_OFFSET edx, IA32_SIGCONTEXT_dx
CFI_OFFSET esp, IA32_SIGCONTEXT_sp
CFI_OFFSET ebp, IA32_SIGCONTEXT_bp
CFI_OFFSET esi, IA32_SIGCONTEXT_si
CFI_OFFSET edi, IA32_SIGCONTEXT_di
CFI_OFFSET es, IA32_SIGCONTEXT_es
CFI_OFFSET cs, IA32_SIGCONTEXT_cs
CFI_OFFSET ss, IA32_SIGCONTEXT_ss
CFI_OFFSET ds, IA32_SIGCONTEXT_ds
/*
* .cfi_offset eflags requires LLVM 16 or newer:
*
* https://github.com/llvm/llvm-project/commit/67bd3c58c0c7389e39c5a2f4d3b1a30459ccf5b7
*
* Check for 16.0.1 to ensure the support is present, as 16.0.0 may be a
* prerelease version.
*/
#if defined(CONFIG_AS_IS_GNU) || (defined(CONFIG_AS_IS_LLVM) && CONFIG_AS_VERSION >= 160001)
CFI_OFFSET eflags, IA32_SIGCONTEXT_flags
#endif
.endm
.text
.globl __kernel_sigreturn
.type __kernel_sigreturn,@function
nop /* this guy is needed for .LSTARTFDEDLSI1 below (watch for HACK) */
ALIGN
__kernel_sigreturn:
.LSTART_sigreturn:
popl %eax /* XXX does this mean it needs unwind info? */
STARTPROC_SIGNAL_FRAME IA32_SIGFRAME_sigcontext
popl %eax
CFI_ADJUST_CFA_OFFSET -4
movl $__NR_sigreturn, %eax
SYSCALL_ENTER_KERNEL
.LEND_sigreturn:
int $0x80
SYM_INNER_LABEL(vdso32_sigreturn_landing_pad, SYM_L_GLOBAL)
nop
.size __kernel_sigreturn,.-.LSTART_sigreturn
ud2a
CFI_ENDPROC
.size __kernel_sigreturn,.-__kernel_sigreturn
.globl __kernel_rt_sigreturn
.type __kernel_rt_sigreturn,@function
ALIGN
__kernel_rt_sigreturn:
.LSTART_rt_sigreturn:
STARTPROC_SIGNAL_FRAME IA32_RT_SIGFRAME_sigcontext
movl $__NR_rt_sigreturn, %eax
SYSCALL_ENTER_KERNEL
.LEND_rt_sigreturn:
int $0x80
SYM_INNER_LABEL(vdso32_rt_sigreturn_landing_pad, SYM_L_GLOBAL)
nop
.size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
.previous
.section .eh_frame,"a",@progbits
.LSTARTFRAMEDLSI1:
.long .LENDCIEDLSI1-.LSTARTCIEDLSI1
.LSTARTCIEDLSI1:
.long 0 /* CIE ID */
.byte 1 /* Version number */
.string "zRS" /* NUL-terminated augmentation string */
.uleb128 1 /* Code alignment factor */
.sleb128 -4 /* Data alignment factor */
.byte 8 /* Return address register column */
.uleb128 1 /* Augmentation value length */
.byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
.byte 0 /* DW_CFA_nop */
.align 4
.LENDCIEDLSI1:
.long .LENDFDEDLSI1-.LSTARTFDEDLSI1 /* Length FDE */
.LSTARTFDEDLSI1:
.long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */
/* HACK: The dwarf2 unwind routines will subtract 1 from the
return address to get an address in the middle of the
presumed call instruction. Since we didn't get here via
a call, we need to include the nop before the real start
to make up for it. */
.long .LSTART_sigreturn-1-. /* PC-relative start address */
.long .LEND_sigreturn-.LSTART_sigreturn+1
.uleb128 0 /* Augmentation */
/* What follows are the instructions for the table generation.
We record the locations of each register saved. This is
complicated by the fact that the "CFA" is always assumed to
be the value of the stack pointer in the caller. This means
that we must define the CFA of this body of code to be the
saved value of the stack pointer in the sigcontext. Which
also means that there is no fixed relation to the other
saved registers, which means that we must use DW_CFA_expression
to compute their addresses. It also means that when we
adjust the stack with the popl, we have to do it all over again. */
#define do_cfa_expr(offset) \
.byte 0x0f; /* DW_CFA_def_cfa_expression */ \
.uleb128 1f-0f; /* length */ \
0: .byte 0x74; /* DW_OP_breg4 */ \
.sleb128 offset; /* offset */ \
.byte 0x06; /* DW_OP_deref */ \
1:
#define do_expr(regno, offset) \
.byte 0x10; /* DW_CFA_expression */ \
.uleb128 regno; /* regno */ \
.uleb128 1f-0f; /* length */ \
0: .byte 0x74; /* DW_OP_breg4 */ \
.sleb128 offset; /* offset */ \
1:
do_cfa_expr(IA32_SIGCONTEXT_sp+4)
do_expr(0, IA32_SIGCONTEXT_ax+4)
do_expr(1, IA32_SIGCONTEXT_cx+4)
do_expr(2, IA32_SIGCONTEXT_dx+4)
do_expr(3, IA32_SIGCONTEXT_bx+4)
do_expr(5, IA32_SIGCONTEXT_bp+4)
do_expr(6, IA32_SIGCONTEXT_si+4)
do_expr(7, IA32_SIGCONTEXT_di+4)
do_expr(8, IA32_SIGCONTEXT_ip+4)
.byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */
do_cfa_expr(IA32_SIGCONTEXT_sp)
do_expr(0, IA32_SIGCONTEXT_ax)
do_expr(1, IA32_SIGCONTEXT_cx)
do_expr(2, IA32_SIGCONTEXT_dx)
do_expr(3, IA32_SIGCONTEXT_bx)
do_expr(5, IA32_SIGCONTEXT_bp)
do_expr(6, IA32_SIGCONTEXT_si)
do_expr(7, IA32_SIGCONTEXT_di)
do_expr(8, IA32_SIGCONTEXT_ip)
.align 4
.LENDFDEDLSI1:
.long .LENDFDEDLSI2-.LSTARTFDEDLSI2 /* Length FDE */
.LSTARTFDEDLSI2:
.long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1 /* CIE pointer */
/* HACK: See above wrt unwind library assumptions. */
.long .LSTART_rt_sigreturn-1-. /* PC-relative start address */
.long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1
.uleb128 0 /* Augmentation */
/* What follows are the instructions for the table generation.
We record the locations of each register saved. This is
slightly less complicated than the above, since we don't
modify the stack pointer in the process. */
do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_sp)
do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ax)
do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_cx)
do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_dx)
do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_bx)
do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_bp)
do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_si)
do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_di)
do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ip)
.align 4
.LENDFDEDLSI2:
ud2a
CFI_ENDPROC
.size __kernel_rt_sigreturn,.-__kernel_rt_sigreturn
.previous
+14 -8
View File
@@ -14,6 +14,18 @@
ALIGN
__kernel_vsyscall:
CFI_STARTPROC
/*
* If using int $0x80, there is no reason to muck about with the
* stack here. Unfortunately just overwriting the push instructions
* would mess up the CFI annotations, but it is only a 3-byte
* NOP in that case. This could be avoided by patching the
* vdso symbol table (not the code) and entry point, but that
* would a fair bit of tooling work or by simply compiling
* two different vDSO images, but that doesn't seem worth it.
*/
ALTERNATIVE "int $0x80; ret", "", X86_FEATURE_SYSFAST32
/*
* Reshuffle regs so that all of any of the entry instructions
* will preserve enough state.
@@ -52,15 +64,9 @@ __kernel_vsyscall:
#define SYSENTER_SEQUENCE "movl %esp, %ebp; sysenter"
#define SYSCALL_SEQUENCE "movl %ecx, %ebp; syscall"
#ifdef CONFIG_X86_64
/* If SYSENTER (Intel) or SYSCALL32 (AMD) is available, use it. */
ALTERNATIVE_2 "", SYSENTER_SEQUENCE, X86_FEATURE_SYSENTER32, \
SYSCALL_SEQUENCE, X86_FEATURE_SYSCALL32
#else
ALTERNATIVE "", SYSENTER_SEQUENCE, X86_FEATURE_SEP
#endif
ALTERNATIVE SYSENTER_SEQUENCE, SYSCALL_SEQUENCE, X86_FEATURE_SYSCALL32
/* Enter using int $0x80 */
/* Re-enter using int $0x80 */
int $0x80
SYM_INNER_LABEL(int80_landing_pad, SYM_L_GLOBAL)
+1 -4
View File
@@ -1,4 +1 @@
// SPDX-License-Identifier: GPL-2.0
#define BUILD_VDSO32
#include "fake_32bit_build.h"
#include "../vclock_gettime.c"
#include "common/vclock_gettime.c"
+1 -1
View File
@@ -11,7 +11,7 @@
#define BUILD_VDSO32
#include "../vdso-layout.lds.S"
#include "common/vdso-layout.lds.S"
/* The ELF entry point can be used to set the AT_SYSINFO value. */
ENTRY(__kernel_vsyscall);
+1 -3
View File
@@ -1,3 +1 @@
// SPDX-License-Identifier: GPL-2.0
#include "fake_32bit_build.h"
#include "../vgetcpu.c"
#include "common/vgetcpu.c"
+46
View File
@@ -0,0 +1,46 @@
# SPDX-License-Identifier: GPL-2.0
#
# 64-bit vDSO images for x86.
#
# The vDSOs built in this directory
vdsos-y := 64
vdsos-$(CONFIG_X86_X32_ABI) += x32
# Files to link into the vDSO:
vobjs-y := note.o vclock_gettime.o vgetcpu.o
vobjs-y += vgetrandom.o vgetrandom-chacha.o
vobjs-$(CONFIG_X86_SGX) += vsgx.o
# Compilation flags
flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
# The location of this include matters!
include $(src)/../common/Makefile.include
#
# X32 processes use x32 vDSO to access 64bit kernel data.
#
# Build x32 vDSO image:
# 1. Compile x32 vDSO as 64bit.
# 2. Convert object files to x32.
# 3. Build x32 VDSO image with x32 objects, which contains 64bit codes
# so that it can reach 64bit address space with 64bit pointers.
#
# Convert 64bit object file to x32 for x32 vDSO.
quiet_cmd_x32 = X32 $@
cmd_x32 = $(OBJCOPY) -O elf32-x86-64 $< $@
$(obj)/%-x32.o: $(obj)/%.o FORCE
$(call if_changed,x32)
vobjsx32 = $(patsubst %.o,%-x32.o,$(vobjs))
targets += $(patsubst %.o,%-x32.o,$(vobjs-y))
# Linker options for the vdso
VDSO_LDFLAGS_64 := -m elf_x86_64 -soname linux-vdso.so.1 -z max-page-size=4096
VDSO_LDFLAGS_x32 := $(subst elf_x86_64,elf32_x86_64,$(VDSO_LDFLAGS_64))
$(obj)/vdso64.so.dbg: $(vobjs)
$(obj)/vdsox32.so.dbg: $(vobjsx32)
+1
View File
@@ -0,0 +1 @@
#include "common/note.S"

Some files were not shown because too many files have changed in this diff Show More