From patchwork Wed Dec 27 08:50:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 122760 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp1919874qgn; Wed, 27 Dec 2017 00:51:14 -0800 (PST) X-Google-Smtp-Source: ACJfBovQWGMU3dDSjwvc2KkDJUSKwRhNCXluN+SEFxpUUr5LviGMZAoEWSTLvR/sRjS/0E/JCdWa X-Received: by 10.101.101.203 with SMTP id y11mr11340223pgv.387.1514364674480; Wed, 27 Dec 2017 00:51:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1514364674; cv=none; d=google.com; s=arc-20160816; b=qC2brAUzhptnFflzACsD/sKBEoD8V/GKPr4MvWWZsxIA29kf1kb7QMJMgOYA1MECvk 5bCTYpOXUmG85tgGQ9M/gpRtCQBU7ovmktOGUdBFCv82wJ/Dbnk2mvYrpA69PRYA/6Ro Ui4Qc3DWvlDOkI4qnCHIjYFIpQfrzXBoPNUTSnNiMyWED7HGxInbviOEC7XCFmW4izBo QVUGcFb06O6CG0t9oeBtMgu5BXjzBLbAdaLoivPVd7807LBK8FEVdeI8m5YZSQmB7P8X fhZBVITZX8T+3YZZlhVh3c6T6mJ6nXTBo0qTGYltNHiBDHCqvZPZhCxAzMr4+Kgse5oz eVSw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=lwLLrS7mueZ/zWj6YdhKL1lPIayLUTMzei7H77VCkQk=; b=Lqvrd4sDrI3LC8KrgFu5Y+FLxbmLs5SELMyQTjC0Xr6uGXca3304RsPA9M37QHjJ2k BreUikF2REoWKVedtqmvq0jLk48fmlIl8r89yH+ZTN9sNm6ApASXVN2fzXXorzqnYP2f RPwSUIrOmnWP+sBhRowtgDMBcRHSwInpXK1IqdzcgZFSn7Hcg2TozicnVXoFDI+Pcbwl 2qgIgQ1B399UMzV+cjttX1rIPEhvxQXFuVHmqZjul/OIZKZW108I7YgcTmetPap4Xwqp LUYes5dM659vpGWyBG0gojrfIEk42k8S15C1YPM6dQf2lD3NIkjATLJwYUN1n+NaF4cw 6+gg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=QtJm4zXV; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n11si18413086plg.13.2017.12.27.00.51.14; Wed, 27 Dec 2017 00:51:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=QtJm4zXV; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751862AbdL0IvK (ORCPT + 28 others); Wed, 27 Dec 2017 03:51:10 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:36653 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751833AbdL0IvG (ORCPT ); Wed, 27 Dec 2017 03:51:06 -0500 Received: by mail-wm0-f66.google.com with SMTP id b76so38343658wmg.1 for ; Wed, 27 Dec 2017 00:51:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lwLLrS7mueZ/zWj6YdhKL1lPIayLUTMzei7H77VCkQk=; b=QtJm4zXVhuLpsXWoyJuUQkhle/5dXy0JI2WcpXmhBquEjre0C3BUPD5ch/f18mczrf DiLO3OML2FGRfJ8GotRLc7hdIbjGDa2Qbkl4gX/eiHwmkj4/1YkM4Ig4gS7IqJTnbFTL WjUFiGZM9AzmnZmYJOL1Yzn18Jf3xY0BnuVrs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=lwLLrS7mueZ/zWj6YdhKL1lPIayLUTMzei7H77VCkQk=; b=fZxrjOcQ4Bh0iS4H2ZGv+jlgEXuz/gPsrU+WV+U07D63iU160NJA2D6o7Lr6e+ajpy 1MXLlewvXdlAYGBYoEV98vqB4wIIdYgTUvmX0Y8L5jfKoinMo7Xp6+4iDZv20dRFaeyJ AFrnPNB9bRqkeDIzktZGurtYsTxYUtuS2K6ANnwY4fxOb4vA15U4m1Bte/j/XQosmls9 sqIv9xAQkAHjAvLftI909Kk75JnZoVROtBicbUY4hphYv8mkbg2teYiQJVGPauyZqTkL CTZs40wWBCWNJBJyOXb0oXX8WLpYrtbjLiRy4XtT1gGPLZdU/fKnkRuCWhquGC3uvvLd cAww== X-Gm-Message-State: AKGB3mIzpBhmjEp8W/Yo5Kmt9XeJ87FMc3UHiu30iCx2mpIoXRFw79/m 11vYcnG6TivTR83g6Gw6as+vlm+m6xA= X-Received: by 10.28.160.23 with SMTP id j23mr21304907wme.54.1514364664371; Wed, 27 Dec 2017 00:51:04 -0800 (PST) Received: from localhost.localdomain ([105.137.110.132]) by smtp.gmail.com with ESMTPSA id q74sm32677226wmg.22.2017.12.27.00.50.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Dec 2017 00:51:03 -0800 (PST) From: Ard Biesheuvel To: linux-kernel@vger.kernel.org Cc: Ard Biesheuvel , "H. Peter Anvin" , Ralf Baechle , Arnd Bergmann , Heiko Carstens , Kees Cook , Will Deacon , Michael Ellerman , Thomas Garnier , Thomas Gleixner , "Serge E. Hallyn" , Bjorn Helgaas , Benjamin Herrenschmidt , Russell King , Paul Mackerras , Catalin Marinas , "David S. Miller" , Petr Mladek , Ingo Molnar , James Morris , Andrew Morton , Nicolas Pitre , Josh Poimboeuf , Steven Rostedt , Martin Schwidefsky , Sergey Senozhatsky , Linus Torvalds , Jessica Yu , linux-arm-kernel@lists.infradead.org, linux-mips@linux-mips.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, sparclinux@vger.kernel.org, x86@kernel.org Subject: [PATCH v6 3/8] init: allow initcall tables to be emitted using relative references Date: Wed, 27 Dec 2017 08:50:28 +0000 Message-Id: <20171227085033.22389-4-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171227085033.22389-1-ard.biesheuvel@linaro.org> References: <20171227085033.22389-1-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Allow the initcall tables to be emitted using relative references that are only half the size on 64-bit architectures and don't require fixups at runtime on relocatable kernels. Cc: Petr Mladek Cc: Sergey Senozhatsky Cc: Steven Rostedt Cc: James Morris Cc: "Serge E. Hallyn" Signed-off-by: Ard Biesheuvel --- include/linux/init.h | 44 +++++++++++++++----- init/main.c | 32 +++++++------- kernel/printk/printk.c | 4 +- security/security.c | 4 +- 4 files changed, 53 insertions(+), 31 deletions(-) -- 2.11.0 diff --git a/include/linux/init.h b/include/linux/init.h index ea1b31101d9e..125bbea99c6b 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -109,8 +109,24 @@ typedef int (*initcall_t)(void); typedef void (*exitcall_t)(void); -extern initcall_t __con_initcall_start[], __con_initcall_end[]; -extern initcall_t __security_initcall_start[], __security_initcall_end[]; +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +typedef signed int initcall_entry_t; + +static inline initcall_t initcall_from_entry(initcall_entry_t *entry) +{ + return (initcall_t)((unsigned long)entry + *entry); +} +#else +typedef initcall_t initcall_entry_t; + +static inline initcall_t initcall_from_entry(initcall_entry_t *entry) +{ + return *entry; +} +#endif + +extern initcall_entry_t __con_initcall_start[], __con_initcall_end[]; +extern initcall_entry_t __security_initcall_start[], __security_initcall_end[]; /* Used for contructor calls. */ typedef void (*ctor_fn_t)(void); @@ -160,9 +176,20 @@ extern bool initcall_debug; * as KEEP() in the linker script. */ -#define __define_initcall(fn, id) \ +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +#define ___define_initcall(fn, id, __sec) \ + __ADDRESSABLE(fn) \ + asm(".section \"" #__sec ".init\", \"a\" \n" \ + "__initcall_" #fn #id ": \n" \ + ".long " VMLINUX_SYMBOL_STR(fn) " - . \n" \ + ".previous \n"); +#else +#define ___define_initcall(fn, id, __sec) \ static initcall_t __initcall_##fn##id __used \ - __attribute__((__section__(".initcall" #id ".init"))) = fn; + __attribute__((__section__(#__sec ".init"))) = fn; +#endif + +#define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) /* * Early initcalls run before initializing SMP. @@ -201,13 +228,8 @@ extern bool initcall_debug; #define __exitcall(fn) \ static exitcall_t __exitcall_##fn __exit_call = fn -#define console_initcall(fn) \ - static initcall_t __initcall_##fn \ - __used __section(.con_initcall.init) = fn - -#define security_initcall(fn) \ - static initcall_t __initcall_##fn \ - __used __section(.security_initcall.init) = fn +#define console_initcall(fn) ___define_initcall(fn,, .con_initcall) +#define security_initcall(fn) ___define_initcall(fn,, .security_initcall) struct obs_kernel_param { const char *str; diff --git a/init/main.c b/init/main.c index 7b606fc48482..2cbe3c2804ab 100644 --- a/init/main.c +++ b/init/main.c @@ -845,18 +845,18 @@ int __init_or_module do_one_initcall(initcall_t fn) } -extern initcall_t __initcall_start[]; -extern initcall_t __initcall0_start[]; -extern initcall_t __initcall1_start[]; -extern initcall_t __initcall2_start[]; -extern initcall_t __initcall3_start[]; -extern initcall_t __initcall4_start[]; -extern initcall_t __initcall5_start[]; -extern initcall_t __initcall6_start[]; -extern initcall_t __initcall7_start[]; -extern initcall_t __initcall_end[]; - -static initcall_t *initcall_levels[] __initdata = { +extern initcall_entry_t __initcall_start[]; +extern initcall_entry_t __initcall0_start[]; +extern initcall_entry_t __initcall1_start[]; +extern initcall_entry_t __initcall2_start[]; +extern initcall_entry_t __initcall3_start[]; +extern initcall_entry_t __initcall4_start[]; +extern initcall_entry_t __initcall5_start[]; +extern initcall_entry_t __initcall6_start[]; +extern initcall_entry_t __initcall7_start[]; +extern initcall_entry_t __initcall_end[]; + +static initcall_entry_t *initcall_levels[] __initdata = { __initcall0_start, __initcall1_start, __initcall2_start, @@ -882,7 +882,7 @@ static char *initcall_level_names[] __initdata = { static void __init do_initcall_level(int level) { - initcall_t *fn; + initcall_entry_t *fn; strcpy(initcall_command_line, saved_command_line); parse_args(initcall_level_names[level], @@ -892,7 +892,7 @@ static void __init do_initcall_level(int level) NULL, &repair_env_string); for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) - do_one_initcall(*fn); + do_one_initcall(initcall_from_entry(fn)); } static void __init do_initcalls(void) @@ -923,10 +923,10 @@ static void __init do_basic_setup(void) static void __init do_pre_smp_initcalls(void) { - initcall_t *fn; + initcall_entry_t *fn; for (fn = __initcall_start; fn < __initcall0_start; fn++) - do_one_initcall(*fn); + do_one_initcall(initcall_from_entry(fn)); } /* diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index b9006617710f..0516005261c7 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2611,7 +2611,7 @@ EXPORT_SYMBOL(unregister_console); */ void __init console_init(void) { - initcall_t *call; + initcall_entry_t *call; /* Setup the default TTY line discipline. */ n_tty_init(); @@ -2622,7 +2622,7 @@ void __init console_init(void) */ call = __con_initcall_start; while (call < __con_initcall_end) { - (*call)(); + initcall_from_entry(call)(); call++; } } diff --git a/security/security.c b/security/security.c index 1cd8526cb0b7..f648eeff06de 100644 --- a/security/security.c +++ b/security/security.c @@ -45,10 +45,10 @@ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = static void __init do_security_initcalls(void) { - initcall_t *call; + initcall_entry_t *call; call = __security_initcall_start; while (call < __security_initcall_end) { - (*call) (); + initcall_from_entry(call)(); call++; } }