From patchwork Sat Sep 30 02:53:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 820164 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 3y3tRm4ysQz9sRm for ; Sat, 30 Sep 2017 12:59:00 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Kf4LTCft"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3y3tRm3gbgzDqlF for ; Sat, 30 Sep 2017 12:59:00 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Kf4LTCft"; dkim-atps=neutral X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:400e:c05::242; helo=mail-pg0-x242.google.com; envelope-from=sergey.senozhatsky@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Kf4LTCft"; dkim-atps=neutral Received: from mail-pg0-x242.google.com (mail-pg0-x242.google.com [IPv6:2607:f8b0:400e:c05::242]) (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 3y3tL60tvCzDqjx for ; Sat, 30 Sep 2017 12:54:06 +1000 (AEST) Received: by mail-pg0-x242.google.com with SMTP id u136so889712pgc.0 for ; Fri, 29 Sep 2017 19:54:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JHyTVZD676N/hZj4/970r0yL5skqRwoSnGbluCR0ZjQ=; b=Kf4LTCft1UDFnfBQESmSHPRq0HWrhJanDnAlpVuvhlHPpANg/0BWDBCOB65/lJEVWP QscmlWiNZ5QEQdf+SG7NsnHnAf+YtbnDpTWGYZulqdVxvAev/flcTB7j43BVEidgXUXp K49MHFqoZ4NLGlL7wMg31XzEfOLm8HS/kHopMtEVy82UBT5detE/41qzyVG678grgoha loQRdZ3mK5Ur6tpZ5hiWZXM1+zh4dLO57ixqegvrtHz0FSJHpwCGuplTJmJQF30YvW/j 3+HwpNEP/JHwUvbrC0Q/zQ8xDLnZ3g0j2vYHFpAwady/jpwYktZWLmMftNBhGygixGEU h+wg== 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=JHyTVZD676N/hZj4/970r0yL5skqRwoSnGbluCR0ZjQ=; b=qVQcBNLoF/qrBjWyB8q6TBoGqeqFp72uht5dJpm3OxJV4ACTNmnRLaN/znjDorMIxx QRhFuzqKEMbV3nkHhF8JEYbvT4bmttJMtgB7Cz588zRUjmzVAeKj0AHespniQPbMAdbw GrYc3dyixjqZYr7q7PeCd73CGqi34nrPVj8wIEvmt0eG/8bkcP21cASK7l/eh/jv/SWH jM2KTSnXVgQSTCYBQx6PEef/CfsNYXRchLS11UIeADtrBKO5Nvxix1yrOpaAti/4AjGD qPuCLDn86O8tJ3Tg/rD5dER/hYktNWnV64X0kfe4tqwe8Bc2Q9re4Ozylx4IaRcoDrh4 WnXA== X-Gm-Message-State: AHPjjUjpCTq+dnpfESS1l0q7NnOn3SJCKNfvL4XDwoAJVHsGvkY3Pu3h aSCZM2IN/AGHM1lF2CxOF5w= X-Google-Smtp-Source: AOwi7QA3iNOEWVvUk+7DzaNVsQoSw5V2y7a0GlglhFHy8XP+YPHD2+qIqBnhk7MOwcypFWqLtY12gw== X-Received: by 10.84.178.164 with SMTP id z33mr8781175plb.53.1506740044299; Fri, 29 Sep 2017 19:54:04 -0700 (PDT) Received: from localhost.localdomain ([175.223.27.84]) by smtp.gmail.com with ESMTPSA id b1sm8680714pgn.94.2017.09.29.19.53.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 29 Sep 2017 19:54:03 -0700 (PDT) From: Sergey Senozhatsky To: Petr Mladek , Steven Rostedt Subject: [PATCHv3 2/7] sections: split dereference_function_descriptor() Date: Sat, 30 Sep 2017 11:53:14 +0900 Message-Id: <20170930025319.987-3-sergey.senozhatsky@gmail.com> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20170930025319.987-1-sergey.senozhatsky@gmail.com> References: <20170930025319.987-1-sergey.senozhatsky@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fenghua Yu , Tony Luck , linux-ia64@vger.kernel.org, linux-parisc@vger.kernel.org, Helge Deller , Jessica Yu , James Bottomley , Alexei Starovoitov , Sergey Senozhatsky , Paul Mackerras , Andrew Morton , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" There are two format specifiers to print out a pointer in symbolic format: '%pS/%ps' and '%pF/%pf'. On most architectures, the two mean exactly the same thing, but some architectures (ia64, ppc64, parisc64) use an indirect pointer for C function pointers, where the function pointer points to a function descriptor (which in turn contains the actual pointer to the code). The '%pF/%pf, when used appropriately, automatically does the appropriate function descriptor dereference on such architectures. The "when used appropriately" part is tricky. Basically this is a subtle ABI detail, specific to some platforms, that made it to the API level and people can be unaware of it and miss the whole "we need to dereference the function" business out. [1] proves that point (note that it fixes only '%pF' and '%pS', there might be '%pf' and '%ps' cases as well). It appears that we can handle everything within the affected arches and make '%pS/%ps' smart enough to retire '%pF/%pf'. Function descriptors live in .opd elf section and all affected arches (ia64, ppc64, parisc64) handle it properly for kernel and modules. So we, technically, can decide if the dereference is needed by simply looking at the pointer: if it belongs to .opd section then we need to dereference it. The kernel and modules have their own .opd sections, obviously, that's why we need to split dereference_function_descriptor() and use separate kernel and module dereference arch callbacks. This patch does the first step, it a) adds dereference_kernel_function_descriptor() function. b) adds a weak alias to dereference_module_function_descriptor() function. So, for the time being, we will have: 1) dereference_function_descriptor() A generic function, that simply dereferences the pointer. There is bunch of places that call it: kgdbts, init/main.c, extable, etc. 2) dereference_kernel_function_descriptor() A function to call on kernel symbols that does kernel .opd section address range test. 3) dereference_module_function_descriptor() A function to call on modules' symbols that does modules' .opd section address range test. [1] https://marc.info/?l=linux-kernel&m=150472969730573 Signed-off-by: Sergey Senozhatsky Tested-by: Helge Deller # parisc64 Tested-by: Santosh Sivaraj # powerpc64 Acked-by: Michael Ellerman # powerpc64 Tested-by: Tony Luck # ia64 --- include/asm-generic/sections.h | 8 ++++++-- include/linux/moduleloader.h | 4 ++++ kernel/module.c | 6 ++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index e5da44eddd2f..387f22c41e0d 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -29,6 +29,7 @@ * __ctors_start, __ctors_end * __irqentry_text_start, __irqentry_text_end * __softirqentry_text_start, __softirqentry_text_end + * __start_opd, __end_opd */ extern char _text[], _stext[], _etext[]; extern char _data[], _sdata[], _edata[]; @@ -47,12 +48,15 @@ extern char __softirqentry_text_start[], __softirqentry_text_end[]; /* Start and end of .ctors section - used for constructor calls. */ extern char __ctors_start[], __ctors_end[]; +/* Start and end of .opd section - used for function descriptors. */ +extern char __start_opd[], __end_opd[]; + extern __visible const void __nosave_begin, __nosave_end; -/* function descriptor handling (if any). Override - * in asm/sections.h */ +/* Function descriptor handling (if any). Override in asm/sections.h */ #ifndef dereference_function_descriptor #define dereference_function_descriptor(p) (p) +#define dereference_kernel_function_descriptor(p) (p) #endif /* random extra sections (if any). Override diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index 4d0cb9bba93e..172904e9cded 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -85,6 +85,10 @@ void module_arch_cleanup(struct module *mod); /* Any cleanup before freeing mod->module_init */ void module_arch_freeing_init(struct module *mod); +/* Dereference module function descriptor */ +unsigned long dereference_module_function_descriptor(struct module *mod, + unsigned long addr); + #ifdef CONFIG_KASAN #include #define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT) diff --git a/kernel/module.c b/kernel/module.c index ea77ab13bead..b792e814150a 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2121,6 +2121,12 @@ void __weak module_arch_freeing_init(struct module *mod) { } +unsigned long __weak dereference_module_function_descriptor(struct module *mod, + unsigned long addr) +{ + return addr; +} + /* Free a module, remove from lists, etc. */ static void free_module(struct module *mod) {