From patchwork Fri Apr 15 07:57:53 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 65883 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp1038932qge; Fri, 15 Apr 2016 00:59:17 -0700 (PDT) X-Received: by 10.98.102.151 with SMTP id s23mr26574613pfj.75.1460707157527; Fri, 15 Apr 2016 00:59:17 -0700 (PDT) Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id uj10si1756770pac.79.2016.04.15.00.59.17 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Apr 2016 00:59:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) client-ip=2001:1868:205::9; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) smtp.mailfrom=linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org 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 1aqydx-0002b3-Vb; Fri, 15 Apr 2016 07:58:21 +0000 Received: from mail-wm0-x230.google.com ([2a00:1450:400c:c09::230]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aqydu-0002L3-8T for linux-arm-kernel@lists.infradead.org; Fri, 15 Apr 2016 07:58:20 +0000 Received: by mail-wm0-x230.google.com with SMTP id l6so7861660wml.1 for ; Fri, 15 Apr 2016 00:57:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding; bh=5kXekJ/aLO3ResBEPWaY3lGrIcr0qnoHA/tBDs7ZT38=; b=V/5nN+GvnzJ6h1lCtD2SivXOxgH8hi6e+TleDPctCJUxiaNityYT1Y1lHqjhvOBt0e gqgQT92aozfd1qpq81w7jpd5xBE84GniLbtrhsWRveVWQD+vC4vdEDIQZ3T43tsusl1p o6J8WrReCf9SY0vet+PaWrcI8sq9KHI1jHbnc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding; bh=5kXekJ/aLO3ResBEPWaY3lGrIcr0qnoHA/tBDs7ZT38=; b=kLMp0WhU90J/0iYV7vKO3QOblbji0enBNjh2pgYUyXk4CdE9t2jF8LV9bznNZ+aBf/ LjIyQOoXb9Hqxv1/3CZDE/um8yAUxLm6aE5GlrDIHlE09TbU7qOU5zvF6DPH7xVkVwXd HRYWvw/dysWPouseXZ74j/CBV8ZjmVrLnpMDsVMlMQca4MCbKWTZ7EKd7mSm12QnEtFn dB27uAKFsDa9Sh1LI3PSFmOEcISoPDnnTNUfbOi6X2AybnA8JI/oYEBcNX49BeU2dhE7 pW1Cy9AiL1TKhE9bDwmZdoseK3I9ZBcChFbZnZZ3HaErAFmez/aqA12eHXz4lpEzhnsr 7S3g== X-Gm-Message-State: AOPr4FWPo4wxw8sEbylsqvFKyztusprY1bePaJeLCCkAEKF66KphtVEuD2Q0ydsUdwyNoO51 X-Received: by 10.28.73.70 with SMTP id w67mr2940824wma.28.1460707076653; Fri, 15 Apr 2016 00:57:56 -0700 (PDT) Received: from [192.168.20.36] ([195.55.142.58]) by smtp.gmail.com with ESMTPSA id o128sm10218770wmb.19.2016.04.15.00.57.55 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 15 Apr 2016 00:57:55 -0700 (PDT) Subject: Re: [PATCH v2 2/4] arm64: move early boot code to the .init segment To: Will Deacon References: <1459352589-28721-1-git-send-email-ard.biesheuvel@linaro.org> <1459352589-28721-3-git-send-email-ard.biesheuvel@linaro.org> <20160414163235.GE4584@arm.com> From: Ard Biesheuvel Message-ID: <57109F01.8010408@linaro.org> Date: Fri, 15 Apr 2016 09:57:53 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0 MIME-Version: 1.0 In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160415_005818_507244_F9231172 X-CRM114-Status: GOOD ( 22.17 ) X-Spam-Score: -2.7 (--) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-2.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [2a00:1450:400c:c09:0:0:0:230 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 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: Mark Rutland , Catalin Marinas , Jeremy Linton , "linux-arm-kernel@lists.infradead.org" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org On 04/14/2016 06:39 PM, Ard Biesheuvel wrote: > On 14 April 2016 at 18:32, Will Deacon wrote: >> Hi Ard, >> >> On Wed, Mar 30, 2016 at 05:43:07PM +0200, Ard Biesheuvel wrote: >>> Apart from the arm64/linux and EFI header data structures, there is nothing >>> in the .head.text section that must reside at the beginning of the Image. >>> So let's move it to the .init section where it belongs. >>> >>> Note that this involves some minor tweaking of the EFI header, primarily >>> because the address of 'stext' no longer coincides with the start of the >>> .text section. It also requires a couple of relocated symbol references >>> to be slightly rewritten or their definition moved to the linker script. >> >> [...] >> >>> ENTRY(stext) >>> bl preserve_boot_args >>> bl el2_setup // Drop to EL1, w20=cpu_boot_mode >>> @@ -223,12 +224,12 @@ ENTRY(stext) >>> * the TCR will have been set. >>> */ >>> ldr x27, 0f // address to jump to after >>> - // MMU has been enabled >>> + neg x27, x27 // MMU has been enabled >>> adr_l lr, __enable_mmu // return (PIC) address >>> b __cpu_setup // initialise processor >>> ENDPROC(stext) >>> .align 3 >>> -0: .quad __mmap_switched - (_head - TEXT_OFFSET) + KIMAGE_VADDR >>> +0: .quad (_text - TEXT_OFFSET) - __mmap_switched - KIMAGE_VADDR >> >> I'm struggling to understand why you need to change this. Furthermore, >> it looks like the gas docs for expressions require that addition/subtraction >> can only be performed on arguments that are in the same section, so >> this feels pretty rickety. >> >> What's the problem you're solving here? >> > > The problem is that this function is no longer in the same section as > _head aka _text, so the latter can only appear in the reloc expression > as a positive term, and the remaining ones will all be combined into > the addend. > Alternatively, if you prefer, we could move the relocation processing out of __mmap_switched() and run the code from the ID map, while accessing the relocations via the virtual mapping. That way, all the dodgy arithmetic (which actually doesn't look as dodgy anymore) is confined to #ifdef CONFIG_RELOCATABLE sections. Something like ------8<-------- _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 4203d5f257bc..f9eeb1936c38 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -222,13 +222,11 @@ ENTRY(stext) * On return, the CPU will be ready for the MMU to be turned on and * the TCR will have been set. */ - ldr x27, 0f // address to jump to after + adr_l x27, __relocate_kernel // address to jump to after // MMU has been enabled adr_l lr, __enable_mmu // return (PIC) address b __cpu_setup // initialise processor ENDPROC(stext) - .align 3 -0: .quad __mmap_switched - (_head - TEXT_OFFSET) + KIMAGE_VADDR /* * Preserve the arguments passed by the bootloader in x0 .. x3 @@ -437,44 +435,6 @@ __mmap_switched: bl __pi_memset dsb ishst // Make zero page visible to PTW -#ifdef CONFIG_RELOCATABLE - - /* - * Iterate over each entry in the relocation table, and apply the - * relocations in place. - */ - adr_l x8, __dynsym_start // start of symbol table - adr_l x9, __reloc_start // start of reloc table - adr_l x10, __reloc_end // end of reloc table - -0: cmp x9, x10 - b.hs 2f - ldp x11, x12, [x9], #24 - ldr x13, [x9, #-8] - cmp w12, #R_AARCH64_RELATIVE - b.ne 1f - add x13, x13, x23 // relocate - str x13, [x11, x23] - b 0b - -1: cmp w12, #R_AARCH64_ABS64 - b.ne 0b - add x12, x12, x12, lsl #1 // symtab offset: 24x top word - add x12, x8, x12, lsr #(32 - 3) // ... shifted into bottom word - ldrsh w14, [x12, #6] // Elf64_Sym::st_shndx - ldr x15, [x12, #8] // Elf64_Sym::st_value - cmp w14, #-0xf // SHN_ABS (0xfff1) ? - add x14, x15, x23 // relocate - csel x15, x14, x15, ne - add x15, x13, x15 - str x15, [x11, x23] - b 0b - -2: adr_l x8, kimage_vaddr // make relocated kimage_vaddr - dc cvac, x8 // value visible to secondaries - dsb sy // with MMU off -#endif - adr_l sp, initial_sp, x4 mov x4, sp and x4, x4, #~(THREAD_SIZE - 1) @@ -795,7 +755,6 @@ __enable_mmu: ic iallu // flush instructions fetched dsb nsh // via old mapping isb - add x27, x27, x23 // relocated __mmap_switched #endif br x27 ENDPROC(__enable_mmu) @@ -808,3 +767,50 @@ __no_granule_support: wfi b 1b ENDPROC(__no_granule_support) + +__relocate_kernel: +#ifdef CONFIG_RELOCATABLE + /* + * Iterate over each entry in the relocation table, and apply the + * relocations in place. + */ + ldr w8, =__dynsym_start_offset // offset to symbol table + ldr w9, =__reloc_start_offset // offset to reloc table + ldr w10, =__reloc_end_offset // offset to end of reloc table + + ldr x11, =KIMAGE_VADDR // default virtual offset + add x11, x11, x23 // actual virtual offset + add x8, x8, x11 // __va(.dynsym) + add x9, x9, x11 // __va(.reloc) + add x10, x10, x11 // __va(.reloc) + sizeof(.reloc) + +0: cmp x9, x10 + b.hs 2f + ldp x11, x12, [x9], #24 + ldr x13, [x9, #-8] + cmp w12, #R_AARCH64_RELATIVE + b.ne 1f + add x13, x13, x23 // relocate + str x13, [x11, x23] + b 0b + +1: cmp w12, #R_AARCH64_ABS64 + b.ne 0b + add x12, x12, x12, lsl #1 // symtab offset: 24x top word + add x12, x8, x12, lsr #(32 - 3) // ... shifted into bottom word + ldrsh w14, [x12, #6] // Elf64_Sym::st_shndx + ldr x15, [x12, #8] // Elf64_Sym::st_value + cmp w14, #-0xf // SHN_ABS (0xfff1) ? + add x14, x15, x23 // relocate + csel x15, x14, x15, ne + add x15, x13, x15 + str x15, [x11, x23] + b 0b + +2: ldr x8, =kimage_vaddr // make relocated kimage_vaddr + dc cvac, x8 // value visible to secondaries + dsb sy // with MMU off +#endif + ldr x8, =__mmap_switched + br x8 +ENDPROC(__relocate_kernel) diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 5a1939a74ff3..e9278013d5d2 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -154,12 +154,12 @@ SECTIONS *(.altinstr_replacement) } .rela : ALIGN(8) { - __reloc_start = .; + __reloc_start_offset = ABSOLUTE(. - KIMAGE_VADDR); *(.rela .rela*) - __reloc_end = .; + __reloc_end_offset = ABSOLUTE(. - KIMAGE_VADDR); } .dynsym : ALIGN(8) { - __dynsym_start = .; + __dynsym_start_offset = ABSOLUTE(. - KIMAGE_VADDR); *(.dynsym) } .dynstr : {