From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756919AbbI2WS4 (ORCPT ); Tue, 29 Sep 2015 18:18:56 -0400 Received: from mail-bl2on0056.outbound.protection.outlook.com ([65.55.169.56]:12943 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1756851AbbI2WSI (ORCPT ); Tue, 29 Sep 2015 18:18:08 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Yuri.Norov@caviumnetworks.com; From: Yury Norov To: , , , , , CC: , , , , , Yury Norov Subject: [PATCH v5 17/23] arm64:ilp32: add vdso-ilp32 and use for signal return Date: Wed, 30 Sep 2015 01:14:14 +0300 Message-ID: <1443564860-31208-18-git-send-email-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1443564860-31208-1-git-send-email-ynorov@caviumnetworks.com> References: <1443564860-31208-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [91.78.158.8] X-ClientProxiedBy: AM3PR07CA0020.eurprd07.prod.outlook.com (10.141.45.148) To DM2PR07MB624.namprd07.prod.outlook.com (10.141.177.154) X-Microsoft-Exchange-Diagnostics: 1;DM2PR07MB624;2:JjLwpB+XxluOLpqhutrxvbzFFfJQlPPKkG4IEG9CvRY/2/EUdbaWeCpBQUucbfEDoZ22H2F8skLjsff65mRG8JWLMnyLH5WktsCufwqoIk/ddXMLeySBhBQ3CiAxmfyuC7CNUjq6sWdg2F+9zmwxSxG1R5AX2E5OTzfZxaAO7BM=;3:Vqv4AQkJhC9Zl4tEgDQLxujwU8bAoeyKVynJR/0lQC7ga2ToTmOoRjo9vSiUJj7MtxMjo7R9pp25H2e2wG18XvaUbPydIHXFmbb5bbUt3dqO5hmrRBJ3BThFNuNCcDbFoa0vaIqvc5w3H+ZcL74ZPw==;25:irqv3gh1cL4aKdUGdPupf3ki8XX74kCBQHjO5keQ8hlnpJrscEc1slMth4bq8tM3vuUxoJ5vHn1rtFbYJTyVy5BCkb38kCy4lpM+lYThq+ThFoOesGJVc1QrqdKhtmlgl9jdhZEPOOCpyoUvjKTK+1oBkI6EJCSZJG+M2qBSQ9YDPGbgaAV/8CKcyd3t09NZedxdW3Knr83EXmpBj9H1Af2AM0JoKyX2dM93t6lIojXugDdjpBX58ASk4GiqYGnS X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DM2PR07MB624; X-Microsoft-Exchange-Diagnostics: 1;DM2PR07MB624;20:pOj5cmjqmWfpvI2h1waQfkTOsuQUdIoJTDh9ztavsANm4IwR46KeUb63oQOm6YMRDAjo6oWJ92O2eU8Ogd2fBNDcssM3xMKr0uwWOBsVt2H0nzeQvO3ftzVXrJGaa7t7Kdjioz2xJlc4uE27wf/BTNNmlczNV4NsIjjrhKUQWHyUxrU5b0ob9RK2HiDYfEQ0WTJHvWV+/oSiBNP5x47ORmxYRfhJcDB4nNVJPNLFCItKkUZKCR+sObVQbsBpvApByobj0TWdlh7oistnVR/kxcT898LBuJk2jbwcz8zSWNFv1nzFIWMSZzZlsQwMBac/uUh+6GGTyFk44ky2xOyeKyAye3HFgiszIR+x1f9OWa4SOUYKRIqW4+01Ny3Cq+6UN4tTWqonAzMVKcwkT4bDowyVIQF9DnJGcP3npXt98fWY8WXQHVpk9z1uhQHpNJ9xmFqGjq3LS/AnlZpQvGPN++cZAU9po9jOnodW0MSDWfhfhlGKAV2cBrBEMcLYWPDIOSV5v53yWzHgGlnFKEl6lBxLgW3BORiUDLELmSWxyNS+WBeU2vkNiOlRex56jMQBwPl+7cVMQ9XudmcYY51Diz8+9owfxxIeNzDBp1MTWwI= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(520078)(5005006)(3002001);SRVR:DM2PR07MB624;BCL:0;PCL:0;RULEID:;SRVR:DM2PR07MB624; X-Microsoft-Exchange-Diagnostics: 1;DM2PR07MB624;4:GXkhOG/bhf47ylpz36MsyC8sL4aLNYFUR08UPtZY6JgctBubXUXL4SZ+uXiAIUi3hIQI23H+1iOG4nwooIbPJpSWkVZBpel7xOwBv3fhj7uolLqW1Upnlg5q39ZAAEGFg08dzKleIyHOjebmUOWi88cQ0NwzjiWEZiA8QDd7RVKHCeGmQAkff62P9F/GMYzVbDwSPPxXwNvkQ7ib0GflxeXJt2Ascf3tOVgMxVSX9xH6X19BxezDxmJ8O3MsngireDnJkBYHqT2Q9d0u5FHhNNpMp37MQ3PyOpF5rLYMhWldZkkJMFmtnuuVm2uL8pAom+g6myQj7m7kDPObBjulc6Wz4EFJf8DsaqnPYme5v+Q= X-Forefront-PRVS: 0714841678 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6069001)(6009001)(199003)(189002)(42186005)(19580405001)(189998001)(50226001)(107886002)(87976001)(92566002)(46102003)(5004730100002)(5001960100002)(5007970100001)(97736004)(122386002)(19580395003)(101416001)(2201001)(50986999)(5001860100001)(47776003)(50466002)(76176999)(4001540100001)(48376002)(68736005)(81156007)(40100003)(5001830100001)(76506005)(5001770100001)(229853001)(36756003)(77156002)(2950100001)(77096005)(66066001)(64706001)(15975445007)(33646002)(105586002)(106356001)(5003940100001)(5008740100001)(62966003)(2004002)(2101003)(4001430100001);DIR:OUT;SFP:1101;SCL:1;SRVR:DM2PR07MB624;H:localhost;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DM2PR07MB624;23:z7oEfT+MdMeM9oZUxbdl6///M9jgIYLdbzm22ZXk2k?= =?us-ascii?Q?9sag9PRsRzhR6fhZRqQVVuI+5vvUP8j+9qY67n8Fre9s3fSQ9hkfea1iA6gy?= =?us-ascii?Q?bLjUBwIciM4ogvGUWk09pzILm9OUfjkK8g9ruqxfdiEUk3VxIEPqmDBbsia5?= =?us-ascii?Q?LQ6VLiHtzrGsx3Prlqme5z32z5vO+BNsr1k/nYBWW9OYkB7CFLU5y/YNDFVX?= =?us-ascii?Q?CC8nnM1Z/ZwYDlnz93EHccdY1Hgh5+Sp4txgAz6xOhkS7q6aWBPHmVkkS7BV?= =?us-ascii?Q?oJ1ElaZe0B8ACAj7/EzhoetxoMxhe0D87LmhT7Q5+ZDgXu97tV3mrkUBxCxM?= =?us-ascii?Q?Z3kqUQUir2U/LSOWxaONkuB8BLC9+ouG8T9D2ZFDbajqZHSdhUJHhHJedu1y?= =?us-ascii?Q?sAUYeP1HAEb9BnPj5mAh3gh8yoD+zQm7IK/o1/Nr01tE2d6LSqXDN+PrSMGH?= =?us-ascii?Q?+uWZwvgCN9xldiUNuaAHJLZXCBWu4LMSWIgp8vO/bxmczQqzXN8U8BnJCZeY?= =?us-ascii?Q?CCKoz8ltQUvP94T9TWtO2s+0zEB4CTlQE//aplHItkQrazyeKA9ywtBjmYPt?= =?us-ascii?Q?jeZ0saU+pEvcAgvbnyGiCHhsErNxXnwVw954iA1xiBpzb07PfSbc/AfU2B2Z?= =?us-ascii?Q?lVff2vGAlWN4JhYxk6zX3Tof5NRS1oLwdCHIrUUPhKq1jPZllPVXFqY4SJrM?= =?us-ascii?Q?pqxIQbYYP48x17kO7gxSjH8DZketg18h53v6ZbbEBtNcNkW3WD+AxWrkccsF?= =?us-ascii?Q?BwwoAtrnYB/3JblTySDfEyjHkAegQrX5BGFvajcnVzjlet+A7LQfHWGXwqdC?= =?us-ascii?Q?HfJnUaBIhFGGB5kNffh/JSHGT0930DWegn3Ne0RgqHbZmRvFpPoTaH8sjpji?= =?us-ascii?Q?Cj/LqpSxnaLyym48xLdL4go+tIUL7wp9OIAlslJNtHPZwRj7Iuh9jJJ766DG?= =?us-ascii?Q?MuiyIs/7BhLcjjGIuqNE1LMo7wuT8tIzFtzQp7gpvw+Ne7lUtpLbpk0Dusm1?= =?us-ascii?Q?04jkUkkX4v4lA5EJ7uK0uJaeziKmlxBE72xRGE4KafFKnorpLsgLka6Xpoun?= =?us-ascii?Q?v8pBV03Omp9AqtsUE5D9R2vqlmNa2AlAAQDhEcVq+pRgde4COuqFp4qzAoZ3?= =?us-ascii?Q?gAup2cF4K5XlLznahwlG3JZm9gV4XZggEmJouJSTD4iwlYHyjTJ3fSIQ2AgN?= =?us-ascii?Q?OI0klPoRedT4bXlo3rAN699yI288gy80/yKvFPKBXmS4JXxRIeWpuCEfgl8r?= =?us-ascii?Q?BguZpZ45JpRhE1cVDDkSmwMrJwkXmbbJkgFWAqZj1Br/oWwPQNhOmLlps12Y?= =?us-ascii?Q?TsqUL8Ct22XB96QOaF8LuxtrcynK404MnJ2/A9Da18AK87l3bGrTYnfrQt/y?= =?us-ascii?Q?kgAg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;DM2PR07MB624;5:PXznRxqE2UShkOjyifM3hk+ROon3wbaKoBkrayY4JkOJ5lg0siTrwbcdDYB+iL0nS/vQIBcCYwxW6G2I2E33F4PpYTN2XrCeudRQMph2iuDkqgiZ9xLidy67rFX9yDsqcNi0/fcOtlGDo1hJWw8b8g==;24:wmf9VRsGngJWlyQVxn+m6fDFdSlYfEHOQgANN7+V4cggIFQNxupkiZncIa+avYzauH33iH8q8XXNwQLG969M3eWfecibNWZfwVllSmWxamo=;20:xBAN9Sb1bxRUbV1URhxaqsDWl5QwGkXCJ4b3SHHQzwlylYL8SkaDvFVS2SwL63HB+nM5QzXKYfYL+Xwu8UbvnA== SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Sep 2015 22:18:06.7329 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM2PR07MB624 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Philipp Tomsich Adjusted to move the move data page before code pages in sync with commit 601255ae3c98fdeeee3a8bb4696425e4f868b4f1 Signed-off-by: Philipp Tomsich Signed-off-by: Christoph Muellner Signed-off-by: Yury Norov create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile copy arch/arm64/{include/asm/vdso.h => kernel/vdso-ilp32/vdso-ilp32.S} (56%) 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..84050c6 100644 --- a/arch/arm64/include/asm/vdso.h +++ b/arch/arm64/include/asm/vdso.h @@ -29,6 +29,10 @@ #include +#ifdef CONFIG_ARM64_ILP32 +#include +#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 1470332..ff60c2f 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -38,6 +38,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 @@ -45,3 +46,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 2e00531..8eb8ed9 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -241,6 +241,10 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, if (ka->sa.sa_flags & SA_RESTORER) sigtramp = ka->sa.sa_restorer; +#ifdef CONFIG_ARM64_ILP32 + else if (is_ilp32_compat_task()) + sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32); +#endif 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 +# 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/include/asm/vdso.h b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S similarity index 56% copy from arch/arm64/include/asm/vdso.h copy to arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S index 839ce00..46ac072 100644 --- a/arch/arm64/include/asm/vdso.h +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S @@ -12,30 +12,22 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . + * + * Author: Will Deacon */ -#ifndef __ASM_VDSO_H -#define __ASM_VDSO_H - -#ifdef __KERNEL__ - -/* - * Default link address for the vDSO. - * Since we randomise the VDSO mapping, there's little point in trying - * to prelink this. - */ -#define VDSO_LBASE 0x0 - -#ifndef __ASSEMBLY__ - -#include -#define VDSO_SYMBOL(base, name) \ -({ \ - (void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \ -}) +#include +#include +#include +#include -#endif /* !__ASSEMBLY__ */ + __PAGE_ALIGNED_DATA -#endif /* __KERNEL__ */ + .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: -#endif /* __ASM_VDSO_H */ + .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..ac8029b --- /dev/null +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S @@ -0,0 +1,98 @@ +/* + * 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 . + * + * Author: Will Deacon + * Heavily based on the vDSO linker scripts for other archs. + */ + +#include +#include +#include + +/*OUTPUT_FORMAT("elf32-littleaarch64", "elf32-bigaarch64", "elf32-littleaarch64") +OUTPUT_ARCH(aarch64) +*/ +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.39 { + 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 b239b9b..bed6cf1 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. */ @@ -117,24 +123,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 inline 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; @@ -143,7 +154,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) { @@ -158,16 +169,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; + 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; @@ -179,7 +220,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; @@ -188,7 +229,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.1.4