From patchwork Tue Jun 26 18:27:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 140076 Delivered-To: patch@linaro.org Received: by 2002:a2e:970d:0:0:0:0:0 with SMTP id r13-v6csp5573613lji; Tue, 26 Jun 2018 11:29:44 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLFJAAHMvbcW/me8z/lZm5+RyL32pRvfqgFJGsAEZyCVa4yX8gaPjpZdydYv+mkiGXqef67 X-Received: by 2002:a65:6409:: with SMTP id a9-v6mr2381582pgv.154.1530037784258; Tue, 26 Jun 2018 11:29:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530037784; cv=none; d=google.com; s=arc-20160816; b=JM+TYjDgR09k3ootJTOR26sQ4Wa9QgF7QHbI1DqhvvZDspFXlll03UnPp/XFLwKN6l IKr5XUCmHVreu6Ahvh3n+2XeqBOhooxC8SfaX77eOKlwTsceuHGJ5FHUop1K7e2vDsoQ XiWCzOg4iow5r32RjNW6Yu+HB1Fmq43HcnBHbeTWipcyKulct/6cuBpmhlNNxMAfYalX 20aMrV8Ue4kCjdJjAsPZP3tBM8y2mgBUf2SPVzYljsblfsOw2k8N4CogyeEYCrJQKsP0 E7pS9gV/ZFnFoWl9vig06dAHgOKyirczZeABxvrzzLlnDfFDwpuucOVxHqJRyqnBlBP4 IuGg== 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=e3jnCZ1uFoNVuf5Qep6Bc6KNPlh/C1aJMc4q0hY5MUE=; b=JBajE1fR9Xe1490zSh00QDG6XjQvT3AhmNibpXL45WdMpZ1zR64W90zUnZmlgBwqvq KWoLNOg7AsJxOQdN5YfXgRltEeTH45WcPhOTOQb0Jpv/+Ga5JZa7orwW768WH8UPfyFF NFrUaHqdrbmx1snrEX/qIy5VagWwIQkKFRBLKVzXLziz8cwQ60M683OZKmPOdPegQoRE AyhNvg7xHMKWYXqL8u5mJhL8Sqo2tzhgw/gvyBqDJ9ouZFd3E62Q8GAbY7hMj2sg0WMz BUtb9v9z6lMNej7NKYFz/GYS9yd8I4kNhE86ADmVVwm9CgEyLv1+3MwPZRdz+a5G0/nz 0nXw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LK5muTqU; 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 n68-v6si2138142pfb.152.2018.06.26.11.29.43; Tue, 26 Jun 2018 11:29:44 -0700 (PDT) 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=LK5muTqU; 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 S1754572AbeFZS3n (ORCPT + 31 others); Tue, 26 Jun 2018 14:29:43 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:47067 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750962AbeFZS2t (ORCPT ); Tue, 26 Jun 2018 14:28:49 -0400 Received: by mail-wr0-f193.google.com with SMTP id l14-v6so13143353wrq.13 for ; Tue, 26 Jun 2018 11:28:48 -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=e3jnCZ1uFoNVuf5Qep6Bc6KNPlh/C1aJMc4q0hY5MUE=; b=LK5muTqU9KKzjP5cU+TC57wGqc+oEWRwIa/cBtdPV5ZGnhL8/xAvrfA/txCA+lbIMl z48mNDc5Sq5oiaKoviBG2gsH1ySZhDXd183Ff1qsFJauPtQzxEtCJbEobv2nYIUlWL+w d1YddENHiJLOVApc+XEX7k0swJFIVgx/2HjyA= 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=e3jnCZ1uFoNVuf5Qep6Bc6KNPlh/C1aJMc4q0hY5MUE=; b=NDfyE8sU1AxXf+CC05P8xMU2pZ4GOEitF1lXyQiR8JeEv1craiDMMbjoJtnIrfF/LH F0NvOHrkVn9pqRvm49ON0z16XAWIWFSKKgbcs65N0/anWbkPKPLtT9XE6h8tqetDPiFA zgspRUMOxaBolOW25kNZgT95rY6Xb8mtw+1RKWwZ6PTG0sC3uverw1AEZ8/kJzyqd9cj Cb8lSC9Ghh96lgMlBTEGlVmvqIfpAly1GH3SPoY2u91kZohbdVVkWa+vc5YqJkRO5Umi WJ8A1rqxeF15M1VZ2IMB5qXv7g859uESwLkxl7KP3dE81rIu60P6BBMi2J3FZrSzzwMg +qgA== X-Gm-Message-State: APt69E04dNc0CZs/Ofj6jNqTKsv/b7hhnbQc/6s1bibB1ushgHzwL2AO MWz/AonDKPeVuVztWoLqwwpFtpKtaJM= X-Received: by 2002:adf:9246:: with SMTP id 64-v6mr2481260wrj.109.1530037727883; Tue, 26 Jun 2018 11:28:47 -0700 (PDT) Received: from rev02.home ([2a01:cb1d:112:6f00:d037:e907:f0a2:a5ea]) by smtp.gmail.com with ESMTPSA id s17-v6sm1707664wmc.34.2018.06.26.11.28.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Jun 2018 11:28:47 -0700 (PDT) From: Ard Biesheuvel To: linux-kernel@vger.kernel.org Cc: Ard Biesheuvel , Arnd Bergmann , Kees Cook , Will Deacon , Michael Ellerman , Thomas Garnier , Thomas Gleixner , "Serge E. Hallyn" , Bjorn Helgaas , Benjamin Herrenschmidt , Russell King , Paul Mackerras , Catalin Marinas , Petr Mladek , Ingo Molnar , James Morris , Andrew Morton , Nicolas Pitre , Josh Poimboeuf , Steven Rostedt , Sergey Senozhatsky , Linus Torvalds , Jessica Yu , linux-arm-kernel@lists.infradead.org, linuxppc-dev@lists.ozlabs.org, x86@kernel.org Subject: [PATCH v9 4/6] init: allow initcall tables to be emitted using relative references Date: Tue, 26 Jun 2018 20:27:59 +0200 Message-Id: <20180626182802.19932-5-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180626182802.19932-1-ard.biesheuvel@linaro.org> References: <20180626182802.19932-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 | 16 +++---- security/security.c | 17 ++++---- 4 files changed, 68 insertions(+), 41 deletions(-) -- 2.11.0 Acked-by: James Morris Acked-by: Sergey Senozhatsky Acked-by: Petr Mladek diff --git a/include/linux/init.h b/include/linux/init.h index bc27cf03c41e..2538d176dd1f 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 " #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 3b4ada11ed52..e59a01f163d6 100644 --- a/init/main.c +++ b/init/main.c @@ -901,18 +901,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, @@ -938,7 +938,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], @@ -949,7 +949,7 @@ static void __init do_initcall_level(int level) trace_initcall_level(initcall_level_names[level]); 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) @@ -980,11 +980,11 @@ static void __init do_basic_setup(void) static void __init do_pre_smp_initcalls(void) { - initcall_t *fn; + initcall_entry_t *fn; trace_initcall_level("early"); 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 247808333ba4..688a27b0888c 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2772,7 +2772,8 @@ EXPORT_SYMBOL(unregister_console); void __init console_init(void) { int ret; - initcall_t *call; + initcall_t call; + initcall_entry_t *ce; /* Setup the default TTY line discipline. */ n_tty_init(); @@ -2781,13 +2782,14 @@ void __init console_init(void) * set up the console device so that later boot sequences can * inform about problems etc.. */ - call = __con_initcall_start; + ce = __con_initcall_start; trace_initcall_level("console"); - while (call < __con_initcall_end) { - trace_initcall_start((*call)); - ret = (*call)(); - trace_initcall_finish((*call), ret); - call++; + while (ce < __con_initcall_end) { + call = initcall_from_entry(ce); + trace_initcall_start(call); + ret = call(); + trace_initcall_finish(call, ret); + ce++; } } diff --git a/security/security.c b/security/security.c index 68f46d849abe..1e7b1486d82a 100644 --- a/security/security.c +++ b/security/security.c @@ -48,14 +48,17 @@ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = static void __init do_security_initcalls(void) { int ret; - initcall_t *call; - call = __security_initcall_start; + initcall_t call; + initcall_entry_t *ce; + + ce = __security_initcall_start; trace_initcall_level("security"); - while (call < __security_initcall_end) { - trace_initcall_start((*call)); - ret = (*call) (); - trace_initcall_finish((*call), ret); - call++; + while (ce < __security_initcall_end) { + call = initcall_from_entry(ce); + trace_initcall_start(call); + ret = call(); + trace_initcall_finish(call, ret); + ce++; } }