Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1a21d4e0 authored by H. J. Lu's avatar H. J. Lu Committed by H. Peter Anvin
Browse files

x32: Add x32 VDSO support



Add support for the x32 VDSO.  The x32 VDSO takes advantage of the
similarity between the x86-64 and the x32 ABIs to contain the same
content, only the container is different, as the x32 VDSO obviously is
an x32 shared object.

Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
parent 5fd92e65
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
vdso.lds
vdso-syms.lds
vdsox32.lds
vdsox32-syms.lds
vdso32-syms.lds
vdso32-syscall-syms.lds
vdso32-sysenter-syms.lds
+45 −1
Original line number Diff line number Diff line
@@ -3,21 +3,29 @@
#

VDSO64-$(CONFIG_X86_64)		:= y
VDSOX32-$(CONFIG_X86_X32_ABI)	:= y
VDSO32-$(CONFIG_X86_32)		:= y
VDSO32-$(CONFIG_COMPAT)		:= y

vdso-install-$(VDSO64-y)	+= vdso.so
vdso-install-$(VDSOX32-y)	+= vdsox32.so
vdso-install-$(VDSO32-y)	+= $(vdso32-images)


# files to link into the vdso
vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o

vobjs-$(VDSOX32-y) += $(vobjx32s-compat)

# Filter out x32 objects.
vobj64s := $(filter-out $(vobjx32s-compat),$(vobjs-y))

# files to link into kernel
obj-$(VDSO64-y)			+= vma.o vdso.o
obj-$(VDSOX32-y)		+= vdsox32.o
obj-$(VDSO32-y)			+= vdso32.o vdso32-setup.o

vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
vobjs := $(foreach F,$(vobj64s),$(obj)/$F)

$(obj)/vdso.o: $(obj)/vdso.so

@@ -72,6 +80,42 @@ endef
$(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE
	$(call if_changed,vdsosym)

#
# 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.
#

targets += vdsox32-syms.lds
obj-$(VDSOX32-y)		+= vdsox32-syms.lds

CPPFLAGS_vdsox32.lds = $(CPPFLAGS_vdso.lds)
VDSO_LDFLAGS_vdsox32.lds = -Wl,-m,elf32_x86_64 \
			   -Wl,-soname=linux-vdso.so.1 \
			   -Wl,-z,max-page-size=4096 \
			   -Wl,-z,common-page-size=4096

vobjx32s-y := $(vobj64s:.o=-x32.o)
vobjx32s := $(foreach F,$(vobjx32s-y),$(obj)/$F)

# 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.so vdsox32.so.dbg vdsox32.lds $(vobjx32s-y)

$(obj)/vdsox32.o: $(src)/vdsox32.S $(obj)/vdsox32.so

$(obj)/vdsox32.so.dbg: $(src)/vdsox32.lds $(vobjx32s) FORCE
	$(call if_changed,vdso)

#
# Build multiple 32-bit vDSO images to choose from at boot time.
#
+6 −0
Original line number Diff line number Diff line
@@ -317,6 +317,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
	int ret = 0;
	bool compat;

#ifdef CONFIG_X86_X32_ABI
	extern int x32_setup_additional_pages(struct linux_binprm *, int);
	if (test_thread_flag(TIF_X32))
		return x32_setup_additional_pages (bprm, uses_interp);
#endif

	if (vdso_enabled == VDSO_DISABLED)
		return 0;

+22 −0
Original line number Diff line number Diff line
#include <asm/page_types.h>
#include <linux/linkage.h>
#include <linux/init.h>

__PAGE_ALIGNED_DATA

	.globl vdsox32_start, vdsox32_end
	.align PAGE_SIZE
vdsox32_start:
	.incbin "arch/x86/vdso/vdsox32.so"
vdsox32_end:
	.align PAGE_SIZE /* extra data here leaks to userspace. */

.previous

	.globl vdsox32_pages
	.bss
	.align 8
	.type vdsox32_pages, @object
vdsox32_pages:
	.zero (vdsox32_end - vdsox32_start + PAGE_SIZE - 1) / PAGE_SIZE * 8
	.size vdsox32_pages, .-vdsox32_pages
+32 −0
Original line number Diff line number Diff line
/*
 * Linker script for x32 vDSO.
 * We #include the file to define the layout details.
 * Here we only choose the prelinked virtual address.
 *
 * This file defines the version script giving the user-exported symbols in
 * the DSO.  We can define local symbols here called VDSO* to make their
 * values visible using the asm-x86/vdso.h macros from the kernel proper.
 */

#define VDSO_PRELINK 0
#include "vdso-layout.lds.S"

/*
 * This controls what userland symbols we export from the vDSO.
 */
VERSION {
	LINUX_2.6 {
	global:
		clock_gettime;
		__vdso_clock_gettime;
		gettimeofday;
		__vdso_gettimeofday;
		getcpu;
		__vdso_getcpu;
		time;
		__vdso_time;
	local: *;
	};
}

VDSOX32_PRELINK = VDSO_PRELINK;
Loading