From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753558AbcEXAGm (ORCPT ); Mon, 23 May 2016 20:06:42 -0400 Received: from mail-bl2on0093.outbound.protection.outlook.com ([65.55.169.93]:47349 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753130AbcEXAGh (ORCPT ); Mon, 23 May 2016 20:06:37 -0400 Authentication-Results: arndb.de; dkim=none (message not signed) header.d=none;arndb.de; dmarc=none action=none header.from=caviumnetworks.com; From: Yury Norov To: , , , , , , , CC: , , , , , , , , , , , , , , , Subject: [PATCH 22/23] arm64:ilp32: add vdso-ilp32 and use for signal return Date: Tue, 24 May 2016 03:04:51 +0300 Message-ID: <1464048292-30136-23-git-send-email-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1464048292-30136-1-git-send-email-ynorov@caviumnetworks.com> References: <1464048292-30136-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [50.233.148.158] X-ClientProxiedBy: DM3PR13CA0019.namprd13.prod.outlook.com (10.164.193.29) To CY1PR07MB2230.namprd07.prod.outlook.com (10.164.112.144) X-MS-Office365-Filtering-Correlation-Id: 8b1e2220-af01-43ad-df5f-08d383674109 X-Microsoft-Exchange-Diagnostics: 1;CY1PR07MB2230;2:fKSIubQwglsUQSrQOzaLwYC4959rmZ8DWEHicMvRh4+H4kTVUcRlFU3pLeYQFk33VPLt/RATIuas3Q1+oqny+4CLnyFsWcZXA+X3Eb9oYqBDwPrHFdVAVG2kKuBIhKdzFi1W5dgf8x+8de/QJDnQPIA+hR7iZDL9FTCpLXAL4VHOWAPFuVG/PffVT8UXj/hb;3:joN34pDes9KVfzc6m6+ahufeALtTzbmsRJV22BQF36wyHlaxV3Cf5wwbM0Qx6fW1uUWjPnHxvl0cfozksEQ32IjszCUiSC6ZAKFxLhXUn1gZPkvS3LIx+E9q/zPw8tQQ;25:9U+K8Mks69gLgxHYZX2f42QwaqE3jC622+CvrO4hn8dXIj4xrnLLJJSLMumFIQ0x2+DnbQdVX8GFg/25MbqJV7oJmJaoczwYOADUGJjbud7OOFH1ykJR53Ua0DJbT+TUdvzyn6con+eRgi3Dp86xYV/PHD2xqoNytNHdx3VSdtZC4kKYX4MyXt57Gqg4MGI/6vKuymSwRF6RMU+HeRfzD8V5QUbKaXzX7yn21HtEy1l9O1/mZJ28O0QvNzkNkpXimnoYwU3zV0tC0k04YVaIA1aL7rXcnhxfc65UeeBhk+fcfYK5jHmTpWN+/qh9r0s9BVTwLRDCRLPJgo+B3A40iej30ELZtx8NHdFVxn/lyJCfuHebKw7CK75bWMbYL3jy2jsI93IAzLLxKigGxgUm5Ai8pWAXTaUf4i/kIot0P7c= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CY1PR07MB2230; X-Microsoft-Exchange-Diagnostics: 1;CY1PR07MB2230;20:OEwzQGFYQeUIDMOYA5gmy+gKUKTbUgCiLSIVfPtVEJT6kKoImuEKrMXVo/CMva/PFo6fcl8MOU/Lus9SSvn0C5zjf9A/OJruGI/SOgEDLWYiSnhjYRTIyJNvgr1qT39oKw5kma0EPbPwMbLTsACbLWZDCwBgg7no7TIAYZjCWAQN4/k8FjFFEixLr+nPUQId1IPm9NtrxlVUUgYAW45mIg9aUtc0Yhp4+gc6fxOy1OnKX08J+SgtsQU0vNG/m7NkpSAT5kV6O8df2drznR4Dqk3GWzoyQi+Ygd6NDIahSjaDB8Q5sEVXKRsZRG4o3flmP4P9SKgG8YOJLj2nGBvRI7TpPbupb8GvO3USkG/LkrncZ5pmZtoHLsS3wUMsBFPpMdTG74H2AnyOzrDNQE3XE2aFM7+eqjdyU6/1Qkjqc/A6xN8Sa67lgEd3v4AcOHMQZbNZbv4rfTPwpv5TA+Hi7bhLfDeWux3fVAqe0vziC8XHfjVwF5PV5KI66ALPVufNulW2x9yAh6e5fxtd7280ky42/ScHKN2Eu9pdF+FT+lbWaE3kTdE41FrORUNYxJPW3NgQfuahht5lLhHdEWa7divgE+By0AkxyMJudujG6wc= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001);SRVR:CY1PR07MB2230;BCL:0;PCL:0;RULEID:;SRVR:CY1PR07MB2230; X-Microsoft-Exchange-Diagnostics: 1;CY1PR07MB2230;4:ba0Cpexg8t6EbGa9Zn2RaImdZcQBWV07AhRMlUo2RYU7im8KUpfI5BmtJZ5d33qy/roY5ULusU/RpPtEYOtSri+9szTxCv7mm2Ge6ySIj58c+HNUyVqfPsnxuIt234EHOZ6s1o3H3mjzuquOOJjpzcea1+R6KZe3KM1uBzqYe7CeSHf/QqSgLSyIBQgS9ILktMghaWLMr6Stlm4jsOnCWTZuPOvr8uEEBTLPNhAUcaU/4ltf7l9B4ia+CGKPEDewSVAClLQuPAzi4fUP94kQCB4N4G4NO7MFdnr2WdlWeYIZf9vaMH0Em801I69U1VWAT3IgIi1ErNXmC6TBhbv+DguUEbR/7Yl042Cu0rXY4X4= X-Forefront-PRVS: 09525C61DB X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(19580395003)(36756003)(5004730100002)(19580405001)(5008740100001)(2906002)(229853001)(2201001)(586003)(47776003)(33646002)(4326007)(66066001)(6116002)(76506005)(42186005)(92566002)(15975445007)(77096005)(2950100001)(189998001)(5001770100001)(81166006)(5003940100001)(76176999)(50986999)(50226002)(50466002)(48376002)(8676002)(2004002)(2101003);DIR:OUT;SFP:1101;SCL:1;SRVR:CY1PR07MB2230;H:localhost;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;CY1PR07MB2230;23:mXOj1tK+31tqeY091+u+Mb4V+cLRO80LvF0KNGagMEWPGmkCrRN41J9KcB1Bu1JplcGQj7KcosFQ//LP5IAesk6kmCDy7c1/wYSmc6FD9/vV/JZHMclJ/zJiHGH2U5tH9HfeH/HMjpW+jYjl1pTRG4UMavOIf/AXWMS5TkVPpUFmXP2rQklGYAjHLRjDl44IzwKCivFRQcnaNi9hVgWj1ANIV+HdHvnEuLOBdd79MCBUHim3f19Z0Di2UPDP+pQpdlDnolI0DH3fTvCPSevtJqPEs1gGztGXsBrFDhG6sClGXoyufk46tIhMTdkC2lRbmv1K/Rr6NnvXz1AGtLfnJ05jtqoxFuRbxpP63hAPjFuEK4sQy24SP5TtFRnZ5HVatnEuDhRg8KFcqbCi+15ILB2mnem5Bs1+VwoDU2qEI4YVJgLj6RMxBY9+LXP/jmt8Ew73CdL22SPtk4XzSjholpVBSoRgX4UcQnQXxq4URYVvyH9D9DZLHO+Q3Z1mm8oVLAJ9n8rRCMR6JNSv00Ev5VP7UPducM9pT2b1+p833KJbP3ugfi966dtWsEWW7uhjhhpk5tFfAz16QYzKhElMoiCEyUCDlvDNlatuLyBVNNjrUCXHzbX9Ey0g3KXSu3mwFYKImKVtB6AWftajAxjW5SWsKh81in/8K1WzKec1wOGuDRbYIcec/tuCrg2uw4AcEPvDEju+E6sUwQMXm/jq8gL9ucBEKm3PYW2rpdGPBddDAs7dofBF09hQVVaHpbyLxt/uCziyZg0xVVc9ua8LhXRIpwDxsIzRaO+p6MGklL9JVGJw37vJgAnXTsmrDltU7RUhoYplJa83kjlJ/ZncvT9uFl2/xKm39l7Ho7SiViin8PaX+FMuCOxurnHIm1pJYh4Nz/H8CVkNxwZi1praVyTWlH8TyTPhsS0iu7GXxEaxmq7VOiMlkrp/sapoZpHi X-Microsoft-Exchange-Diagnostics: 1;CY1PR07MB2230;5:UH3G0ZZClAETGQkX3YwCiuac2ZtbV/Qr/6ucEJSYTPSLUPLVqwjyQzjv3ETIgRdFzhYnXpOlhwRzzkDQYrpfM4ZWW0oDuHTErKvvJfsXQhFiIXhME6Pw4QfTcrzU8im1esGrLyLtfOMb9wZMPOKH4g==;24:CneD5oAHG0jqza6QzfL/VTw1S0LGtnwsp9pSHDJIZc7nVOVCXqGxAFCRMn5pBFcxmgTtU1+r38hMvxSgw0LG9IBX2Gy5VOcPP50yGzNNNYA=;7:e2RPiz24FYj9Ow9O7NE2wCvP7QTb06UVbNcH+zrXqETcRuVr/t0Wq1jrDUECKkoLJyimQ5MyBE7BsmOYmABEt4rKIRqrPj/1v4o0GrrSqBRIZ8mzHDIQ4HWVJjBH1IksQNh+kpEuGxDjpjkUMX2TPjhFB46VApnY2CBAfdtJ0AFAQa+oG4L40Om0CyqLJLmg SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2016 00:06:28.3366 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR07MB2230 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Philipp Tomsich 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 Signed-off-by: Christoph Muellner Signed-off-by: Yury Norov --- arch/arm64/include/asm/vdso.h | 6 ++ arch/arm64/kernel/Makefile | 7 ++ arch/arm64/kernel/asm-offsets.c | 7 ++ arch/arm64/kernel/signal.c | 2 + arch/arm64/kernel/vdso-ilp32/.gitignore | 2 + arch/arm64/kernel/vdso-ilp32/Makefile | 74 +++++++++++++++++++++ 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 ++++++++++++++--- arch/arm64/kernel/vdso/gettimeofday.S | 20 +++++- 10 files changed, 294 insertions(+), 13 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 +#ifdef CONFIG_ARM64_ILP32 +#include +#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 09e4373..e98add5 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -50,6 +50,7 @@ arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.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 @@ -57,3 +58,9 @@ 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 + +ifeq ($(CONFIG_ARM64_ILP32),y) +# 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 +endif diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index e229525..af69b81 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -101,6 +101,13 @@ int main(void) DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec)); DEFINE(TSPEC_TV_NSEC, offsetof(struct timespec, tv_nsec)); 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(); diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 45bcd96..933cdcf 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -264,6 +264,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..0671e88 --- /dev/null +++ b/arch/arm64/kernel/vdso-ilp32/Makefile @@ -0,0 +1,74 @@ +# +# 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) + +# 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)/$@.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 . + * + * Author: Will Deacon + */ + +#include +#include +#include +#include + + __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..1dde31f --- /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 . + * + * Author: Will Deacon + * Heavily based on the vDSO linker scripts for other archs. + */ + +#include +#include +#include + +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.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; diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S index efa79e8..a2d8a70 100644 --- a/arch/arm64/kernel/vdso/gettimeofday.S +++ b/arch/arm64/kernel/vdso/gettimeofday.S @@ -25,6 +25,16 @@ #define NSEC_PER_SEC_LO16 0xca00 #define NSEC_PER_SEC_HI16 0x3b9a +#ifdef __LP64__ +#define PTR_REG(n) x##n +#define OFFSET(n) n +#define DELOUSE(n) +#else +#define PTR_REG(n) w##n +#define OFFSET(n) COMPAT_##n +#define DELOUSE(n) mov w##n, w##n +#endif + vdso_data .req x6 use_syscall .req w7 seqcnt .req w8 @@ -51,6 +61,8 @@ seqcnt .req w8 /* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */ ENTRY(__kernel_gettimeofday) .cfi_startproc + DELOUSE(0) + DELOUSE(1) mov x2, x30 .cfi_register x30, x2 @@ -68,7 +80,7 @@ ENTRY(__kernel_gettimeofday) mov x13, #1000 lsl x13, x13, x12 udiv x11, x11, x13 - stp x10, x11, [x0, #TVAL_TV_SEC] + stp PTR_REG(10), PTR_REG(11), [x0, #OFFSET(TVAL_TV_SEC)] 2: /* If tz is NULL, return 0. */ cbz x1, 3f @@ -88,6 +100,7 @@ ENDPROC(__kernel_gettimeofday) /* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */ ENTRY(__kernel_clock_gettime) .cfi_startproc + DELOUSE(1) cmp w0, #CLOCK_REALTIME ccmp w0, #CLOCK_MONOTONIC, #0x4, ne b.ne 2f @@ -159,7 +172,7 @@ ENTRY(__kernel_clock_gettime) 6: /* Store to the user timespec. */ lsr x11, x11, x12 - stp x10, x11, [x1, #TSPEC_TV_SEC] + stp PTR_REG(10), PTR_REG(11), [x1, #OFFSET(TSPEC_TV_SEC)] mov x0, xzr ret 7: @@ -174,6 +187,7 @@ ENDPROC(__kernel_clock_gettime) /* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */ ENTRY(__kernel_clock_getres) .cfi_startproc + DELOUSE(1) cmp w0, #CLOCK_REALTIME ccmp w0, #CLOCK_MONOTONIC, #0x4, ne b.ne 1f @@ -187,7 +201,7 @@ ENTRY(__kernel_clock_getres) ldr x2, 6f 2: cbz w1, 3f - stp xzr, x2, [x1] + stp PTR_REG(zr), PTR_REG(2), [x1] 3: /* res == NULL. */ mov w0, wzr -- 2.5.0