From: Yury Norov <ynorov@caviumnetworks.com> To: <arnd@arndb.de>, <catalin.marinas@arm.com>, <linux-arm-kernel@lists.infradead.org>, <linux-kernel@vger.kernel.org> Cc: <schwidefsky@de.ibm.com>, <heiko.carstens@de.ibm.com>, <ynorov@caviumnetworks.com>, <pinskia@gmail.com>, <Prasun.Kapoor@caviumnetworks.com>, <schwab@suse.de>, <Nathan_Lynch@mentor.com>, <agraf@suse.de>, <klimov.linux@gmail.com>, <broonie@kernel.org>, <jan.dakinevich@gmail.com>, <joseph@codesourcery.com>, <christoph.muellner@theobroma-systems.com>, Philipp Tomsich <philipp.tomsich@theobroma-systems.com> Subject: [PATCH v6 18/21] arm64:ilp32: add vdso-ilp32 and use for signal return Date: Thu, 14 Jan 2016 20:23:15 +0300 [thread overview] Message-ID: <1452792198-10718-19-git-send-email-ynorov@caviumnetworks.com> (raw) In-Reply-To: <1452792198-10718-1-git-send-email-ynorov@caviumnetworks.com> From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> ILP32 VDSO exports next 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 move data page before code pages in sync with commit 601255ae3c98fdeeee3a8bb4696425e4f868b4f1 Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com> --- arch/arm64/include/asm/vdso.h | 6 ++ arch/arm64/kernel/Makefile | 5 ++ arch/arm64/kernel/signal.c | 2 + arch/arm64/kernel/vdso-ilp32/.gitignore | 2 + arch/arm64/kernel/vdso-ilp32/Makefile | 72 ++++++++++++++++++++ arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S | 33 ++++++++++ arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 95 +++++++++++++++++++++++++++ arch/arm64/kernel/vdso.c | 61 ++++++++++++++--- 8 files changed, 266 insertions(+), 10 deletions(-) create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h index 839ce00..649a9a4 100644 --- a/arch/arm64/include/asm/vdso.h +++ b/arch/arm64/include/asm/vdso.h @@ -29,6 +29,12 @@ #include <generated/vdso-offsets.h> +#ifdef CONFIG_ARM64_ILP32 +#include <generated/vdso-ilp32-offsets.h> +#else +#define vdso_offset_sigtramp_ilp32 +#endif + #define VDSO_SYMBOL(base, name) \ ({ \ (void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index c846626..19d7e17 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -46,6 +46,7 @@ arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o arm64-obj-$(CONFIG_ACPI) += acpi.o obj-y += $(arm64-obj-y) vdso/ +obj-$(CONFIG_ARM64_ILP32) += vdso-ilp32/ obj-m += $(arm64-obj-m) head-y := head.o extra-y += $(head-y) vmlinux.lds @@ -53,3 +54,7 @@ extra-y += $(head-y) vmlinux.lds # vDSO - this must be built first to generate the symbol offsets $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h $(obj)/vdso/vdso-offsets.h: $(obj)/vdso + +# vDSO - this must be built first to generate the symbol offsets +$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h +$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32 diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index f8d4c92..0648aa5 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -241,6 +241,8 @@ void setup_return(struct pt_regs *regs, struct k_sigaction *ka, if (ka->sa.sa_flags & SA_RESTORER) sigtramp = ka->sa.sa_restorer; + else if (is_ilp32_compat_task()) + sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32); else sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp); diff --git a/arch/arm64/kernel/vdso-ilp32/.gitignore b/arch/arm64/kernel/vdso-ilp32/.gitignore new file mode 100644 index 0000000..61806c3 --- /dev/null +++ b/arch/arm64/kernel/vdso-ilp32/.gitignore @@ -0,0 +1,2 @@ +vdso-ilp32.lds +vdso-ilp32-offsets.h diff --git a/arch/arm64/kernel/vdso-ilp32/Makefile b/arch/arm64/kernel/vdso-ilp32/Makefile new file mode 100644 index 0000000..c8f5472 --- /dev/null +++ b/arch/arm64/kernel/vdso-ilp32/Makefile @@ -0,0 +1,72 @@ +# +# Building a vDSO image for AArch64. +# +# Author: Will Deacon <will.deacon@arm.com> +# 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) + +obj-y += vdso-ilp32.o +extra-y += vdso-ilp32.lds vdso-ilp32-offsets.h +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 > $@ && \ + cp $@ include/generated/ +endef + +$(obj)/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) + +$(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)/$@.dbg $(MODLIB)/vdso/$@ + +vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg + @mkdir -p $(MODLIB)/vdso + $(call cmd,vdso_install) + +vdso_install: vdso-ilp32.so diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S new file mode 100644 index 0000000..46ac072 --- /dev/null +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2012 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Will Deacon <will.deacon@arm.com> + */ + +#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 diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S new file mode 100644 index 0000000..ddc63fd --- /dev/null +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S @@ -0,0 +1,95 @@ +/* + * GNU linker script for the VDSO library. + * + * Copyright (C) 2012 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Will Deacon <will.deacon@arm.com> + * 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_2.6 { + 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; diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 26352a6..521a8e4 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -40,6 +40,12 @@ extern char vdso_start, vdso_end; static unsigned long vdso_pages; static struct page **vdso_pagelist; +#ifdef CONFIG_ARM64_ILP32 +extern char vdso_ilp32_start, vdso_ilp32_end; +static unsigned long vdso_ilp32_pages; +static struct page **vdso_ilp32_pagelist; +#endif + /* * The vDSO data page. */ @@ -109,24 +115,29 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) } #endif /* CONFIG_AARCH32_EL0 */ -static struct vm_special_mapping vdso_spec[2]; - -static int __init vdso_init(void) +static int __init vdso_init_common(char *vdso_start, char *vdso_end, + unsigned long *vdso_pagesp, + struct page ***vdso_pagelistp, + struct vm_special_mapping* vdso_spec) { int i; + unsigned long vdso_pages; + struct page **vdso_pagelist; - if (memcmp(&vdso_start, "\177ELF", 4)) { + if (memcmp(vdso_start, "\177ELF", 4)) { pr_err("vDSO is not a valid ELF object!\n"); return -EINVAL; } - vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT; + vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; + *vdso_pagesp = vdso_pages; pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n", - vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data); + vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data); /* Allocate the vDSO pagelist, plus a page for the data. */ vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *), GFP_KERNEL); + *vdso_pagelistp = vdso_pagelist; if (vdso_pagelist == NULL) return -ENOMEM; @@ -135,7 +146,7 @@ static int __init vdso_init(void) /* Grab the vDSO code pages. */ for (i = 0; i < vdso_pages; i++) - vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE); + vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE); /* Populate the special mapping structures */ vdso_spec[0] = (struct vm_special_mapping) { @@ -150,16 +161,46 @@ static int __init vdso_init(void) return 0; } + +static struct vm_special_mapping vdso_spec[2]; + +static int __init vdso_init(void) +{ + return vdso_init_common(&vdso_start, &vdso_end, + &vdso_pages, &vdso_pagelist, + vdso_spec); +} arch_initcall(vdso_init); +#ifdef CONFIG_ARM64_ILP32 +static struct vm_special_mapping vdso_ilp32_spec[2]; + +static int __init vdso_ilp32_init(void) +{ + return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end, + &vdso_ilp32_pages, &vdso_ilp32_pagelist, + 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_pages; + struct vm_special_mapping *spec = vdso_spec; + +#ifdef CONFIG_ARM64_ILP32 + if (is_ilp32_compat_task()) { + pages = vdso_ilp32_pages; + 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; @@ -171,7 +212,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, } ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE, VM_READ|VM_MAYREAD, - &vdso_spec[0]); + &spec[0]); if (IS_ERR(ret)) goto up_fail; @@ -180,7 +221,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, ret = _install_special_mapping(mm, vdso_base, vdso_text_len, VM_READ|VM_EXEC| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, - &vdso_spec[1]); + &spec[1]); if (IS_ERR(ret)) goto up_fail; -- 2.5.0
WARNING: multiple messages have this Message-ID (diff)
From: ynorov@caviumnetworks.com (Yury Norov) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v6 18/21] arm64:ilp32: add vdso-ilp32 and use for signal return Date: Thu, 14 Jan 2016 20:23:15 +0300 [thread overview] Message-ID: <1452792198-10718-19-git-send-email-ynorov@caviumnetworks.com> (raw) In-Reply-To: <1452792198-10718-1-git-send-email-ynorov@caviumnetworks.com> From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> ILP32 VDSO exports next 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 move data page before code pages in sync with commit 601255ae3c98fdeeee3a8bb4696425e4f868b4f1 Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com> --- arch/arm64/include/asm/vdso.h | 6 ++ arch/arm64/kernel/Makefile | 5 ++ arch/arm64/kernel/signal.c | 2 + arch/arm64/kernel/vdso-ilp32/.gitignore | 2 + arch/arm64/kernel/vdso-ilp32/Makefile | 72 ++++++++++++++++++++ arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S | 33 ++++++++++ arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 95 +++++++++++++++++++++++++++ arch/arm64/kernel/vdso.c | 61 ++++++++++++++--- 8 files changed, 266 insertions(+), 10 deletions(-) create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h index 839ce00..649a9a4 100644 --- a/arch/arm64/include/asm/vdso.h +++ b/arch/arm64/include/asm/vdso.h @@ -29,6 +29,12 @@ #include <generated/vdso-offsets.h> +#ifdef CONFIG_ARM64_ILP32 +#include <generated/vdso-ilp32-offsets.h> +#else +#define vdso_offset_sigtramp_ilp32 +#endif + #define VDSO_SYMBOL(base, name) \ ({ \ (void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index c846626..19d7e17 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -46,6 +46,7 @@ arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o arm64-obj-$(CONFIG_ACPI) += acpi.o obj-y += $(arm64-obj-y) vdso/ +obj-$(CONFIG_ARM64_ILP32) += vdso-ilp32/ obj-m += $(arm64-obj-m) head-y := head.o extra-y += $(head-y) vmlinux.lds @@ -53,3 +54,7 @@ extra-y += $(head-y) vmlinux.lds # vDSO - this must be built first to generate the symbol offsets $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h $(obj)/vdso/vdso-offsets.h: $(obj)/vdso + +# vDSO - this must be built first to generate the symbol offsets +$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h +$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32 diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index f8d4c92..0648aa5 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -241,6 +241,8 @@ void setup_return(struct pt_regs *regs, struct k_sigaction *ka, if (ka->sa.sa_flags & SA_RESTORER) sigtramp = ka->sa.sa_restorer; + else if (is_ilp32_compat_task()) + sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32); else sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp); diff --git a/arch/arm64/kernel/vdso-ilp32/.gitignore b/arch/arm64/kernel/vdso-ilp32/.gitignore new file mode 100644 index 0000000..61806c3 --- /dev/null +++ b/arch/arm64/kernel/vdso-ilp32/.gitignore @@ -0,0 +1,2 @@ +vdso-ilp32.lds +vdso-ilp32-offsets.h diff --git a/arch/arm64/kernel/vdso-ilp32/Makefile b/arch/arm64/kernel/vdso-ilp32/Makefile new file mode 100644 index 0000000..c8f5472 --- /dev/null +++ b/arch/arm64/kernel/vdso-ilp32/Makefile @@ -0,0 +1,72 @@ +# +# Building a vDSO image for AArch64. +# +# Author: Will Deacon <will.deacon@arm.com> +# 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) + +obj-y += vdso-ilp32.o +extra-y += vdso-ilp32.lds vdso-ilp32-offsets.h +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 > $@ && \ + cp $@ include/generated/ +endef + +$(obj)/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) + +$(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)/$@.dbg $(MODLIB)/vdso/$@ + +vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg + @mkdir -p $(MODLIB)/vdso + $(call cmd,vdso_install) + +vdso_install: vdso-ilp32.so diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S new file mode 100644 index 0000000..46ac072 --- /dev/null +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2012 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Will Deacon <will.deacon@arm.com> + */ + +#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 diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S new file mode 100644 index 0000000..ddc63fd --- /dev/null +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S @@ -0,0 +1,95 @@ +/* + * GNU linker script for the VDSO library. + * + * Copyright (C) 2012 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Will Deacon <will.deacon@arm.com> + * 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_2.6 { + 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; diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 26352a6..521a8e4 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -40,6 +40,12 @@ extern char vdso_start, vdso_end; static unsigned long vdso_pages; static struct page **vdso_pagelist; +#ifdef CONFIG_ARM64_ILP32 +extern char vdso_ilp32_start, vdso_ilp32_end; +static unsigned long vdso_ilp32_pages; +static struct page **vdso_ilp32_pagelist; +#endif + /* * The vDSO data page. */ @@ -109,24 +115,29 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) } #endif /* CONFIG_AARCH32_EL0 */ -static struct vm_special_mapping vdso_spec[2]; - -static int __init vdso_init(void) +static int __init vdso_init_common(char *vdso_start, char *vdso_end, + unsigned long *vdso_pagesp, + struct page ***vdso_pagelistp, + struct vm_special_mapping* vdso_spec) { int i; + unsigned long vdso_pages; + struct page **vdso_pagelist; - if (memcmp(&vdso_start, "\177ELF", 4)) { + if (memcmp(vdso_start, "\177ELF", 4)) { pr_err("vDSO is not a valid ELF object!\n"); return -EINVAL; } - vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT; + vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; + *vdso_pagesp = vdso_pages; pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n", - vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data); + vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data); /* Allocate the vDSO pagelist, plus a page for the data. */ vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *), GFP_KERNEL); + *vdso_pagelistp = vdso_pagelist; if (vdso_pagelist == NULL) return -ENOMEM; @@ -135,7 +146,7 @@ static int __init vdso_init(void) /* Grab the vDSO code pages. */ for (i = 0; i < vdso_pages; i++) - vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE); + vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE); /* Populate the special mapping structures */ vdso_spec[0] = (struct vm_special_mapping) { @@ -150,16 +161,46 @@ static int __init vdso_init(void) return 0; } + +static struct vm_special_mapping vdso_spec[2]; + +static int __init vdso_init(void) +{ + return vdso_init_common(&vdso_start, &vdso_end, + &vdso_pages, &vdso_pagelist, + vdso_spec); +} arch_initcall(vdso_init); +#ifdef CONFIG_ARM64_ILP32 +static struct vm_special_mapping vdso_ilp32_spec[2]; + +static int __init vdso_ilp32_init(void) +{ + return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end, + &vdso_ilp32_pages, &vdso_ilp32_pagelist, + 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_pages; + struct vm_special_mapping *spec = vdso_spec; + +#ifdef CONFIG_ARM64_ILP32 + if (is_ilp32_compat_task()) { + pages = vdso_ilp32_pages; + 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; @@ -171,7 +212,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, } ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE, VM_READ|VM_MAYREAD, - &vdso_spec[0]); + &spec[0]); if (IS_ERR(ret)) goto up_fail; @@ -180,7 +221,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, ret = _install_special_mapping(mm, vdso_base, vdso_text_len, VM_READ|VM_EXEC| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, - &vdso_spec[1]); + &spec[1]); if (IS_ERR(ret)) goto up_fail; -- 2.5.0
next prev parent reply other threads:[~2016-01-14 17:28 UTC|newest] Thread overview: 143+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-01-14 17:22 [RFC5 PATCH v6 00/21] ILP32 for ARM64 Yury Norov 2016-01-14 17:22 ` Yury Norov 2016-01-14 17:22 ` [PATCH v6 01/21] arm64: ilp32: add documentation on the ILP32 ABI " Yury Norov 2016-01-14 17:22 ` Yury Norov 2016-01-14 17:22 ` [PATCH v6 02/21] arm64: ensure the kernel is compiled for LP64 Yury Norov 2016-01-14 17:22 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 03/21] arm64: rename COMPAT to AARCH32_EL0 in Kconfig Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 04/21] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 05/21] arm64: compat: change config dependences to aarch32 Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 06/21] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64 Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 07/21] thread: move thread bits accessors to separated file Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 08/21] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat) Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 09/21] arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64 Yury Norov 2016-01-14 17:23 ` [PATCH v6 09/21] arm64: ilp32: add is_ilp32_compat_{task, thread} " Yury Norov 2016-01-14 17:23 ` [PATCH v6 10/21] arm64: introduce binfmt_elf32.c Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 11/21] arm64: ilp32: introduce binfmt_ilp32.c Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 12/21] arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32 Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 13/21] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 14/21] arm64: signal: wrap struct ucontext, fp and lr with struct sigframe Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 15/21] arm64: signal: share lp64 signal routines to ilp32 Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 16/21] arm64: signal32: move ilp32 and aarch32 common code to separated file Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 17/21] arm64: ilp32: introduce ilp32-specific handlers for sigframe Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-02-29 8:27 ` Andreas Schwab 2016-02-29 8:27 ` Andreas Schwab 2016-01-14 17:23 ` Yury Norov [this message] 2016-01-14 17:23 ` [PATCH v6 18/21] arm64:ilp32: add vdso-ilp32 and use for signal return Yury Norov 2016-01-14 17:23 ` [PATCH v6 19/21] arm64:ilp32: add ARM64_ILP32 to Kconfig Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 20/21] all: s390: make compat wrappers the generic solution Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-14 18:11 ` Yury Norov 2016-01-14 18:11 ` Yury Norov 2016-01-15 12:46 ` Heiko Carstens 2016-01-15 12:46 ` Heiko Carstens 2016-01-19 17:52 ` Yury Norov 2016-01-20 8:16 ` Heiko Carstens 2016-01-20 8:16 ` Heiko Carstens 2016-01-20 12:17 ` Yury Norov 2016-01-20 12:17 ` Yury Norov 2016-01-14 17:23 ` [PATCH v6 21/21] arm64: ilp32: wrap syscalls to remove top 32-bit vulnerability Yury Norov 2016-01-14 17:23 ` Yury Norov 2016-01-18 13:18 ` [RFC5 PATCH v6 00/21] ILP32 for ARM64 Zhangjian (Bamvor) 2016-01-18 13:18 ` Zhangjian (Bamvor) 2016-01-18 13:26 ` Andreas Schwab 2016-01-18 13:26 ` Andreas Schwab 2016-01-18 13:41 ` Bamvor Zhang Jian 2016-01-18 13:41 ` Bamvor Zhang Jian 2016-01-29 9:59 ` Zhangjian (Bamvor) 2016-01-29 9:59 ` Zhangjian (Bamvor) 2016-01-29 17:09 ` Yury Norov 2016-01-29 17:09 ` Yury Norov 2016-01-30 4:15 ` Zhangjian (Bamvor) 2016-01-30 4:15 ` Zhangjian (Bamvor) 2016-02-18 22:35 ` Yury Norov 2016-02-18 22:35 ` Yury Norov 2016-02-19 8:23 ` Arnd Bergmann 2016-02-19 8:23 ` Arnd Bergmann 2016-02-19 12:59 ` Yury Norov 2016-02-19 12:59 ` Yury Norov 2016-02-19 14:06 ` Arnd Bergmann 2016-02-19 14:06 ` Arnd Bergmann 2016-02-29 15:39 ` Yury Norov 2016-02-29 15:39 ` Yury Norov 2016-02-29 16:00 ` Andreas Schwab 2016-02-29 16:00 ` Andreas Schwab 2016-02-29 16:30 ` Arnd Bergmann 2016-02-29 16:30 ` Arnd Bergmann 2016-02-25 10:50 ` Andreas Schwab 2016-02-25 10:50 ` Andreas Schwab 2016-02-25 20:28 ` Yury Norov 2016-02-25 20:28 ` Yury Norov 2016-03-18 10:28 ` Zhangjian (Bamvor) 2016-03-18 10:28 ` Zhangjian (Bamvor) 2016-03-18 15:49 ` Yury Norov 2016-03-18 15:49 ` Yury Norov 2016-03-18 15:55 ` Alexander Graf 2016-03-18 15:55 ` Alexander Graf 2016-03-18 16:46 ` Yury Norov 2016-03-18 16:46 ` Yury Norov 2016-03-20 8:12 ` Zhangjian (Bamvor) 2016-03-20 8:12 ` Zhangjian (Bamvor) 2016-03-21 11:23 ` Zhangjian (Bamvor) 2016-03-21 11:23 ` Zhangjian (Bamvor) 2016-03-21 18:43 ` Yury Norov 2016-03-21 18:43 ` Yury Norov 2016-03-22 1:49 ` Yury Norov 2016-03-22 1:49 ` Yury Norov 2016-03-21 9:07 ` Andreas Schwab 2016-03-21 9:07 ` Andreas Schwab 2016-03-21 9:43 ` Arnd Bergmann 2016-03-21 9:43 ` Arnd Bergmann 2016-03-21 10:52 ` Andreas Schwab 2016-03-21 10:52 ` Andreas Schwab 2016-03-21 17:02 ` Arnd Bergmann 2016-03-21 17:02 ` Arnd Bergmann 2016-03-26 12:36 ` Zhangjian (Bamvor) 2016-03-26 12:36 ` Zhangjian (Bamvor) 2016-03-29 10:58 ` Arnd Bergmann 2016-03-29 10:58 ` Arnd Bergmann 2016-03-29 12:01 ` Yury Norov 2016-03-29 12:01 ` Yury Norov 2016-03-29 12:42 ` Arnd Bergmann 2016-03-29 12:42 ` Arnd Bergmann 2016-03-29 13:21 ` Zhangjian (Bamvor) 2016-03-29 13:21 ` Zhangjian (Bamvor) 2016-03-29 13:27 ` Arnd Bergmann 2016-03-29 13:27 ` Arnd Bergmann 2016-03-29 15:54 ` Joseph Myers 2016-03-29 15:54 ` Joseph Myers 2016-03-29 19:30 ` Arnd Bergmann 2016-03-29 19:30 ` Arnd Bergmann 2016-03-29 20:15 ` Joseph Myers 2016-03-29 20:15 ` Joseph Myers 2016-03-29 20:24 ` Arnd Bergmann 2016-03-29 20:24 ` Arnd Bergmann 2016-03-29 21:00 ` Joseph Myers 2016-03-29 21:00 ` Joseph Myers 2016-03-29 21:39 ` Arnd Bergmann 2016-03-29 21:39 ` Arnd Bergmann 2016-03-31 7:35 ` Zhangjian (Bamvor) 2016-03-31 7:35 ` Zhangjian (Bamvor) 2016-03-21 18:40 ` Yury Norov 2016-03-21 18:40 ` Yury Norov 2016-03-26 13:08 ` Zhangjian (Bamvor) 2016-03-26 13:08 ` Zhangjian (Bamvor) 2016-03-26 13:45 ` Zhangjian (Bamvor) 2016-03-26 13:45 ` Zhangjian (Bamvor) 2016-03-26 22:46 ` Yury Norov 2016-03-26 22:46 ` Yury Norov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1452792198-10718-19-git-send-email-ynorov@caviumnetworks.com \ --to=ynorov@caviumnetworks.com \ --cc=Nathan_Lynch@mentor.com \ --cc=Prasun.Kapoor@caviumnetworks.com \ --cc=agraf@suse.de \ --cc=arnd@arndb.de \ --cc=broonie@kernel.org \ --cc=catalin.marinas@arm.com \ --cc=christoph.muellner@theobroma-systems.com \ --cc=heiko.carstens@de.ibm.com \ --cc=jan.dakinevich@gmail.com \ --cc=joseph@codesourcery.com \ --cc=klimov.linux@gmail.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=philipp.tomsich@theobroma-systems.com \ --cc=pinskia@gmail.com \ --cc=schwab@suse.de \ --cc=schwidefsky@de.ibm.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.