From patchwork Tue Jul 23 06:32:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zheng Yejian X-Patchwork-Id: 13739398 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A1B1614A611; Tue, 23 Jul 2024 06:32:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721716332; cv=none; b=NX+iou6+ox1nqG7aueKZoPLfxaGgNjVGlKxXGHsWvNc11B4RbrBZbHVs1FlBd2j9u4nrpMguDs77y3k/sBiHjK2tp5N/VU8lubYaxkHmVeNx7sXDtoW4gYwAalOsvM7zZFQoa0XoxCHRqLyEmouDlWx4Pwcx1n179TgpSrQX7qs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721716332; c=relaxed/simple; bh=IA1VKL3MvIYjPz7nwh+mOgEyBbw8WVZrT+VtknO8ITc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=lfK5ICK7YCCVHe4oVWEhnenF1q68wXjtKeDgV+fAeqm+CF2KL92pgFUXndt/RAKWYwpRkUn1Dev/H2TYDwqfmoToO7ChU5DcpuOmB6ENqTeW7eXg9dcAqC1n45egTnyW8sS9lNh173TmiBmQHi0KAc/j3N1V9XY3w6Cf+LVomCM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.235]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTP id 4WSnP10gjfz4f3kFN; Tue, 23 Jul 2024 14:31:49 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.75]) by mail.maildlp.com (Postfix) with ESMTP id 7210C1A06D7; Tue, 23 Jul 2024 14:32:01 +0800 (CST) Received: from localhost.localdomain (unknown [10.67.175.61]) by APP2 (Coremail) with SMTP id Syh0CgA34wpOTp9mjImuAw--.48686S3; Tue, 23 Jul 2024 14:32:00 +0800 (CST) From: Zheng Yejian To: masahiroy@kernel.org, peterz@infradead.org, rostedt@goodmis.org, mhiramat@kernel.org, mark.rutland@arm.com, mpe@ellerman.id.au, npiggin@gmail.com, christophe.leroy@csgroup.eu, naveen.n.rao@linux.ibm.com, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, mcgrof@kernel.org, mathieu.desnoyers@efficios.com, nathan@kernel.org, nicolas@fjasle.eu, ojeda@kernel.org, akpm@linux-foundation.org, surenb@google.com, pasha.tatashin@soleen.com, kent.overstreet@linux.dev, james.clark@arm.com, jpoimboe@kernel.org Cc: x86@kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-modules@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, zhengyejian@huaweicloud.com Subject: [PATCH v2 1/5] kallsyms: Emit symbol at the holes in the text Date: Tue, 23 Jul 2024 14:32:54 +0800 Message-Id: <20240723063258.2240610-2-zhengyejian@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240723063258.2240610-1-zhengyejian@huaweicloud.com> References: <20240723063258.2240610-1-zhengyejian@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-kbuild@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: Syh0CgA34wpOTp9mjImuAw--.48686S3 X-Coremail-Antispam: 1UD129KBjvJXoW3AF4UtFyxuF4fJF1kXFy7ZFb_yoWxWFyfpa 4Fk3yYgrWrJrn7W3srGw48WFW3uws7Zan5G3srG34YyFn0qrWSqay7K3yYyFWUJry8JFyj kr9ayFW2kF4vy3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmF14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr4l82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWrXVW3AwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWU JVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Wrv_Gr1UMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAI cVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIx AIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2 KfnxnUUI43ZEXa7sRETKZJUUUUU== X-CM-SenderInfo: x2kh0w51hmxt3q6k3tpzhluzxrxghudrp/ When a weak type function is overridden, its symbol will be removed from the symbol table, but its code will not be removed. Besides, due to lacking of size for kallsyms, kernel compute function size by substracting its symbol address from its next symbol address (see kallsyms_lookup_size_offset()). These will cause that size of some function is computed to be larger than it actually is, just because symbol of its following weak function is removed. This issue also causes multiple __fentry__ locations to be counted in the same function scope, and eventually causes ftrace_location() to find wrong __fentry__ location. It was reported in Link: https://lore.kernel.org/all/20240607115211.734845-1-zhengyejian1@huawei.com/ Peter suggested to change scipts/kallsyms.c to emit readily identifiable symbol names for all the weak junk. So in this patch: 1. Pass size info to scripts/kallsyms (see mksysmap()); 2. Traverse sorted function symbols, if one function address plus its size less than next function address, it means there's a hole, with Masahiro's suggestion, then emit a symbol there of which type and name are both empty to represent the hole. Suggested-by: Peter Zijlstra Suggested-by: Masahiro Yamada Signed-off-by: Zheng Yejian --- scripts/kallsyms.c | 94 +++++++++++++++++++++++++++++++++++++++-- scripts/link-vmlinux.sh | 4 +- scripts/mksysmap | 2 +- 3 files changed, 94 insertions(+), 6 deletions(-) diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 47978efe4797..cf64c20a8292 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -34,6 +34,7 @@ struct sym_entry { unsigned long long addr; + unsigned long long size; unsigned int len; unsigned int seq; unsigned int start_pos; @@ -72,7 +73,6 @@ static int token_profit[0x10000]; static unsigned char best_table[256][2]; static unsigned char best_table_len[256]; - static void usage(void) { fprintf(stderr, "Usage: kallsyms [--all-symbols] [--absolute-percpu] " @@ -128,8 +128,16 @@ static struct sym_entry *read_symbol(FILE *in, char **buf, size_t *buf_len) size_t len; ssize_t readlen; struct sym_entry *sym; + unsigned long long size = 0; errno = 0; + /* + * Example of expected symbol format: + * 1. symbol with size info: + * ffffffff81000070 00000000000001d7 T __startup_64 + * 2. symbol without size info: + * 0000000002a00000 A text_size + */ readlen = getline(buf, buf_len, in); if (readlen < 0) { if (errno) { @@ -143,9 +151,24 @@ static struct sym_entry *read_symbol(FILE *in, char **buf, size_t *buf_len) (*buf)[readlen - 1] = 0; addr = strtoull(*buf, &p, 16); + if (*buf == p || *p++ != ' ') { + fprintf(stderr, "line format error: unable to parse address\n"); + exit(EXIT_FAILURE); + } + + if (*p == '0') { + char *str = p; + + size = strtoull(str, &p, 16); + if (str == p || *p++ != ' ') { + fprintf(stderr, "line format error: unable to parse size\n"); + exit(EXIT_FAILURE); + } + } - if (*buf == p || *p++ != ' ' || !isascii((type = *p++)) || *p++ != ' ') { - fprintf(stderr, "line format error\n"); + type = *p++; + if (!isascii(type) || *p++ != ' ') { + fprintf(stderr, "line format error: unable to parse type\n"); exit(EXIT_FAILURE); } @@ -180,6 +203,7 @@ static struct sym_entry *read_symbol(FILE *in, char **buf, size_t *buf_len) exit(EXIT_FAILURE); } sym->addr = addr; + sym->size = size; sym->len = len; sym->sym[0] = type; strcpy(sym_name(sym), name); @@ -788,6 +812,69 @@ static void sort_symbols(void) qsort(table, table_cnt, sizeof(table[0]), compare_symbols); } +static bool has_hole(const struct sym_entry *se1, const struct sym_entry *se2) +{ + char type = se1->sym[0]; + + /* Only check text symbol or weak symbol */ + if (type != 't' && type != 'T' && + type != 'w' && type != 'W') + return 0; + /* Symbol without size has no hole */ + if (!se1->size) + return 0; + return se1->addr + se1->size < se2->addr; +} + +static struct sym_entry *gen_hole_symbol(const struct sym_entry *se) +{ + struct sym_entry *sym; + + /* Use empty symbol type/name as a special case to represent the hole */ + sym = malloc(sizeof(*sym) + 1); + if (!sym) { + fprintf(stderr, "unable to allocate memory for hole symbol\n"); + exit(EXIT_FAILURE); + } + sym->addr = se->addr + se->size; + sym->size = 0; + sym->len = 1; + sym->sym[0] = '\0'; + sym->percpu_absolute = 0; + return sym; +} + +static void emit_hole_symbols(void) +{ + unsigned int i, j, nr_emit; + unsigned int new_cnt; + + nr_emit = 0; + for (i = 0; i < table_cnt - 1; i++) { + if (has_hole(table[i], table[i+1])) + nr_emit++; + } + if (!nr_emit) + return; + + new_cnt = table_cnt + nr_emit; + table = realloc(table, sizeof(*table) * new_cnt); + if (!table) { + fprintf(stderr, "unable to allocate memory for emitting hole symbols\n"); + exit(EXIT_FAILURE); + } + + for (i = table_cnt - 1, j = new_cnt - 1; i >= 0; i--, j--) { + if ((i != table_cnt - 1) && has_hole(table[i], table[i+1])) + table[j--] = gen_hole_symbol(table[i]); + if (j != i) + table[j] = table[i]; + else + break; + } + table_cnt = new_cnt; +} + static void make_percpus_absolute(void) { unsigned int i; @@ -847,6 +934,7 @@ int main(int argc, char **argv) if (absolute_percpu) make_percpus_absolute(); sort_symbols(); + emit_hole_symbols(); if (base_relative) record_relative_base(); optimize_token_table(); diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 518c70b8db50..8e1373902bfe 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -189,11 +189,11 @@ kallsyms_step() } # Create map file with all symbols from ${1} -# See mksymap for additional details +# See mksysmap for additional details mksysmap() { info NM ${2} - ${NM} -n "${1}" | sed -f "${srctree}/scripts/mksysmap" > "${2}" + ${NM} -nS "${1}" | sed -f "${srctree}/scripts/mksysmap" > "${2}" } sorttable() diff --git a/scripts/mksysmap b/scripts/mksysmap index c12723a04655..7a4415f21143 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-2.0-only # # sed script to filter out symbols that are not needed for System.map, -# or not suitable for kallsyms. The input should be 'nm -n '. +# or not suitable for kallsyms. The input should be 'nm -nS '. # # System.map is used by module-init tools and some debugging # tools to retrieve the actual addresses of symbols in the kernel. From patchwork Tue Jul 23 06:32:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zheng Yejian X-Patchwork-Id: 13739394 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F114913CF85; Tue, 23 Jul 2024 06:32:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721716329; cv=none; b=h6ZykdvqCMvEcC+dukyeRpFBql0IdFzCsD7mfrJGIbI4x9V5i42cdUh992LKjRTDNJJdbbBRfyoTMtBfRqF7pk4KQG5KNnu43i2RZxRCljHeRo8V+v+d1eTUWSCBKFFD6t0GZkN9cnpfRW203QDb38/VrS2FX/Bt8ettg4nDSMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721716329; c=relaxed/simple; bh=LLO1F1XA2C13CWuFfwDqmzGNIc8dg7seX4y/8W9IzB8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BQI5WAfMwBY0xuxF4gUij2lI/67+FR33skMT05wIAPWt6F65iJeRDzp7M7sNafOGd+KXFbJdtyLN6A3tIP1fZyoAQo/ZhWktfcmzH481c3I1YffFNHb9keK5ZiWF01U50KhqUWKqanJqRLlc8O4NsP2R0AIswQFiuTDb2x6AxjM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.235]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTP id 4WSnP00S3Xz4f3lVL; Tue, 23 Jul 2024 14:31:48 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.75]) by mail.maildlp.com (Postfix) with ESMTP id 8D8FB1A0572; Tue, 23 Jul 2024 14:32:01 +0800 (CST) Received: from localhost.localdomain (unknown [10.67.175.61]) by APP2 (Coremail) with SMTP id Syh0CgA34wpOTp9mjImuAw--.48686S4; Tue, 23 Jul 2024 14:32:01 +0800 (CST) From: Zheng Yejian To: masahiroy@kernel.org, peterz@infradead.org, rostedt@goodmis.org, mhiramat@kernel.org, mark.rutland@arm.com, mpe@ellerman.id.au, npiggin@gmail.com, christophe.leroy@csgroup.eu, naveen.n.rao@linux.ibm.com, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, mcgrof@kernel.org, mathieu.desnoyers@efficios.com, nathan@kernel.org, nicolas@fjasle.eu, ojeda@kernel.org, akpm@linux-foundation.org, surenb@google.com, pasha.tatashin@soleen.com, kent.overstreet@linux.dev, james.clark@arm.com, jpoimboe@kernel.org Cc: x86@kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-modules@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, zhengyejian@huaweicloud.com Subject: [PATCH v2 2/5] module: kallsyms: Determine exact function size Date: Tue, 23 Jul 2024 14:32:55 +0800 Message-Id: <20240723063258.2240610-3-zhengyejian@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240723063258.2240610-1-zhengyejian@huaweicloud.com> References: <20240723063258.2240610-1-zhengyejian@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-kbuild@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: Syh0CgA34wpOTp9mjImuAw--.48686S4 X-Coremail-Antispam: 1UD129KBjvJXoWxZr47Wry3tF4UAr4xKw47twb_yoW5Ary5pF 45Ar4rGF48Xr47uFWxAay09ry5Gr1kur4UKasxK34fZFnIqFy093Z7t3y5C3s8Zr48GF18 JrnagFWakF4UArJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmY14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jryl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr1j6rxdM2 8EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0DM2AI xVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20x vE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xv r2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8cxan2IY04 v7MxkF7I0En4kS14v26rWY6Fy7MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j 6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7 AF67AKxVWrXVW8Jr1lIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42 IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIev Ja73UjIFyTuYvjTRC2NtUUUUU X-CM-SenderInfo: x2kh0w51hmxt3q6k3tpzhluzxrxghudrp/ When a weak type function is overridden, its symbol will be removed from the symbol table, but its code will not been removed. It will cause find_kallsyms_symbol() to compute a larger function size than it actually is, just because symbol of its following weak function is removed. To fix this issue, check that given address is within the size of the function found. Signed-off-by: Zheng Yejian --- include/linux/module.h | 7 +++++++ kernel/module/kallsyms.c | 19 +++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 4213d8993cd8..0299d79433ae 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -599,6 +599,13 @@ static inline unsigned long kallsyms_symbol_value(const Elf_Sym *sym) } #endif +#ifndef HAVE_ARCH_KALLSYMS_SYMBOL_TYPE +static inline unsigned int kallsyms_symbol_type(const Elf_Sym *sym) +{ + return ELF_ST_TYPE(sym->st_info); +} +#endif + /* FIXME: It'd be nice to isolate modules during init, too, so they aren't used before they (may) fail. But presently too much code (IDE & SCSI) require entry into the module during init.*/ diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c index bf65e0c3c86f..cce4f81b9933 100644 --- a/kernel/module/kallsyms.c +++ b/kernel/module/kallsyms.c @@ -262,6 +262,7 @@ static const char *find_kallsyms_symbol(struct module *mod, unsigned long nextval, bestval; struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms); struct module_memory *mod_mem; + const Elf_Sym *sym; /* At worse, next value is at end of module */ if (within_module_init(addr, mod)) @@ -278,9 +279,10 @@ static const char *find_kallsyms_symbol(struct module *mod, * starts real symbols at 1). */ for (i = 1; i < kallsyms->num_symtab; i++) { - const Elf_Sym *sym = &kallsyms->symtab[i]; - unsigned long thisval = kallsyms_symbol_value(sym); + unsigned long thisval; + sym = &kallsyms->symtab[i]; + thisval = kallsyms_symbol_value(sym); if (sym->st_shndx == SHN_UNDEF) continue; @@ -292,6 +294,13 @@ static const char *find_kallsyms_symbol(struct module *mod, is_mapping_symbol(kallsyms_symbol_name(kallsyms, i))) continue; + if (kallsyms_symbol_type(sym) == STT_FUNC && + addr >= thisval && addr < thisval + sym->st_size) { + best = i; + bestval = thisval; + nextval = thisval + sym->st_size; + goto found; + } if (thisval <= addr && thisval > bestval) { best = i; bestval = thisval; @@ -303,6 +312,12 @@ static const char *find_kallsyms_symbol(struct module *mod, if (!best) return NULL; + sym = &kallsyms->symtab[best]; + if (kallsyms_symbol_type(sym) == STT_FUNC && sym->st_size && + addr >= kallsyms_symbol_value(sym) + sym->st_size) + return NULL; + +found: if (size) *size = nextval - bestval; if (offset) From patchwork Tue Jul 23 06:32:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zheng Yejian X-Patchwork-Id: 13739396 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F118414A09E; Tue, 23 Jul 2024 06:32:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721716330; cv=none; b=HWvRJTkBX7C0B/pOXJMXxNgHY114qRsZy2mWFNFcOSP3xuDGMwTKcxVX24rmUsEUspKTHKMVmnQ5RjES3b9BtEW2mAgyWlNf6Wg9eN6cT2e/aieVPNTToYaiDkmgZ9rlZ3anP9pMO3lQBcihd1ruqrioWEueEyMC9pqO9IMKkn8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721716330; c=relaxed/simple; bh=98G5EYcrA0w8Bz5Q6obe7L6l3nViGXyN1IU2svx+MGc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BpFL5LTmRAMc9XEHn3v7n27uqVtnMcutV5lTHMmxfrLp6BUWbsv4WDU59mGByz3VTDYFkr78QUz22bRnj1aiSnMgi7N02S2Y0Ta0r/r/VdRU10xZGwVGj7VurE+ngsX+75AaAjiop7td9DnMamZPJdo4MIUe1UkyzDiO5A8zMXc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.216]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTP id 4WSnP01bB3z4f3lVg; Tue, 23 Jul 2024 14:31:48 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.75]) by mail.maildlp.com (Postfix) with ESMTP id B1E811A1421; Tue, 23 Jul 2024 14:32:01 +0800 (CST) Received: from localhost.localdomain (unknown [10.67.175.61]) by APP2 (Coremail) with SMTP id Syh0CgA34wpOTp9mjImuAw--.48686S5; Tue, 23 Jul 2024 14:32:01 +0800 (CST) From: Zheng Yejian To: masahiroy@kernel.org, peterz@infradead.org, rostedt@goodmis.org, mhiramat@kernel.org, mark.rutland@arm.com, mpe@ellerman.id.au, npiggin@gmail.com, christophe.leroy@csgroup.eu, naveen.n.rao@linux.ibm.com, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, mcgrof@kernel.org, mathieu.desnoyers@efficios.com, nathan@kernel.org, nicolas@fjasle.eu, ojeda@kernel.org, akpm@linux-foundation.org, surenb@google.com, pasha.tatashin@soleen.com, kent.overstreet@linux.dev, james.clark@arm.com, jpoimboe@kernel.org Cc: x86@kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-modules@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, zhengyejian@huaweicloud.com Subject: [PATCH v2 3/5] ftrace: Skip invalid __fentry__ in ftrace_process_locs() Date: Tue, 23 Jul 2024 14:32:56 +0800 Message-Id: <20240723063258.2240610-4-zhengyejian@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240723063258.2240610-1-zhengyejian@huaweicloud.com> References: <20240723063258.2240610-1-zhengyejian@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-kbuild@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: Syh0CgA34wpOTp9mjImuAw--.48686S5 X-Coremail-Antispam: 1UD129KBjvJXoWxtryxKrWfZw17Cw48Xr47Jwb_yoWxGryDpF yUAr45Kr48Jr1jgan3ur4kury5G397ur47ta9xKrySvrnxXF10vanFvwn8A34UJrWkZFyx Ja43ZFy2kFWUZF7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUm214x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JrWl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr1j6rxdM2 8EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0DM2AI xVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20x vE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xv r2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8cxan2IY04 v7MxkF7I0En4kS14v26rWY6Fy7MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j 6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7 AF67AKxVWrXVW8Jr1lIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIx AIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBIdaVF xhVjvjDU0xZFpf9x0pRVOJ5UUUUU= X-CM-SenderInfo: x2kh0w51hmxt3q6k3tpzhluzxrxghudrp/ ftrace_location() was changed to not only return the __fentry__ location when called for the __fentry__ location, but also when called for the sym+0 location after commit aebfd12521d9 ("x86/ibt,ftrace: Search for __fentry__ location"). That is, if sym+0 location is not __fentry__, ftrace_location() would find one over the entire size of the sym. However, there is case that more than one __fentry__ exist in the sym range (described below) and ftrace_location() would find wrong __fentry__ location by binary searching, which would cause its users like livepatch/ kprobe/bpf to not work properly on this sym! The case is that, based on current compiler behavior, suppose: - function A is followed by weak function B1 in same binary file; - weak function B1 is overridden by function B2; Then in the final binary file: - symbol B1 will be removed from symbol table while its instructions are not removed; - __fentry__ of B1 will be still in __mcount_loc table; - function size of A is computed by substracting the symbol address of A from its next symbol address (see kallsyms_lookup_size_offset()), but because symbol info of B1 is removed, the next symbol of A is originally the next symbol of B1. See following example, function sizeof A will be (symbol_address_C - symbol_address_A): symbol_address_A symbol_address_B1 (Not in symbol table) symbol_address_C The weak function issue has been discovered in commit b39181f7c690 ("ftrace: Add FTRACE_MCOUNT_MAX_OFFSET to avoid adding weak function") but it didn't resolve the issue in ftrace_location(). To solve the issue, with Peter's suggestions, in previous patches, all holes in the text have been found and filled with specail symbols, also the same case with module weak function has been handled. Then check and skip __fentry__ that locate in the holes. Also in this patch, introduce module_kallsyms_find_symbol() to check if a __fentry__ locate in a valid function of the given module. It is needed because other symbol lookup functions like module_address_lookup() will find module of the passed address first, but as ftrace_process_locs() is called, the module has not been fully loaded, so those lookup functions can not work. Fixes: aebfd12521d9 ("x86/ibt,ftrace: Search for __fentry__ location") Signed-off-by: Zheng Yejian --- include/linux/module.h | 7 +++++++ kernel/module/kallsyms.c | 23 +++++++++++++++++------ kernel/trace/ftrace.c | 12 +++++++++++- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 0299d79433ae..4f5dd018e33d 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -962,6 +962,8 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, unsigned long module_kallsyms_lookup_name(const char *name); unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name); +int module_kallsyms_find_symbol(struct module *mod, unsigned long addr, + unsigned long *size, unsigned long *offset); #else /* CONFIG_MODULES && CONFIG_KALLSYMS */ @@ -1006,6 +1008,11 @@ static inline unsigned long find_kallsyms_symbol_value(struct module *mod, return 0; } +static inline int module_kallsyms_find_symbol(struct module *mod, unsigned long addr, + unsigned long *size, unsigned long *offset) +{ + return 0; +} #endif /* CONFIG_MODULES && CONFIG_KALLSYMS */ #endif /* _LINUX_MODULE_H */ diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c index cce4f81b9933..71b3ed25cd40 100644 --- a/kernel/module/kallsyms.c +++ b/kernel/module/kallsyms.c @@ -253,10 +253,10 @@ static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned * Given a module and address, find the corresponding symbol and return its name * while providing its size and offset if needed. */ -static const char *find_kallsyms_symbol(struct module *mod, - unsigned long addr, - unsigned long *size, - unsigned long *offset) +static const char *__find_kallsyms_symbol(struct module *mod, + unsigned long addr, + unsigned long *size, + unsigned long *offset) { unsigned int i, best = 0; unsigned long nextval, bestval; @@ -326,6 +326,17 @@ static const char *find_kallsyms_symbol(struct module *mod, return kallsyms_symbol_name(kallsyms, best); } +int module_kallsyms_find_symbol(struct module *mod, unsigned long addr, + unsigned long *size, unsigned long *offset) +{ + const char *ret; + + preempt_disable(); + ret = __find_kallsyms_symbol(mod, addr, size, offset); + preempt_enable(); + return !!ret; +} + void * __weak dereference_module_function_descriptor(struct module *mod, void *ptr) { @@ -360,7 +371,7 @@ int module_address_lookup(unsigned long addr, #endif } - sym = find_kallsyms_symbol(mod, addr, size, offset); + sym = __find_kallsyms_symbol(mod, addr, size, offset); if (sym) ret = strscpy(namebuf, sym, KSYM_NAME_LEN); @@ -381,7 +392,7 @@ int lookup_module_symbol_name(unsigned long addr, char *symname) if (within_module(addr, mod)) { const char *sym; - sym = find_kallsyms_symbol(mod, addr, NULL, NULL); + sym = __find_kallsyms_symbol(mod, addr, NULL, NULL); if (!sym) goto out; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 0f579430f02a..fff5d3466c41 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -6989,6 +6989,16 @@ static void test_is_sorted(unsigned long *start, unsigned long count) } #endif +static int is_invalid_rec(struct module *mod, unsigned long addr) +{ + char str[KSYM_SYMBOL_LEN]; + + if (mod) + return !module_kallsyms_find_symbol(mod, addr, NULL, NULL); + + return !kallsyms_lookup(addr, NULL, NULL, NULL, str); +} + static int ftrace_process_locs(struct module *mod, unsigned long *start, unsigned long *end) @@ -7060,7 +7070,7 @@ static int ftrace_process_locs(struct module *mod, * object files to satisfy alignments. * Skip any NULL pointers. */ - if (!addr) { + if (!addr || is_invalid_rec(mod, addr)) { skipped++; continue; } From patchwork Tue Jul 23 06:32:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zheng Yejian X-Patchwork-Id: 13739397 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A1AA514A60F; Tue, 23 Jul 2024 06:32:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721716332; cv=none; b=XdK41ISXaW0SLCu3E1Uti+JAs4nScDLGJIyIPtOCQ4hbBKf2L6tSdX8sY0U6jXuhJZbW2JS/s+GOB9d+AfPzM1jfRjC9OsZjfOteZpeknd5htVXAxNnRRM/f1FpjrYzWMQAH4i0K1l7YhYqY4a/SDgTaZ7b10a7XzkpLaV/LX6Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721716332; c=relaxed/simple; bh=MHUArHOlS3ABc3VTGuZAUpyYis5yQzmCYZycpKOAu6o=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=j4hRpUhbQqlKQyAOYnf7fNPfCN6SQA+Uvm3zh0rlQT7quUE/vqpFHaZvF7j16DdO5pBIfO3fqpFg/HC3Nuajse3R5ier4uJcl8jV6hKRI2msJdOtLuN0BfM09tDexmfD388dzkJGXKUkZURaDGLh0OtUoLZSk4mV8APeIezRt6g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.235]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTP id 4WSnP13nP3z4f3khJ; Tue, 23 Jul 2024 14:31:49 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.75]) by mail.maildlp.com (Postfix) with ESMTP id DDC8E1A06D6; Tue, 23 Jul 2024 14:32:01 +0800 (CST) Received: from localhost.localdomain (unknown [10.67.175.61]) by APP2 (Coremail) with SMTP id Syh0CgA34wpOTp9mjImuAw--.48686S6; Tue, 23 Jul 2024 14:32:01 +0800 (CST) From: Zheng Yejian To: masahiroy@kernel.org, peterz@infradead.org, rostedt@goodmis.org, mhiramat@kernel.org, mark.rutland@arm.com, mpe@ellerman.id.au, npiggin@gmail.com, christophe.leroy@csgroup.eu, naveen.n.rao@linux.ibm.com, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, mcgrof@kernel.org, mathieu.desnoyers@efficios.com, nathan@kernel.org, nicolas@fjasle.eu, ojeda@kernel.org, akpm@linux-foundation.org, surenb@google.com, pasha.tatashin@soleen.com, kent.overstreet@linux.dev, james.clark@arm.com, jpoimboe@kernel.org Cc: x86@kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-modules@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, zhengyejian@huaweicloud.com Subject: [PATCH v2 4/5] ftrace: Fix possible out-of-bound issue in ftrace_process_locs() Date: Tue, 23 Jul 2024 14:32:57 +0800 Message-Id: <20240723063258.2240610-5-zhengyejian@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240723063258.2240610-1-zhengyejian@huaweicloud.com> References: <20240723063258.2240610-1-zhengyejian@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-kbuild@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: Syh0CgA34wpOTp9mjImuAw--.48686S6 X-Coremail-Antispam: 1UD129KBjvJXoW7urykXF47Aw15uF47WrWfXwb_yoW8tFWDpF W5Kan3tr4DJa9I9anIga1kWFyfJ3yrG3y8Ga13G3s3Awn3Gr409r12vrnxZr9xJr95trW2 kF4jvrsxGFWxXrDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr1j6r xdM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0D M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjx v20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1l F7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8cxan2 IY04v7MxkF7I0En4kS14v26rWY6Fy7MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY 6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17 CEb7AF67AKxVWrXVW8Jr1lIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0pR4E__UUUUU= X-CM-SenderInfo: x2kh0w51hmxt3q6k3tpzhluzxrxghudrp/ In ftrace_process_locs(), a series pages are prepared and linked in start_pg, then fentry records are skipped or added, then unused pages are freed. However, assume that all records are skipped, currently the start_pg will still be in list of ftrace_pages_start but without any record. Then in ftrace_free_mem() index record by (pg->index - 1) will be out of bound. To fix this issue, properly handle with unused start_pg and add WARN_ON_ONCE() where the records need to be indexed. Fixes: 26efd79c4624 ("ftrace: Fix possible warning on checking all pages used in ftrace_process_locs()") Signed-off-by: Zheng Yejian --- kernel/trace/ftrace.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index fff5d3466c41..6947be8801d9 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -7087,10 +7087,22 @@ static int ftrace_process_locs(struct module *mod, rec->ip = addr; } - if (pg->next) { + if (pg->index == 0) { + /* No record is added on the current page, so it's unused */ + pg_unuse = pg; + } else if (pg->next) { + /* Current page has records, so it's next page is unused */ pg_unuse = pg->next; pg->next = NULL; } + /* + * Even the start_pg hasn't been used, that means, no record has + * been added, so restore state of ftrace_pages and just go out. + */ + if (pg_unuse == start_pg) { + ftrace_pages->next = NULL; + goto out; + } /* Assign the last page to ftrace_pages */ ftrace_pages = pg; @@ -7306,6 +7318,8 @@ void ftrace_release_mod(struct module *mod) */ last_pg = &ftrace_pages_start; for (pg = ftrace_pages_start; pg; pg = *last_pg) { + /* The page should have at lease one record */ + WARN_ON_ONCE(!pg->index); rec = &pg->records[0]; if (within_module(rec->ip, mod)) { /* @@ -7685,6 +7699,8 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) mod_map = allocate_ftrace_mod_map(mod, start, end); for (pg = ftrace_pages_start; pg; last_pg = &pg->next, pg = *last_pg) { + /* The page should have at lease one record */ + WARN_ON_ONCE(!pg->index); if (end < pg->records[0].ip || start >= (pg->records[pg->index - 1].ip + MCOUNT_INSN_SIZE)) continue; From patchwork Tue Jul 23 06:32:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zheng Yejian X-Patchwork-Id: 13739395 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F10F313C8F9; Tue, 23 Jul 2024 06:32:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721716330; cv=none; b=q6NR2CN8/I3X2UQ/0ZTkRasmLRwhzgicVw7PFCE0PwpIJhjYH8hNCyBDNpBMD8WqZj4RquYbcl68M8M7q6C80eJaydZ8X8ZrvFpmVx70lA6p4hg/LUOQqjDMbBblFXdQZK5OEjzZcyfhxTaWyBgII9d47VZE7RV+Z/YfkBX17pY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721716330; c=relaxed/simple; bh=5cGJToLxMVX7rT0OWUoOXanxJBRHKsYsfRfzUURgNtE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=pqlHRVSn34sgC/nE50eRC1p30JqYpUjLvKJbDK9mJW7ooF7/uwOBxPuYySMwh7eAMfhi6LcsJwXnB8rkvdUGYBZdGtCio2V1/RwLKYNTyucu21VjEfNAADqWp0hPdjkel4s31hVTAfFqfjUwJxuZJOHGHZ0IGmDreLpv5YYkgkk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.235]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTP id 4WSnP55gp0z4f3jZ8; Tue, 23 Jul 2024 14:31:53 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.75]) by mail.maildlp.com (Postfix) with ESMTP id 0C4941A0568; Tue, 23 Jul 2024 14:32:02 +0800 (CST) Received: from localhost.localdomain (unknown [10.67.175.61]) by APP2 (Coremail) with SMTP id Syh0CgA34wpOTp9mjImuAw--.48686S7; Tue, 23 Jul 2024 14:32:01 +0800 (CST) From: Zheng Yejian To: masahiroy@kernel.org, peterz@infradead.org, rostedt@goodmis.org, mhiramat@kernel.org, mark.rutland@arm.com, mpe@ellerman.id.au, npiggin@gmail.com, christophe.leroy@csgroup.eu, naveen.n.rao@linux.ibm.com, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, mcgrof@kernel.org, mathieu.desnoyers@efficios.com, nathan@kernel.org, nicolas@fjasle.eu, ojeda@kernel.org, akpm@linux-foundation.org, surenb@google.com, pasha.tatashin@soleen.com, kent.overstreet@linux.dev, james.clark@arm.com, jpoimboe@kernel.org Cc: x86@kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-modules@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, zhengyejian@huaweicloud.com Subject: [PATCH v2 5/5] ftrace: Revert the FTRACE_MCOUNT_MAX_OFFSET workaround Date: Tue, 23 Jul 2024 14:32:58 +0800 Message-Id: <20240723063258.2240610-6-zhengyejian@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240723063258.2240610-1-zhengyejian@huaweicloud.com> References: <20240723063258.2240610-1-zhengyejian@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-kbuild@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: Syh0CgA34wpOTp9mjImuAw--.48686S7 X-Coremail-Antispam: 1UD129KBjvJXoWxKFy7Cw17Zw1kCFy7CF4kWFg_yoW3GFWfpF ZIya1qgrW7CF4jga9Fgr1DCFyakrn0kryaq3yDG34FywnYqr4j9F92yrWqvr97JrWkCa4f XFW7ZrW2yFnxZ3JanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmS14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr1j6r xdM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0D M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjx v20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1l F7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8cxan2 IY04v7MxkF7I0En4kS14v26rWY6Fy7MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY 6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17 CEb7AF67AKxVWrXVW8Jr1lIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBI daVFxhVjvjDU0xZFpf9x0pR4E__UUUUU= X-CM-SenderInfo: x2kh0w51hmxt3q6k3tpzhluzxrxghudrp/ After patch titled "ftrace: Skip invalid __fentry__ in ftrace_process_locs()", __fentry__ locations in overridden weak function have been checked and skipped, then all records in ftrace_pages are valid, the FTRACE_MCOUNT_MAX_OFFSET workaround can be reverted, include: 1. commit b39181f7c690 ("ftrace: Add FTRACE_MCOUNT_MAX_OFFSET to avoid adding weak function") 2. commit 7af82ff90a2b ("powerpc/ftrace: Ignore weak functions") 3. commit f6834c8c59a8 ("powerpc/ftrace: Fix dropping weak symbols with older toolchains") Signed-off-by: Zheng Yejian --- arch/powerpc/include/asm/ftrace.h | 7 -- arch/x86/include/asm/ftrace.h | 7 -- kernel/trace/ftrace.c | 141 +----------------------------- 3 files changed, 2 insertions(+), 153 deletions(-) diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index 559560286e6d..328cf55acfb7 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h @@ -8,13 +8,6 @@ #define MCOUNT_ADDR ((unsigned long)(_mcount)) #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ -/* Ignore unused weak functions which will have larger offsets */ -#if defined(CONFIG_MPROFILE_KERNEL) || defined(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY) -#define FTRACE_MCOUNT_MAX_OFFSET 16 -#elif defined(CONFIG_PPC32) -#define FTRACE_MCOUNT_MAX_OFFSET 8 -#endif - #ifndef __ASSEMBLY__ extern void _mcount(void); diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index 0152a81d9b4a..6a3a4a8830dc 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h @@ -9,13 +9,6 @@ # define MCOUNT_ADDR ((unsigned long)(__fentry__)) #define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */ -/* Ignore unused weak functions which will have non zero offsets */ -#ifdef CONFIG_HAVE_FENTRY -# include -/* Add offset for endbr64 if IBT enabled */ -# define FTRACE_MCOUNT_MAX_OFFSET ENDBR_INSN_SIZE -#endif - #ifdef CONFIG_DYNAMIC_FTRACE #define ARCH_SUPPORTS_FTRACE_OPS 1 #endif diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 6947be8801d9..37510c591498 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -49,8 +49,6 @@ #define FTRACE_NOCLEAR_FLAGS (FTRACE_FL_DISABLED | FTRACE_FL_TOUCHED | \ FTRACE_FL_MODIFIED) -#define FTRACE_INVALID_FUNCTION "__ftrace_invalid_address__" - #define FTRACE_WARN_ON(cond) \ ({ \ int ___r = cond; \ @@ -4208,105 +4206,6 @@ static void add_trampoline_func(struct seq_file *m, struct ftrace_ops *ops, seq_printf(m, " ->%pS", ptr); } -#ifdef FTRACE_MCOUNT_MAX_OFFSET -/* - * Weak functions can still have an mcount/fentry that is saved in - * the __mcount_loc section. These can be detected by having a - * symbol offset of greater than FTRACE_MCOUNT_MAX_OFFSET, as the - * symbol found by kallsyms is not the function that the mcount/fentry - * is part of. The offset is much greater in these cases. - * - * Test the record to make sure that the ip points to a valid kallsyms - * and if not, mark it disabled. - */ -static int test_for_valid_rec(struct dyn_ftrace *rec) -{ - char str[KSYM_SYMBOL_LEN]; - unsigned long offset; - const char *ret; - - ret = kallsyms_lookup(rec->ip, NULL, &offset, NULL, str); - - /* Weak functions can cause invalid addresses */ - if (!ret || offset > FTRACE_MCOUNT_MAX_OFFSET) { - rec->flags |= FTRACE_FL_DISABLED; - return 0; - } - return 1; -} - -static struct workqueue_struct *ftrace_check_wq __initdata; -static struct work_struct ftrace_check_work __initdata; - -/* - * Scan all the mcount/fentry entries to make sure they are valid. - */ -static __init void ftrace_check_work_func(struct work_struct *work) -{ - struct ftrace_page *pg; - struct dyn_ftrace *rec; - - mutex_lock(&ftrace_lock); - do_for_each_ftrace_rec(pg, rec) { - test_for_valid_rec(rec); - } while_for_each_ftrace_rec(); - mutex_unlock(&ftrace_lock); -} - -static int __init ftrace_check_for_weak_functions(void) -{ - INIT_WORK(&ftrace_check_work, ftrace_check_work_func); - - ftrace_check_wq = alloc_workqueue("ftrace_check_wq", WQ_UNBOUND, 0); - - queue_work(ftrace_check_wq, &ftrace_check_work); - return 0; -} - -static int __init ftrace_check_sync(void) -{ - /* Make sure the ftrace_check updates are finished */ - if (ftrace_check_wq) - destroy_workqueue(ftrace_check_wq); - return 0; -} - -late_initcall_sync(ftrace_check_sync); -subsys_initcall(ftrace_check_for_weak_functions); - -static int print_rec(struct seq_file *m, unsigned long ip) -{ - unsigned long offset; - char str[KSYM_SYMBOL_LEN]; - char *modname; - const char *ret; - - ret = kallsyms_lookup(ip, NULL, &offset, &modname, str); - /* Weak functions can cause invalid addresses */ - if (!ret || offset > FTRACE_MCOUNT_MAX_OFFSET) { - snprintf(str, KSYM_SYMBOL_LEN, "%s_%ld", - FTRACE_INVALID_FUNCTION, offset); - ret = NULL; - } - - seq_puts(m, str); - if (modname) - seq_printf(m, " [%s]", modname); - return ret == NULL ? -1 : 0; -} -#else -static inline int test_for_valid_rec(struct dyn_ftrace *rec) -{ - return 1; -} - -static inline int print_rec(struct seq_file *m, unsigned long ip) -{ - seq_printf(m, "%ps", (void *)ip); - return 0; -} -#endif - static int t_show(struct seq_file *m, void *v) { struct ftrace_iterator *iter = m->private; @@ -4334,13 +4233,7 @@ static int t_show(struct seq_file *m, void *v) if (iter->flags & FTRACE_ITER_ADDRS) seq_printf(m, "%lx ", rec->ip); - if (print_rec(m, rec->ip)) { - /* This should only happen when a rec is disabled */ - WARN_ON_ONCE(!(rec->flags & FTRACE_FL_DISABLED)); - seq_putc(m, '\n'); - return 0; - } - + seq_printf(m, "%ps", (void *)rec->ip); if (iter->flags & (FTRACE_ITER_ENABLED | FTRACE_ITER_TOUCHED)) { struct ftrace_ops *ops; @@ -4720,24 +4613,6 @@ add_rec_by_index(struct ftrace_hash *hash, struct ftrace_glob *func_g, return 0; } -#ifdef FTRACE_MCOUNT_MAX_OFFSET -static int lookup_ip(unsigned long ip, char **modname, char *str) -{ - unsigned long offset; - - kallsyms_lookup(ip, NULL, &offset, modname, str); - if (offset > FTRACE_MCOUNT_MAX_OFFSET) - return -1; - return 0; -} -#else -static int lookup_ip(unsigned long ip, char **modname, char *str) -{ - kallsyms_lookup(ip, NULL, NULL, modname, str); - return 0; -} -#endif - static int ftrace_match_record(struct dyn_ftrace *rec, struct ftrace_glob *func_g, struct ftrace_glob *mod_g, int exclude_mod) @@ -4745,12 +4620,7 @@ ftrace_match_record(struct dyn_ftrace *rec, struct ftrace_glob *func_g, char str[KSYM_SYMBOL_LEN]; char *modname; - if (lookup_ip(rec->ip, &modname, str)) { - /* This should only happen when a rec is disabled */ - WARN_ON_ONCE(system_state == SYSTEM_RUNNING && - !(rec->flags & FTRACE_FL_DISABLED)); - return 0; - } + kallsyms_lookup(rec->ip, NULL, NULL, &modname, str); if (mod_g) { int mod_matches = (modname) ? ftrace_match(modname, mod_g) : 0; @@ -7399,13 +7269,6 @@ void ftrace_module_enable(struct module *mod) if (!within_module(rec->ip, mod)) break; - /* Weak functions should still be ignored */ - if (!test_for_valid_rec(rec)) { - /* Clear all other flags. Should not be enabled anyway */ - rec->flags = FTRACE_FL_DISABLED; - continue; - } - cnt = 0; /*