* VDSO rework and cleanups
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEV76QKkVc4xCGURexaDWVMHDJkrAFAmmKGBcACgkQaDWVMHDJ krDRRg/6AjkL6Hcx+3jC7X2VWOY6UK8giMdyDOOBtA82/TLmch4BL3Zcf/eJky6j OAVd6E22eWNNIRGJqhhSWY/0IZwnWj+VP57S1pFDeS8NVU1kTau2li5xT2tBQOm5 b+zztHZXsgYrAFTUOyVKbNncUlD67YIXl9t2KzS4obRa2HLOrkJotZmni86bGlyF oBHL14cgCpXdHVH1RawCNxXa3LJSlk39+kgoM4aeJdxlb0WCB2n23ek+QIQ75TPY mBzmF3Yxt7nri/2Lhf0cRV5Z9JQuk+6kIjbxEmFJ9nyg34CDzYt8nJiT8AlctOe0 Os3+hstgCKcvXKDK5N0UUnG/GvVlZp515fClaNeYIYraZk86WWEUA8tBGEiwghuX SUL6Xm2OpRUClfk5nW44B01/4NIUKm78Ch6Q3QkMGRfDfWXwXQyQkjX8jiBs7GAQ xJvN8oqj4QSiMSC9OWZnZwDxMqrnyfbEl69Iibf6ojQhf4rl6ADwzOb6U7V0XGXa y/VJik7l7EG+UK3t3ACzWLfJ/CwvwL5D/B+O8HEpVn6vXDOFJOg/jtXovrf0LmjL ynWttGLkXBm6rU4H02jdaHIRwu7OvTj/lNfpiIupvHFt0uKIvwng3pIk8KookQHi E05nwLtrvvLTNQ04hXHOwxGMLL6DkVaZyOWUN3pJGC92/HEXRRU= =Izzg -----END PGP SIGNATURE----- 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*_imagemaster
commit
6f7e6393d1
|
|
@ -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/*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 +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"
|
||||
|
|
|
|||
|
|
@ -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,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 +1 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define BUILD_VDSO32
|
||||
#include "fake_32bit_build.h"
|
||||
#include "../vclock_gettime.c"
|
||||
#include "common/vclock_gettime.c"
|
||||
|
|
|
|||
|
|
@ -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 +1 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "fake_32bit_build.h"
|
||||
#include "../vgetcpu.c"
|
||||
#include "common/vgetcpu.c"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -0,0 +1 @@
|
|||
#include "common/note.S"
|
||||
|
|
@ -0,0 +1 @@
|
|||
#include "common/vclock_gettime.c"
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#define BUILD_VDSO64
|
||||
|
||||
#include "vdso-layout.lds.S"
|
||||
#include "common/vdso-layout.lds.S"
|
||||
|
||||
/*
|
||||
* This controls what userland symbols we export from the vDSO.
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#define BUILD_VDSOX32
|
||||
|
||||
#include "vdso-layout.lds.S"
|
||||
#include "common/vdso-layout.lds.S"
|
||||
|
||||
/*
|
||||
* This controls what userland symbols we export from the vDSO.
|
||||
|
|
@ -0,0 +1 @@
|
|||
#include "common/vgetcpu.c"
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "../../../../lib/vdso/getrandom.c"
|
||||
#include "lib/vdso/getrandom.c"
|
||||
|
||||
ssize_t __vdso_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state, size_t opaque_len)
|
||||
{
|
||||
|
|
@ -65,16 +65,12 @@ static vm_fault_t vdso_fault(const struct vm_special_mapping *sm,
|
|||
static void vdso_fix_landing(const struct vdso_image *image,
|
||||
struct vm_area_struct *new_vma)
|
||||
{
|
||||
if (in_ia32_syscall() && image == &vdso_image_32) {
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
unsigned long vdso_land = image->sym_int80_landing_pad;
|
||||
unsigned long old_land_addr = vdso_land +
|
||||
(unsigned long)current->mm->context.vdso;
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
unsigned long ipoffset = regs->ip -
|
||||
(unsigned long)current->mm->context.vdso;
|
||||
|
||||
/* Fixing userspace landing - look at do_fast_syscall_32 */
|
||||
if (regs->ip == old_land_addr)
|
||||
regs->ip = new_vma->vm_start + vdso_land;
|
||||
}
|
||||
if (ipoffset < image->size)
|
||||
regs->ip = new_vma->vm_start + ipoffset;
|
||||
}
|
||||
|
||||
static int vdso_mremap(const struct vm_special_mapping *sm,
|
||||
|
|
@ -230,7 +226,7 @@ static int load_vdso32(void)
|
|||
if (vdso32_enabled != 1) /* Other values all mean "disabled" */
|
||||
return 0;
|
||||
|
||||
return map_vdso(&vdso_image_32, 0);
|
||||
return map_vdso(&vdso32_image, 0);
|
||||
}
|
||||
|
||||
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||
|
|
@ -239,7 +235,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
|||
if (!vdso64_enabled)
|
||||
return 0;
|
||||
|
||||
return map_vdso(&vdso_image_64, 0);
|
||||
return map_vdso(&vdso64_image, 0);
|
||||
}
|
||||
|
||||
return load_vdso32();
|
||||
|
|
@ -252,7 +248,7 @@ int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
|
|||
if (IS_ENABLED(CONFIG_X86_X32_ABI) && x32) {
|
||||
if (!vdso64_enabled)
|
||||
return 0;
|
||||
return map_vdso(&vdso_image_x32, 0);
|
||||
return map_vdso(&vdsox32_image, 0);
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_IA32_EMULATION))
|
||||
|
|
@ -267,7 +263,7 @@ bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
|
|||
const struct vdso_image *image = current->mm->context.vdso_image;
|
||||
unsigned long vdso = (unsigned long) current->mm->context.vdso;
|
||||
|
||||
if (in_ia32_syscall() && image == &vdso_image_32) {
|
||||
if (in_ia32_syscall() && image == &vdso32_image) {
|
||||
if (regs->ip == vdso + image->sym_vdso32_sigreturn_landing_pad ||
|
||||
regs->ip == vdso + image->sym_vdso32_rt_sigreturn_landing_pad)
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@
|
|||
#define X86_FEATURE_PEBS ( 3*32+12) /* "pebs" Precise-Event Based Sampling */
|
||||
#define X86_FEATURE_BTS ( 3*32+13) /* "bts" Branch Trace Store */
|
||||
#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* syscall in IA32 userspace */
|
||||
#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* sysenter in IA32 userspace */
|
||||
#define X86_FEATURE_SYSFAST32 ( 3*32+15) /* sysenter/syscall in IA32 userspace */
|
||||
#define X86_FEATURE_REP_GOOD ( 3*32+16) /* "rep_good" REP microcode works well */
|
||||
#define X86_FEATURE_AMD_LBR_V2 ( 3*32+17) /* "amd_lbr_v2" AMD Last Branch Record Extension Version 2 */
|
||||
#define X86_FEATURE_CLEAR_CPU_BUF ( 3*32+18) /* Clear CPU buffers using VERW */
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#define CFI_RESTORE_STATE .cfi_restore_state
|
||||
#define CFI_UNDEFINED .cfi_undefined
|
||||
#define CFI_ESCAPE .cfi_escape
|
||||
#define CFI_SIGNAL_FRAME .cfi_signal_frame
|
||||
|
||||
#ifndef BUILD_VDSO
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ else if (IS_ENABLED(CONFIG_IA32_EMULATION)) \
|
|||
|
||||
#define VDSO_ENTRY \
|
||||
((unsigned long)current->mm->context.vdso + \
|
||||
vdso_image_32.sym___kernel_vsyscall)
|
||||
vdso32_image.sym___kernel_vsyscall)
|
||||
|
||||
struct linux_binprm;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ struct vdso_image {
|
|||
long sym_vdso32_rt_sigreturn_landing_pad;
|
||||
};
|
||||
|
||||
extern const struct vdso_image vdso_image_64;
|
||||
extern const struct vdso_image vdso_image_x32;
|
||||
extern const struct vdso_image vdso_image_32;
|
||||
extern const struct vdso_image vdso64_image;
|
||||
extern const struct vdso_image vdsox32_image;
|
||||
extern const struct vdso_image vdso32_image;
|
||||
|
||||
extern int __init init_vdso_image(const struct vdso_image *image);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <asm/msr.h>
|
||||
#include <asm/pvclock.h>
|
||||
#include <clocksource/hyperv_timer.h>
|
||||
#include <asm/vdso/sys_call.h>
|
||||
|
||||
#define VDSO_HAS_TIME 1
|
||||
|
||||
|
|
@ -53,130 +54,37 @@ extern struct ms_hyperv_tsc_page hvclock_page
|
|||
__attribute__((visibility("hidden")));
|
||||
#endif
|
||||
|
||||
#ifndef BUILD_VDSO32
|
||||
|
||||
static __always_inline
|
||||
long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
|
||||
{
|
||||
long ret;
|
||||
|
||||
asm ("syscall" : "=a" (ret), "=m" (*_ts) :
|
||||
"0" (__NR_clock_gettime), "D" (_clkid), "S" (_ts) :
|
||||
"rcx", "r11");
|
||||
|
||||
return ret;
|
||||
return VDSO_SYSCALL2(clock_gettime,64,_clkid,_ts);
|
||||
}
|
||||
|
||||
static __always_inline
|
||||
long gettimeofday_fallback(struct __kernel_old_timeval *_tv,
|
||||
struct timezone *_tz)
|
||||
{
|
||||
long ret;
|
||||
|
||||
asm("syscall" : "=a" (ret) :
|
||||
"0" (__NR_gettimeofday), "D" (_tv), "S" (_tz) : "memory");
|
||||
|
||||
return ret;
|
||||
return VDSO_SYSCALL2(gettimeofday,,_tv,_tz);
|
||||
}
|
||||
|
||||
static __always_inline
|
||||
long clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
|
||||
{
|
||||
long ret;
|
||||
|
||||
asm ("syscall" : "=a" (ret), "=m" (*_ts) :
|
||||
"0" (__NR_clock_getres), "D" (_clkid), "S" (_ts) :
|
||||
"rcx", "r11");
|
||||
|
||||
return ret;
|
||||
return VDSO_SYSCALL2(clock_getres,_time64,_clkid,_ts);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static __always_inline
|
||||
long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
|
||||
{
|
||||
long ret;
|
||||
|
||||
asm (
|
||||
"mov %%ebx, %%edx \n"
|
||||
"mov %[clock], %%ebx \n"
|
||||
"call __kernel_vsyscall \n"
|
||||
"mov %%edx, %%ebx \n"
|
||||
: "=a" (ret), "=m" (*_ts)
|
||||
: "0" (__NR_clock_gettime64), [clock] "g" (_clkid), "c" (_ts)
|
||||
: "edx");
|
||||
|
||||
return ret;
|
||||
}
|
||||
#ifndef CONFIG_X86_64
|
||||
|
||||
static __always_inline
|
||||
long clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
|
||||
{
|
||||
long ret;
|
||||
|
||||
asm (
|
||||
"mov %%ebx, %%edx \n"
|
||||
"mov %[clock], %%ebx \n"
|
||||
"call __kernel_vsyscall \n"
|
||||
"mov %%edx, %%ebx \n"
|
||||
: "=a" (ret), "=m" (*_ts)
|
||||
: "0" (__NR_clock_gettime), [clock] "g" (_clkid), "c" (_ts)
|
||||
: "edx");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __always_inline
|
||||
long gettimeofday_fallback(struct __kernel_old_timeval *_tv,
|
||||
struct timezone *_tz)
|
||||
{
|
||||
long ret;
|
||||
|
||||
asm(
|
||||
"mov %%ebx, %%edx \n"
|
||||
"mov %2, %%ebx \n"
|
||||
"call __kernel_vsyscall \n"
|
||||
"mov %%edx, %%ebx \n"
|
||||
: "=a" (ret)
|
||||
: "0" (__NR_gettimeofday), "g" (_tv), "c" (_tz)
|
||||
: "memory", "edx");
|
||||
|
||||
return ret;
|
||||
return VDSO_SYSCALL2(clock_gettime,,_clkid,_ts);
|
||||
}
|
||||
|
||||
static __always_inline long
|
||||
clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
|
||||
clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
|
||||
{
|
||||
long ret;
|
||||
|
||||
asm (
|
||||
"mov %%ebx, %%edx \n"
|
||||
"mov %[clock], %%ebx \n"
|
||||
"call __kernel_vsyscall \n"
|
||||
"mov %%edx, %%ebx \n"
|
||||
: "=a" (ret), "=m" (*_ts)
|
||||
: "0" (__NR_clock_getres_time64), [clock] "g" (_clkid), "c" (_ts)
|
||||
: "edx");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __always_inline
|
||||
long clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
|
||||
{
|
||||
long ret;
|
||||
|
||||
asm (
|
||||
"mov %%ebx, %%edx \n"
|
||||
"mov %[clock], %%ebx \n"
|
||||
"call __kernel_vsyscall \n"
|
||||
"mov %%edx, %%ebx \n"
|
||||
: "=a" (ret), "=m" (*_ts)
|
||||
: "0" (__NR_clock_getres), [clock] "g" (_clkid), "c" (_ts)
|
||||
: "edx");
|
||||
|
||||
return ret;
|
||||
return VDSO_SYSCALL2(clock_getres,,_clkid,_ts);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Macros for issuing an inline system call from the vDSO.
|
||||
*/
|
||||
|
||||
#ifndef X86_ASM_VDSO_SYS_CALL_H
|
||||
#define X86_ASM_VDSO_SYS_CALL_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/cpufeatures.h>
|
||||
#include <asm/alternative.h>
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
# define __sys_instr "syscall"
|
||||
# define __sys_clobber "rcx", "r11", "memory"
|
||||
# define __sys_nr(x,y) __NR_ ## x
|
||||
# define __sys_reg1 "rdi"
|
||||
# define __sys_reg2 "rsi"
|
||||
# define __sys_reg3 "rdx"
|
||||
# define __sys_reg4 "r10"
|
||||
# define __sys_reg5 "r8"
|
||||
#else
|
||||
# define __sys_instr ALTERNATIVE("ds;ds;ds;int $0x80", \
|
||||
"call __kernel_vsyscall", \
|
||||
X86_FEATURE_SYSFAST32)
|
||||
# define __sys_clobber "memory"
|
||||
# define __sys_nr(x,y) __NR_ ## x ## y
|
||||
# define __sys_reg1 "ebx"
|
||||
# define __sys_reg2 "ecx"
|
||||
# define __sys_reg3 "edx"
|
||||
# define __sys_reg4 "esi"
|
||||
# define __sys_reg5 "edi"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Example usage:
|
||||
*
|
||||
* result = VDSO_SYSCALL3(foo,64,x,y,z);
|
||||
*
|
||||
* ... calls foo(x,y,z) on 64 bits, and foo64(x,y,z) on 32 bits.
|
||||
*
|
||||
* VDSO_SYSCALL6() is currently missing, because it would require
|
||||
* special handling for %ebp on 32 bits when the vdso is compiled with
|
||||
* frame pointers enabled (the default on 32 bits.) Add it as a special
|
||||
* case when and if it becomes necessary.
|
||||
*/
|
||||
#define _VDSO_SYSCALL(name,suf32,...) \
|
||||
({ \
|
||||
long _sys_num_ret = __sys_nr(name,suf32); \
|
||||
asm_inline volatile( \
|
||||
__sys_instr \
|
||||
: "+a" (_sys_num_ret) \
|
||||
: __VA_ARGS__ \
|
||||
: __sys_clobber); \
|
||||
_sys_num_ret; \
|
||||
})
|
||||
|
||||
#define VDSO_SYSCALL0(name,suf32) \
|
||||
_VDSO_SYSCALL(name,suf32)
|
||||
#define VDSO_SYSCALL1(name,suf32,a1) \
|
||||
({ \
|
||||
register long _sys_arg1 asm(__sys_reg1) = (long)(a1); \
|
||||
_VDSO_SYSCALL(name,suf32, \
|
||||
"r" (_sys_arg1)); \
|
||||
})
|
||||
#define VDSO_SYSCALL2(name,suf32,a1,a2) \
|
||||
({ \
|
||||
register long _sys_arg1 asm(__sys_reg1) = (long)(a1); \
|
||||
register long _sys_arg2 asm(__sys_reg2) = (long)(a2); \
|
||||
_VDSO_SYSCALL(name,suf32, \
|
||||
"r" (_sys_arg1), "r" (_sys_arg2)); \
|
||||
})
|
||||
#define VDSO_SYSCALL3(name,suf32,a1,a2,a3) \
|
||||
({ \
|
||||
register long _sys_arg1 asm(__sys_reg1) = (long)(a1); \
|
||||
register long _sys_arg2 asm(__sys_reg2) = (long)(a2); \
|
||||
register long _sys_arg3 asm(__sys_reg3) = (long)(a3); \
|
||||
_VDSO_SYSCALL(name,suf32, \
|
||||
"r" (_sys_arg1), "r" (_sys_arg2), \
|
||||
"r" (_sys_arg3)); \
|
||||
})
|
||||
#define VDSO_SYSCALL4(name,suf32,a1,a2,a3,a4) \
|
||||
({ \
|
||||
register long _sys_arg1 asm(__sys_reg1) = (long)(a1); \
|
||||
register long _sys_arg2 asm(__sys_reg2) = (long)(a2); \
|
||||
register long _sys_arg3 asm(__sys_reg3) = (long)(a3); \
|
||||
register long _sys_arg4 asm(__sys_reg4) = (long)(a4); \
|
||||
_VDSO_SYSCALL(name,suf32, \
|
||||
"r" (_sys_arg1), "r" (_sys_arg2), \
|
||||
"r" (_sys_arg3), "r" (_sys_arg4)); \
|
||||
})
|
||||
#define VDSO_SYSCALL5(name,suf32,a1,a2,a3,a4,a5) \
|
||||
({ \
|
||||
register long _sys_arg1 asm(__sys_reg1) = (long)(a1); \
|
||||
register long _sys_arg2 asm(__sys_reg2) = (long)(a2); \
|
||||
register long _sys_arg3 asm(__sys_reg3) = (long)(a3); \
|
||||
register long _sys_arg4 asm(__sys_reg4) = (long)(a4); \
|
||||
register long _sys_arg5 asm(__sys_reg5) = (long)(a5); \
|
||||
_VDSO_SYSCALL(name,suf32, \
|
||||
"r" (_sys_arg1), "r" (_sys_arg2), \
|
||||
"r" (_sys_arg3), "r" (_sys_arg4), \
|
||||
"r" (_sys_arg5)); \
|
||||
})
|
||||
|
||||
#endif /* X86_VDSO_SYS_CALL_H */
|
||||
|
|
@ -63,8 +63,14 @@ static void __used common(void)
|
|||
OFFSET(IA32_SIGCONTEXT_bp, sigcontext_32, bp);
|
||||
OFFSET(IA32_SIGCONTEXT_sp, sigcontext_32, sp);
|
||||
OFFSET(IA32_SIGCONTEXT_ip, sigcontext_32, ip);
|
||||
OFFSET(IA32_SIGCONTEXT_es, sigcontext_32, es);
|
||||
OFFSET(IA32_SIGCONTEXT_cs, sigcontext_32, cs);
|
||||
OFFSET(IA32_SIGCONTEXT_ss, sigcontext_32, ss);
|
||||
OFFSET(IA32_SIGCONTEXT_ds, sigcontext_32, ds);
|
||||
OFFSET(IA32_SIGCONTEXT_flags, sigcontext_32, flags);
|
||||
|
||||
BLANK();
|
||||
OFFSET(IA32_SIGFRAME_sigcontext, sigframe_ia32, sc);
|
||||
OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe_ia32, uc.uc_mcontext);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -102,9 +102,6 @@ static void early_init_centaur(struct cpuinfo_x86 *c)
|
|||
(c->x86 >= 7))
|
||||
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
set_cpu_cap(c, X86_FEATURE_SYSENTER32);
|
||||
#endif
|
||||
if (c->x86_power & (1 << 8)) {
|
||||
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
|
||||
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
|
||||
|
|
|
|||
|
|
@ -1068,6 +1068,9 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
|
|||
init_scattered_cpuid_features(c);
|
||||
init_speculation_control(c);
|
||||
|
||||
if (IS_ENABLED(CONFIG_X86_64) || cpu_has(c, X86_FEATURE_SEP))
|
||||
set_cpu_cap(c, X86_FEATURE_SYSFAST32);
|
||||
|
||||
/*
|
||||
* Clear/Set all flags overridden by options, after probe.
|
||||
* This needs to happen each time we re-probe, which may happen
|
||||
|
|
@ -1813,6 +1816,11 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
|
|||
* that it can't be enabled in 32-bit mode.
|
||||
*/
|
||||
setup_clear_cpu_cap(X86_FEATURE_PCID);
|
||||
|
||||
/*
|
||||
* Never use SYSCALL on a 32-bit kernel
|
||||
*/
|
||||
setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -236,9 +236,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
|
|||
clear_cpu_cap(c, X86_FEATURE_PSE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
set_cpu_cap(c, X86_FEATURE_SYSENTER32);
|
||||
#else
|
||||
#ifndef CONFIG_X86_64
|
||||
/* Netburst reports 64 bytes clflush size, but does IO in 128 bytes */
|
||||
if (c->x86 == 15 && c->x86_cache_alignment == 64)
|
||||
c->x86_cache_alignment = 128;
|
||||
|
|
|
|||
|
|
@ -59,9 +59,7 @@ static void early_init_zhaoxin(struct cpuinfo_x86 *c)
|
|||
{
|
||||
if (c->x86 >= 0x6)
|
||||
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
|
||||
#ifdef CONFIG_X86_64
|
||||
set_cpu_cap(c, X86_FEATURE_SYSENTER32);
|
||||
#endif
|
||||
|
||||
if (c->x86_power & (1 << 8)) {
|
||||
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
|
||||
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ void cpu_init_fred_exceptions(void)
|
|||
idt_invalidate();
|
||||
|
||||
/* Use int $0x80 for 32-bit system calls in FRED mode */
|
||||
setup_clear_cpu_cap(X86_FEATURE_SYSENTER32);
|
||||
setup_clear_cpu_cap(X86_FEATURE_SYSFAST32);
|
||||
setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -941,14 +941,14 @@ long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2)
|
|||
#ifdef CONFIG_CHECKPOINT_RESTORE
|
||||
# ifdef CONFIG_X86_X32_ABI
|
||||
case ARCH_MAP_VDSO_X32:
|
||||
return prctl_map_vdso(&vdso_image_x32, arg2);
|
||||
return prctl_map_vdso(&vdsox32_image, arg2);
|
||||
# endif
|
||||
# ifdef CONFIG_IA32_EMULATION
|
||||
case ARCH_MAP_VDSO_32:
|
||||
return prctl_map_vdso(&vdso_image_32, arg2);
|
||||
return prctl_map_vdso(&vdso32_image, arg2);
|
||||
# endif
|
||||
case ARCH_MAP_VDSO_64:
|
||||
return prctl_map_vdso(&vdso_image_64, arg2);
|
||||
return prctl_map_vdso(&vdso64_image, arg2);
|
||||
#endif
|
||||
#ifdef CONFIG_ADDRESS_MASKING
|
||||
case ARCH_GET_UNTAG_MASK:
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs)
|
|||
/* Return stub is in 32bit vsyscall page */
|
||||
if (current->mm->context.vdso)
|
||||
restorer = current->mm->context.vdso +
|
||||
vdso_image_32.sym___kernel_sigreturn;
|
||||
vdso32_image.sym___kernel_sigreturn;
|
||||
else
|
||||
restorer = &frame->retcode;
|
||||
}
|
||||
|
|
@ -368,7 +368,7 @@ int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
|
|||
restorer = ksig->ka.sa.sa_restorer;
|
||||
else
|
||||
restorer = current->mm->context.vdso +
|
||||
vdso_image_32.sym___kernel_rt_sigreturn;
|
||||
vdso32_image.sym___kernel_rt_sigreturn;
|
||||
unsafe_put_user(ptr_to_compat(restorer), &frame->pretcode, Efault);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
relocs
|
||||
vdso2c
|
||||
|
|
|
|||
|
|
@ -38,9 +38,14 @@ $(obj)/insn_decoder_test.o: $(srctree)/tools/arch/x86/lib/insn.c $(srctree)/tool
|
|||
|
||||
$(obj)/insn_sanity.o: $(srctree)/tools/arch/x86/lib/insn.c $(srctree)/tools/arch/x86/lib/inat.c $(srctree)/tools/arch/x86/include/asm/inat_types.h $(srctree)/tools/arch/x86/include/asm/inat.h $(srctree)/tools/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c
|
||||
|
||||
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
|
||||
hostprogs += relocs
|
||||
relocs-objs := relocs_32.o relocs_64.o relocs_common.o
|
||||
PHONY += relocs
|
||||
relocs: $(obj)/relocs
|
||||
HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi \
|
||||
-I$(srctree)/arch/$(SUBARCH)/include/uapi
|
||||
|
||||
hostprogs += relocs vdso2c
|
||||
relocs-objs := relocs_32.o relocs_64.o relocs_common.o
|
||||
|
||||
always-y := $(hostprogs)
|
||||
|
||||
PHONY += $(hostprogs)
|
||||
$(hostprogs): %: $(obj)/%
|
||||
@:
|
||||
|
|
|
|||
|
|
@ -990,13 +990,6 @@ static int register_callback(unsigned type, const void *func)
|
|||
return HYPERVISOR_callback_op(CALLBACKOP_register, &callback);
|
||||
}
|
||||
|
||||
void xen_enable_sysenter(void)
|
||||
{
|
||||
if (cpu_feature_enabled(X86_FEATURE_SYSENTER32) &&
|
||||
register_callback(CALLBACKTYPE_sysenter, xen_entry_SYSENTER_compat))
|
||||
setup_clear_cpu_cap(X86_FEATURE_SYSENTER32);
|
||||
}
|
||||
|
||||
void xen_enable_syscall(void)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -1008,11 +1001,27 @@ void xen_enable_syscall(void)
|
|||
mechanism for syscalls. */
|
||||
}
|
||||
|
||||
if (cpu_feature_enabled(X86_FEATURE_SYSCALL32) &&
|
||||
register_callback(CALLBACKTYPE_syscall32, xen_entry_SYSCALL_compat))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_SYSFAST32))
|
||||
return;
|
||||
|
||||
if (cpu_feature_enabled(X86_FEATURE_SYSCALL32)) {
|
||||
/* Use SYSCALL32 */
|
||||
ret = register_callback(CALLBACKTYPE_syscall32,
|
||||
xen_entry_SYSCALL_compat);
|
||||
|
||||
} else {
|
||||
/* Use SYSENTER32 */
|
||||
ret = register_callback(CALLBACKTYPE_sysenter,
|
||||
xen_entry_SYSENTER_compat);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
|
||||
setup_clear_cpu_cap(X86_FEATURE_SYSFAST32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void __init xen_pvmmu_arch_setup(void)
|
||||
{
|
||||
HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
|
||||
|
|
@ -1022,7 +1031,6 @@ static void __init xen_pvmmu_arch_setup(void)
|
|||
register_callback(CALLBACKTYPE_failsafe, xen_failsafe_callback))
|
||||
BUG();
|
||||
|
||||
xen_enable_sysenter();
|
||||
xen_enable_syscall();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,10 +65,9 @@ static void cpu_bringup(void)
|
|||
touch_softlockup_watchdog();
|
||||
|
||||
/* PVH runs in ring 0 and allows us to do native syscalls. Yay! */
|
||||
if (!xen_feature(XENFEAT_supervisor_mode_kernel)) {
|
||||
xen_enable_sysenter();
|
||||
if (!xen_feature(XENFEAT_supervisor_mode_kernel))
|
||||
xen_enable_syscall();
|
||||
}
|
||||
|
||||
cpu = smp_processor_id();
|
||||
identify_secondary_cpu(cpu);
|
||||
set_cpu_sibling_map(cpu);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ phys_addr_t __init xen_find_free_area(phys_addr_t size);
|
|||
char * __init xen_memory_setup(void);
|
||||
void __init xen_arch_setup(void);
|
||||
void xen_banner(void);
|
||||
void xen_enable_sysenter(void);
|
||||
void xen_enable_syscall(void);
|
||||
void xen_vcpu_restore(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,5 +16,5 @@
|
|||
#elif defined(__s390x__)
|
||||
#include "../../../../arch/s390/kernel/vdso/vgetrandom-chacha.S"
|
||||
#elif defined(__x86_64__)
|
||||
#include "../../../../arch/x86/entry/vdso/vgetrandom-chacha.S"
|
||||
#include "../../../../arch/x86/entry/vdso/vdso64/vgetrandom-chacha.S"
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue