From patchwork Tue Sep 17 12:43:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Russ Dill X-Patchwork-Id: 2902341 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.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 252D8BFF05 for ; Tue, 17 Sep 2013 12:46:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A8F2B2038E for ; Tue, 17 Sep 2013 12:46:40 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 48B2E20378 for ; Tue, 17 Sep 2013 12:46:36 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VLuem-0000mc-9b; Tue, 17 Sep 2013 12:45:29 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VLueV-0004Dg-73; Tue, 17 Sep 2013 12:45:11 +0000 Received: from mail-pa0-x231.google.com ([2607:f8b0:400e:c03::231]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VLudo-00045t-DG for linux-arm-kernel@lists.infradead.org; Tue, 17 Sep 2013 12:44:34 +0000 Received: by mail-pa0-f49.google.com with SMTP id ld10so6687567pab.8 for ; Tue, 17 Sep 2013 05:44:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=sSHhQABwcafBoAOKTARpxLd+oxZ17gK7EjRXyRW/mFc=; b=0Z5k8Ce4PBVAgzyAY6eCvOp+9d1PiALK2IkbTYh83sru9Z+/uwqCb6KxUrJbZG6D42 JTt1LvPGss8u7boVNTYv2fD4/avAJQhaI5YEmJlfOO93dE/uUp1GlAdnoU/V7CcAddXF Dc6vyQEs4Ga77F58BcGBEXXXtEddZ/OFm17YAHqg3pMGE6IlqW9k9Zv5W7RTohUwHYVV 6DlgdWRtb0sB98V4MD+HPOELgZoaRFZH7Yf0Dgdtw7oA0Y/SZOGT9dXViGNuf/eB0U9I SyCDu8cjmNmQ2c1i7di0lXBeJvO1509Xrn2/UaQdDafrJLI1A7eSakmtGl3W90xM10JR LoFQ== X-Received: by 10.68.189.70 with SMTP id gg6mr13306923pbc.123.1379421846944; Tue, 17 Sep 2013 05:44:06 -0700 (PDT) Received: from localhost (pool-71-189-49-9.lsanca.fios.verizon.net. [71.189.49.9]) by mx.google.com with ESMTPSA id yo2sm45843234pab.8.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 17 Sep 2013 05:44:06 -0700 (PDT) From: Russ Dill To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-omap@vger.kernel.org Subject: [RFC PATCH 07/11] ARM: PIE: Add support for updating PIE relocations Date: Tue, 17 Sep 2013 05:43:33 -0700 Message-Id: <1379421817-15759-8-git-send-email-Russ.Dill@ti.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1379421817-15759-1-git-send-email-Russ.Dill@ti.com> References: <1379421817-15759-1-git-send-email-Russ.Dill@ti.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130917_084428_711672_9971B231 X-CRM114-Status: GOOD ( 21.10 ) X-Spam-Score: -1.9 (-) Cc: mans@mansr.com, Russell King - ARM Linux , Ard Biesheuvel , linux-kbuild@vger.kernel.org, Shawn Guo , Dave Martin X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 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.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,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 This adds support for updating PIE relocations under ARM. This is necessary in the case that the same PIE must run both with virtual mapping (MMU enabled) and physical mapping (MMU disabled). Signed-off-by: Russ Dill --- arch/arm/include/asm/pie.h | 42 +++++++++++++++++++++++++ arch/arm/kernel/pie.c | 9 ++++++ arch/arm/libpie/Makefile | 2 +- arch/arm/libpie/relocate.S | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/pie.h create mode 100644 arch/arm/libpie/relocate.S diff --git a/arch/arm/include/asm/pie.h b/arch/arm/include/asm/pie.h new file mode 100644 index 0000000..977f11d --- /dev/null +++ b/arch/arm/include/asm/pie.h @@ -0,0 +1,42 @@ +/* + * arch/arm/include/asm/pie.h + * + * Copyright 2013 Texas Instruments, Inc + * Russ Dill + * + * 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. + */ + +#ifndef _ASMARM_PIE_H +#define _ASMARM_PIE_H + +#include + +#ifdef CONFIG_PIE +extern void __pie_relocate(void); +extern void __pie___pie_relocate(void); + +#define pie_relocate_from_pie() \ + __asm__ __volatile__("bl __pie_relocate\n" \ + : : : "cc", "memory", "lr", "r4", "r5", "r6", "r7", "r8", "r9"); + +static inline void pie_relocate_from_kern(struct pie_chunk *chunk) +{ + void (*fn)(void) = fn_to_pie(chunk, &__pie___pie_relocate); + __asm__ __volatile__("" : : : "cc", "memory", "r4", "r5", "r6", + "r7", "r8", "r9"); + fn(); +} +#else + +#define pie_relocate_from_pie() do {} while(0) + +static inline void pie_relocate_from_kern(struct pie_chunk *chunk) +{ +} + +#endif + +#endif diff --git a/arch/arm/kernel/pie.c b/arch/arm/kernel/pie.c index 5dff5d6..598562f 100644 --- a/arch/arm/kernel/pie.c +++ b/arch/arm/kernel/pie.c @@ -12,10 +12,12 @@ #include #include +#include extern char __pie_rel_dyn_start[]; extern char __pie_rel_dyn_end[]; extern char __pie_tail_offset[]; +extern char __pie_reloc_offset[]; struct arm_pie_tail { int count; @@ -72,12 +74,19 @@ int pie_arch_fixup(struct pie_chunk *chunk, void *base, void *tail, unsigned long offset) { struct arm_pie_tail *pie_tail = tail; + void *reloc; int i; /* Perform relocation fixups for given offset */ for (i = 0; i < pie_tail->count; i++) *((uintptr_t *) (pie_tail->offset[i] + base)) += offset; + /* Store the PIE offset to tail and recol func */ + *kern_to_pie(chunk, (uintptr_t *) __pie_tail_offset) = tail - base; + reloc = kern_to_pie(chunk, + (void *) fnptr_to_addr(&__pie___pie_relocate)); + *kern_to_pie(chunk, (uintptr_t *) __pie_reloc_offset) = reloc - base; + return 0; } EXPORT_SYMBOL_GPL(pie_arch_fixup); diff --git a/arch/arm/libpie/Makefile b/arch/arm/libpie/Makefile index 5662e99..b1ac52a 100644 --- a/arch/arm/libpie/Makefile +++ b/arch/arm/libpie/Makefile @@ -3,7 +3,7 @@ # ccflags-y := -fpic -mno-single-pic-base -fno-builtin -obj-y := empty.o +obj-y := relocate.o empty.o obj-y += lib1funcs.o ashldi3.o string.o # string library code (-Os is enforced to keep it much smaller) diff --git a/arch/arm/libpie/relocate.S b/arch/arm/libpie/relocate.S new file mode 100644 index 0000000..70cc36e --- /dev/null +++ b/arch/arm/libpie/relocate.S @@ -0,0 +1,76 @@ +/* + * arch/arm/libpie/relocate.S - Relocation updating for PIEs + * + * Copyright 2013 Texas Instruments, Inc. + * Russ Dill + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include + +/* + * Update relocations based on current pc + * + * On exit: + * r4-r9 corrupted + */ + +ENTRY(__pie_relocate) + /* Calculate offset of our code compared to existing relocations */ + ldr r4, pie_relocate_address + adr r5, __pie_relocate + subs r6, r5, r4 + moveq pc, lr /* 0 offset, no need to do anything */ + + /* Base of PIE group */ + ldr r7, reloc_offset + sub r5, r5, r7 + + /* Calculate address of tail */ + ldr r7, tail_offset + add r7, r7, r5 + + /* First byte of tail is number of entries */ + ldr r8, [r7], #4 + add r8, r7, r8, lsl #2 + + /* + * r5 - current base address of PIE group + * r6 - fixup offset needed for relocs + * r7 - relocs start + * r8 - relocs end + */ + +1: + cmp r7, r8 + ldrne r4, [r7], #4 /* Load next reloc offset */ + + addne r4, r4, r5 /* Calculate address of reloc entry */ + ldrne r9, [r4] + addne r9, r9, r6 /* Fixup reloc entry */ + strne r9, [r4] + + bne 1b + + mov pc, lr +ENDPROC(__pie_relocate) + +/* + * This ends up in the .rel.dyn section and can be used to read the current + * relocation offset + */ +pie_relocate_address: + .long __pie_relocate + +/* Offset from PIE section start to reloc function */ +.global reloc_offset +reloc_offset: + .space 4 + +/* Offset from PIE section start to tail */ +.globl tail_offset +tail_offset: + .space 4