Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9862b47
arm64: signal: Make parse_user_sigframe() independent of rt_sigframe …
May 16, 2018
4f5074e
ptrace: Add compat PTRACE_{G,S}ETSIGMASK handlers
May 16, 2018
b36de00
thread: move thread bits accessors to separated file
norov May 16, 2018
8f9e256
arm64: ilp32: add documentation on the ILP32 ABI for ARM64
norov May 16, 2018
61dbb68
arm64: rename COMPAT to AARCH32_EL0
apinski-cavium May 16, 2018
f56309c
arm64: rename functions that reference compat term
norov May 16, 2018
42a2714
arm64: uapi: set __BITS_PER_LONG correctly for ILP32 and LP64
apinski-cavium May 16, 2018
fc856ed
arm64: introduce is_a32_compat_{task,thread} for AArch32 compat
norov May 16, 2018
a943e7c
arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64
norov May 16, 2018
2312ac1
arm64: introduce AUDIT_ARCH_AARCH64ILP32 for ilp32
Jan 7, 2019
4f4fb85
arm64: introduce binfmt_elf32.c
norov May 16, 2018
5331393
arm64: change compat_elf_hwcap and compat_elf_hwcap2 prefix to a32
norov May 16, 2018
8fde72a
arm64: ilp32: introduce binfmt_ilp32.c
norov May 16, 2018
a4a5422
arm64: ilp32: share aarch32 syscall handlers
norov Oct 19, 2018
c7ecdd8
arm64: ilp32: introduce syscall table for ILP32
norov Oct 19, 2018
6bba78d
arm64: signal: share lp64 signal structures and routines to ilp32
norov May 16, 2018
59391d9
arm64: signal32: move ilp32 and aarch32 common code to separated file
norov May 16, 2018
ffb1353
arm64: ilp32: introduce ilp32-specific sigframe and ucontext
May 16, 2018
0f8e9bb
arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32
norov May 16, 2018
e613acc
arm64:ilp32: add vdso-ilp32 and use for signal return
May 16, 2018
6d1ff42
arm64:ilp32: add ARM64_ILP32 to Kconfig
apinski-cavium May 16, 2018
5270931
arm64: ilp32: Make the Kconfig option default y
ctmarinas May 16, 2018
fe1ef0a
arm64: seccomp: customize compat syscall whitelist
YuryNorov Nov 24, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
arm64:ilp32: add vdso-ilp32 and use for signal return
ILP32 VDSO exports following symbols:
 __kernel_rt_sigreturn;
 __kernel_gettimeofday;
 __kernel_clock_gettime;
 __kernel_clock_getres.

What shared object to use, kernel selects depending on result of
is_ilp32_compat_task() in arch/arm64/kernel/vdso.c, so it substitutes
correct pages and spec.

Adjusted to move the data page before code pages in sync with
commit 601255a ("arm64: vdso: move data page before code pages")

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Bamvor Jian Zhang <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
  • Loading branch information
Philipp Tomsich authored and YuryNorov committed Jul 9, 2019
commit e613acc4d45aea9f0cfb620a06f112cc726ba1b3
3 changes: 3 additions & 0 deletions arch/arm64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ ifeq ($(KBUILD_EXTMOD),)
prepare: vdso_prepare
vdso_prepare: prepare0
$(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h
ifeq ($(CONFIG_ARM64_ILP32), y)
$(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso-ilp32 include/generated/vdso-ilp32-offsets.h
endif
endif

define archhelp
Expand Down
6 changes: 6 additions & 0 deletions arch/arm64/include/asm/vdso.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@

#include <generated/vdso-offsets.h>

#ifdef CONFIG_ARM64_ILP32
#include <generated/vdso-ilp32-offsets.h>
#else
#define vdso_offset_sigtramp_ilp32 ({ BUILD_BUG(); 0; })
#endif

#define VDSO_SYMBOL(base, name) \
({ \
(void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ obj-$(CONFIG_ARM64_SSBD) += ssbd.o
obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o

obj-y += vdso/ probes/
obj-$(CONFIG_ARM64_ILP32) += vdso-ilp32/
head-y := head.o
extra-y += $(head-y) vmlinux.lds

Expand Down
7 changes: 7 additions & 0 deletions arch/arm64/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ int main(void)
DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec));
DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec));
BLANK();
#ifdef CONFIG_COMPAT
DEFINE(COMPAT_TVAL_TV_SEC, offsetof(struct compat_timeval, tv_sec));
DEFINE(COMPAT_TVAL_TV_USEC, offsetof(struct compat_timeval, tv_usec));
DEFINE(COMPAT_TSPEC_TV_SEC, offsetof(struct compat_timespec, tv_sec));
DEFINE(COMPAT_TSPEC_TV_NSEC, offsetof(struct compat_timespec, tv_nsec));
BLANK();
#endif
DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
BLANK();
Expand Down
2 changes: 2 additions & 0 deletions arch/arm64/kernel/vdso-ilp32/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
vdso-ilp32.lds
vdso-ilp32-offsets.h
82 changes: 82 additions & 0 deletions arch/arm64/kernel/vdso-ilp32/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# SPDX-License-Identifier: GPL-2.0

#
# Building a vDSO image for AArch64.
#
# Author: Will Deacon <[email protected]>
# Heavily based on the vDSO Makefiles for other archs.
#

obj-ilp32-vdso := gettimeofday-ilp32.o note-ilp32.o sigreturn-ilp32.o

# Build rules
targets := $(obj-ilp32-vdso) vdso-ilp32.so vdso-ilp32.so.dbg
obj-ilp32-vdso := $(addprefix $(obj)/, $(obj-ilp32-vdso))

ccflags-y := -shared -fno-common -fno-builtin
ccflags-y += -nostdlib -Wl,-soname=linux-ilp32-vdso.so.1 \
$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)

