From patchwork Thu Jan 7 23:34:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 7980771 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 96F57BEEE5 for ; Thu, 7 Jan 2016 23:48:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 21B9C20149 for ; Thu, 7 Jan 2016 23:48:22 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9B0B92010E for ; Thu, 7 Jan 2016 23:48:20 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aHKGN-000357-Vp; Thu, 07 Jan 2016 23:46:40 +0000 Received: from mail-bl2on0054.outbound.protection.outlook.com ([65.55.169.54] helo=na01-bl2-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aHKBB-0004mn-Mh for linux-arm-kernel@lists.infradead.org; Thu, 07 Jan 2016 23:42:24 +0000 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Yuri.Norov@caviumnetworks.com; Received: from localhost (95.143.213.121) by DM2PR07MB622.namprd07.prod.outlook.com (10.141.177.146) with Microsoft SMTP Server (TLS) id 15.1.361.13; Thu, 7 Jan 2016 23:40:54 +0000 From: Yury Norov To: , , , Subject: [PATCH v6 19/21] arm64:ilp32: add vdso-ilp32 and use for signal return Date: Fri, 8 Jan 2016 02:34:37 +0300 Message-ID: <1452209679-19445-20-git-send-email-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1452209679-19445-1-git-send-email-ynorov@caviumnetworks.com> References: <1452209679-19445-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 X-Originating-IP: [95.143.213.121] X-ClientProxiedBy: AM3PR01CA045.eurprd01.prod.exchangelabs.com (10.141.191.35) To DM2PR07MB622.namprd07.prod.outlook.com (10.141.177.146) X-Microsoft-Exchange-Diagnostics: 1; DM2PR07MB622; 2:w6qipnl7pL1DbMrPs9lK9JL5D2LnKbrGhqmgH//xdMlM2LKT+abbsRfAD3nYBKXX/3iDjvp/mvJkypBuMdQc01jJ6NB2lhb4QY6oyBgOzyhr8ipl14UHWGdIoJfve8AQ6s9STaOe+j3fPm3EDZiVGQ==; 3:AFx1I6JxlOPT9rtc+q8/lEYQPUJGtT9z5MvBrEtvyxjBRIzJ623bih3KrDtNWe1NuzceBF02+2/8VxMvfJ2P7hU6RpgXgM/F23keELU06bGKHi/IY8jvcCXnZ5oBtuW0; 25:dFipWoX5u4umXtuA57HC5KnGG0EfPgj9nboWtYqSu1cUMGrPrz1+EQG+TZu4TATspcJvSM41TkZ8gBx5IUXFkg4YZoypnzBGDaNBPBH/onf9ZjD6GcDIaQ0uQTJo6WYN+8ZIgiHWTQkTOCTSP0I7ML70ouJXmne9vh+sXT8DxOERMCgr9MAvpEs+SUIDUOQ2YLa58Gun698dIfT6pOgYvgQzMiQImq9M7pGkl7gHALrZnK3Y8hA0a7hWQFw9mJq/ X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DM2PR07MB622; X-MS-Office365-Filtering-Correlation-Id: 5651ab4a-f585-42a9-57bb-08d317bbfc24 X-Microsoft-Exchange-Diagnostics: 1; DM2PR07MB622; 20:gYGHvKLb82ZJxxlZct3RogpWFpbqcrfhf3f1e0ZHHP0cAY8dvwYCMrAXUym/yLVMOoQEbSh6JkUqdIckaUD4RNWybp9p2uYtmhh2pjnKdDcyh5O6UkaeZRtWb+lNE9XT312WQJKK+6+U+ALYoU2RfDwNPqut+McScVbXg34DIOAbe+QFZ2tW2T8SkAYtjxg/ULy203qf2HtPhzChz/5a2XnMAPKZJf9jlxBptZsa1qWS17rdRObyPOQWP/0YU1iitpYA3ik1SrnhX5sIj2MUhPEp4468/Ut4n9HINKfUHYDFw8rBfSFANg14FoZaoSHQwaSlqlkJaqRS9kMgfCMX45gm6JcKTY9FZzCAi5t5w818DZf5our29obs9n//SvkVKyV8gSZAg+dzkngCZkSu6bcrwH6QrZay+NjHRJ+d2i90RJy9t4rqFJAhVE6CrYqs0KuzGB0RXnS3kaJSSofHpPjx1HSnSX28IkZHv/vVbjzRoB7YHYNp1VR63OjiLeiyNz5GuMIjxwWORsq1z/EQ3PNvsWutEhwu4TYMpYEVishes4Q9Mf3rH+zgATVTMM5uYaEAdSUJ46QIwnGCsv9lfrfxKtv657iKs8SxgEGQvbk= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(236414709691187)(180628864354917); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(5005006)(520078)(8121501046)(3002001)(10201501046); SRVR:DM2PR07MB622; BCL:0; PCL:0; RULEID:; SRVR:DM2PR07MB622; X-Microsoft-Exchange-Diagnostics: 1; DM2PR07MB622; 4:Cfcp+h6ZXThgQNMYhZ1X8mnTALSV4RlVzKUqckHv1hsRkBVdeN5jDrCXKsRHby82pV3mcXu4s+jhuWfDktExNAJ/RX/dyWpeW0pN9AQ/sn3KbDGy3VSHp8Vj+zEYRUqk/JR1AwBL6JCYqrHIZdPvyInlPDPMqCfSd34Lb1Jy3ueInRUWdakwdGiFFUXySQaNIhWxuNsLuEAUbcCzzZhsc9zXfzYvQ1eLKwxezu4HkQyyIw6l27YVOKHsvyCQuOcxzEXlNbcbzfiPmeKA5TiD1KvLw1gRZjbyTzVyZhb3mKz4om9lXn/iALrYQIBzWSb/2Hy26qWd4vpTCv//pQxwIHAOF7wxl75IwVa8LDpItkZCISNJH77gi8LIe7YYUlZwAsDX6tM4ZhnT2n08snmAT1mxZXYaF3xPmzPHI6C87at4XltEZrevoNSYxO3LRreRjks0gdQr9yc/scmBsG2akA== X-Forefront-PRVS: 0814A2C7A3 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(6069001)(189002)(199003)(101416001)(229853001)(50466002)(47776003)(92566002)(586003)(4326007)(5004730100002)(2201001)(87976001)(42186005)(19580405001)(2906002)(6116002)(1096002)(3846002)(50986999)(5003940100001)(5008740100001)(105586002)(76506005)(189998001)(76176999)(106356001)(15975445007)(2950100001)(122386002)(77096005)(36756003)(48376002)(40100003)(81156007)(97736004)(5001770100001)(19580395003)(66066001)(33646002)(5001960100002)(50226001)(2004002)(2101003); DIR:OUT; SFP:1101; SCL:1; SRVR:DM2PR07MB622; H:localhost; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: caviumnetworks.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM2PR07MB622; 23:dryVYy5MHx5l+ctJYkbRfLAXBv10Y+I81TGNNjNgiQ?= =?us-ascii?Q?sbpuQTjIfgv5kd+MtF2BVC5hKTPnWXL2NKq+IpR9Kiq5NYKRV2tgrwR239sg?= =?us-ascii?Q?DZiXIWxJNB8mUQENOkrakfnNdUL/tmXV2DoWRq8MePRXCB+1AKc75uCpt6lE?= =?us-ascii?Q?zMFjM+dtKdbknCqxwaoPjd/BARou4xITVb/ipJr/NDk5krxIIiFUlFTIDvnV?= =?us-ascii?Q?TP6ZWWNzRdpKQoXz54kMlDj2nlkcU2KpmxgLXysDgc4tLGNtSvqMpRr19Ngr?= =?us-ascii?Q?hclvKa68LqPT7rBfQNXsuWAGp8NbriUdxOZerBVNLgFLF7DxxAK9RuaXSZR7?= =?us-ascii?Q?66MjhiJ/Y48IBxAz/NqhT787DssWSBiRImWb95CelFZvVVkGf1p+kxk9HmtE?= =?us-ascii?Q?PhgRfuMQUFtEUjjE3JXJAjvsJSH1UY+oQ+OoKdTBLNojycO9nxK3GT5horVg?= =?us-ascii?Q?nU1fRz+hUvBe8Uyqfgd0oU8G1vJtLlvtYYhtnMZ7QkTmPp+dYcDneMU6OHCI?= =?us-ascii?Q?jjtLNgCIkO/Xdj8Z7F1VzHMGi8MptwmZ3AdRFDJvWyjpZb3aB/1/WB1jxIzJ?= =?us-ascii?Q?ZvoLhSZ7m8AcvhAz5Il1WimFLcmjeXJEx6wweoty9VVXp4yB/VMvvYFO2JCT?= =?us-ascii?Q?yAwfQnBwa5N5ZnvX+pipy5T0g42DPcIt1EOi60cUHQfK8FUNnIB9dhBSfw9e?= =?us-ascii?Q?BQ2dWhf8CkdYoh33x1vL2PbQ7Xu63Oayu473yWeuJgnfdndb+r1CpCLn/HJf?= =?us-ascii?Q?mbGDbmTtsxdiR80fGoGhOVbzb/D2tH/XDU0PmvTcVaS+wjJMCP8UacrqA1MO?= =?us-ascii?Q?tIxRAdJ8oIYlqmKFgpvZ1QlL/+YJSnTM9DvnQl5CvOZDnAMKf6mDT/aMhiQf?= =?us-ascii?Q?JC3mUTEeubHoxBDsofWglV1sc46rLi7Ab1dtIAHLpcfCc5ddwyJHG2RRyEP2?= =?us-ascii?Q?GAU0DzTYqR+c6HVNAXs5doH6ine8DFCuiY92xovvWvDC9hsXn6f+f0/Njp0s?= =?us-ascii?Q?zGWXqx1oBJaV6sCRug2oQ0E1yryKF+zfaGkpGm0L0XnNU5Ssj77CU7i01LY4?= =?us-ascii?Q?9vh7aeOeQ3Un2sJwJ4oq2+0V780w6m2RAGyt3YKi1ov1+5OsfhLjGOjMXMA3?= =?us-ascii?Q?DkZp6P9itQMrE+xw4Fu5wCT7Lh+n6HffLnkpsXiyeh9CLiBPTSTw=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; DM2PR07MB622; 5:naqBFJojXGhdNl+z1+wr+twRNDGTjArKamCvkn7SMwMafrLccEQ2LIV2SWXCmhVRKaA3rnAgUUWnUytMwRPDCMPDXFPY2HG2zY5flI6OTbl1bclJ3lKBFNOGvhtOtvVKrWSMfTWM1yUr8L+1OuYxvA==; 24:Dcc4YR7kPlfW2xwRSyK7DGdD9+WqczAzlt4y7MxVit2B1argkvZtQfi4UIIhVdRPu8Cs3LYuDw/P+vcFkOc/1Y5lTbfL9p5sUTrmOF0HRXc= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Jan 2016 23:40:54.2185 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM2PR07MB622 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160107_154119_141585_68C5B42B X-CRM114-Status: GOOD ( 15.16 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pinskia@gmail.com, Prasun.Kapoor@caviumnetworks.com, schwab@suse.de, broonie@kernel.org, Nathan_Lynch@mentor.com, agraf@suse.de, klimov.linux@gmail.com, ynorov@caviumnetworks.com, jan.dakinevich@gmail.com, ddaney.cavm@gmail.com, bamvor.zhangjian@huawei.com, philipp.tomsich@theobroma-systems.com, joseph@codesourcery.com, christoph.muellner@theobroma-systems.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 601255ae3c98 ("arm64: vdso: move data page before code pages"). 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 | 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 +#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 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 +# 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 . + * + * 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..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 . + * + * 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_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;