From nobody Thu Apr 2 20:08:15 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4906D3A7F49 for ; Thu, 26 Mar 2026 21:21:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774560101; cv=none; b=bZfPNOVtPTqjzXo46qN16EfV5Y8Qqq5fjHB9yDtFiXhqFsvRyNjqqqujpD3LmYcIfEoHiFRliemXldPaF8s0OnP15zIR2nH/sjMoxQr4KMpe2fcGQQACSdf8GlB26aZok7yTBTHEKW7Lxd3YGggC9FcsmgMZOcR+ogUZRm+sV8g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774560101; c=relaxed/simple; bh=siB77Fn1mr2A8ag+YsCmtEedmZaaEXq5RbfZxU90iRg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=QnJpe03up6qX88Ar3yv7gffL1k3EKjtE+DNiikiibL/LP2Bl39B5eZ0tAtusKGaKuTi5K34Z6IluirZVN1JmYWDKPclQVRZgJDZ/3GZBs+mx4FHI9zDv5/UF6tr+PBuyQNL/MrP/+15uFdfGtWIFQWDiBO5TELpqeRuX8hUZ/+o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--sidnayyar.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=i3cv8mzm; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--sidnayyar.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="i3cv8mzm" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-486fc42c83aso11601805e9.0 for ; Thu, 26 Mar 2026 14:21:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774560097; x=1775164897; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=66LkDoxiIORn8ltcTUmDR4YaWJ5RIn42FKIzW6ohdiA=; b=i3cv8mzmpzMqlGu0BdoigL+8b1gTnQyLpMhM5OTPvsvQ1DhI0Rj83iEaZ44bGHrxAg JVcBXh70XdgvmXGQGA3KEBn+Xq9w5jUp1aE8s4ziRusboBvbA7NLoPrtyq3c3IfeEAvd ci8rguZBmGW2G+2T38ag2w3enE5p83xLZG0upeEff7zRjaJQ4APfeFbbnFEqu894zyte gmKeZGF6D3XFSIYB82oFYRHtL+fpgOFbq9LAjyrH+F8n5kzzVdkoWaHFLT9JSbg0Ah63 K3dnQ6eqBH1z2M2QNKAjjupZLXnNYN5pFWw/B4W9PB/eaUvucelXSlsgZOhMRZ5fpcVP 4PnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774560097; x=1775164897; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=66LkDoxiIORn8ltcTUmDR4YaWJ5RIn42FKIzW6ohdiA=; b=lvyL60tXzzpsvXwEIoEl4tw0M1rqCVa8bW+/tyeO/zwk2fCfYXV7Wzw4iwctEANSMd 0rAD5a/4Jw2Pb220o0uQMqYMD0AtqW3Ya4tQIaEIrtuAmJZervJ3oDlSjQGmwtloEVy4 Cvo9V2R7JaIwliDGlVRVomSTRL8YBeC1+tIgn4Lhf/Jmqy33uk3E1068q35M9ng6WCq4 xPmYKUniZ/SlGffhTq4aaauRsOnJeBWYX6GUAUAXHx4iJ3O4V3IR9jKzApYuEskRCAYC HJ4NTA7jHn7d3zbUHaFP2ZX2O/9iloowe2nJ6zTtxceJ1zDcUpzmCsd0evLdjL8/f1w4 /3Xw== X-Forwarded-Encrypted: i=1; AJvYcCV4/UDD7QMQm76j/T/B69/aDuXFXwvymVhvS00TcI3ZZZ/9ROGukZyI/cI+YNaXz9B6rbywX0MCaZIE7mQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxaV7lFivFHc5bh+JLOcbAeE+jYwOJMBlbI9stVes2sOLF0flOq pWANcH/cv9JqjjYHk3NdXAlTCRoqwo9RJwX6I9/52k+kJZsUdm45wEI7SFazy/df/HM82yun3v/ cSDCLGH0bqCumeUgURQ== X-Received: from wruo7.prod.google.com ([2002:a5d:6707:0:b0:43b:88ab:dd35]) (user=sidnayyar job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:a06:b0:487:1108:48af with SMTP id 5b1f17b1804b1-48727d59ce3mr4100605e9.4.1774560097408; Thu, 26 Mar 2026 14:21:37 -0700 (PDT) Date: Thu, 26 Mar 2026 21:21:32 +0000 In-Reply-To: <20260326-kflagstab-v5-0-455cd723dddf@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260326-kflagstab-v5-0-455cd723dddf@google.com> X-Mailer: b4 0.14.3 Message-ID: <20260326-kflagstab-v5-4-455cd723dddf@google.com> Subject: [PATCH v5 4/7] module: use kflagstab instead of *_gpl sections From: Siddharth Nayyar To: Luis Chamberlain , Petr Pavlu , Daniel Gomez , Sami Tolvanen , Aaron Tomlin , Arnd Bergmann , Nathan Chancellor , Nicolas Schier , Jonathan Corbet , Shuah Khan Cc: linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, linux-kbuild@vger.kernel.org, linux-doc@vger.kernel.org, Siddharth Nayyar , gprocida@google.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Read kflagstab section for vmlinux and modules to determine whether kernel symbols are GPL only. This patch eliminates the need for fragmenting the ksymtab for infering the value of GPL-only symbol flag, henceforth stop using the *_gpl versions of the ksymtab and kcrctab in modpost. Signed-off-by: Siddharth Nayyar Reviewed-by: Petr Pavlu --- include/linux/export-internal.h | 21 ++++++++-------- include/linux/module.h | 1 + kernel/module/internal.h | 1 + kernel/module/main.c | 55 ++++++++++++++++++++++---------------= ---- scripts/mod/modpost.c | 8 +++--- 5 files changed, 46 insertions(+), 40 deletions(-) diff --git a/include/linux/export-internal.h b/include/linux/export-interna= l.h index 4123c7592404..726054614752 100644 --- a/include/linux/export-internal.h +++ b/include/linux/export-internal.h @@ -37,14 +37,14 @@ * section flag requires it. Use '%progbits' instead of '@progbits' since = the * former apparently works on all arches according to the binutils source. */ -#define __KSYMTAB(name, sym, sec, ns) \ +#define __KSYMTAB(name, sym, ns) \ asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1" "\n" \ "__kstrtab_" #name ":" "\n" \ " .asciz \"" #name "\"" "\n" \ "__kstrtabns_" #name ":" "\n" \ " .asciz \"" ns "\"" "\n" \ " .previous" "\n" \ - " .section \"___ksymtab" sec "+" #name "\", \"a\"" "\n" \ + " .section \"___ksymtab+" #name "\", \"a\"" "\n" \ __KSYM_ALIGN "\n" \ "__ksymtab_" #name ":" "\n" \ __KSYM_REF(sym) "\n" \ @@ -59,15 +59,16 @@ #define KSYM_FUNC(name) name #endif =20 -#define KSYMTAB_FUNC(name, sec, ns) __KSYMTAB(name, KSYM_FUNC(name), sec, = ns) -#define KSYMTAB_DATA(name, sec, ns) __KSYMTAB(name, name, sec, ns) +#define KSYMTAB_FUNC(name, ns) __KSYMTAB(name, KSYM_FUNC(name), ns) +#define KSYMTAB_DATA(name, ns) __KSYMTAB(name, name, ns) =20 -#define SYMBOL_CRC(sym, crc, sec) \ - asm(".section \"___kcrctab" sec "+" #sym "\",\"a\"" "\n" \ - ".balign 4" "\n" \ - "__crc_" #sym ":" "\n" \ - ".long " #crc "\n" \ - ".previous" "\n") +#define SYMBOL_CRC(sym, crc) \ + asm(" .section \"___kcrctab+" #sym "\",\"a\"" "\n" \ + " .balign 4" "\n" \ + "__crc_" #sym ":" "\n" \ + " .long " #crc "\n" \ + " .previous" "\n" \ + ) =20 #define SYMBOL_FLAGS(sym, flags) \ asm(" .section \"___kflagstab+" #sym "\",\"a\"" "\n" \ diff --git a/include/linux/module.h b/include/linux/module.h index 14f391b186c6..aee3accba73c 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -418,6 +418,7 @@ struct module { /* Exported symbols */ const struct kernel_symbol *syms; const u32 *crcs; + const u8 *flagstab; unsigned int num_syms; =20 #ifdef CONFIG_ARCH_USES_CFI_TRAPS diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 618202578b42..69b84510e097 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -57,6 +57,7 @@ extern const struct kernel_symbol __start___ksymtab_gpl[]; extern const struct kernel_symbol __stop___ksymtab_gpl[]; extern const u32 __start___kcrctab[]; extern const u32 __start___kcrctab_gpl[]; +extern const u8 __start___kflagstab[]; =20 #define KMOD_PATH_LEN 256 extern char modprobe_path[]; diff --git a/kernel/module/main.c b/kernel/module/main.c index c3ce106c70af..d237fa4e0737 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,7 @@ struct mod_tree_root mod_tree __cacheline_aligned =3D { struct symsearch { const struct kernel_symbol *start, *stop; const u32 *crcs; - enum mod_license license; + const u8 *flagstab; }; =20 /* @@ -364,19 +365,21 @@ static bool find_exported_symbol_in_section(const str= uct symsearch *syms, struct find_symbol_arg *fsa) { struct kernel_symbol *sym; - - if (!fsa->gplok && syms->license =3D=3D GPL_ONLY) - return false; + u8 sym_flags; =20 sym =3D bsearch(fsa->name, syms->start, syms->stop - syms->start, sizeof(struct kernel_symbol), cmp_name); if (!sym) return false; =20 + sym_flags =3D *(syms->flagstab + (sym - syms->start)); + if (!fsa->gplok && (sym_flags & KSYM_FLAG_GPL_ONLY)) + return false; + fsa->owner =3D owner; fsa->crc =3D symversion(syms->crcs, sym - syms->start); fsa->sym =3D sym; - fsa->license =3D syms->license; + fsa->license =3D (sym_flags & KSYM_FLAG_GPL_ONLY) ? GPL_ONLY : NOT_GPL_ON= LY; =20 return true; } @@ -387,36 +390,31 @@ static bool find_exported_symbol_in_section(const str= uct symsearch *syms, */ bool find_symbol(struct find_symbol_arg *fsa) { - static const struct symsearch arr[] =3D { - { __start___ksymtab, __stop___ksymtab, __start___kcrctab, - NOT_GPL_ONLY }, - { __start___ksymtab_gpl, __stop___ksymtab_gpl, - __start___kcrctab_gpl, - GPL_ONLY }, + const struct symsearch syms =3D { + .start =3D __start___ksymtab, + .stop =3D __stop___ksymtab, + .crcs =3D __start___kcrctab, + .flagstab =3D __start___kflagstab, }; struct module *mod; - unsigned int i; =20 - for (i =3D 0; i < ARRAY_SIZE(arr); i++) - if (find_exported_symbol_in_section(&arr[i], NULL, fsa)) - return true; + if (find_exported_symbol_in_section(&syms, NULL, fsa)) + return true; =20 list_for_each_entry_rcu(mod, &modules, list, lockdep_is_held(&module_mutex)) { - struct symsearch arr[] =3D { - { mod->syms, mod->syms + mod->num_syms, mod->crcs, - NOT_GPL_ONLY }, - { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms, - mod->gpl_crcs, - GPL_ONLY }, + const struct symsearch syms =3D { + .start =3D mod->syms, + .stop =3D mod->syms + mod->num_syms, + .crcs =3D mod->crcs, + .flagstab =3D mod->flagstab, }; =20 if (mod->state =3D=3D MODULE_STATE_UNFORMED) continue; =20 - for (i =3D 0; i < ARRAY_SIZE(arr); i++) - if (find_exported_symbol_in_section(&arr[i], mod, fsa)) - return true; + if (find_exported_symbol_in_section(&syms, mod, fsa)) + return true; } =20 pr_debug("Failed to find symbol %s\n", fsa->name); @@ -2614,6 +2612,7 @@ static int find_module_sections(struct module *mod, s= truct load_info *info) sizeof(*mod->gpl_syms), &mod->num_gpl_syms); mod->gpl_crcs =3D section_addr(info, "__kcrctab_gpl"); + mod->flagstab =3D section_addr(info, "__kflagstab"); =20 #ifdef CONFIG_CONSTRUCTORS mod->ctors =3D section_objs(info, ".ctors", @@ -2817,8 +2816,12 @@ static int move_module(struct module *mod, struct lo= ad_info *info) return ret; } =20 -static int check_export_symbol_versions(struct module *mod) +static int check_export_symbol_sections(struct module *mod) { + if (mod->num_syms && !mod->flagstab) { + pr_err("%s: no flags for exported symbols\n", mod->name); + return -ENOEXEC; + } #ifdef CONFIG_MODVERSIONS if ((mod->num_syms && !mod->crcs) || (mod->num_gpl_syms && !mod->gpl_crcs)) { @@ -3434,7 +3437,7 @@ static int load_module(struct load_info *info, const = char __user *uargs, if (err) goto free_unload; =20 - err =3D check_export_symbol_versions(mod); + err =3D check_export_symbol_sections(mod); if (err) goto free_unload; =20 diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1d721fe67caf..9d96acce60a8 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1876,9 +1876,9 @@ static void add_exported_symbols(struct buffer *buf, = struct module *mod) if (trim_unused_exports && !sym->used) continue; =20 - buf_printf(buf, "KSYMTAB_%s(%s, \"%s\", \"%s\");\n", + buf_printf(buf, "KSYMTAB_%s(%s, \"%s\");\n", sym->is_func ? "FUNC" : "DATA", sym->name, - sym->is_gpl_only ? "_gpl" : "", sym->namespace); + sym->namespace); =20 buf_printf(buf, "SYMBOL_FLAGS(%s, 0x%02x);\n", sym->name, get_symbol_flags(sym)); @@ -1899,8 +1899,8 @@ static void add_exported_symbols(struct buffer *buf, = struct module *mod) sym->name, mod->name, mod->is_vmlinux ? "" : ".ko", sym->name); =20 - buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n", - sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : ""); + buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x);\n", + sym->name, sym->crc); } } =20 --=20 2.53.0.1018.g2bb0e51243-goog