# Disable gcov profiling for VDSO code
GCOV_PROFILE := n

# Workaround for bare-metal (ELF) toolchains that neglect to pass -shared
# down to collect2, resulting in silent corruption of the vDSO image.
ccflags-y += -Wl,-shared

obj-y += vdso-ilp32.o
extra-y += vdso-ilp32.lds
CPPFLAGS_vdso-ilp32.lds += -P -C -U$(ARCH) -mabi=ilp32

# Force dependency (incbin is bad)
$(obj)/vdso-ilp32.o : $(obj)/vdso-ilp32.so

# Link rule for the .so file, .lds has to be first
$(obj)/vdso-ilp32.so.dbg: $(src)/vdso-ilp32.lds $(obj-ilp32-vdso)
$(call if_changed,vdso-ilp32ld)

# 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 := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh
quiet_cmd_vdsosym = VDSOSYM $@
define cmd_vdsosym
$(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
endef

include/generated/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32.so.dbg FORCE
$(call if_changed,vdsosym)

# Assembly rules for the .S files
#$(obj-ilp32-vdso): %.o: $(src)/../vdso/$(subst -ilp32,,%.S)
# $(call if_changed_dep,vdso-ilp32as)

$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
$(call if_changed_dep,vdso-ilp32as)

$(obj)/note-ilp32.o: $(src)/../vdso/note.S
$(call if_changed_dep,vdso-ilp32as)

# This one should be fine because ILP32 uses the same generic
# __NR_rt_sigreturn syscall number.
$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S
$(call if_changed_dep,vdso-ilp32as)

# Actual build commands
quiet_cmd_vdso-ilp32ld = VDSOILP32L $@
cmd_vdso-ilp32ld = $(CC) $(c_flags) -mabi=ilp32 -Wl,-n -Wl,-T $^ -o $@
quiet_cmd_vdso-ilp32as = VDSOILP32A $@
cmd_vdso-ilp32as = $(CC) $(a_flags) -mabi=ilp32 -c -o $@ $<

# Install commands for the unstripped file
quiet_cmd_vdso_install = INSTALL $@
cmd_vdso_install = cp $(obj)/[email protected] $(MODLIB)/vdso/$@

vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg
@mkdir -p $(MODLIB)/vdso
$(call cmd,vdso_install)

vdso_install: vdso-ilp32.so
22 changes: 22 additions & 0 deletions arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */

/*
* Copyright (C) 2012 ARM Limited
* Author: Will Deacon <[email protected]>
*/

#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/const.h>
#include <asm/page.h>

__PAGE_ALIGNED_DATA

.globl vdso_ilp32_start, vdso_ilp32_end
.balign PAGE_SIZE
vdso_ilp32_start:
.incbin "arch/arm64/kernel/vdso-ilp32/vdso-ilp32.so"
.balign PAGE_SIZE
vdso_ilp32_end:

.previous
84 changes: 84 additions & 0 deletions arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* SPDX-License-Identifier: GPL-2.0 */

/*
* GNU linker script for the VDSO library.
*
* Copyright (C) 2012 ARM Limited
* Author: Will Deacon <[email protected]>
* Heavily based on the vDSO linker scripts for other archs.
*/

#include <linux/const.h>
#include <asm/page.h>
#include <asm/vdso.h>

SECTIONS
{
PROVIDE(_vdso_data = . - PAGE_SIZE);
. = VDSO_LBASE + SIZEOF_HEADERS;

.hash : { *(.hash) } :text
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }

.note : { *(.note.*) } :text :note

. = ALIGN(16);

.text : { *(.text*) } :text =0xd503201f
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);

.eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
.eh_frame : { KEEP (*(.eh_frame)) } :text

.dynamic : { *(.dynamic) } :text :dynamic

.rodata : { *(.rodata*) } :text

_end = .;
PROVIDE(end = .);

/DISCARD/ : {
*(.note.GNU-stack)
*(.data .data.* .gnu.linkonce.d.* .sdata*)
*(.bss .sbss .dynbss .dynsbss)
}
}

/*
* 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.
*/
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;
}

/*
* This controls what symbols we export from the DSO.
*/
VERSION
{
LINUX_4.12 {
global:
__kernel_rt_sigreturn;
__kernel_gettimeofday;
__kernel_clock_gettime;
__kernel_clock_getres;
local: *;
};
}

/*
* Make the sigreturn code visible to the kernel.
*/
VDSO_sigtramp_ilp32 = __kernel_rt_sigreturn;
58 changes: 51 additions & 7 deletions arch/arm64/kernel/vdso.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@
#include <asm/vdso.h>
#include <asm/vdso_datapage.h>

extern char vdso_start[], vdso_end[];
static unsigned long vdso_pages __ro_after_init;
extern char vdso_lp64_start[], vdso_lp64_end[];
static unsigned long vdso_lp64_pages __ro_after_init;

#ifdef CONFIG_ARM64_ILP32
extern char vdso_ilp32_start[], vdso_ilp32_end[];
static unsigned long vdso_ilp32_pages __ro_after_init;
#endif

/*
* The vDSO data page.
Expand Down Expand Up @@ -171,7 +176,7 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
struct vm_area_struct *new_vma)
{
unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
unsigned long vdso_size = vdso_end - vdso_start;
unsigned long vdso_size = vdso_lp64_end - vdso_lp64_start;

if (vdso_size != new_size)
return -EINVAL;
Expand All @@ -181,7 +186,7 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
return 0;
}

static struct vm_special_mapping vdso_spec[2] __ro_after_init = {
static struct vm_special_mapping vdso_lp64_spec[2] __ro_after_init = {
{
.name = "[vvar]",
},
Expand All @@ -191,9 +196,23 @@ static struct vm_special_mapping vdso_spec[2] __ro_after_init = {
},
};

static int __init vdso_init(void)
#ifdef CONFIG_ARM64_ILP32
static struct vm_special_mapping vdso_ilp32_spec[2] __ro_after_init = {
{
.name = "[vvar]",
},
{
.name = "[vdso]",
},
};
#endif

static int __init vdso_init(char *vdso_start, char *vdso_end,
unsigned long *vdso_pagesp,
struct vm_special_mapping *vdso_spec)
{
int i;
unsigned long vdso_pages;
struct page **vdso_pagelist;
unsigned long pfn;

Expand All @@ -203,6 +222,7 @@ static int __init vdso_init(void)
}

vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
*vdso_pagesp = vdso_pages;

/* Allocate the vDSO pagelist, plus a page for the data. */
vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
Expand All @@ -225,16 +245,40 @@ static int __init vdso_init(void)

return 0;
}
arch_initcall(vdso_init);

static int __init vdso_lp64_init(void)
{
return vdso_init(vdso_lp64_start, vdso_lp64_end,
&vdso_lp64_pages, vdso_lp64_spec);
}
arch_initcall(vdso_lp64_init);

#ifdef CONFIG_ARM64_ILP32
static int __init vdso_ilp32_init(void)
{
return vdso_init(vdso_ilp32_start, vdso_ilp32_end,
&vdso_ilp32_pages, vdso_ilp32_spec);
}
arch_initcall(vdso_ilp32_init);
#endif

int arch_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp)
{
struct mm_struct *mm = current->mm;
unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
void *ret;
unsigned long pages = vdso_lp64_pages;
struct vm_special_mapping *vdso_spec = vdso_lp64_spec;

#ifdef CONFIG_ARM64_ILP32
if (is_ilp32_compat_task()) {
pages = vdso_ilp32_pages;
vdso_spec = vdso_ilp32_spec;
}
#endif

vdso_text_len = vdso_pages << PAGE_SHIFT;
vdso_text_len = pages << PAGE_SHIFT;
/* Be sure to map the data page */
vdso_mapping_len = vdso_text_len + PAGE_SIZE;

Expand Down
Loading