From patchwork Sun Mar 11 12:38:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 884249 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zzhXz1KkCz9sBp for ; Mon, 12 Mar 2018 00:19:31 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="HDlfrQqh"; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3zzhXy4zgJzDrFQ for ; Mon, 12 Mar 2018 00:19:30 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="HDlfrQqh"; dkim-atps=neutral X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=linaro.org (client-ip=2a00:1450:400c:c09::243; helo=mail-wm0-x243.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: lists.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="HDlfrQqh"; dkim-atps=neutral Received: from mail-wm0-x243.google.com (mail-wm0-x243.google.com [IPv6:2a00:1450:400c:c09::243]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3zzgfS6kLGzDrbH for ; Sun, 11 Mar 2018 23:39:12 +1100 (AEDT) Received: by mail-wm0-x243.google.com with SMTP id i3so11210276wmi.4 for ; Sun, 11 Mar 2018 05:39:12 -0700 (PDT) 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=A6CdKGtcFxvkcJyprZ73SqXJmQeUMwPknEJEYW8ClQg=; b=HDlfrQqhCKNaq81bcQzsRKbMg/kFKS4+WUFlfWP3mLAJ0D7fn0+BT5VP8f0NnXiG0y RjHQxTnnDpFm9AHfDdaCSxP1NdV5nP2tR+JkXE1RnBk5lt8sqndIQZCaxjElFMxdSv0H Yt4YnZyueus1wuWYfSgP2/JilnSM9JC+n0J5s= 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=A6CdKGtcFxvkcJyprZ73SqXJmQeUMwPknEJEYW8ClQg=; b=haf4JKVvi1L9rsvSoVgEDk+O0e/QGYrezFdxul15XjW5jpWB0Y5N2tDuOIqHUkkWpr p0/bBNUZNDodlxdmV2/g1eXLc01rGAUJzaBa08O9mK/B63gwscLkVBP+g8JdQYz8Sk7T hyT5wKYTpq3VlmPRUGBzdrkGaDFOgw6jLAZKOGQq3gI0HleI0OiI3PS6h9fmemnYSBuP KgcqBDd9Y6WE8gcOGX1IWMhb3cDCWXiNGdhxiQwJo30CxORsx17cHPEmX6/4GIFeoG0K dLpfFKOLMAr+iP0j+2AQUoa4ft+t2I2KFce6oTdGIUnE/J7nX1O5HDbOpkLegwJVlPwM W6AA== X-Gm-Message-State: AElRT7EK3jlbEqS0qJOOGL0KQQhUg2BnUfLHvcqsIEGVZgBErCpdVdZI VyuoUUyOx3YW/N9S03XZSL9oPQ== X-Google-Smtp-Source: AG47ELuj2AHHToHJdoG1C0nodQKInly9FE0wqX1fAOZ79EGs/hSD52XkPV5hobYxYWVrRAP6Z+ZG3g== X-Received: by 10.28.217.205 with SMTP id q196mr3300150wmg.149.1520771950287; Sun, 11 Mar 2018 05:39:10 -0700 (PDT) Received: from localhost.localdomain ([105.148.128.186]) by smtp.gmail.com with ESMTPSA id h188sm2569103wmf.37.2018.03.11.05.39.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 11 Mar 2018 05:39:09 -0700 (PDT) From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v8 4/6] init: allow initcall tables to be emitted using relative references Date: Sun, 11 Mar 2018 12:38:13 +0000 Message-Id: <20180311123815.17916-5-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180311123815.17916-1-ard.biesheuvel@linaro.org> References: <20180311123815.17916-1-ard.biesheuvel@linaro.org> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Catalin Marinas , Will Deacon , Paul Mackerras , Nicolas Pitre , x86@kernel.org, Russell King , Ingo Molnar , "Serge E. Hallyn" , Petr Mladek , Kees Cook , Arnd Bergmann , Steven Rostedt , James Morris , Josh Poimboeuf , Bjorn Helgaas , Thomas Gleixner , Ard Biesheuvel , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, Sergey Senozhatsky , Jessica Yu , Andrew Morton , Linus Torvalds , Thomas Garnier Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" 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(-) diff --git a/include/linux/init.h b/include/linux/init.h index 506a98151131..cca0f76bf4a6 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -116,8 +116,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 int initcall_entry_t; + +static inline initcall_t initcall_from_entry(initcall_entry_t *entry) +{ + return offset_to_ptr(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); @@ -167,9 +183,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. @@ -208,13 +235,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 a8100b954839..d81487cc126d 100644 --- a/init/main.c +++ b/init/main.c @@ -848,18 +848,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, @@ -885,7 +885,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], @@ -895,7 +895,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) @@ -926,10 +926,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 fc1123583fa6..0be1e8524873 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2780,7 +2780,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(); @@ -2791,7 +2791,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++; } }