From 654102df2ac2a0d02a416100c3d44ff1dae932ca Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 23 Sep 2024 16:56:03 +0900 Subject: kbuild: add generic support for built-in boot DTBs Some architectures embed boot DTBs in vmlinux. A potential issue for these architectures is a race condition during parallel builds because Kbuild descends into arch/*/boot/dts/ twice. One build thread is initiated by the 'dtbs' target, which is a prerequisite of the 'all' target in the top-level Makefile: ifdef CONFIG_OF_EARLY_FLATTREE all: dtbs endif For architectures that support the built-in boot dtb, arch/*/boot/dts/ is visited also during the ordinary directory traversal in order to build obj-y objects that wrap DTBs. Since these build threads are unaware of each other, they can run simultaneously during parallel builds. This commit introduces a generic build rule to scripts/Makefile.vmlinux to support embedded boot DTBs in a race-free way. Architectures that want to use this rule need to select CONFIG_GENERIC_BUILTIN_DTB. After the migration, Makefiles under arch/*/boot/dts/ will be visited only once to build only *.dtb files. This change also aims to unify the CONFIG options used for built-in DTBs support. Currently, different architectures use different CONFIG options for the same purposes. With this commit, the CONFIG options will be unified as follows: - CONFIG_GENERIC_BUILTIN_DTB This enables the generic rule for built-in boot DTBs. This will be renamed to CONFIG_BUILTIN_DTB after all architectures migrate to the generic rule. - CONFIG_BUILTIN_DTB_NAME This specifies the path to the embedded DTB. (relative to arch/*/boot/dts/) - CONFIG_BUILTIN_DTB_ALL If this is enabled, all DTB files compiled under arch/*/boot/dts/ are embedded into vmlinux. Only used by MIPS. Signed-off-by: Masahiro Yamada --- scripts/Makefile.vmlinux | 44 ++++++++++++++++++++++++++++++++++++++++++++ scripts/link-vmlinux.sh | 4 ++++ 2 files changed, 48 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 1284f05555b9..9ef0480ed755 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -17,6 +17,50 @@ quiet_cmd_cc_o_c = CC $@ %.o: %.c FORCE $(call if_changed_dep,cc_o_c) +quiet_cmd_as_o_S = AS $@ + cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< + +%.o: %.S FORCE + $(call if_changed_dep,as_o_S) + +# Built-in dtb +# --------------------------------------------------------------------------- + +quiet_cmd_wrap_dtbs = WRAP $@ + cmd_wrap_dtbs = { \ + echo '\#include '; \ + echo '.section .dtb.init.rodata,"a"'; \ + while read dtb; do \ + symbase=__dtb_$$(basename -s .dtb "$${dtb}" | tr - _); \ + echo '.balign STRUCT_ALIGNMENT'; \ + echo ".global $${symbase}_begin"; \ + echo "$${symbase}_begin:"; \ + echo '.incbin "'$$dtb'" '; \ + echo ".global $${symbase}_end"; \ + echo "$${symbase}_end:"; \ + done < $<; \ + } > $@ + +.builtin-dtbs.S: .builtin-dtbs-list FORCE + $(call if_changed,wrap_dtbs) + +quiet_cmd_gen_dtbs_list = GEN $@ + cmd_gen_dtbs_list = \ + $(if $(CONFIG_BUILTIN_DTB_NAME), echo "arch/$(SRCARCH)/boot/dts/$(CONFIG_BUILTIN_DTB_NAME).dtb",:) > $@ + +.builtin-dtbs-list: arch/$(SRCARCH)/boot/dts/dtbs-list FORCE + $(call if_changed,$(if $(CONFIG_BUILTIN_DTB_ALL),copy,gen_dtbs_list)) + +targets += .builtin-dtbs-list + +ifdef CONFIG_GENERIC_BUILTIN_DTB +targets += .builtin-dtbs.S .builtin-dtbs.o +vmlinux: .builtin-dtbs.o +endif + +# vmlinux +# --------------------------------------------------------------------------- + ifdef CONFIG_MODULES targets += .vmlinux.export.o vmlinux: .vmlinux.export.o diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index a9b3f34a78d2..53bd4b727e21 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -68,6 +68,10 @@ vmlinux_link() libs="${KBUILD_VMLINUX_LIBS}" fi + if is_enabled CONFIG_GENERIC_BUILTIN_DTB; then + objs="${objs} .builtin-dtbs.o" + fi + if is_enabled CONFIG_MODULES; then objs="${objs} .vmlinux.export.o" fi -- cgit From bea2c5ef789a37bace99f2f45eeef3be4559b228 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 30 Sep 2024 02:32:37 +0900 Subject: kconfig: remove support for "bool" prompt for choice entries Since commit fde192511bdb ("kconfig: remove tristate choice support"), all choice blocks are now boolean. There is no longer a need to specify the choice type explicitly. All "bool" prompts in choice entries have been converted to "prompt". This commit removes support for the "bool" syntax in choice entries. Signed-off-by: Masahiro Yamada --- scripts/kconfig/parser.y | 6 ------ 1 file changed, 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index bc43fb67c7c4..f0f17b21d1b5 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -293,12 +293,6 @@ choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno); }; -choice_option: T_BOOL T_WORD_QUOTE if_expr T_EOL -{ - menu_add_prompt(P_PROMPT, $2, $3); - printd(DEBUG_PARSE, "%s:%d:bool\n", cur_filename, cur_lineno); -}; - choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL { menu_add_symbol(P_DEFAULT, $2, $3); -- cgit From 6971f7192c12043667173cc78fe88d52ff7ee488 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 30 Sep 2024 02:32:38 +0900 Subject: kconfig: remove zconfprint() Turn all warnings during parsing into hard errors. Signed-off-by: Masahiro Yamada --- scripts/kconfig/parser.y | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index f0f17b21d1b5..68372d3ff325 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -24,7 +24,6 @@ int cdebug = PRINTD; static void yyerror(const char *err); -static void zconfprint(const char *err, ...); static void zconf_error(const char *err, ...); static bool zconf_endtoken(const char *tokenname, const char *expected_tokenname); @@ -183,7 +182,7 @@ menuconfig_stmt: menuconfig_entry_start config_option_list if (current_entry->prompt) current_entry->prompt->type = P_MENU; else - zconfprint("warning: menuconfig statement without prompt"); + zconf_error("menuconfig statement without prompt"); printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno); }; @@ -402,14 +401,14 @@ help: help_start T_HELPTEXT { if (current_entry->help) { free(current_entry->help); - zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used", - current_entry->sym->name ?: ""); + zconf_error("'%s' defined with more than one help text", + current_entry->sym->name ?: ""); } /* Is the help text empty or all whitespace? */ if ($2[strspn($2, " \f\n\r\t\v")] == '\0') - zconfprint("warning: '%s' defined with blank help text", - current_entry->sym->name ?: ""); + zconf_error("'%s' defined with blank help text", + current_entry->sym->name ?: ""); current_entry->help = $2; }; @@ -592,17 +591,6 @@ static bool zconf_endtoken(const char *tokenname, return true; } -static void zconfprint(const char *err, ...) -{ - va_list ap; - - fprintf(stderr, "%s:%d: ", cur_filename, cur_lineno); - va_start(ap, err); - vfprintf(stderr, err, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - static void zconf_error(const char *err, ...) { va_list ap; -- cgit From ccb3ee82fa50dccdcd186ed0f6c0d8d14c86a24f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 9 Oct 2024 03:00:06 +0900 Subject: kconfig: qconf: set QSplitter orientation in the constructor The orientation of the QSplitter can be specified directly in its constructor. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index e260cab1c2af..202823aad393 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1240,8 +1240,7 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent) layout2->addWidget(searchButton); layout1->addLayout(layout2); - split = new QSplitter(this); - split->setOrientation(Qt::Vertical); + split = new QSplitter(Qt::Vertical, this); list = new ConfigList(split, "search"); list->mode = listMode; info = new ConfigInfoView(split, "search"); @@ -1344,15 +1343,13 @@ ConfigMainWindow::ConfigMainWindow(void) QVBoxLayout *layout = new QVBoxLayout(widget); setCentralWidget(widget); - split1 = new QSplitter(widget); - split1->setOrientation(Qt::Horizontal); + split1 = new QSplitter(Qt::Horizontal, widget); split1->setChildrenCollapsible(false); menuList = new ConfigList(widget, "menu"); - split2 = new QSplitter(widget); + split2 = new QSplitter(Qt::Vertical, widget); split2->setChildrenCollapsible(false); - split2->setOrientation(Qt::Vertical); // create config tree configList = new ConfigList(widget, "config"); -- cgit From 7d48998b58e83a11500d2234e528003ef5d7e982 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 9 Oct 2024 03:00:07 +0900 Subject: kconfig: qconf: reorder code in ConfigMainWindow() constructor Rearrange the code to make the upcoming refactoring easier to understand. No functional changes intended. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 202823aad393..2c80e3e1a91a 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1340,29 +1340,28 @@ ConfigMainWindow::ConfigMainWindow(void) ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback)); QWidget *widget = new QWidget(this); - QVBoxLayout *layout = new QVBoxLayout(widget); setCentralWidget(widget); - split1 = new QSplitter(Qt::Horizontal, widget); - split1->setChildrenCollapsible(false); - - menuList = new ConfigList(widget, "menu"); + QVBoxLayout *layout = new QVBoxLayout(widget); split2 = new QSplitter(Qt::Vertical, widget); + layout->addWidget(split2); split2->setChildrenCollapsible(false); - // create config tree - configList = new ConfigList(widget, "config"); - - helpText = new ConfigInfoView(widget, "help"); - - layout->addWidget(split2); + split1 = new QSplitter(Qt::Horizontal, widget); split2->addWidget(split1); + split1->setChildrenCollapsible(false); + + configList = new ConfigList(widget, "config"); split1->addWidget(configList); + + menuList = new ConfigList(widget, "menu"); split1->addWidget(menuList); - split2->addWidget(helpText); + helpText = new ConfigInfoView(widget, "help"); + split2->addWidget(helpText); setTabOrder(configList, helpText); + configList->setFocus(); backAction = new QAction(QPixmap(xpm_back), "Back", this); -- cgit From 93096d7d2a86b45d1590b041fa9b31546f2f8095 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 9 Oct 2024 03:00:08 +0900 Subject: kconfig: qconf: set parent in the widget constructor The ->addWidget() method re-parents the widget. The parent QWidget can be specified directly in the constructor. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 2c80e3e1a91a..7bac48ac5d21 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1348,18 +1348,14 @@ ConfigMainWindow::ConfigMainWindow(void) layout->addWidget(split2); split2->setChildrenCollapsible(false); - split1 = new QSplitter(Qt::Horizontal, widget); - split2->addWidget(split1); + split1 = new QSplitter(Qt::Horizontal, split2); split1->setChildrenCollapsible(false); - configList = new ConfigList(widget, "config"); - split1->addWidget(configList); + configList = new ConfigList(split1, "config"); - menuList = new ConfigList(widget, "menu"); - split1->addWidget(menuList); + menuList = new ConfigList(split1, "menu"); - helpText = new ConfigInfoView(widget, "help"); - split2->addWidget(helpText); + helpText = new ConfigInfoView(split2, "help"); setTabOrder(configList, helpText); configList->setFocus(); -- cgit From 4da0f0d0cc16606376b3fdb8a257f539b37ab057 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 14 Oct 2024 11:18:28 +0200 Subject: kconfig: nconf: Use TAB to cycle thru dialog buttons Add the ability to cycle through dialog buttons with the TAB key. Signed-off-by: Thorsten Blum Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.gui.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 72b605efe549..4bfdf8ac2a9a 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -277,6 +277,15 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) case KEY_RIGHT: menu_driver(menu, REQ_RIGHT_ITEM); break; + case 9: /* TAB */ + if (btn_num > 1) { + /* cycle through buttons */ + if (item_index(current_item(menu)) == btn_num - 1) + menu_driver(menu, REQ_FIRST_ITEM); + else + menu_driver(menu, REQ_NEXT_ITEM); + } + break; case 10: /* ENTER */ case 27: /* ESCAPE */ case ' ': -- cgit From f16c8c08185420092d04edce6066eaf4a454bb20 Mon Sep 17 00:00:00 2001 From: David Hunter Date: Mon, 14 Oct 2024 10:13:31 -0400 Subject: streamline_config.pl: fix missing variable operator in debug print Put in the dollar sign for the variable '$config'. That way, the debug message has more meaning. Signed-off-by: David Hunter Signed-off-by: Masahiro Yamada --- scripts/kconfig/streamline_config.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index d51cd7ac15d2..a85d6a3108a1 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -503,7 +503,7 @@ sub parse_config_selects # Check if something other than a module selects this config if (defined($orig_configs{$conf}) && $orig_configs{$conf} ne "m") { - dprint "$conf (non module) selects config, we are good\n"; + dprint "$conf (non module) selects $config, we are good\n"; # we are good with this return; } -- cgit From 074c2241d0fe182bb62d010625aa9faa99cbfeac Mon Sep 17 00:00:00 2001 From: Costa Shulyupin Date: Thu, 24 Oct 2024 08:32:06 +0300 Subject: scripts/tags.sh: add regex to map IDT entries Source code samples: DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER, common_interrupt); DEFINE_IDTENTRY_IRQ(common_interrupt) Signed-off-by: Costa Shulyupin Link: https://lore.kernel.org/r/20241024053212.2810988-1-costa.shul@redhat.com Signed-off-by: Greg Kroah-Hartman --- scripts/tags.sh | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/tags.sh b/scripts/tags.sh index 191e0461d6d5..4a9b75f5bd6f 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -212,6 +212,8 @@ regex_c=( '/\<\(DEFINE\|DECLARE\)_STATIC_KEY_\(TRUE\|FALSE\)\(\|_RO\)([[:space:]]*\([[:alnum:]_]\+\)/\4/' '/^SEQCOUNT_LOCKTYPE(\([^,]*\),[[:space:]]*\([^,]*\),[^)]*)/seqcount_\2_t/' '/^SEQCOUNT_LOCKTYPE(\([^,]*\),[[:space:]]*\([^,]*\),[^)]*)/seqcount_\2_init/' + '/^\ Date: Fri, 25 Oct 2024 09:45:30 +0300 Subject: scripts/tags.sh: use list of identifiers to ignore Literal string of ctags arguments is too long and overloaded. Replace it with neat bash list. Identifiers are sorted, and those with a new first letter start on a new line for better maintainability. Signed-off-by: Costa Shulyupin Link: https://lore.kernel.org/r/20241025064536.3022849-1-costa.shul@redhat.com Signed-off-by: Greg Kroah-Hartman --- scripts/tags.sh | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/tags.sh b/scripts/tags.sh index 4a9b75f5bd6f..933e923e085a 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -259,19 +259,29 @@ exuberant() CTAGS_EXTRA="extras" fi setup_regex exuberant asm c - all_target_sources | xargs $1 -a \ - -I __initdata,__exitdata,__initconst,__ro_after_init \ - -I __initdata_memblock \ - -I __refdata,__attribute,__maybe_unused,__always_unused \ - -I __acquires,__releases,__deprecated,__always_inline \ - -I __read_mostly,__aligned,____cacheline_aligned \ - -I ____cacheline_aligned_in_smp \ - -I __cacheline_aligned,__cacheline_aligned_in_smp \ - -I ____cacheline_internodealigned_in_smp \ - -I __used,__packed,__packed2__,__must_check,__must_hold \ - -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL,ACPI_EXPORT_SYMBOL \ - -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ - -I static,const \ + # identifiers to ignore by ctags + local ign=( + ACPI_EXPORT_SYMBOL + DEFINE_TRACE + EXPORT_SYMBOL EXPORT_SYMBOL_GPL + EXPORT_TRACEPOINT_SYMBOL EXPORT_TRACEPOINT_SYMBOL_GPL + ____cacheline_aligned ____cacheline_aligned_in_smp + ____cacheline_internodealigned_in_smp + __acquires __aligned __always_inline __always_unused + __attribute + __cacheline_aligned __cacheline_aligned_in_smp + __deprecated + __exitdata + __initconst __initdata __initdata_memblock + __maybe_unused __must_check __must_hold + __packed __packed2__ + __read_mostly __refdata __releases __ro_after_init + __used + const + static + ) + all_target_sources | \ + xargs $1 -a -I "$(IFS=','; echo "${ign[*]}")" \ --$CTAGS_EXTRA=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \ "${regex[@]}" -- cgit From 7428f9d97006e35a9c4798bcbf0e26101144d12d Mon Sep 17 00:00:00 2001 From: Costa Shulyupin Date: Fri, 25 Oct 2024 16:03:16 +0300 Subject: scripts/tags.sh: Fix warnings "null expansion of name pattern" Warnings such as ctags: Warning: include/linux/wait_bit.h:59: null expansion of name pattern "\1" are triggered when parsing DECLARE_BITMAP() inside comments, resulting in an empty token. To avoid this, ensure only non-empty tokens. Signed-off-by: Costa Shulyupin Link: https://lore.kernel.org/r/20241025130322.3077455-1-costa.shul@redhat.com Signed-off-by: Greg Kroah-Hartman --- scripts/tags.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/tags.sh b/scripts/tags.sh index 933e923e085a..c04f43d91517 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -191,7 +191,7 @@ regex_c=( '/\ Date: Mon, 14 Oct 2024 10:13:32 -0400 Subject: streamline_config.pl: ensure all defaults are tracked Track default options on the second line. On the second line of some config entries, default and dependency options sometimes appear. In those instances, the state will be "NEW" and not "DEP". Signed-off-by: David Hunter Signed-off-by: Masahiro Yamada --- scripts/kconfig/streamline_config.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index a85d6a3108a1..85f4712e2bf3 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -220,7 +220,7 @@ sub read_kconfig { $depends{$config} = $1; } elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) { $depends{$config} .= " " . $1; - } elsif ($state eq "DEP" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) { + } elsif ($state ne "NONE" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) { my $dep = $3; if ($dep !~ /^\s*(y|m|n)\s*$/) { $dep =~ s/.*\sif\s+//; -- cgit From bf98f6d1082463392f7fadd6292f3289207e07c7 Mon Sep 17 00:00:00 2001 From: David Hunter Date: Mon, 14 Oct 2024 10:13:33 -0400 Subject: streamline_config.pl: remove prompt warnings for configs with defaults Ignore process select warnings for config entries that have a default option. Some config entries have no prompt, and nothing selects them, but these config options are okay because they have a default option. Signed-off-by: David Hunter Signed-off-by: Masahiro Yamada --- scripts/kconfig/streamline_config.pl | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 85f4712e2bf3..8e23faab5d22 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -144,6 +144,7 @@ my %selects; my %prompts; my %objects; my %config2kfile; +my %defaults; my $var; my $iflevel = 0; my @ifdeps; @@ -222,6 +223,7 @@ sub read_kconfig { $depends{$config} .= " " . $1; } elsif ($state ne "NONE" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) { my $dep = $3; + $defaults{$config} = 1; if ($dep !~ /^\s*(y|m|n)\s*$/) { $dep =~ s/.*\sif\s+//; $depends{$config} .= " " . $dep; @@ -523,8 +525,16 @@ sub parse_config_selects # If no possible config selected this, then something happened. if (!defined($next_config)) { - print STDERR "WARNING: $config is required, but nothing in the\n"; - print STDERR " current config selects it.\n"; + + # Some config options have no prompt, and nothing selects them, but + # they stay turned on once the final checks for the configs + # are done. These configs have a default option, so turn off the + # warnings for configs with default options. + if (!defined($defaults{$config})) { + print STDERR "WARNING: $config is required, but nothing in the\n"; + print STDERR " current config selects it.\n"; + } + return; } -- cgit From cdb1e767c8db704965e0ca13f6e91a94a5d6cfb1 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Sat, 19 Oct 2024 23:17:47 +0200 Subject: kconfig: nconf: Fix typo in function comment s/handles/handled/ Signed-off-by: Thorsten Blum Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 063b4f7ccbdb..c0b2dabf6c89 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -467,7 +467,7 @@ static void handle_f9(int *key, struct menu *current_item) return; } -/* return != 0 to indicate the key was handles */ +/* return != 0 to indicate the key was handled */ static int process_special_keys(int *key, struct menu *menu) { int i; -- cgit From cdb37fe66fb260acce16c999a61a963fca93468a Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Wed, 23 Oct 2024 08:31:46 +0200 Subject: kconfig: qconf: use QString to store path to configuration file This is the native type used by the file dialogs and avoids any hassle with filename encoding when converting this back and forth to a character array. Signed-off-by: Rolf Eike Beer Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 24 ++++++------------------ scripts/kconfig/qconf.h | 2 +- 2 files changed, 7 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 7bac48ac5d21..b620efac7da0 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1381,7 +1381,7 @@ ConfigMainWindow::ConfigMainWindow(void) conf_set_changed_callback(conf_changed); - configname = xstrdup(conf_get_configname()); + configname = conf_get_configname(); QAction *saveAsAction = new QAction("Save &As...", this); connect(saveAsAction, &QAction::triggered, @@ -1520,28 +1520,22 @@ ConfigMainWindow::ConfigMainWindow(void) void ConfigMainWindow::loadConfig(void) { QString str; - QByteArray ba; - const char *name; str = QFileDialog::getOpenFileName(this, "", configname); if (str.isNull()) return; - ba = str.toLocal8Bit(); - name = ba.data(); - - if (conf_read(name)) + if (conf_read(str.toLocal8Bit().constData())) QMessageBox::information(this, "qconf", "Unable to load configuration!"); - free(configname); - configname = xstrdup(name); + configname = str; ConfigList::updateListAllForAll(); } bool ConfigMainWindow::saveConfig(void) { - if (conf_write(configname)) { + if (conf_write(configname.toLocal8Bit().constData())) { QMessageBox::information(this, "qconf", "Unable to save configuration!"); return false; } @@ -1553,23 +1547,17 @@ bool ConfigMainWindow::saveConfig(void) void ConfigMainWindow::saveConfigAs(void) { QString str; - QByteArray ba; - const char *name; str = QFileDialog::getSaveFileName(this, "", configname); if (str.isNull()) return; - ba = str.toLocal8Bit(); - name = ba.data(); - - if (conf_write(name)) { + if (conf_write(str.toLocal8Bit().constData())) { QMessageBox::information(this, "qconf", "Unable to save configuration!"); } conf_write_autoconf(0); - free(configname); - configname = xstrdup(name); + configname = str; } void ConfigMainWindow::searchConfig(void) diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index 53373064d90a..aab25ece95c6 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -237,7 +237,7 @@ protected: class ConfigMainWindow : public QMainWindow { Q_OBJECT - char *configname; + QString configname; static QAction *saveAction; static void conf_changed(bool); public: -- cgit From 5a4bed0fad83cdecc91dfd541b326801d3979564 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Wed, 23 Oct 2024 08:36:10 +0200 Subject: kconfig: qconf: use default platform shortcuts This renames "Load" to "Open" and switches Ctrl-L to Ctrl-O for the default platforms. This may break the workflow for those used to it, but will make it actually work for everyone else like me who would just expect the default behavior. Add some more standard shortcuts where available. If they replace the existing shortcuts they would have the same value in my case. Signed-off-by: Rolf Eike Beer Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index b620efac7da0..f01fa1481d6e 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1361,21 +1361,22 @@ ConfigMainWindow::ConfigMainWindow(void) configList->setFocus(); backAction = new QAction(QPixmap(xpm_back), "Back", this); + backAction->setShortcut(QKeySequence::Back); connect(backAction, &QAction::triggered, this, &ConfigMainWindow::goBack); QAction *quitAction = new QAction("&Quit", this); - quitAction->setShortcut(Qt::CTRL | Qt::Key_Q); + quitAction->setShortcut(QKeySequence::Quit); connect(quitAction, &QAction::triggered, this, &ConfigMainWindow::close); - QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this); - loadAction->setShortcut(Qt::CTRL | Qt::Key_L); + QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this); + loadAction->setShortcut(QKeySequence::Open); connect(loadAction, &QAction::triggered, this, &ConfigMainWindow::loadConfig); saveAction = new QAction(QPixmap(xpm_save), "&Save", this); - saveAction->setShortcut(Qt::CTRL | Qt::Key_S); + saveAction->setShortcut(QKeySequence::Save); connect(saveAction, &QAction::triggered, this, &ConfigMainWindow::saveConfig); @@ -1384,10 +1385,11 @@ ConfigMainWindow::ConfigMainWindow(void) configname = conf_get_configname(); QAction *saveAsAction = new QAction("Save &As...", this); + saveAsAction->setShortcut(QKeySequence::SaveAs); connect(saveAsAction, &QAction::triggered, this, &ConfigMainWindow::saveConfigAs); QAction *searchAction = new QAction("&Find", this); - searchAction->setShortcut(Qt::CTRL | Qt::Key_F); + searchAction->setShortcut(QKeySequence::Find); connect(searchAction, &QAction::triggered, this, &ConfigMainWindow::searchConfig); singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); -- cgit From 8b36d3f2e612866e705b16e9c792e10b62c6c10e Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Wed, 23 Oct 2024 08:39:15 +0200 Subject: kconfig: qconf: simplify character replacement Replace the hand crafted lookup table with a QHash. This has the nice benefit that the added offsets can not get out of sync with the length of the replacement strings. Signed-off-by: Rolf Eike Beer Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index f01fa1481d6e..90f139480eda 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1122,28 +1122,19 @@ QString ConfigInfoView::print_filter(const QString &str) { QRegularExpression re("[<>&\"\\n]"); QString res = str; + + QHash patterns; + patterns['<'] = "<"; + patterns['>'] = ">"; + patterns['&'] = "&"; + patterns['"'] = """; + patterns['\n'] = "
"; + for (int i = 0; (i = res.indexOf(re, i)) >= 0;) { - switch (res[i].toLatin1()) { - case '<': - res.replace(i, 1, "<"); - i += 4; - break; - case '>': - res.replace(i, 1, ">"); - i += 4; - break; - case '&': - res.replace(i, 1, "&"); - i += 5; - break; - case '"': - res.replace(i, 1, """); - i += 6; - break; - case '\n': - res.replace(i, 1, "
"); - i += 4; - break; + const QString n = patterns.value(res[i], QString()); + if (!n.isEmpty()) { + res.replace(i, 1, n); + i += n.length(); } } return res; -- cgit From 4a798a1e1017ef72240e23882aa2ab93efb553e7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:17:51 +0900 Subject: kconfig: qconf: remove mouse{Press,Move}Event() functions These functions simply passes the event to the parent. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 14 -------------- scripts/kconfig/qconf.h | 2 -- 2 files changed, 16 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 90f139480eda..18cc5c184f56 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -781,13 +781,6 @@ void ConfigList::keyPressEvent(QKeyEvent* ev) ev->accept(); } -void ConfigList::mousePressEvent(QMouseEvent* e) -{ - //QPoint p(contentsToViewport(e->pos())); - //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y()); - Parent::mousePressEvent(e); -} - void ConfigList::mouseReleaseEvent(QMouseEvent* e) { QPoint p = e->pos(); @@ -834,13 +827,6 @@ skip: Parent::mouseReleaseEvent(e); } -void ConfigList::mouseMoveEvent(QMouseEvent* e) -{ - //QPoint p(contentsToViewport(e->pos())); - //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y()); - Parent::mouseMoveEvent(e); -} - void ConfigList::mouseDoubleClickEvent(QMouseEvent* e) { QPoint p = e->pos(); diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index aab25ece95c6..0b62fb26821a 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -55,9 +55,7 @@ public: protected: void keyPressEvent(QKeyEvent *e); - void mousePressEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); - void mouseMoveEvent(QMouseEvent *e); void mouseDoubleClickEvent(QMouseEvent *e); void focusInEvent(QFocusEvent *e); void contextMenuEvent(QContextMenuEvent *e); -- cgit From 0bab492cfe04e8b61188d4162b302b1f7ae9f4df Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:17:52 +0900 Subject: kconfig: qconf: remove redundant type check for choice members Since commit fde192511bdb ("kconfig: remove tristate choice support"), choice members are always boolean. The type check is redundant. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 18cc5c184f56..58c57c908149 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -159,7 +159,7 @@ void ConfigItem::updateMenu(void) ch = 'M'; break; default: - if (sym_is_choice_value(sym) && type == S_BOOLEAN) + if (sym_is_choice_value(sym)) setIcon(promptColIdx, choiceNoIcon); else setIcon(promptColIdx, symbolNoIcon); -- cgit From ac845932cbaa30020d5943fc4448bba7b7327158 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:17:53 +0900 Subject: kconfig: qconf: remove unnecessary setRootIsDecorated() call The default value of the rootIsDecorated property is true. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 58c57c908149..120090fa4ac9 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -307,7 +307,6 @@ ConfigList::ConfigList(QWidget *parent, const char *name) { setObjectName(name); setSortingEnabled(false); - setRootIsDecorated(true); setVerticalScrollMode(ScrollPerPixel); setHorizontalScrollMode(ScrollPerPixel); -- cgit From 375a4f4ea719ad68e305373cfe0f77ecd1378531 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:17:54 +0900 Subject: kconfig: qconf: remove unnecessary lastWindowClosed() signal connection The default value of the quitOnLastWindowClosed property is true. Hence, the application implicitly quits when the last window is closed. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 120090fa4ac9..49a3d0365c39 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1863,7 +1863,6 @@ int main(int ac, char** av) v = new ConfigMainWindow(); //zconfdump(stdout); - configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); v->show(); -- cgit From b6962d8694963620401c24f051999678943a7123 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:17:55 +0900 Subject: kconfig: qconf: convert the last old connection syntax to Qt5 style Commit a2574c12df0d ("kconfig: qconf: convert to Qt5 new signal/slot connection syntax") converted most of the old string-based connections, but one more instance still remains. Convert it to the new style. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 49a3d0365c39..c922c34621a4 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1475,6 +1475,9 @@ ConfigMainWindow::ConfigMainWindow(void) connect(helpText, &ConfigInfoView::menuSelected, this, &ConfigMainWindow::setMenuLink); + connect(configApp, &QApplication::aboutToQuit, + this, &ConfigMainWindow::saveSettings); + conf_read(NULL); QString listMode = configSettings->value("/listMode", "symbol").toString(); @@ -1863,7 +1866,6 @@ int main(int ac, char** av) v = new ConfigMainWindow(); //zconfdump(stdout); - configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); v->show(); configApp->exec(); -- cgit From 76567f93b3454cae3a3eaa23a3b28c94b70ee013 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:17:56 +0900 Subject: kconfig: qconf: do not show goParent button in split view When a menu is selected in the split view, the right pane displays the goParent button, but it is never functional. This is unnecessary, as you can select a menu from the menu tree in the left pane. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index c922c34621a4..7c844c4a119e 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -436,8 +436,7 @@ void ConfigList::updateList() return; } - if (rootEntry != &rootmenu && (mode == singleMode || - (mode == symbolMode && rootEntry->parent != &rootmenu))) { + if (rootEntry != &rootmenu && mode == singleMode) { item = (ConfigItem *)topLevelItem(0); if (!item) item = new ConfigItem(this, 0, true); -- cgit From 511ff539c31d89e3f7132a61dae2ebcb0c4b2912 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:17:57 +0900 Subject: kconfig: qconf: remove ConfigItem::visible member The " (NEW)" string should be displayed regardless of the visibility of the associated menu. The ConfigItem::visible member is not used for any other purpose. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 28 +++++++++++----------------- scripts/kconfig/qconf.h | 15 +++++++-------- 2 files changed, 18 insertions(+), 25 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 7c844c4a119e..5b1237bf085a 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -175,17 +175,16 @@ void ConfigItem::updateMenu(void) setText(dataColIdx, sym_get_string_value(sym)); break; } - if (!sym_has_value(sym) && visible) + if (!sym_has_value(sym)) prompt += " (NEW)"; set_prompt: setText(promptColIdx, prompt); } -void ConfigItem::testUpdateMenu(bool v) +void ConfigItem::testUpdateMenu(void) { ConfigItem* i; - visible = v; if (!menu) return; @@ -429,7 +428,7 @@ void ConfigList::updateList() item = (ConfigItem*)(*it); if (!item->menu) continue; - item->testUpdateMenu(menu_is_visible(item->menu)); + item->testUpdateMenu(); ++it; } @@ -439,16 +438,16 @@ void ConfigList::updateList() if (rootEntry != &rootmenu && mode == singleMode) { item = (ConfigItem *)topLevelItem(0); if (!item) - item = new ConfigItem(this, 0, true); + item = new ConfigItem(this, 0); last = item; } if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) && rootEntry->sym && rootEntry->prompt) { item = last ? last->nextSibling() : nullptr; if (!item) - item = new ConfigItem(this, last, rootEntry, true); + item = new ConfigItem(this, last, rootEntry); else - item->testUpdateMenu(true); + item->testUpdateMenu(); updateMenuList(item, rootEntry); update(); @@ -597,7 +596,6 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu) struct menu* child; ConfigItem* item; ConfigItem* last; - bool visible; enum prop_type type; if (!menu) { @@ -629,14 +627,13 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu) break; } - visible = menu_is_visible(child); if (!menuSkip(child)) { if (!child->sym && !child->list && !child->prompt) continue; if (!item || item->menu != child) - item = new ConfigItem(parent, last, child, visible); + item = new ConfigItem(parent, last, child); else - item->testUpdateMenu(visible); + item->testUpdateMenu(); if (mode == fullMode || mode == menuMode || type != P_MENU) updateMenuList(item, child); @@ -662,7 +659,6 @@ void ConfigList::updateMenuList(struct menu *menu) struct menu* child; ConfigItem* item; ConfigItem* last; - bool visible; enum prop_type type; if (!menu) { @@ -694,14 +690,13 @@ void ConfigList::updateMenuList(struct menu *menu) break; } - visible = menu_is_visible(child); if (!menuSkip(child)) { if (!child->sym && !child->list && !child->prompt) continue; if (!item || item->menu != child) - item = new ConfigItem(this, last, child, visible); + item = new ConfigItem(this, last, child); else - item->testUpdateMenu(visible); + item->testUpdateMenu(); if (mode == fullMode || mode == menuMode || type != P_MENU) updateMenuList(item, child); @@ -1274,8 +1269,7 @@ void ConfigSearchWindow::search(void) return; for (p = result; *p; p++) { for_all_prompts((*p), prop) - lastItem = new ConfigItem(list, lastItem, prop->menu, - menu_is_visible(prop->menu)); + lastItem = new ConfigItem(list, lastItem, prop->menu); } } diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index 0b62fb26821a..62ab3286d04f 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -114,25 +114,25 @@ public: class ConfigItem : public QTreeWidgetItem { typedef class QTreeWidgetItem Parent; public: - ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m, bool v) - : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false) + ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m) + : Parent(parent, after), nextItem(0), menu(m), goParent(false) { init(); } - ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v) - : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false) + ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m) + : Parent(parent, after), nextItem(0), menu(m), goParent(false) { init(); } - ConfigItem(ConfigList *parent, ConfigItem *after, bool v) - : Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true) + ConfigItem(ConfigList *parent, ConfigItem *after) + : Parent(parent, after), nextItem(0), menu(0), goParent(true) { init(); } ~ConfigItem(void); void init(void); void updateMenu(void); - void testUpdateMenu(bool v); + void testUpdateMenu(void); ConfigList* listView() const { return (ConfigList*)Parent::treeWidget(); @@ -159,7 +159,6 @@ public: ConfigItem* nextItem; struct menu *menu; - bool visible; bool goParent; static QIcon symbolYesIcon, symbolModIcon, symbolNoIcon; -- cgit From 572cd1d2a9a68b66af98a60f4aad4f01d6589447 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:17:58 +0900 Subject: kconfig: qconf: avoid unnecessary parentSelected() when ESC is pressed When the ESC key is pressed, the parentSelected() signal is currently emitted for singleMode, menuMode, and symbolMode. However, parentSelected() signal is functional only for singleMode. In menuMode, the signal is connected to the goBack() slot, but nothing occurs because configList->rootEntry is always &rootmenu. In symbolMode (in the right pane), the parentSelected() signal is not connected to any slot. This commit prevents the unnecessary emission of the parentSelected() signal. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 5b1237bf085a..1948cda048d2 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -724,7 +724,7 @@ void ConfigList::keyPressEvent(QKeyEvent* ev) struct menu *menu; enum prop_type type; - if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) { + if (ev->key() == Qt::Key_Escape && mode == singleMode) { emit parentSelected(); ev->accept(); return; -- cgit From 8e8ce9531e09376d987ff0e09491bea82a0f6411 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:17:59 +0900 Subject: kconfig: qconf: remove redundant check in goBack() The same check is performed in the configList->setParentMenu() call. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 3 --- 1 file changed, 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 1948cda048d2..acbc4331ebc5 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1616,9 +1616,6 @@ void ConfigMainWindow::listFocusChanged(void) void ConfigMainWindow::goBack(void) { - if (configList->rootEntry == &rootmenu) - return; - configList->setParentMenu(); } -- cgit From 929ce506d60ede917f241fb40e0bed6ab3e52999 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:18:00 +0900 Subject: kconfig: qconf: remove non-functional href="m..." tag The only functional tag is href="s". Commit c4f7398bee9c ("kconfig: qconf: make debug links work again") changed prop->name to sym->name for this reference, but it missed to change the tag "m" to "s". This tag is not functional at all. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index acbc4331ebc5..a208ef33128f 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1065,9 +1065,9 @@ QString ConfigInfoView::debug_info(struct symbol *sym) switch (prop->type) { case P_PROMPT: case P_MENU: - stream << "prompt: name << "\">"; + stream << "prompt: "; stream << print_filter(prop->text); - stream << "
"; + stream << "
"; break; case P_DEFAULT: case P_SELECT: -- cgit From bce590f1020742d81e9fbfe3b045538973111c11 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:18:01 +0900 Subject: kconfig: add sym_get_prompt_menu() helper function Split out the code that retrieves the menu entry with a prompt, so it can be reused in other functions. Signed-off-by: Masahiro Yamada --- scripts/kconfig/lkc_proto.h | 1 + scripts/kconfig/symbol.c | 26 +++++++++++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 63519cd24bc7..8914b4e8f2a8 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -34,6 +34,7 @@ bool sym_string_valid(struct symbol *sym, const char *newval); bool sym_string_within_range(struct symbol *sym, const char *str); bool sym_set_string_value(struct symbol *sym, const char *newval); bool sym_is_changeable(const struct symbol *sym); +struct menu *sym_get_prompt_menu(const struct symbol *sym); struct menu *sym_get_choice_menu(const struct symbol *sym); const char * sym_get_string_value(struct symbol *sym); diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index a3af93aaaf32..89b84bf8e21f 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -70,6 +70,24 @@ const char *sym_type_name(enum symbol_type type) return "???"; } +/** + * sym_get_prompt_menu - get the menu entry with a prompt + * + * @sym: a symbol pointer + * + * Return: the menu entry with a prompt. + */ +struct menu *sym_get_prompt_menu(const struct symbol *sym) +{ + struct menu *m; + + list_for_each_entry(m, &sym->menus, link) + if (m->prompt) + return m; + + return NULL; +} + /** * sym_get_choice_menu - get the parent choice menu if present * @@ -80,18 +98,12 @@ const char *sym_type_name(enum symbol_type type) struct menu *sym_get_choice_menu(const struct symbol *sym) { struct menu *menu = NULL; - struct menu *m; /* * Choice members must have a prompt. Find a menu entry with a prompt, * and assume it resides inside a choice block. */ - list_for_each_entry(m, &sym->menus, link) - if (m->prompt) { - menu = m; - break; - } - + menu = sym_get_prompt_menu(sym); if (!menu) return NULL; -- cgit From a914032b71f0a74e9c9114ff9be8babb55bbca67 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:18:02 +0900 Subject: kconfig: qconf: refactor ConfigInfoView::clicked() Most of the code in ConfigInfoView::clicked() is unnecessary. There is no need to use the regular expression to search for a symbol. Calling sym_find() is simpler and faster. The hyperlink always begins with the "s" tag, and there is no other tag used. Remove it. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 43 ++++++------------------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index a208ef33128f..f59a9597f09b 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1001,7 +1001,7 @@ void ConfigInfoView::menuInfo(void) if (sym->name) { stream << " ("; if (showDebug()) - stream << "name << "\">"; + stream << "name << "\">"; stream << print_filter(sym->name); if (showDebug()) stream << ""; @@ -1010,7 +1010,7 @@ void ConfigInfoView::menuInfo(void) } else if (sym->name) { stream << ""; if (showDebug()) - stream << "name << "\">"; + stream << "name << "\">"; stream << print_filter(sym->name); if (showDebug()) stream << ""; @@ -1124,7 +1124,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char QTextStream *stream = reinterpret_cast(data); if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) { - *stream << "name << "\">"; + *stream << "name << "\">"; *stream << print_filter(str); *stream << ""; } else { @@ -1134,39 +1134,11 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char void ConfigInfoView::clicked(const QUrl &url) { - QByteArray str = url.toEncoded(); - const std::size_t count = str.size(); - char *data = new char[count + 2]; // '$' + '\0' - struct symbol **result; - struct menu *m = NULL; + struct menu *m; - if (count < 1) { - delete[] data; - return; - } - - memcpy(data, str.constData(), count); - data[count] = '\0'; - - /* Seek for exact match */ - data[0] = '^'; - strcat(data, "$"); - result = sym_re_search(data); - if (!result) { - delete[] data; - return; - } - - sym = *result; - - /* Seek for the menu which holds the symbol */ - for (struct property *prop = sym->prop; prop; prop = prop->next) { - if (prop->type != P_PROMPT && prop->type != P_MENU) - continue; - m = prop->menu; - break; - } + sym = sym_find(url.toEncoded().constData()); + m = sym_get_prompt_menu(sym); if (!m) { /* Symbol is not visible as a menu */ symbolInfo(); @@ -1174,9 +1146,6 @@ void ConfigInfoView::clicked(const QUrl &url) } else { emit menuSelected(m); } - - free(result); - delete[] data; } void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event) -- cgit From d6a91e28d11902e6cd5715633ed6f9b6df75de32 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 03:18:03 +0900 Subject: kconfig: qconf: remove unnecessary mode check in ConfigItem::updateMenu() The P_MENU entries ("menu" and "menuconfig") are never displayed in symbolMode. The condition, list->mode == symbolMode, is never met here. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index f59a9597f09b..6c92ef1e16ef 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -110,7 +110,7 @@ void ConfigItem::updateMenu(void) if (prop) switch (prop->type) { case P_MENU: - if (list->mode == singleMode || list->mode == symbolMode) { + if (list->mode == singleMode) { /* a menuconfig entry is displayed differently * depending whether it's at the view root or a child. */ -- cgit From a49401be4c780f3397ca19a070d7c38e6f032efa Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Oct 2024 20:25:45 +0900 Subject: kconfig: document the positional argument in the help message The positional argument specifies the top-level Kconfig. Include this information in the help message. Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 3d7d454c54da..8abe57041955 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -628,7 +628,7 @@ static const struct option long_opts[] = { static void conf_usage(const char *progname) { - printf("Usage: %s [options] \n", progname); + printf("Usage: %s [options] kconfig_file\n", progname); printf("\n"); printf("Generic options:\n"); printf(" -h, --help Print this message and exit.\n"); @@ -653,6 +653,9 @@ static void conf_usage(const char *progname) printf(" --mod2yesconfig Change answers from mod to yes if possible\n"); printf(" --mod2noconfig Change answers from mod to no if possible\n"); printf(" (If none of the above is given, --oldaskconfig is the default)\n"); + printf("\n"); + printf("Arguments:\n"); + printf(" kconfig_file Top-level Kconfig file.\n"); } int main(int ac, char **av) -- cgit From 315ad8780a129e82e2c5c65ee6e970d91a577acb Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Sat, 2 Nov 2024 10:51:08 -0700 Subject: kbuild: Add AutoFDO support for Clang build Add the build support for using Clang's AutoFDO. Building the kernel with AutoFDO does not reduce the optimization level from the compiler. AutoFDO uses hardware sampling to gather information about the frequency of execution of different code paths within a binary. This information is then used to guide the compiler's optimization decisions, resulting in a more efficient binary. Experiments showed that the kernel can improve up to 10% in latency. The support requires a Clang compiler after LLVM 17. This submission is limited to x86 platforms that support PMU features like LBR on Intel machines and AMD Zen3 BRS. Support for SPE on ARM 1, and BRBE on ARM 1 is part of planned future work. Here is an example workflow for AutoFDO kernel: 1) Build the kernel on the host machine with LLVM enabled, for example, $ make menuconfig LLVM=1 Turn on AutoFDO build config: CONFIG_AUTOFDO_CLANG=y With a configuration that has LLVM enabled, use the following command: scripts/config -e AUTOFDO_CLANG After getting the config, build with $ make LLVM=1 2) Install the kernel on the test machine. 3) Run the load tests. The '-c' option in perf specifies the sample event period. We suggest using a suitable prime number, like 500009, for this purpose. For Intel platforms: $ perf record -e BR_INST_RETIRED.NEAR_TAKEN:k -a -N -b -c \ -o -- For AMD platforms: The supported system are: Zen3 with BRS, or Zen4 with amd_lbr_v2 For Zen3: $ cat proc/cpuinfo | grep " brs" For Zen4: $ cat proc/cpuinfo | grep amd_lbr_v2 $ perf record --pfm-events RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a \ -N -b -c -o -- 4) (Optional) Download the raw perf file to the host machine. 5) To generate an AutoFDO profile, two offline tools are available: create_llvm_prof and llvm_profgen. The create_llvm_prof tool is part of the AutoFDO project and can be found on GitHub (https://github.com/google/autofdo), version v0.30.1 or later. The llvm_profgen tool is included in the LLVM compiler itself. It's important to note that the version of llvm_profgen doesn't need to match the version of Clang. It needs to be the LLVM 19 release or later, or from the LLVM trunk. $ llvm-profgen --kernel --binary= --perfdata= \ -o or $ create_llvm_prof --binary= --profile= \ --format=extbinary --out= Note that multiple AutoFDO profile files can be merged into one via: $ llvm-profdata merge -o ... 6) Rebuild the kernel using the AutoFDO profile file with the same config as step 1, (Note CONFIG_AUTOFDO_CLANG needs to be enabled): $ make LLVM=1 CLANG_AUTOFDO_PROFILE= Co-developed-by: Han Shen Signed-off-by: Han Shen Signed-off-by: Rong Xu Suggested-by: Sriraman Tallam Suggested-by: Krzysztof Pszeniczny Suggested-by: Nick Desaulniers Suggested-by: Stephane Eranian Tested-by: Yonghong Song Tested-by: Yabin Cui Tested-by: Nathan Chancellor Reviewed-by: Kees Cook Tested-by: Peter Jung Signed-off-by: Masahiro Yamada --- scripts/Makefile.autofdo | 22 ++++++++++++++++++++++ scripts/Makefile.lib | 10 ++++++++++ 2 files changed, 32 insertions(+) create mode 100644 scripts/Makefile.autofdo (limited to 'scripts') diff --git a/scripts/Makefile.autofdo b/scripts/Makefile.autofdo new file mode 100644 index 000000000000..ff96a63fea7c --- /dev/null +++ b/scripts/Makefile.autofdo @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Enable available and selected Clang AutoFDO features. + +CFLAGS_AUTOFDO_CLANG := -fdebug-info-for-profiling -mllvm -enable-fs-discriminator=true -mllvm -improved-fs-discriminator=true + +ifndef CONFIG_DEBUG_INFO + CFLAGS_AUTOFDO_CLANG += -gmlt +endif + +ifdef CLANG_AUTOFDO_PROFILE + CFLAGS_AUTOFDO_CLANG += -fprofile-sample-use=$(CLANG_AUTOFDO_PROFILE) +endif + +ifdef CONFIG_LTO_CLANG_THIN + ifdef CLANG_AUTOFDO_PROFILE + KBUILD_LDFLAGS += --lto-sample-profile=$(CLANG_AUTOFDO_PROFILE) + endif + KBUILD_LDFLAGS += --mllvm=-enable-fs-discriminator=true --mllvm=-improved-fs-discriminator=true -plugin-opt=thinlto +endif + +export CFLAGS_AUTOFDO_CLANG diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 01a9f567d5af..2d0942c1a027 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -191,6 +191,16 @@ _c_flags += $(if $(patsubst n%,, \ -D__KCSAN_INSTRUMENT_BARRIERS__) endif +# +# Enable AutoFDO build flags except some files or directories we don't want to +# enable (depends on variables AUTOFDO_PROFILE_obj.o and AUTOFDO_PROFILE). +# +ifeq ($(CONFIG_AUTOFDO_CLANG),y) +_c_flags += $(if $(patsubst n%,, \ + $(AUTOFDO_PROFILE_$(target-stem).o)$(AUTOFDO_PROFILE)$(is-kernel-object)), \ + $(CFLAGS_AUTOFDO_CLANG)) +endif + # $(src) for including checkin headers from generated source files # $(obj) for including generated headers from checkin source files ifeq ($(KBUILD_EXTMOD),) -- cgit From 03e6a10bbe60334ad9796086f6a77836b16b4070 Mon Sep 17 00:00:00 2001 From: Costa Shulyupin Date: Tue, 5 Nov 2024 11:56:37 +0200 Subject: scripts/tags.sh: Don't tag usages of DEFINE_MUTEX Curly braces expression expands to "DEFINE_TRACE DEFINE_MUTEX". Signed-off-by: Costa Shulyupin Link: https://lore.kernel.org/r/20241105095648.1472862-2-costa.shul@redhat.com Signed-off-by: Greg Kroah-Hartman --- scripts/tags.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/tags.sh b/scripts/tags.sh index c04f43d91517..6a69ecac4e5b 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -262,7 +262,7 @@ exuberant() # identifiers to ignore by ctags local ign=( ACPI_EXPORT_SYMBOL - DEFINE_TRACE + DEFINE_{TRACE,MUTEX} EXPORT_SYMBOL EXPORT_SYMBOL_GPL EXPORT_TRACEPOINT_SYMBOL EXPORT_TRACEPOINT_SYMBOL_GPL ____cacheline_aligned ____cacheline_aligned_in_smp -- cgit From f6dee26d26e3ef2a00620703fb5bf272dd459f47 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Tue, 29 Oct 2024 21:49:08 +0700 Subject: sparc/build: Add SPARC target flags for compiling with clang clang only supports building 64-bit kernel, so we use the sparc64-linux-gnu target. See also: https://lore.kernel.org/lkml/e26PTXUXEz8OYXmaeKn4Mpuejr4IOlFfFwdB5vpsluXlYiqDdlyQTYcDtdAny_o4gO4SfPeQCCN2qpyT6e0nog5EaP3xk2SeUPTrF54p1gM=@protonmail.com/T/#m068e010dcf8b99d3510a90d7532bcdb70e2e2c6b Signed-off-by: Koakuma Acked-by: Masahiro Yamada Acked-by: Nathan Chancellor Reviewed-by: Andreas Larsson Link: https://lore.kernel.org/r/20241029-sparc-cflags-v3-2-b28745a6bd71@protonmail.com Signed-off-by: Andreas Larsson --- scripts/Makefile.clang | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang index 6c23c6af797f..2435efae67f5 100644 --- a/scripts/Makefile.clang +++ b/scripts/Makefile.clang @@ -10,6 +10,7 @@ CLANG_TARGET_FLAGS_mips := mipsel-linux-gnu CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu +CLANG_TARGET_FLAGS_sparc := sparc64-linux-gnu CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu CLANG_TARGET_FLAGS_um := $(CLANG_TARGET_FLAGS_$(SUBARCH)) CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(SRCARCH)) -- cgit From 52892ed6b03a14b961c1df783ed05763758abc73 Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Tue, 26 Nov 2024 09:34:09 -0800 Subject: MIPS: Place __kernel_entry at the beginning of text section Mark __kernel_entry as ".head.text" and place HEAD_TEXT before TEXT_TEXT in the linker script. This ensures that __kernel_entry will be placed at the beginning of text section. Drop mips from scripts/head-object-list.txt. Signed-off-by: Rong Xu Reported-by: Chris Packham Closes: https://lore.kernel.org/lkml/c6719149-8531-4174-824e-a3caf4bc6d0e@alliedtelesis.co.nz/T/ Tested-by: Chris Packham Signed-off-by: Masahiro Yamada --- scripts/head-object-list.txt | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt index fd5d00bac447..f12b4a7b8406 100644 --- a/scripts/head-object-list.txt +++ b/scripts/head-object-list.txt @@ -23,7 +23,6 @@ arch/m68k/coldfire/head.o arch/m68k/kernel/head.o arch/m68k/kernel/sun3-head.o arch/microblaze/kernel/head.o -arch/mips/kernel/head.o arch/nios2/kernel/head.o arch/openrisc/kernel/head.o arch/parisc/kernel/head.o -- cgit From 0847420f5e499a7ab518942fff71482179290163 Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Sat, 2 Nov 2024 10:51:12 -0700 Subject: AutoFDO: Enable -ffunction-sections for the AutoFDO build Enable -ffunction-sections by default for the AutoFDO build. With -ffunction-sections, the compiler places each function in its own section named .text.function_name instead of placing all functions in the .text section. In the AutoFDO build, this allows the linker to utilize profile information to reorganize functions for improved utilization of iCache and iTLB. Co-developed-by: Han Shen Signed-off-by: Han Shen Signed-off-by: Rong Xu Suggested-by: Sriraman Tallam Tested-by: Yonghong Song Tested-by: Yabin Cui Tested-by: Nathan Chancellor Reviewed-by: Kees Cook Signed-off-by: Masahiro Yamada --- scripts/Makefile.autofdo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.autofdo b/scripts/Makefile.autofdo index ff96a63fea7c..6155d6fc4ca7 100644 --- a/scripts/Makefile.autofdo +++ b/scripts/Makefile.autofdo @@ -9,7 +9,7 @@ ifndef CONFIG_DEBUG_INFO endif ifdef CLANG_AUTOFDO_PROFILE - CFLAGS_AUTOFDO_CLANG += -fprofile-sample-use=$(CLANG_AUTOFDO_PROFILE) + CFLAGS_AUTOFDO_CLANG += -fprofile-sample-use=$(CLANG_AUTOFDO_PROFILE) -ffunction-sections endif ifdef CONFIG_LTO_CLANG_THIN -- cgit From 2fd65f7afd5a73b685a1651cb651ade120b53e15 Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Sat, 2 Nov 2024 10:51:13 -0700 Subject: AutoFDO: Enable machine function split optimization for AutoFDO Enable the machine function split optimization for AutoFDO in Clang. Machine function split (MFS) is a pass in the Clang compiler that splits a function into hot and cold parts. The linker groups all cold blocks across functions together. This decreases hot code fragmentation and improves iCache and iTLB utilization. MFS requires a profile so this is enabled only for the AutoFDO builds. Co-developed-by: Han Shen Signed-off-by: Han Shen Signed-off-by: Rong Xu Suggested-by: Sriraman Tallam Suggested-by: Krzysztof Pszeniczny Tested-by: Yonghong Song Tested-by: Yabin Cui Tested-by: Nathan Chancellor Reviewed-by: Kees Cook Signed-off-by: Masahiro Yamada --- scripts/Makefile.autofdo | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.autofdo b/scripts/Makefile.autofdo index 6155d6fc4ca7..1caf2457e585 100644 --- a/scripts/Makefile.autofdo +++ b/scripts/Makefile.autofdo @@ -10,6 +10,7 @@ endif ifdef CLANG_AUTOFDO_PROFILE CFLAGS_AUTOFDO_CLANG += -fprofile-sample-use=$(CLANG_AUTOFDO_PROFILE) -ffunction-sections + CFLAGS_AUTOFDO_CLANG += -fsplit-machine-functions endif ifdef CONFIG_LTO_CLANG_THIN @@ -17,6 +18,7 @@ ifdef CONFIG_LTO_CLANG_THIN KBUILD_LDFLAGS += --lto-sample-profile=$(CLANG_AUTOFDO_PROFILE) endif KBUILD_LDFLAGS += --mllvm=-enable-fs-discriminator=true --mllvm=-improved-fs-discriminator=true -plugin-opt=thinlto + KBUILD_LDFLAGS += -plugin-opt=-split-machine-functions endif export CFLAGS_AUTOFDO_CLANG -- cgit From d5dc95836147f2e25b134c0ca3a0bc1a5867ea29 Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Sat, 2 Nov 2024 10:51:14 -0700 Subject: kbuild: Add Propeller configuration for kernel build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the build support for using Clang's Propeller optimizer. Like AutoFDO, Propeller uses hardware sampling to gather information about the frequency of execution of different code paths within a binary. This information is then used to guide the compiler's optimization decisions, resulting in a more efficient binary. The support requires a Clang compiler LLVM 19 or later, and the create_llvm_prof tool (https://github.com/google/autofdo/releases/tag/v0.30.1). This commit is limited to x86 platforms that support PMU features like LBR on Intel machines and AMD Zen3 BRS. Here is an example workflow for building an AutoFDO+Propeller optimized kernel: 1) Build the kernel on the host machine, with AutoFDO and Propeller build config CONFIG_AUTOFDO_CLANG=y CONFIG_PROPELLER_CLANG=y then $ make LLVM=1 CLANG_AUTOFDO_PROFILE=” is the profile collected when doing a non-Propeller AutoFDO build. This step builds a kernel that has the same optimization level as AutoFDO, plus a metadata section that records basic block information. This kernel image runs as fast as an AutoFDO optimized kernel. 2) Install the kernel on test/production machines. 3) Run the load tests. The '-c' option in perf specifies the sample event period. We suggest using a suitable prime number, like 500009, for this purpose. For Intel platforms: $ perf record -e BR_INST_RETIRED.NEAR_TAKEN:k -a -N -b -c \ -o -- For AMD platforms: The supported system are: Zen3 with BRS, or Zen4 with amd_lbr_v2 # To see if Zen3 support LBR: $ cat proc/cpuinfo | grep " brs" # To see if Zen4 support LBR: $ cat proc/cpuinfo | grep amd_lbr_v2 # If the result is yes, then collect the profile using: $ perf record --pfm-events RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a \ -N -b -c -o -- 4) (Optional) Download the raw perf file to the host machine. 5) Generate Propeller profile: $ create_llvm_prof --binary= --profile= \ --format=propeller --propeller_output_module_name \ --out=_cc_profile.txt \ --propeller_symorder=_ld_profile.txt “create_llvm_prof” is the profile conversion tool, and a prebuilt binary for linux can be found on https://github.com/google/autofdo/releases/tag/v0.30.1 (can also build from source). "" can be something like "/home/user/dir/any_string". This command generates a pair of Propeller profiles: "_cc_profile.txt" and "_ld_profile.txt". 6) Rebuild the kernel using the AutoFDO and Propeller profile files. CONFIG_AUTOFDO_CLANG=y CONFIG_PROPELLER_CLANG=y and $ make LLVM=1 CLANG_AUTOFDO_PROFILE= \ CLANG_PROPELLER_PROFILE_PREFIX= Co-developed-by: Han Shen Signed-off-by: Han Shen Signed-off-by: Rong Xu Suggested-by: Sriraman Tallam Suggested-by: Krzysztof Pszeniczny Suggested-by: Nick Desaulniers Suggested-by: Stephane Eranian Tested-by: Yonghong Song Tested-by: Nathan Chancellor Reviewed-by: Kees Cook Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 10 ++++++++++ scripts/Makefile.propeller | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 scripts/Makefile.propeller (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 2d0942c1a027..e7859ad90224 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -201,6 +201,16 @@ _c_flags += $(if $(patsubst n%,, \ $(CFLAGS_AUTOFDO_CLANG)) endif +# +# Enable Propeller build flags except some files or directories we don't want to +# enable (depends on variables AUTOFDO_PROPELLER_obj.o and PROPELLER_PROFILE). +# +ifdef CONFIG_PROPELLER_CLANG +_c_flags += $(if $(patsubst n%,, \ + $(AUTOFDO_PROFILE_$(target-stem).o)$(AUTOFDO_PROFILE)$(PROPELLER_PROFILE))$(is-kernel-object), \ + $(CFLAGS_PROPELLER_CLANG)) +endif + # $(src) for including checkin headers from generated source files # $(obj) for including generated headers from checkin source files ifeq ($(KBUILD_EXTMOD),) diff --git a/scripts/Makefile.propeller b/scripts/Makefile.propeller new file mode 100644 index 000000000000..344190717e47 --- /dev/null +++ b/scripts/Makefile.propeller @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Enable available and selected Clang Propeller features. +ifdef CLANG_PROPELLER_PROFILE_PREFIX + CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=list=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt -ffunction-sections + KBUILD_LDFLAGS += --symbol-ordering-file=$(CLANG_PROPELLER_PROFILE_PREFIX)_ld_profile.txt --no-warn-symbol-ordering +else + CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=labels +endif + +# Propeller requires debug information to embed module names in the profiles. +# If CONFIG_DEBUG_INFO is not enabled, set -gmlt option. Skip this for AutoFDO, +# as the option should already be set. +ifndef CONFIG_DEBUG_INFO + ifndef CONFIG_AUTOFDO_CLANG + CFLAGS_PROPELLER_CLANG += -gmlt + endif +endif + +ifdef CONFIG_LTO_CLANG_THIN + ifdef CLANG_PROPELLER_PROFILE_PREFIX + KBUILD_LDFLAGS += --lto-basic-block-sections=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt + else + KBUILD_LDFLAGS += --lto-basic-block-sections=labels + endif +endif + +export CFLAGS_PROPELLER_CLANG -- cgit From d63b852430be7fa2b6d7c550ea67e94b6681d0b5 Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Fri, 8 Nov 2024 13:49:53 -0800 Subject: kbuild: Fix Propeller build option The '-fbasic-block-sections=labels' option has been deprecated in tip of tree clang (20.0.0) [1]. While the option still works, a warning is emitted: clang: warning: argument '-fbasic-block-sections=labels' is deprecated, use '-fbasic-block-address-map' instead [-Wdeprecated] Add a version check to set the proper option. Link: https://github.com/llvm/llvm-project/pull/110039 [1] Signed-off-by: Rong Xu Reported-by: Nathan Chancellor Suggested-by: Nathan Chancellor Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- scripts/Makefile.propeller | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.propeller b/scripts/Makefile.propeller index 344190717e47..48a660128e25 100644 --- a/scripts/Makefile.propeller +++ b/scripts/Makefile.propeller @@ -5,7 +5,14 @@ ifdef CLANG_PROPELLER_PROFILE_PREFIX CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=list=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt -ffunction-sections KBUILD_LDFLAGS += --symbol-ordering-file=$(CLANG_PROPELLER_PROFILE_PREFIX)_ld_profile.txt --no-warn-symbol-ordering else - CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=labels + # Starting with Clang v20, the '-fbasic-block-sections=labels' option is + # deprecated. Use the recommended '-fbasic-block-address-map' option. + # Link: https://github.com/llvm/llvm-project/pull/110039 + ifeq ($(call clang-min-version, 200000),y) + CFLAGS_PROPELLER_CLANG := -fbasic-block-address-map + else + CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=labels + endif endif # Propeller requires debug information to embed module names in the profiles. @@ -21,7 +28,11 @@ ifdef CONFIG_LTO_CLANG_THIN ifdef CLANG_PROPELLER_PROFILE_PREFIX KBUILD_LDFLAGS += --lto-basic-block-sections=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt else - KBUILD_LDFLAGS += --lto-basic-block-sections=labels + ifeq ($(call test-ge, $(CONFIG_LLD_VERSION), 200000),y) + KBUILD_LDFLAGS += --lto-basic-block-address-map + else + KBUILD_LDFLAGS += --lto-basic-block-sections=labels + endif endif endif -- cgit From bcbbf493f2fa6fa1f0832f6b5b4c80a65de242d6 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 7 Nov 2024 15:05:08 +0000 Subject: kbuild: deb-pkg: Don't fail if modules.order is missing Kernels built without CONFIG_MODULES might still want to create -dbg deb packages but install_linux_image_dbg() assumes modules.order always exists. This obviously isn't true if no modules were built, so we should skip reading modules.order in that case. Fixes: 16c36f8864e3 ("kbuild: deb-pkg: use build ID instead of debug link for dbg package") Signed-off-by: Matt Fleming Signed-off-by: Masahiro Yamada --- scripts/package/builddeb | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 441b0bb66e0d..fb686fd3266f 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -96,16 +96,18 @@ install_linux_image_dbg () { # Parse modules.order directly because 'make modules_install' may sign, # compress modules, and then run unneeded depmod. - while read -r mod; do - mod="${mod%.o}.ko" - dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}" - buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p') - link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug" - - mkdir -p "${dbg%/*}" "${link%/*}" - "${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}" - ln -sf --relative "${dbg}" "${link}" - done < modules.order + if is_enabled CONFIG_MODULES; then + while read -r mod; do + mod="${mod%.o}.ko" + dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}" + buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p') + link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug" + + mkdir -p "${dbg%/*}" "${link%/*}" + "${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}" + ln -sf --relative "${dbg}" "${link}" + done < modules.order + fi # Build debug package # Different tools want the image in different locations -- cgit From 214c0eea43b2ea66bcd6467ea57e47ce8874191b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 10 Nov 2024 10:34:30 +0900 Subject: kbuild: add $(objtree)/ prefix to some in-kernel build artifacts $(objtree) refers to the top of the output directory of kernel builds. This commit adds the explicit $(objtree)/ prefix to build artifacts needed for building external modules. This change has no immediate impact, as the top-level Makefile currently defines: objtree := . This commit prepares for supporting the building of external modules in a different directory. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Kbuild.include | 2 +- scripts/Makefile.build | 4 ++-- scripts/Makefile.modfinal | 14 +++++++------- scripts/Makefile.modinst | 2 +- scripts/Makefile.modpost | 12 ++++++------ scripts/depmod.sh | 4 ++-- 6 files changed, 19 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index ed8a7493524b..8c311b997e24 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -205,7 +205,7 @@ if_changed_dep = $(if $(if-changed-cond),$(cmd_and_fixdep),@:) cmd_and_fixdep = \ $(cmd); \ - scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\ + $(objtree)/scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\ rm -f $(depfile) # Usage: $(call if_changed_rule,foo) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 8f423a1faf50..dd7a80ebca62 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -34,7 +34,7 @@ subdir-asflags-y := subdir-ccflags-y := # Read auto.conf if it exists, otherwise ignore --include include/config/auto.conf +-include $(objtree)/include/config/auto.conf include $(srctree)/scripts/Kbuild.include include $(srctree)/scripts/Makefile.compiler @@ -107,7 +107,7 @@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $< $(obj)/%.i: $(obj)/%.c FORCE $(call if_changed_dep,cpp_i_c) -genksyms = scripts/genksyms/genksyms \ +genksyms = $(objtree)/scripts/genksyms/genksyms \ $(if $(1), -T $(2)) \ $(if $(KBUILD_PRESERVE), -p) \ -r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null) diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 1482884ec3ca..6d8aa3059ee2 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -6,7 +6,7 @@ PHONY := __modfinal __modfinal: -include include/config/auto.conf +include $(objtree)/include/config/auto.conf include $(srctree)/scripts/Kbuild.include # for c_flags @@ -37,15 +37,15 @@ quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = \ $(LD) -r $(KBUILD_LDFLAGS) \ $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ - -T scripts/module.lds -o $@ $(filter %.o, $^) + -T $(objtree)/scripts/module.lds -o $@ $(filter %.o, $^) quiet_cmd_btf_ko = BTF [M] $@ cmd_btf_ko = \ - if [ ! -f vmlinux ]; then \ + if [ ! -f $(objtree)/vmlinux ]; then \ printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ else \ - LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base vmlinux $@; \ - $(RESOLVE_BTFIDS) -b vmlinux $@; \ + LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base $(objtree)/vmlinux $@; \ + $(RESOLVE_BTFIDS) -b $(objtree)/vmlinux $@; \ fi; # Same as newer-prereqs, but allows to exclude specified extra dependencies @@ -57,8 +57,8 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) # Re-generate module BTFs if either module's .ko or vmlinux changed -%.ko: %.o %.mod.o $(extmod_prefix).module-common.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE - +$(call if_changed_except,ld_ko_o,vmlinux) +%.ko: %.o %.mod.o $(extmod_prefix).module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE + +$(call if_changed_except,ld_ko_o,$(objtree)/vmlinux) ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) endif diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index d97720943189..6fa9af4a25b4 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -6,7 +6,7 @@ PHONY := __modinst __modinst: -include include/config/auto.conf +include $(objtree)/include/config/auto.conf include $(srctree)/scripts/Kbuild.include install-y := diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 44936ebad161..12e7c15d099c 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -35,10 +35,10 @@ PHONY := __modpost __modpost: -include include/config/auto.conf +include $(objtree)/include/config/auto.conf include $(srctree)/scripts/Kbuild.include -MODPOST = scripts/mod/modpost +MODPOST = $(objtree)/scripts/mod/modpost modpost-args = \ $(if $(CONFIG_MODULES),-M) \ @@ -119,11 +119,11 @@ include $(kbuild-file) output-symdump := $(KBUILD_EXTMOD)/Module.symvers -ifeq ($(wildcard Module.symvers),) -missing-input := Module.symvers +ifeq ($(wildcard $(objtree)/Module.symvers),) +missing-input := $(objtree)/Module.symvers else -modpost-args += -i Module.symvers -modpost-deps += Module.symvers +modpost-args += -i $(objtree)/Module.symvers +modpost-deps += $(objtree)/Module.symvers endif modpost-args += -e $(addprefix -i , $(KBUILD_EXTRA_SYMBOLS)) diff --git a/scripts/depmod.sh b/scripts/depmod.sh index e22da27fe13e..3c34fecacbc8 100755 --- a/scripts/depmod.sh +++ b/scripts/depmod.sh @@ -12,7 +12,7 @@ KERNELRELEASE=$1 : ${DEPMOD:=depmod} -if ! test -r System.map ; then +if ! test -r "${objtree}/System.map" ; then echo "Warning: modules_install: missing 'System.map' file. Skipping depmod." >&2 exit 0 fi @@ -25,7 +25,7 @@ if [ -z $(command -v $DEPMOD) ]; then exit 0 fi -set -- -ae -F System.map +set -- -ae -F "${objtree}/System.map" if test -n "$INSTALL_MOD_PATH"; then set -- "$@" -b "$INSTALL_MOD_PATH" fi -- cgit From 13b25489b6f8bd73ed65f07928f7c27a481f1820 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 10 Nov 2024 10:34:33 +0900 Subject: kbuild: change working directory to external module directory with M= Currently, Kbuild always operates in the output directory of the kernel, even when building external modules. This increases the risk of external module Makefiles attempting to write to the kernel directory. This commit switches the working directory to the external module directory, allowing the removal of the $(KBUILD_EXTMOD)/ prefix from some build artifacts. The command for building external modules maintains backward compatibility, but Makefiles that rely on working in the kernel directory may break. In such cases, $(objtree) and $(srctree) should be used to refer to the output and source directories of the kernel. The appearance of the build log will change as follows: [Before] $ make -C /path/to/my/linux M=/path/to/my/externel/module make: Entering directory '/path/to/my/linux' CC [M] /path/to/my/externel/module/helloworld.o MODPOST /path/to/my/externel/module/Module.symvers CC [M] /path/to/my/externel/module/helloworld.mod.o CC [M] /path/to/my/externel/module/.module-common.o LD [M] /path/to/my/externel/module/helloworld.ko make: Leaving directory '/path/to/my/linux' [After] $ make -C /path/to/my/linux M=/path/to/my/externel/module make: Entering directory '/path/to/my/linux' make[1]: Entering directory '/path/to/my/externel/module' CC [M] helloworld.o MODPOST Module.symvers CC [M] helloworld.mod.o CC [M] .module-common.o LD [M] helloworld.ko make[1]: Leaving directory '/path/to/my/externel/module' make: Leaving directory '/path/to/my/linux' Printing "Entering directory" twice is cumbersome. This will be addressed later. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Makefile.build | 2 +- scripts/Makefile.clean | 2 +- scripts/Makefile.compiler | 2 +- scripts/Makefile.modpost | 6 +++--- scripts/coccicheck | 6 +----- scripts/nsdeps | 8 +------- scripts/package/install-extmod-build | 7 +++++++ 7 files changed, 15 insertions(+), 18 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index dd7a80ebca62..e5e382a1d64d 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -3,7 +3,7 @@ # Building # ========================================================================== -src := $(if $(VPATH),$(VPATH)/)$(obj) +src := $(srcroot)/$(obj) PHONY := $(obj)/ $(obj)/: diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 4fcfab40ed61..6ead00ec7313 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -3,7 +3,7 @@ # Cleaning up # ========================================================================== -src := $(if $(VPATH),$(VPATH)/)$(obj) +src := $(srcroot)/$(obj) PHONY := __clean __clean: diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler index e0842496d26e..8c1029687e2e 100644 --- a/scripts/Makefile.compiler +++ b/scripts/Makefile.compiler @@ -13,7 +13,7 @@ cc-cross-prefix = $(firstword $(foreach c, $(1), \ $(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c)))) # output directory for tests below -TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$ +TMPOUT = .tmp_$$$$ # try-run # Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 12e7c15d099c..78d2ca4f25f5 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -111,13 +111,13 @@ endif else # set src + obj - they may be used in the modules's Makefile -obj := $(KBUILD_EXTMOD) -src := $(if $(VPATH),$(VPATH)/)$(obj) +obj := . +src := $(srcroot) # Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS include $(kbuild-file) -output-symdump := $(KBUILD_EXTMOD)/Module.symvers +output-symdump := Module.symvers ifeq ($(wildcard $(objtree)/Module.symvers),) missing-input := $(objtree)/Module.symvers diff --git a/scripts/coccicheck b/scripts/coccicheck index e52cb43fede6..0e6bc5a10320 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -80,11 +80,7 @@ command results in a shift count error.' NPROC=1 else ONLINE=0 - if [ "$KBUILD_EXTMOD" = "" ] ; then - OPTIONS="--dir $srctree $COCCIINCLUDE" - else - OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE" - fi + OPTIONS="--dir $srcroot $COCCIINCLUDE" # Use only one thread per core by default if hyperthreading is enabled THREADS_PER_CORE=$(LANG=C lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]") diff --git a/scripts/nsdeps b/scripts/nsdeps index f1718cc0d700..8ca12e2b5c03 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -19,12 +19,6 @@ if ! { echo "$SPATCH_REQ_VERSION"; echo "$SPATCH_VERSION"; } | sort -CV ; then exit 1 fi -if [ "$KBUILD_EXTMOD" ]; then - src_prefix= -else - src_prefix=$srctree/ -fi - generate_deps_for_ns() { $SPATCH --very-quiet --in-place --sp-file \ $srctree/scripts/coccinelle/misc/add_namespace.cocci -D nsdeps -D ns=$1 $2 @@ -34,7 +28,7 @@ generate_deps() { local mod=${1%.ko:} shift local namespaces="$*" - local mod_source_files=$(sed "s|^\(.*\)\.o$|${src_prefix}\1.c|" $mod.mod) + local mod_source_files=$(sed "s|^\(.*\)\.o$|${srcroot}/\1.c|" $mod.mod) for ns in $namespaces; do echo "Adding namespace $ns to module $mod.ko." diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build index 7ec1f061a519..64d958ee45f3 100755 --- a/scripts/package/install-extmod-build +++ b/scripts/package/install-extmod-build @@ -51,6 +51,13 @@ mkdir -p "${destdir}" if [ "${CC}" != "${HOSTCC}" ]; then echo "Rebuilding host programs with ${CC}..." + # This leverages external module building. + # - Clear sub_make_done to allow the top-level Makefile to redo sub-make. + # - Filter out --no-print-directory to print "Entering directory" logs + # when Make changes the working directory. + unset sub_make_done + MAKEFLAGS=$(echo "${MAKEFLAGS}" | sed s/--no-print-directory//) + cat <<-'EOF' > "${destdir}/Kbuild" subdir-y := scripts EOF -- cgit From bad6beb2c0bb982b830f592a7b3e3eee76cbb85a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 10 Nov 2024 10:34:34 +0900 Subject: kbuild: remove extmod_prefix, MODORDER, MODULES_NSDEPS variables With the previous changes, $(extmod_prefix), $(MODORDER), and $(MODULES_NSDEPS) are constant. (empty, modules.order, and modules.nsdeps, respectively). Remove these variables and hard-code their values. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Makefile.modfinal | 8 ++++---- scripts/Makefile.modinst | 6 +++--- scripts/Makefile.modpost | 6 +++--- scripts/nsdeps | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 6d8aa3059ee2..bab53884f7e3 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -13,7 +13,7 @@ include $(srctree)/scripts/Kbuild.include include $(srctree)/scripts/Makefile.lib # find all modules listed in modules.order -modules := $(call read-file, $(MODORDER)) +modules := $(call read-file, modules.order) __modfinal: $(modules:%.o=%.ko) @: @@ -30,7 +30,7 @@ quiet_cmd_cc_o_c = CC [M] $@ %.mod.o: %.mod.c FORCE $(call if_changed_dep,cc_o_c) -$(extmod_prefix).module-common.o: $(srctree)/scripts/module-common.c FORCE +.module-common.o: $(srctree)/scripts/module-common.c FORCE $(call if_changed_dep,cc_o_c) quiet_cmd_ld_ko_o = LD [M] $@ @@ -57,13 +57,13 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) # Re-generate module BTFs if either module's .ko or vmlinux changed -%.ko: %.o %.mod.o $(extmod_prefix).module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE +%.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE +$(call if_changed_except,ld_ko_o,$(objtree)/vmlinux) ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) endif -targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) $(extmod_prefix).module-common.o +targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) .module-common.o # Add FORCE to the prerequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 6fa9af4a25b4..f97c9926ed31 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -40,7 +40,7 @@ $(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo modules.builtin. endif -modules := $(call read-file, $(MODORDER)) +modules := $(call read-file, modules.order) ifeq ($(KBUILD_EXTMOD),) dst := $(MODLIB)/kernel @@ -59,7 +59,7 @@ suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst endif -modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules)) +modules := $(patsubst %.o, $(dst)/%.ko$(suffix-y), $(modules)) install-$(CONFIG_MODULES) += $(modules) __modinst: $(install-y) @@ -119,7 +119,7 @@ endif # Create necessary directories $(foreach dir, $(sort $(dir $(install-y))), $(shell mkdir -p $(dir))) -$(dst)/%.ko: $(extmod_prefix)%.ko FORCE +$(dst)/%.ko: %.ko FORCE $(call cmd,install) $(call cmd,strip) $(call cmd,sign) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 78d2ca4f25f5..ab0e94ea6249 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -46,7 +46,7 @@ modpost-args = \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ $(if $(KBUILD_MODPOST_WARN),-w) \ - $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \ + $(if $(KBUILD_NSDEPS),-d modules.nsdeps) \ $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \ $(if $(findstring 1, $(KBUILD_EXTRA_WARN)),-W) \ -o $@ @@ -61,8 +61,8 @@ endif # Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". ifdef KBUILD_MODULES -modpost-args += -T $(MODORDER) -modpost-deps += $(MODORDER) +modpost-args += -T modules.order +modpost-deps += modules.order endif ifeq ($(KBUILD_EXTMOD),) diff --git a/scripts/nsdeps b/scripts/nsdeps index 8ca12e2b5c03..bab4ec870e50 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -51,4 +51,4 @@ generate_deps() { while read line do generate_deps $line -done < $MODULES_NSDEPS +done < modules.nsdeps -- cgit From 11b3d5175e6bc3779159228e6077be202d2b0069 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 10 Nov 2024 10:34:35 +0900 Subject: kbuild: support building external modules in a separate build directory There has been a long-standing request to support building external modules in a separate build directory. This commit introduces a new environment variable, KBUILD_EXTMOD_OUTPUT, and its shorthand Make variable, MO. A simple usage: $ make -C M= MO= Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Makefile.host | 8 +++----- scripts/Makefile.lib | 2 -- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.host b/scripts/Makefile.host index e01c13a588dd..c1dedf646a39 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -96,12 +96,10 @@ hostrust_flags = --out-dir $(dir $@) --emit=dep-info=$(depfile) \ $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \ $(HOSTRUSTFLAGS_$(target-stem)) -# $(objtree)/$(obj) for including generated headers from checkin source files -ifeq ($(KBUILD_EXTMOD),) +# $(obj) for including generated headers from checkin source files ifdef building_out_of_srctree -hostc_flags += -I $(objtree)/$(obj) -hostcxx_flags += -I $(objtree)/$(obj) -endif +hostc_flags += -I $(obj) +hostcxx_flags += -I $(obj) endif ##### diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index e7859ad90224..5660dfc9ed36 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -213,13 +213,11 @@ endif # $(src) for including checkin headers from generated source files # $(obj) for including generated headers from checkin source files -ifeq ($(KBUILD_EXTMOD),) ifdef building_out_of_srctree _c_flags += $(addprefix -I, $(src) $(obj)) _a_flags += $(addprefix -I, $(src) $(obj)) _cpp_flags += $(addprefix -I, $(src) $(obj)) endif -endif # If $(is-kernel-object) is 'y', this object will be linked to vmlinux or modules is-kernel-object = $(or $(part-of-builtin),$(part-of-module)) -- cgit From c2386abf55616b979b07a63b4eb2a14eedb4c9e5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 12 Nov 2024 02:17:40 +0900 Subject: kbuild: do not pass -r to genksyms when *.symref does not exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no need to pass '-r /dev/null', which is no-op. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Makefile.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index e5e382a1d64d..628e0ce28dc8 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -110,7 +110,7 @@ $(obj)/%.i: $(obj)/%.c FORCE genksyms = $(objtree)/scripts/genksyms/genksyms \ $(if $(1), -T $(2)) \ $(if $(KBUILD_PRESERVE), -p) \ - -r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null) + $(addprefix -r , $(wildcard $(2:.symtypes=.symref))) # These mirror gensymtypes_S and co below, keep them in synch. cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms) -- cgit From 91ca8be3c402c566de75685ce99c714b0e8638bf Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 12 Nov 2024 02:17:41 +0900 Subject: kbuild: remove support for single %.symtypes build rule This rule is unnecessary because you can generate foo/bar.symtypes as a side effect using: $ make KBUILD_SYMTYPES=1 foo/bar.o While compiling *.o is slower than preprocessing, the impact is negligible. I prioritize keeping the code simpler. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Makefile.build | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 628e0ce28dc8..15a88f4d6ef6 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -108,19 +108,13 @@ $(obj)/%.i: $(obj)/%.c FORCE $(call if_changed_dep,cpp_i_c) genksyms = $(objtree)/scripts/genksyms/genksyms \ - $(if $(1), -T $(2)) \ - $(if $(KBUILD_PRESERVE), -p) \ - $(addprefix -r , $(wildcard $(2:.symtypes=.symref))) + $(if $(KBUILD_SYMTYPES), -T $(@:.o=.symtypes)) \ + $(if $(KBUILD_PRESERVE), -p) \ + $(addprefix -r , $(wildcard $(@:.o=.symref))) # These mirror gensymtypes_S and co below, keep them in synch. cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms) -quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ - cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null - -$(obj)/%.symtypes : $(obj)/%.c FORCE - $(call cmd,cc_symtypes_c) - # LLVM assembly # Generate .ll files from .c quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@ @@ -158,8 +152,7 @@ ifdef CONFIG_MODVERSIONS gen_symversions = \ if $(NM) $@ 2>/dev/null | grep -q ' __export_symbol_'; then \ - $(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ - >> $(dot-target).cmd; \ + $(cmd_gensymtypes_$1) >> $(dot-target).cmd; \ fi cmd_gen_symversions_c = $(call gen_symversions,c) @@ -323,13 +316,6 @@ cmd_gensymtypes_S = \ $(NM) $@ | sed -n 's/.* __export_symbol_\(.*\)/EXPORT_SYMBOL(\1);/p' ; } | \ $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms) -quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ - cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null - -$(obj)/%.symtypes : $(obj)/%.S FORCE - $(call cmd,cc_symtypes_S) - - quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@ cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $< -- cgit From 000e22a80de0727839bb753159ac05c8ba20c3e3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 14 Nov 2024 08:45:21 +0900 Subject: kbuild: move cmd_cc_o_c and cmd_as_o_S to scripts/Malefile.lib The cmd_cc_o_c and cmd_as_o_S macros are duplicated in scripts/Makefile.{build,modfinal,vmlinux}. This commit factors them out to scripts/Makefile.lib. No functional changes are intended. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 8 -------- scripts/Makefile.lib | 12 ++++++++++++ scripts/Makefile.modfinal | 6 +----- scripts/Makefile.vmlinux | 8 -------- 4 files changed, 13 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 15a88f4d6ef6..c0b61ae71e3e 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -135,11 +135,6 @@ ifdef CONFIG_LTO_CLANG cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@) endif -quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ - cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \ - $(cmd_ld_single_m) \ - $(cmd_objtool) - ifdef CONFIG_MODVERSIONS # When module versioning is enabled the following steps are executed: # o compile a .o from .c @@ -322,9 +317,6 @@ cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $< $(obj)/%.s: $(obj)/%.S FORCE $(call if_changed_dep,cpp_s_S) -quiet_cmd_as_o_S = AS $(quiet_modtag) $@ - cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool) - ifdef CONFIG_ASM_MODVERSIONS # versioning matches the C process described above, with difference that diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 5660dfc9ed36..c0b485ab029a 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -298,6 +298,18 @@ $(foreach m, $1, \ $(addprefix $(obj)/, $(call suffix-search, $(patsubst $(obj)/%,%,$m), $2, $3)))) endef +# Build commands +# =========================================================================== +# These are shared by some Makefile.* files. + +quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \ + $(cmd_ld_single_m) \ + $(cmd_objtool) + +quiet_cmd_as_o_S = AS $(quiet_modtag) $@ + cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool) + # Copy a file # =========================================================================== # 'cp' preserves permissions. If you use it to copy a file in read-only srctree, diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index bab53884f7e3..f63410ba5c2c 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -8,8 +8,6 @@ __modfinal: include $(objtree)/include/config/auto.conf include $(srctree)/scripts/Kbuild.include - -# for c_flags include $(srctree)/scripts/Makefile.lib # find all modules listed in modules.order @@ -23,9 +21,7 @@ modname = $(notdir $(@:.mod.o=)) part-of-module = y GCOV_PROFILE := n KCSAN_SANITIZE := n - -quiet_cmd_cc_o_c = CC [M] $@ - cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI), $(c_flags)) -c -o $@ $< +ccflags-remove-y := $(CC_FLAGS_CFI) %.mod.o: %.mod.c FORCE $(call if_changed_dep,cc_o_c) diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 9ef0480ed755..2ce61f6c79c6 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -5,21 +5,13 @@ __default: vmlinux include include/config/auto.conf include $(srctree)/scripts/Kbuild.include - -# for c_flags include $(srctree)/scripts/Makefile.lib targets := -quiet_cmd_cc_o_c = CC $@ - cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< - %.o: %.c FORCE $(call if_changed_dep,cc_o_c) -quiet_cmd_as_o_S = AS $@ - cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< - %.o: %.S FORCE $(call if_changed_dep,as_o_S) -- cgit From bede169618c68379e1be7ace14e8ac85b964a9ec Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 14 Nov 2024 08:45:22 +0900 Subject: kbuild: enable objtool for *.mod.o and additional kernel objects Currently, objtool is disabled in scripts/Makefile.{modfinal,vmlinux}. This commit moves rule_cc_o_c and rule_as_o_S to scripts/Makefile.lib and set objtool-enabled to y there. With this change, *.mod.o, .module-common.o, builtin-dtb.o, and vmlinux.export.o will now be covered by objtool. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 23 ----------------------- scripts/Makefile.lib | 26 +++++++++++++++++++++++++- scripts/Makefile.modfinal | 4 ++-- scripts/Makefile.vmlinux | 4 ++-- 4 files changed, 29 insertions(+), 28 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index c0b61ae71e3e..f41ce2131979 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -129,12 +129,6 @@ $(obj)/%.ll: $(obj)/%.c FORCE is-single-obj-m = $(and $(part-of-module),$(filter $@, $(obj-m)),y) -# When a module consists of a single object, there is no reason to keep LLVM IR. -# Make $(LD) covert LLVM IR to ELF here. -ifdef CONFIG_LTO_CLANG -cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@) -endif - ifdef CONFIG_MODVERSIONS # When module versioning is enabled the following steps are executed: # o compile a .o from .c @@ -195,23 +189,6 @@ ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) cmd_warn_shared_object = $(if $(word 2, $(modname-multi)),$(warning $(kbuild-file): $*.o is added to multiple modules: $(modname-multi))) endif -define rule_cc_o_c - $(call cmd_and_fixdep,cc_o_c) - $(call cmd,checksrc) - $(call cmd,checkdoc) - $(call cmd,gen_objtooldep) - $(call cmd,gen_symversions_c) - $(call cmd,record_mcount) - $(call cmd,warn_shared_object) -endef - -define rule_as_o_S - $(call cmd_and_fixdep,as_o_S) - $(call cmd,gen_objtooldep) - $(call cmd,gen_symversions_S) - $(call cmd,warn_shared_object) -endef - # Built-in and composite module parts $(obj)/%.o: $(obj)/%.c $(recordmcount_source) FORCE $(call if_changed_rule,cc_o_c) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index c0b485ab029a..01040a767c1d 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -302,14 +302,38 @@ endef # =========================================================================== # These are shared by some Makefile.* files. +objtool-enabled := y + +ifdef CONFIG_LTO_CLANG +# objtool cannot process LLVM IR. Make $(LD) covert LLVM IR to ELF here. +cmd_ld_single = $(if $(objtool-enabled), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@) +endif + quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \ - $(cmd_ld_single_m) \ + $(cmd_ld_single) \ $(cmd_objtool) +define rule_cc_o_c + $(call cmd_and_fixdep,cc_o_c) + $(call cmd,checksrc) + $(call cmd,checkdoc) + $(call cmd,gen_objtooldep) + $(call cmd,gen_symversions_c) + $(call cmd,record_mcount) + $(call cmd,warn_shared_object) +endef + quiet_cmd_as_o_S = AS $(quiet_modtag) $@ cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool) +define rule_as_o_S + $(call cmd_and_fixdep,as_o_S) + $(call cmd,gen_objtooldep) + $(call cmd,gen_symversions_S) + $(call cmd,warn_shared_object) +endef + # Copy a file # =========================================================================== # 'cp' preserves permissions. If you use it to copy a file in read-only srctree, diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index f63410ba5c2c..85d5fadbcc93 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -24,10 +24,10 @@ KCSAN_SANITIZE := n ccflags-remove-y := $(CC_FLAGS_CFI) %.mod.o: %.mod.c FORCE - $(call if_changed_dep,cc_o_c) + $(call if_changed_rule,cc_o_c) .module-common.o: $(srctree)/scripts/module-common.c FORCE - $(call if_changed_dep,cc_o_c) + $(call if_changed_rule,cc_o_c) quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = \ diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 2ce61f6c79c6..997be5dc7bf5 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -10,10 +10,10 @@ include $(srctree)/scripts/Makefile.lib targets := %.o: %.c FORCE - $(call if_changed_dep,cc_o_c) + $(call if_changed_rule,cc_o_c) %.o: %.S FORCE - $(call if_changed_dep,as_o_S) + $(call if_changed_rule,as_o_S) # Built-in dtb # --------------------------------------------------------------------------- -- cgit From 1b466b29a3bf02ed95f28682a975f41ae47bce7d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 14 Nov 2024 08:45:23 +0900 Subject: kbuild: re-enable KCSAN for autogenerated *.mod.c intermediaries This reverts commit 54babdc0343f ("kbuild: Disable KCSAN for autogenerated *.mod.c intermediaries"). Now that objtool is enabled for *.mod.c, there is no need to filter out CFLAGS_KCSAN. I no longer see "Unpatched return thunk in use. This should not happen!" error with KCSAN when loading a module. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modfinal | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 85d5fadbcc93..542ba462ed3e 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -20,7 +20,6 @@ __modfinal: $(modules:%.o=%.ko) modname = $(notdir $(@:.mod.o=)) part-of-module = y GCOV_PROFILE := n -KCSAN_SANITIZE := n ccflags-remove-y := $(CC_FLAGS_CFI) %.mod.o: %.mod.c FORCE -- cgit From e397a603e49cc7c7c113fad9f55a09637f290c34 Mon Sep 17 00:00:00 2001 From: Parth Pancholi Date: Thu, 14 Nov 2024 15:56:44 +0100 Subject: kbuild: switch from lz4c to lz4 for compression Replace lz4c with lz4 for kernel image compression. Although lz4 and lz4c are functionally similar, lz4c has been deprecated upstream since 2018. Since as early as Ubuntu 16.04 and Fedora 25, lz4 and lz4c have been packaged together, making it safe to update the requirement from lz4c to lz4. Consequently, some distributions and build systems, such as OpenEmbedded, have fully transitioned to using lz4. OpenEmbedded core adopted this change in commit fe167e082cbd ("bitbake.conf: require lz4 instead of lz4c"), causing compatibility issues when building the mainline kernel in the latest OpenEmbedded environment, as seen in the errors below. This change also updates the LZ4 compression commands to make it backward compatible by replacing stdin and stdout with the '-' option, due to some unclear reason, the stdout keyword does not work for lz4 and '-' works for both. In addition, this modifies the legacy '-c1' with '-9' which is also compatible with both. This fixes the mainline kernel build failures with the latest master OpenEmbedded builds associated with the mentioned compatibility issues. LZ4 arch/arm/boot/compressed/piggy_data /bin/sh: 1: lz4c: not found ... ... ERROR: oe_runmake failed Link: https://github.com/lz4/lz4/pull/553 Suggested-by: Francesco Dolcini Signed-off-by: Parth Pancholi Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 01040a767c1d..7395200538da 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -425,10 +425,10 @@ quiet_cmd_lzo_with_size = LZO $@ cmd_lzo_with_size = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@ quiet_cmd_lz4 = LZ4 $@ - cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout > $@ + cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -9 - - > $@ quiet_cmd_lz4_with_size = LZ4 $@ - cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \ + cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -9 - -; \ $(size_append); } > $@ # U-Boot mkimage -- cgit From 523f3dbc187a9618d4fd80c2b438e4d490705dcd Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Mon, 18 Nov 2024 12:01:54 +0100 Subject: setlocalversion: work around "git describe" performance Contrary to expectations, passing a single candidate tag to "git describe" is slower than not passing any --match options. $ time git describe --debug ... traversed 10619 commits ... v6.12-rc5-63-g0fc810ae3ae1 real 0m0.169s $ time git describe --match=v6.12-rc5 --debug ... traversed 1310024 commits v6.12-rc5-63-g0fc810ae3ae1 real 0m1.281s In fact, the --debug output shows that git traverses all or most of history. For some repositories and/or git versions, those 1.3s are actually 10-15 seconds. This has been acknowledged as a performance bug in git [1], and a fix is on its way [2]. However, no solution is yet in git.git, and even when one lands, it will take quite a while before it finds its way to a release and for $random_kernel_developer to pick that up. So rewrite the logic to use plumbing commands. For each of the candidate values of $tag, we ask: (1) is $tag even an annotated tag? (2) Is it eligible to describe HEAD, i.e. an ancestor of HEAD? (3) If so, how many commits are in $tag..HEAD? I have tested that this produces the same output as the current script for ~700 random commits between v6.9..v6.10. For those 700 commits, and in my git repo, the 'make -s kernelrelease' command is on average ~4 times faster with this patch applied (geometric mean of ratios). For the commit mentioned in Josh's original report [3], the time-consuming part of setlocalversion goes from $ time git describe --match=v6.12-rc5 c1e939a21eb1 v6.12-rc5-44-gc1e939a21eb1 real 0m1.210s to $ time git rev-list --count --left-right v6.12-rc5..c1e939a21eb1 0 44 real 0m0.037s [1] https://lore.kernel.org/git/20241101113910.GA2301440@coredump.intra.peff.net/ [2] https://lore.kernel.org/git/20241106192236.GC880133@coredump.intra.peff.net/ [3] https://lore.kernel.org/lkml/309549cafdcfe50c4fceac3263220cc3d8b109b2.1730337435.git.jpoimboe@kernel.org/ Reported-by: Sean Christopherson Closes: https://lore.kernel.org/lkml/ZPtlxmdIJXOe0sEy@google.com/ Reported-by: Josh Poimboeuf Closes: https://lore.kernel.org/lkml/309549cafdcfe50c4fceac3263220cc3d8b109b2.1730337435.git.jpoimboe@kernel.org/ Tested-by: Josh Poimboeuf Signed-off-by: Rasmus Villemoes Signed-off-by: Masahiro Yamada --- scripts/setlocalversion | 54 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 38b96c6797f4..5818465abba9 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -30,6 +30,27 @@ if test $# -gt 0 -o ! -d "$srctree"; then usage fi +try_tag() { + tag="$1" + + # Is $tag an annotated tag? + [ "$(git cat-file -t "$tag" 2> /dev/null)" = tag ] || return 1 + + # Is it an ancestor of HEAD, and if so, how many commits are in $tag..HEAD? + # shellcheck disable=SC2046 # word splitting is the point here + set -- $(git rev-list --count --left-right "$tag"...HEAD 2> /dev/null) + + # $1 is 0 if and only if $tag is an ancestor of HEAD. Use + # string comparison, because $1 is empty if the 'git rev-list' + # command somehow failed. + [ "$1" = 0 ] || return 1 + + # $2 is the number of commits in the range $tag..HEAD, possibly 0. + count="$2" + + return 0 +} + scm_version() { local short=false @@ -61,33 +82,33 @@ scm_version() # stable kernel: 6.1.7 -> v6.1.7 version_tag=v$(echo "${KERNELVERSION}" | sed -E 's/^([0-9]+\.[0-9]+)\.0(.*)$/\1\2/') + # try_tag initializes count if the tag is usable. + count= + # If a localversion* file exists, and the corresponding # annotated tag exists and is an ancestor of HEAD, use # it. This is the case in linux-next. - tag=${file_localversion#-} - desc= - if [ -n "${tag}" ]; then - desc=$(git describe --match=$tag 2>/dev/null) + if [ -n "${file_localversion#-}" ] ; then + try_tag "${file_localversion#-}" fi # Otherwise, if a localversion* file exists, and the tag # obtained by appending it to the tag derived from # KERNELVERSION exists and is an ancestor of HEAD, use # it. This is e.g. the case in linux-rt. - if [ -z "${desc}" ] && [ -n "${file_localversion}" ]; then - tag="${version_tag}${file_localversion}" - desc=$(git describe --match=$tag 2>/dev/null) + if [ -z "${count}" ] && [ -n "${file_localversion}" ]; then + try_tag "${version_tag}${file_localversion}" fi # Otherwise, default to the annotated tag derived from KERNELVERSION. - if [ -z "${desc}" ]; then - tag="${version_tag}" - desc=$(git describe --match=$tag 2>/dev/null) + if [ -z "${count}" ]; then + try_tag "${version_tag}" fi - # If we are at the tagged commit, we ignore it because the version is - # well-defined. - if [ "${tag}" != "${desc}" ]; then + # If we are at the tagged commit, we ignore it because the + # version is well-defined. If none of the attempted tags exist + # or were usable, $count is still empty. + if [ -z "${count}" ] || [ "${count}" -gt 0 ]; then # If only the short version is requested, don't bother # running further git commands @@ -95,14 +116,15 @@ scm_version() echo "+" return fi + # If we are past the tagged commit, we pretty print it. # (like 6.1.0-14595-g292a089d78d3) - if [ -n "${desc}" ]; then - echo "${desc}" | awk -F- '{printf("-%05d", $(NF-1))}' + if [ -n "${count}" ]; then + printf "%s%05d" "-" "${count}" fi # Add -g and exactly 12 hex chars. - printf '%s%s' -g "$(echo $head | cut -c1-12)" + printf '%s%.12s' -g "$head" fi if ${no_dirty}; then -- cgit From e2ff1219a5541a22921016219c4d86a6d0190d15 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 19 Nov 2024 08:09:06 +0900 Subject: setlocalversion: add -e option Set the -e option to ensure this script fails on any unexpected errors. Without this change, the kernel build may continue running with an incorrect string in include/config/kernel.release. Currently, try_tag() returns 1 when the expected tag is not found as an ancestor, but this is a case where the script should continue. Signed-off-by: Masahiro Yamada --- scripts/setlocalversion | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 5818465abba9..28169d7e143b 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -10,6 +10,8 @@ # # +set -e + usage() { echo "Usage: $0 [--no-local] [srctree]" >&2 exit 1 @@ -34,7 +36,9 @@ try_tag() { tag="$1" # Is $tag an annotated tag? - [ "$(git cat-file -t "$tag" 2> /dev/null)" = tag ] || return 1 + if [ "$(git cat-file -t "$tag" 2> /dev/null)" != tag ]; then + return + fi # Is it an ancestor of HEAD, and if so, how many commits are in $tag..HEAD? # shellcheck disable=SC2046 # word splitting is the point here @@ -43,12 +47,12 @@ try_tag() { # $1 is 0 if and only if $tag is an ancestor of HEAD. Use # string comparison, because $1 is empty if the 'git rev-list' # command somehow failed. - [ "$1" = 0 ] || return 1 + if [ "$1" != 0 ]; then + return + fi # $2 is the number of commits in the range $tag..HEAD, possibly 0. count="$2" - - return 0 } scm_version() -- cgit From 0c3e091319e4748cb36ac9a50848903dc6f54054 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:39 +0900 Subject: modpost: remove incorrect code in do_eisa_entry() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function contains multiple bugs after the following commits:  - ac551828993e ("modpost: i2c aliases need no trailing wildcard")  - 6543becf26ff ("mod/file2alias: make modalias generation safe for cross compiling") Commit ac551828993e inserted the following code to do_eisa_entry():     else             strcat(alias, "*"); This is incorrect because 'alias' is uninitialized. If it is not NULL-terminated, strcat() could cause a buffer overrun. Even if 'alias' happens to be zero-filled, it would output: MODULE_ALIAS("*"); This would match anything. As a result, the module could be loaded by any unrelated uevent from an unrelated subsystem. Commit ac551828993e introduced another bug.             Prior to that commit, the conditional check was:     if (eisa->sig[0]) This checked if the first character of eisa_device_id::sig was not '\0'. However, commit ac551828993e changed it as follows:     if (sig[0]) sig[0] is NOT the first character of the eisa_device_id::sig. The type of 'sig' is 'char (*)[8]', meaning that the type of 'sig[0]' is 'char [8]' instead of 'char'. 'sig[0]' and 'symval' refer to the same address, which never becomes NULL. The correct conversion would have been:     if ((*sig)[0]) However, this if-conditional was meaningless because the earlier change in commit ac551828993e was incorrect. This commit removes the entire incorrect code, which should never have been executed. Fixes: ac551828993e ("modpost: i2c aliases need no trailing wildcard") Fixes: 6543becf26ff ("mod/file2alias: make modalias generation safe for cross compiling") Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index c4cc11aa558f..634e40748287 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -809,10 +809,7 @@ static int do_eisa_entry(const char *filename, void *symval, char *alias) { DEF_FIELD_ADDR(symval, eisa_device_id, sig); - if (sig[0]) - sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", *sig); - else - strcat(alias, "*"); + sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", *sig); return 1; } -- cgit From b7bca42d101d8d9678068cde645bd6d0afa8a20f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:40 +0900 Subject: modpost: remove unnecessary check in do_acpi_entry() The 'id' pointer is never NULL since it has the same address as 'symval'. Also, checking (*id)[0] is simpler than calling strlen(). Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 634e40748287..34678ed40fdb 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -570,7 +570,7 @@ static int do_acpi_entry(const char *filename, DEF_FIELD(symval, acpi_device_id, cls); DEF_FIELD(symval, acpi_device_id, cls_msk); - if (id && strlen((const char *)*id)) + if ((*id)[0]) sprintf(alias, "acpi*:%s:*", *id); else { int i, byte_shift, cnt = 0; -- cgit From f4fdb17ca5a5285d4a0ed81b25d5a3d7b9b3ebf3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:41 +0900 Subject: modpost: introduce module_alias_printf() helper The generic ->do_entry() handler is currently limited to returning a single alias string. However, this is not flexible enough for several subsystems, which currently require their own implementations: - do_usb_table() - do_of_table() - do_pnp_device_entry() - do_pnp_card_entries() This commit introduces a helper function so that these special cases can add multiple MODULE_ALIAS() and then migrate to the generic framework. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 91 +++++++++++++++++++++++++++++++++++------------- scripts/mod/modpost.c | 11 +++++- scripts/mod/modpost.h | 19 ++++++++-- 3 files changed, 93 insertions(+), 28 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 34678ed40fdb..d6c8d5e08821 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -10,6 +10,12 @@ * of the GNU General Public License, incorporated herein by reference. */ +#include +#include + +#include "list.h" +#include "xalloc.h" + #include "modpost.h" #include "devicetable-offsets.h" @@ -31,6 +37,58 @@ typedef Elf64_Addr kernel_ulong_t; #include #include +/** + * module_alias_printf - add auto-generated MODULE_ALIAS() + * + * @mod: module + * @append_wildcard: append '*' for future extension if not exist yet + * @fmt: printf(3)-like format + */ +static void __attribute__((format (printf, 3, 4))) +module_alias_printf(struct module *mod, bool append_wildcard, + const char *fmt, ...) +{ + struct module_alias *new; + size_t len; + int n; + va_list ap; + + /* Determine required size. */ + va_start(ap, fmt); + n = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + if (n < 0) { + error("vsnprintf failed\n"); + return; + } + + len = n + 1; /* extra byte for '\0' */ + + if (append_wildcard) + len++; /* extra byte for '*' */ + + new = xmalloc(sizeof(*new) + len); + + /* Now, really print it to the allocated buffer */ + va_start(ap, fmt); + n = vsnprintf(new->str, len, fmt, ap); + va_end(ap); + + if (n < 0) { + error("vsnprintf failed\n"); + free(new); + return; + } + + if (append_wildcard && (n == 0 || new->str[n - 1] != '*')) { + new->str[n] = '*'; + new->str[n + 1] = '\0'; + } + + list_add_tail(&new->node, &mod->aliases); +} + typedef uint32_t __u32; typedef uint16_t __u16; typedef unsigned char __u8; @@ -229,9 +287,7 @@ static void do_usb_entry(void *symval, ADD(alias, "in", match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER, bInterfaceNumber); - add_wildcard(alias); - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"%s\");\n", alias); + module_alias_printf(mod, true, "%s", alias); } /* Handles increment/decrement of BCD formatted integers */ @@ -375,10 +431,8 @@ static void do_of_entry_multi(void *symval, struct module *mod) if (isspace(*tmp)) *tmp = '_'; - buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); - strcat(alias, "C"); - add_wildcard(alias); - buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); + module_alias_printf(mod, false, "%s", alias); + module_alias_printf(mod, false, "%sC*", alias); } static void do_of_table(void *symval, unsigned long size, @@ -608,14 +662,12 @@ static void do_pnp_device_entry(void *symval, unsigned long size, char acpi_id[sizeof(*id)]; int j; - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"pnp:d%s*\");\n", *id); + module_alias_printf(mod, false, "pnp:d%s*", *id); /* fix broken pnp bus lowercasing */ for (j = 0; j < sizeof(acpi_id); j++) acpi_id[j] = toupper((*id)[j]); - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } } @@ -666,14 +718,12 @@ static void do_pnp_card_entries(void *symval, unsigned long size, char acpi_id[PNP_ID_LEN]; int k; - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"pnp:d%s*\");\n", id); + module_alias_printf(mod, false, "pnp:d%s*", id); /* fix broken pnp bus lowercasing */ for (k = 0; k < sizeof(acpi_id); k++) acpi_id[k] = toupper(id[k]); - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } } } @@ -1534,8 +1584,7 @@ static void do_table(void *symval, unsigned long size, for (i = 0; i < size; i += id_size) { if (do_entry(mod->name, symval+i, alias)) { - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"%s\");\n", alias); + module_alias_printf(mod, false, "%s", alias); } } } @@ -1660,11 +1709,3 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, } free(zeros); } - -/* Now add out buffered information to the generated C source */ -void add_moddevtable(struct buffer *buf, struct module *mod) -{ - buf_printf(buf, "\n"); - buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos); - free(mod->dev_table_buf.p); -} diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 107393a8c48a..1948d69ce2b9 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -176,6 +176,7 @@ static struct module *new_module(const char *name, size_t namelen) INIT_LIST_HEAD(&mod->unresolved_symbols); INIT_LIST_HEAD(&mod->missing_namespaces); INIT_LIST_HEAD(&mod->imported_namespaces); + INIT_LIST_HEAD(&mod->aliases); memcpy(mod->name, name, namelen); mod->name[namelen] = '\0'; @@ -1966,6 +1967,7 @@ static void write_vmlinux_export_c_file(struct module *mod) static void write_mod_c_file(struct module *mod) { struct buffer buf = { }; + struct module_alias *alias, *next; char fname[PATH_MAX]; int ret; @@ -1973,7 +1975,14 @@ static void write_mod_c_file(struct module *mod) add_exported_symbols(&buf, mod); add_versions(&buf, mod); add_depends(&buf, mod); - add_moddevtable(&buf, mod); + + buf_printf(&buf, "\n"); + list_for_each_entry_safe(alias, next, &mod->aliases, node) { + buf_printf(&buf, "MODULE_ALIAS(\"%s\");\n", alias->str); + list_del(&alias->node); + free(alias); + } + add_srcversion(&buf, mod); ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index ada3a36cc4bc..52efe0026b34 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -79,6 +79,22 @@ buf_printf(struct buffer *buf, const char *fmt, ...); void buf_write(struct buffer *buf, const char *s, int len); +/** + * struct module_alias - auto-generated MODULE_ALIAS() + * + * @node: linked to module::aliases + * @str: a string for MODULE_ALIAS() + */ +struct module_alias { + struct list_head node; + char str[]; +}; + +/** + * struct module - represent a module (vmlinux or *.ko) + * + * @aliases: list head for module_aliases + */ struct module { struct list_head list; struct list_head exported_symbols; @@ -89,12 +105,12 @@ struct module { bool seen; bool has_init; bool has_cleanup; - struct buffer dev_table_buf; char srcversion[25]; // Missing namespace dependencies struct list_head missing_namespaces; // Actual imported namespaces struct list_head imported_namespaces; + struct list_head aliases; char name[]; }; @@ -170,7 +186,6 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, /* file2alias.c */ void handle_moddevtable(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname); -void add_moddevtable(struct buffer *buf, struct module *mod); /* sumversion.c */ void get_src_version(const char *modname, char sum[], unsigned sumlen); -- cgit From d92b7a3b528bb4b69fa8b6f99c63fe8ad7927cec Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:42 +0900 Subject: modpost: deduplicate MODULE_ALIAS() for all drivers MODULE_DEVICE_TABLE(pnp_card, ...) may have duplicated IDs. For instance, snd_ad1816a_pnpids[] in sound/isa/ad1816a/ad1816a.c includes multiple occurrences of the "ADS7180" string within its .devs fields. Currently, do_pnp_card_entries() handles deduplication on its own, but this logic should be moved to a common helper function, as drivers in other subsystems might also have similar duplication issues. For example, drivers/media/i2c/s5c73m3/s5c73m3.mod.c contains duplicated MODULE_ALIAS() entries because both s5c73m3-core.c and s5c73m3-spi.c define the same compatible string. This commit eliminates redundant MODULE_ALIAS() entries across all drivers. [Before] $ grep MODULE_ALIAS drivers/media/i2c/s5c73m3/s5c73m3.mod.c MODULE_ALIAS("i2c:S5C73M3"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3C*"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3C*"); [After] $ grep MODULE_ALIAS drivers/media/i2c/s5c73m3/s5c73m3.mod.c MODULE_ALIAS("i2c:S5C73M3"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3C*"); Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 48 +++++++++++++++--------------------------------- 1 file changed, 15 insertions(+), 33 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index d6c8d5e08821..71dd5272013b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -48,7 +48,7 @@ static void __attribute__((format (printf, 3, 4))) module_alias_printf(struct module *mod, bool append_wildcard, const char *fmt, ...) { - struct module_alias *new; + struct module_alias *new, *als; size_t len; int n; va_list ap; @@ -86,6 +86,14 @@ module_alias_printf(struct module *mod, bool append_wildcard, new->str[n + 1] = '\0'; } + /* avoid duplication */ + list_for_each_entry(als, &mod->aliases, node) { + if (!strcmp(als->str, new->str)) { + free(new); + return; + } + } + list_add_tail(&new->node, &mod->aliases); } @@ -687,44 +695,18 @@ static void do_pnp_card_entries(void *symval, unsigned long size, for (j = 0; j < PNP_MAX_DEVICES; j++) { const char *id = (char *)(*devs)[j].id; - int i2, j2; - int dup = 0; + char acpi_id[PNP_ID_LEN]; if (!id[0]) break; - /* find duplicate, already added value */ - for (i2 = 0; i2 < i && !dup; i2++) { - DEF_FIELD_ADDR_VAR(symval + i2 * id_size, - pnp_card_device_id, - devs, devs_dup); - - for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) { - const char *id2 = - (char *)(*devs_dup)[j2].id; - - if (!id2[0]) - break; - - if (!strcmp(id, id2)) { - dup = 1; - break; - } - } - } - /* add an individual alias for every device entry */ - if (!dup) { - char acpi_id[PNP_ID_LEN]; - int k; + module_alias_printf(mod, false, "pnp:d%s*", id); - module_alias_printf(mod, false, "pnp:d%s*", id); - - /* fix broken pnp bus lowercasing */ - for (k = 0; k < sizeof(acpi_id); k++) - acpi_id[k] = toupper(id[k]); - module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); - } + /* fix broken pnp bus lowercasing */ + for (int k = 0; k < sizeof(acpi_id); k++) + acpi_id[k] = toupper(id[k]); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } } } -- cgit From c4d1a9f9d11b5d7c5cf4fab33f86f7d7a978801e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:43 +0900 Subject: modpost: remove DEF_FIELD_ADDR_VAR() macro With the former cleanups in do_pnp_card_entries(), this macro is no longer used by anyone. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 71dd5272013b..cd8be749260c 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -138,19 +138,12 @@ struct devtable { #define DEF_FIELD(m, devid, f) \ typeof(((struct devid *)0)->f) f = TO_NATIVE(*(typeof(f) *)((m) + OFF_##devid##_##f)) -/* Define a variable v that holds the address of field f of struct devid - * based at address m. Due to the way typeof works, for a field of type - * T[N] the variable has type T(*)[N], _not_ T*. - */ -#define DEF_FIELD_ADDR_VAR(m, devid, f, v) \ - typeof(((struct devid *)0)->f) *v = ((m) + OFF_##devid##_##f) - /* Define a variable f that holds the address of field f of struct devid * based at address m. Due to the way typeof works, for a field of type * T[N] the variable has type T(*)[N], _not_ T*. */ #define DEF_FIELD_ADDR(m, devid, f) \ - DEF_FIELD_ADDR_VAR(m, devid, f, f) + typeof(((struct devid *)0)->f) *f = ((m) + OFF_##devid##_##f) #define ADD(str, sep, cond, field) \ do { \ -- cgit From c7c24d60151c022bd8e357f5395a327d354a676a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:44 +0900 Subject: modpost: pass (struct module *) to do_*_entry() functions Replace the first argument with a pointer to struct module. 'filename' can be replaced with mod->name. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 118 +++++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 59 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index cd8be749260c..b23ef324b155 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -126,7 +126,7 @@ typedef struct { struct devtable { const char *device_id; /* name of table, __mod___*_device_table. */ unsigned long id_size; - int (*do_entry)(const char *filename, void *symval, char *alias); + int (*do_entry)(struct module *mod, void *symval, char *alias); }; /* Size of alias provided to do_entry functions */ @@ -452,7 +452,7 @@ static void do_of_table(void *symval, unsigned long size, } /* Looks like: hid:bNvNpN */ -static int do_hid_entry(const char *filename, +static int do_hid_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, hid_device_id, bus); @@ -470,7 +470,7 @@ static int do_hid_entry(const char *filename, } /* Looks like: ieee1394:venNmoNspNverN */ -static int do_ieee1394_entry(const char *filename, +static int do_ieee1394_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ieee1394_device_id, match_flags); @@ -494,7 +494,7 @@ static int do_ieee1394_entry(const char *filename, } /* Looks like: pci:vNdNsvNsdNbcNscNiN or _pci:vNdNsvNsdNbcNscNiN. */ -static int do_pci_entry(const char *filename, +static int do_pci_entry(struct module *mod, void *symval, char *alias) { /* Class field can be divided into these three. */ @@ -538,7 +538,7 @@ static int do_pci_entry(const char *filename, || (subclass_mask != 0 && subclass_mask != 0xFF) || (interface_mask != 0 && interface_mask != 0xFF)) { warn("Can't handle masks in %s:%04X\n", - filename, class_mask); + mod->name, class_mask); return 0; } @@ -550,7 +550,7 @@ static int do_pci_entry(const char *filename, } /* looks like: "ccw:tNmNdtNdmN" */ -static int do_ccw_entry(const char *filename, +static int do_ccw_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ccw_device_id, match_flags); @@ -573,7 +573,7 @@ static int do_ccw_entry(const char *filename, } /* looks like: "ap:tN" */ -static int do_ap_entry(const char *filename, +static int do_ap_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ap_device_id, dev_type); @@ -583,7 +583,7 @@ static int do_ap_entry(const char *filename, } /* looks like: "css:tN" */ -static int do_css_entry(const char *filename, +static int do_css_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, css_device_id, type); @@ -593,7 +593,7 @@ static int do_css_entry(const char *filename, } /* Looks like: "serio:tyNprNidNexN" */ -static int do_serio_entry(const char *filename, +static int do_serio_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, serio_device_id, type); @@ -618,7 +618,7 @@ static int do_serio_entry(const char *filename, * or _CLS. Also, bb, ss, and pp can be substituted with ?? * as don't care byte. */ -static int do_acpi_entry(const char *filename, +static int do_acpi_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, acpi_device_id, id); @@ -705,7 +705,7 @@ static void do_pnp_card_entries(void *symval, unsigned long size, } /* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */ -static int do_pcmcia_entry(const char *filename, +static int do_pcmcia_entry(struct module *mod, void *symval, char *alias) { unsigned int i; @@ -741,7 +741,7 @@ static int do_pcmcia_entry(const char *filename, return 1; } -static int do_vio_entry(const char *filename, void *symval, +static int do_vio_entry(struct module *mod, void *symval, char *alias) { char *tmp; @@ -773,7 +773,7 @@ static void do_input(char *alias, } /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ -static int do_input_entry(const char *filename, void *symval, +static int do_input_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, input_device_id, flags); @@ -830,7 +830,7 @@ static int do_input_entry(const char *filename, void *symval, return 1; } -static int do_eisa_entry(const char *filename, void *symval, +static int do_eisa_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, eisa_device_id, sig); @@ -839,7 +839,7 @@ static int do_eisa_entry(const char *filename, void *symval, } /* Looks like: parisc:tNhvNrevNsvN */ -static int do_parisc_entry(const char *filename, void *symval, +static int do_parisc_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, parisc_device_id, hw_type); @@ -858,7 +858,7 @@ static int do_parisc_entry(const char *filename, void *symval, } /* Looks like: sdio:cNvNdN. */ -static int do_sdio_entry(const char *filename, +static int do_sdio_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, sdio_device_id, class); @@ -874,7 +874,7 @@ static int do_sdio_entry(const char *filename, } /* Looks like: ssb:vNidNrevN. */ -static int do_ssb_entry(const char *filename, +static int do_ssb_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ssb_device_id, vendor); @@ -890,7 +890,7 @@ static int do_ssb_entry(const char *filename, } /* Looks like: bcma:mNidNrevNclN. */ -static int do_bcma_entry(const char *filename, +static int do_bcma_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, bcma_device_id, manuf); @@ -908,7 +908,7 @@ static int do_bcma_entry(const char *filename, } /* Looks like: virtio:dNvN */ -static int do_virtio_entry(const char *filename, void *symval, +static int do_virtio_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, virtio_device_id, device); @@ -928,7 +928,7 @@ static int do_virtio_entry(const char *filename, void *symval, * in the name. */ -static int do_vmbus_entry(const char *filename, void *symval, +static int do_vmbus_entry(struct module *mod, void *symval, char *alias) { int i; @@ -945,7 +945,7 @@ static int do_vmbus_entry(const char *filename, void *symval, } /* Looks like: rpmsg:S */ -static int do_rpmsg_entry(const char *filename, void *symval, +static int do_rpmsg_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, rpmsg_device_id, name); @@ -955,7 +955,7 @@ static int do_rpmsg_entry(const char *filename, void *symval, } /* Looks like: i2c:S */ -static int do_i2c_entry(const char *filename, void *symval, +static int do_i2c_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, i2c_device_id, name); @@ -964,7 +964,7 @@ static int do_i2c_entry(const char *filename, void *symval, return 1; } -static int do_i3c_entry(const char *filename, void *symval, +static int do_i3c_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, i3c_device_id, match_flags); @@ -982,7 +982,7 @@ static int do_i3c_entry(const char *filename, void *symval, return 1; } -static int do_slim_entry(const char *filename, void *symval, char *alias) +static int do_slim_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, slim_device_id, manf_id); DEF_FIELD(symval, slim_device_id, prod_code); @@ -993,7 +993,7 @@ static int do_slim_entry(const char *filename, void *symval, char *alias) } /* Looks like: spi:S */ -static int do_spi_entry(const char *filename, void *symval, +static int do_spi_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, spi_device_id, name); @@ -1034,7 +1034,7 @@ static void dmi_ascii_filter(char *d, const char *s) } -static int do_dmi_entry(const char *filename, void *symval, +static int do_dmi_entry(struct module *mod, void *symval, char *alias) { int i, j; @@ -1058,7 +1058,7 @@ static int do_dmi_entry(const char *filename, void *symval, return 1; } -static int do_platform_entry(const char *filename, +static int do_platform_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, platform_device_id, name); @@ -1066,7 +1066,7 @@ static int do_platform_entry(const char *filename, return 1; } -static int do_mdio_entry(const char *filename, +static int do_mdio_entry(struct module *mod, void *symval, char *alias) { int i; @@ -1091,7 +1091,7 @@ static int do_mdio_entry(const char *filename, } /* Looks like: zorro:iN. */ -static int do_zorro_entry(const char *filename, void *symval, +static int do_zorro_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, zorro_device_id, id); @@ -1101,7 +1101,7 @@ static int do_zorro_entry(const char *filename, void *symval, } /* looks like: "pnp:dD" */ -static int do_isapnp_entry(const char *filename, +static int do_isapnp_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, isapnp_device_id, vendor); @@ -1116,7 +1116,7 @@ static int do_isapnp_entry(const char *filename, } /* Looks like: "ipack:fNvNdN". */ -static int do_ipack_entry(const char *filename, +static int do_ipack_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ipack_device_id, format); @@ -1178,7 +1178,7 @@ static void append_nibble_mask(char **outp, * N is exactly 8 digits, where each is an upper-case hex digit, or * a ? or [] pattern matching exactly one digit. */ -static int do_amba_entry(const char *filename, +static int do_amba_entry(struct module *mod, void *symval, char *alias) { unsigned int digit; @@ -1188,7 +1188,7 @@ static int do_amba_entry(const char *filename, if ((id & mask) != id) fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: id=0x%08X, mask=0x%08X. Please fix this driver.\n", - filename, id, mask); + mod->name, id, mask); p += sprintf(alias, "amba:d"); for (digit = 0; digit < 8; digit++) @@ -1205,7 +1205,7 @@ static int do_amba_entry(const char *filename, * N is exactly 2 digits, where each is an upper-case hex digit, or * a ? or [] pattern matching exactly one digit. */ -static int do_mips_cdmm_entry(const char *filename, +static int do_mips_cdmm_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, mips_cdmm_device_id, type); @@ -1220,7 +1220,7 @@ static int do_mips_cdmm_entry(const char *filename, * complicated. */ -static int do_x86cpu_entry(const char *filename, void *symval, +static int do_x86cpu_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, x86_cpu_id, feature); @@ -1239,7 +1239,7 @@ static int do_x86cpu_entry(const char *filename, void *symval, } /* LOOKS like cpu:type:*:feature:*FEAT* */ -static int do_cpu_entry(const char *filename, void *symval, char *alias) +static int do_cpu_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, cpu_feature, feature); @@ -1248,7 +1248,7 @@ static int do_cpu_entry(const char *filename, void *symval, char *alias) } /* Looks like: mei:S:uuid:N:* */ -static int do_mei_entry(const char *filename, void *symval, +static int do_mei_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, mei_cl_device_id, name); @@ -1266,7 +1266,7 @@ static int do_mei_entry(const char *filename, void *symval, } /* Looks like: rapidio:vNdNavNadN */ -static int do_rio_entry(const char *filename, +static int do_rio_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, rio_device_id, did); @@ -1285,7 +1285,7 @@ static int do_rio_entry(const char *filename, } /* Looks like: ulpi:vNpN */ -static int do_ulpi_entry(const char *filename, void *symval, +static int do_ulpi_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ulpi_device_id, vendor); @@ -1297,7 +1297,7 @@ static int do_ulpi_entry(const char *filename, void *symval, } /* Looks like: hdaudio:vNrNaN */ -static int do_hda_entry(const char *filename, void *symval, char *alias) +static int do_hda_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, hda_device_id, vendor_id); DEF_FIELD(symval, hda_device_id, rev_id); @@ -1313,7 +1313,7 @@ static int do_hda_entry(const char *filename, void *symval, char *alias) } /* Looks like: sdw:mNpNvNcN */ -static int do_sdw_entry(const char *filename, void *symval, char *alias) +static int do_sdw_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, sdw_device_id, mfg_id); DEF_FIELD(symval, sdw_device_id, part_id); @@ -1331,7 +1331,7 @@ static int do_sdw_entry(const char *filename, void *symval, char *alias) } /* Looks like: fsl-mc:vNdN */ -static int do_fsl_mc_entry(const char *filename, void *symval, +static int do_fsl_mc_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, fsl_mc_device_id, vendor); @@ -1342,7 +1342,7 @@ static int do_fsl_mc_entry(const char *filename, void *symval, } /* Looks like: tbsvc:kSpNvNrN */ -static int do_tbsvc_entry(const char *filename, void *symval, char *alias) +static int do_tbsvc_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, tb_service_id, match_flags); DEF_FIELD_ADDR(symval, tb_service_id, protocol_key); @@ -1366,7 +1366,7 @@ static int do_tbsvc_entry(const char *filename, void *symval, char *alias) } /* Looks like: typec:idNmN */ -static int do_typec_entry(const char *filename, void *symval, char *alias) +static int do_typec_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, typec_device_id, svid); DEF_FIELD(symval, typec_device_id, mode); @@ -1378,7 +1378,7 @@ static int do_typec_entry(const char *filename, void *symval, char *alias) } /* Looks like: tee:uuid */ -static int do_tee_entry(const char *filename, void *symval, char *alias) +static int do_tee_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, tee_client_device_id, uuid); @@ -1393,28 +1393,28 @@ static int do_tee_entry(const char *filename, void *symval, char *alias) } /* Looks like: wmi:guid */ -static int do_wmi_entry(const char *filename, void *symval, char *alias) +static int do_wmi_entry(struct module *mod, void *symval, char *alias) { int len; DEF_FIELD_ADDR(symval, wmi_device_id, guid_string); if (strlen(*guid_string) != UUID_STRING_LEN) { warn("Invalid WMI device id 'wmi:%s' in '%s'\n", - *guid_string, filename); + *guid_string, mod->name); return 0; } len = snprintf(alias, ALIAS_SIZE, WMI_MODULE_PREFIX "%s", *guid_string); if (len < 0 || len >= ALIAS_SIZE) { warn("Could not generate all MODULE_ALIAS's in '%s'\n", - filename); + mod->name); return 0; } return 1; } /* Looks like: mhi:S */ -static int do_mhi_entry(const char *filename, void *symval, char *alias) +static int do_mhi_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan); @@ -1422,7 +1422,7 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias) } /* Looks like: mhi_ep:S */ -static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) +static int do_mhi_ep_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); sprintf(alias, MHI_EP_DEVICE_MODALIAS_FMT, *chan); @@ -1431,7 +1431,7 @@ static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) } /* Looks like: ishtp:{guid} */ -static int do_ishtp_entry(const char *filename, void *symval, char *alias) +static int do_ishtp_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, ishtp_device_id, guid); @@ -1442,7 +1442,7 @@ static int do_ishtp_entry(const char *filename, void *symval, char *alias) return 1; } -static int do_auxiliary_entry(const char *filename, void *symval, char *alias) +static int do_auxiliary_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, auxiliary_device_id, name); sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name); @@ -1455,7 +1455,7 @@ static int do_auxiliary_entry(const char *filename, void *symval, char *alias) * * N is exactly 2 digits, where each is an upper-case hex digit. */ -static int do_ssam_entry(const char *filename, void *symval, char *alias) +static int do_ssam_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ssam_device_id, match_flags); DEF_FIELD(symval, ssam_device_id, domain); @@ -1473,7 +1473,7 @@ static int do_ssam_entry(const char *filename, void *symval, char *alias) } /* Looks like: dfl:tNfN */ -static int do_dfl_entry(const char *filename, void *symval, char *alias) +static int do_dfl_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, dfl_device_id, type); DEF_FIELD(symval, dfl_device_id, feature_id); @@ -1485,7 +1485,7 @@ static int do_dfl_entry(const char *filename, void *symval, char *alias) } /* Looks like: cdx:vNdN */ -static int do_cdx_entry(const char *filename, void *symval, +static int do_cdx_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, cdx_device_id, vendor); @@ -1518,7 +1518,7 @@ static int do_cdx_entry(const char *filename, void *symval, return 1; } -static int do_vchiq_entry(const char *filename, void *symval, char *alias) +static int do_vchiq_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, vchiq_device_id, name); sprintf(alias, "vchiq:%s", *name); @@ -1527,7 +1527,7 @@ static int do_vchiq_entry(const char *filename, void *symval, char *alias) } /* Looks like: coreboot:tN */ -static int do_coreboot_entry(const char *filename, void *symval, char *alias) +static int do_coreboot_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, coreboot_device_id, tag); sprintf(alias, "coreboot:t%08X", tag); @@ -1547,7 +1547,7 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol) static void do_table(void *symval, unsigned long size, unsigned long id_size, const char *device_id, - int (*do_entry)(const char *filename, void *symval, char *alias), + int (*do_entry)(struct module *mod, void *symval, char *alias), struct module *mod) { unsigned int i; @@ -1558,7 +1558,7 @@ static void do_table(void *symval, unsigned long size, size -= id_size; for (i = 0; i < size; i += id_size) { - if (do_entry(mod->name, symval+i, alias)) { + if (do_entry(mod, symval+i, alias)) { module_alias_printf(mod, false, "%s", alias); } } -- cgit From 6d3b3dd26fd71dde0b41478755a59ca30aaeb664 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:45 +0900 Subject: modpost: call module_alias_printf() from all do_*_entry() functions The do_*_entry() functions cannot check the length of the given buffer. Use module_alias_printf() helper consistently for these functions. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 438 ++++++++++++++++++++--------------------------- 1 file changed, 181 insertions(+), 257 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index b23ef324b155..5ef87a6d33f8 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -126,12 +126,9 @@ typedef struct { struct devtable { const char *device_id; /* name of table, __mod___*_device_table. */ unsigned long id_size; - int (*do_entry)(struct module *mod, void *symval, char *alias); + void (*do_entry)(struct module *mod, void *symval); }; -/* Size of alias provided to do_entry functions */ -#define ALIAS_SIZE 500 - /* Define a variable f that holds the value of field f of struct devid * based at address m. */ @@ -158,15 +155,6 @@ do { \ sprintf(str + strlen(str), "*"); \ } while(0) -/* End in a wildcard, for future extension */ -static inline void add_wildcard(char *str) -{ - int len = strlen(str); - - if (str[len - 1] != '*') - strcat(str + len, "*"); -} - static inline void add_uuid(char *str, uuid_le uuid) { int len = strlen(str); @@ -452,34 +440,34 @@ static void do_of_table(void *symval, unsigned long size, } /* Looks like: hid:bNvNpN */ -static int do_hid_entry(struct module *mod, - void *symval, char *alias) +static void do_hid_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, hid_device_id, bus); DEF_FIELD(symval, hid_device_id, group); DEF_FIELD(symval, hid_device_id, vendor); DEF_FIELD(symval, hid_device_id, product); - sprintf(alias, "hid:"); ADD(alias, "b", bus != HID_BUS_ANY, bus); ADD(alias, "g", group != HID_GROUP_ANY, group); ADD(alias, "v", vendor != HID_ANY_ID, vendor); ADD(alias, "p", product != HID_ANY_ID, product); - return 1; + module_alias_printf(mod, false, "hid:%s", alias); } /* Looks like: ieee1394:venNmoNspNverN */ -static int do_ieee1394_entry(struct module *mod, - void *symval, char *alias) +static void do_ieee1394_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ieee1394_device_id, match_flags); DEF_FIELD(symval, ieee1394_device_id, vendor_id); DEF_FIELD(symval, ieee1394_device_id, model_id); DEF_FIELD(symval, ieee1394_device_id, specifier_id); DEF_FIELD(symval, ieee1394_device_id, version); - strcpy(alias, "ieee1394:"); ADD(alias, "ven", match_flags & IEEE1394_MATCH_VENDOR_ID, vendor_id); ADD(alias, "mo", match_flags & IEEE1394_MATCH_MODEL_ID, @@ -489,14 +477,13 @@ static int do_ieee1394_entry(struct module *mod, ADD(alias, "ver", match_flags & IEEE1394_MATCH_VERSION, version); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "ieee1394:%s", alias); } /* Looks like: pci:vNdNsvNsdNbcNscNiN or _pci:vNdNsvNsdNbcNscNiN. */ -static int do_pci_entry(struct module *mod, - void *symval, char *alias) +static void do_pci_entry(struct module *mod, void *symval) { + char alias[256]; /* Class field can be divided into these three. */ unsigned char baseclass, subclass, interface, baseclass_mask, subclass_mask, interface_mask; @@ -519,7 +506,6 @@ static int do_pci_entry(struct module *mod, default: warn("Unknown PCI driver_override alias %08X\n", override_only); - return 0; } ADD(alias, "v", vendor != PCI_ANY_ID, vendor); @@ -539,27 +525,27 @@ static int do_pci_entry(struct module *mod, || (interface_mask != 0 && interface_mask != 0xFF)) { warn("Can't handle masks in %s:%04X\n", mod->name, class_mask); - return 0; + return; } ADD(alias, "bc", baseclass_mask == 0xFF, baseclass); ADD(alias, "sc", subclass_mask == 0xFF, subclass); ADD(alias, "i", interface_mask == 0xFF, interface); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "%s", alias); } /* looks like: "ccw:tNmNdtNdmN" */ -static int do_ccw_entry(struct module *mod, - void *symval, char *alias) +static void do_ccw_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ccw_device_id, match_flags); DEF_FIELD(symval, ccw_device_id, cu_type); DEF_FIELD(symval, ccw_device_id, cu_model); DEF_FIELD(symval, ccw_device_id, dev_type); DEF_FIELD(symval, ccw_device_id, dev_model); - strcpy(alias, "ccw:"); ADD(alias, "t", match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE, cu_type); ADD(alias, "m", match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL, @@ -568,47 +554,42 @@ static int do_ccw_entry(struct module *mod, dev_type); ADD(alias, "dm", match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL, dev_model); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "ccw:%s", alias); } /* looks like: "ap:tN" */ -static int do_ap_entry(struct module *mod, - void *symval, char *alias) +static void do_ap_entry(struct module *mod, void *symval) { DEF_FIELD(symval, ap_device_id, dev_type); - sprintf(alias, "ap:t%02X*", dev_type); - return 1; + module_alias_printf(mod, false, "ap:t%02X*", dev_type); } /* looks like: "css:tN" */ -static int do_css_entry(struct module *mod, - void *symval, char *alias) +static void do_css_entry(struct module *mod, void *symval) { DEF_FIELD(symval, css_device_id, type); - sprintf(alias, "css:t%01X", type); - return 1; + module_alias_printf(mod, false, "css:t%01X", type); } /* Looks like: "serio:tyNprNidNexN" */ -static int do_serio_entry(struct module *mod, - void *symval, char *alias) +static void do_serio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, serio_device_id, type); DEF_FIELD(symval, serio_device_id, proto); DEF_FIELD(symval, serio_device_id, id); DEF_FIELD(symval, serio_device_id, extra); - strcpy(alias, "serio:"); ADD(alias, "ty", type != SERIO_ANY, type); ADD(alias, "pr", proto != SERIO_ANY, proto); ADD(alias, "id", id != SERIO_ANY, id); ADD(alias, "ex", extra != SERIO_ANY, extra); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "serio:%s", alias); } /* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or @@ -618,21 +599,19 @@ static int do_serio_entry(struct module *mod, * or _CLS. Also, bb, ss, and pp can be substituted with ?? * as don't care byte. */ -static int do_acpi_entry(struct module *mod, - void *symval, char *alias) +static void do_acpi_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, acpi_device_id, id); DEF_FIELD(symval, acpi_device_id, cls); DEF_FIELD(symval, acpi_device_id, cls_msk); if ((*id)[0]) - sprintf(alias, "acpi*:%s:*", *id); + module_alias_printf(mod, false, "acpi*:%s:*", *id); else { + char alias[256]; int i, byte_shift, cnt = 0; unsigned int msk; - sprintf(&alias[cnt], "acpi*:"); - cnt = 6; for (i = 1; i <= 3; i++) { byte_shift = 8 * (3-i); msk = (cls_msk >> byte_shift) & 0xFF; @@ -643,9 +622,8 @@ static int do_acpi_entry(struct module *mod, sprintf(&alias[cnt], "??"); cnt += 2; } - sprintf(&alias[cnt], ":*"); + module_alias_printf(mod, false, "acpi*:%s:*", alias); } - return 1; } /* looks like: "pnp:dD" */ @@ -705,9 +683,9 @@ static void do_pnp_card_entries(void *symval, unsigned long size, } /* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */ -static int do_pcmcia_entry(struct module *mod, - void *symval, char *alias) +static void do_pcmcia_entry(struct module *mod, void *symval) { + char alias[256] = {}; unsigned int i; DEF_FIELD(symval, pcmcia_device_id, match_flags); DEF_FIELD(symval, pcmcia_device_id, manf_id); @@ -721,7 +699,6 @@ static int do_pcmcia_entry(struct module *mod, (*prod_id_hash)[i] = TO_NATIVE((*prod_id_hash)[i]); } - strcpy(alias, "pcmcia:"); ADD(alias, "m", match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID, manf_id); ADD(alias, "c", match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID, @@ -737,13 +714,12 @@ static int do_pcmcia_entry(struct module *mod, ADD(alias, "pc", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, (*prod_id_hash)[2]); ADD(alias, "pd", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, (*prod_id_hash)[3]); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "pcmcia:%s", alias); } -static int do_vio_entry(struct module *mod, void *symval, - char *alias) +static void do_vio_entry(struct module *mod, void *symval) { + char alias[256]; char *tmp; DEF_FIELD_ADDR(symval, vio_device_id, type); DEF_FIELD_ADDR(symval, vio_device_id, compat); @@ -756,8 +732,7 @@ static int do_vio_entry(struct module *mod, void *symval, if (isspace (*tmp)) *tmp = '_'; - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "%s", alias); } static void do_input(char *alias, @@ -773,9 +748,10 @@ static void do_input(char *alias, } /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ -static int do_input_entry(struct module *mod, void *symval, - char *alias) +static void do_input_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, input_device_id, flags); DEF_FIELD(symval, input_device_id, bustype); DEF_FIELD(symval, input_device_id, vendor); @@ -791,8 +767,6 @@ static int do_input_entry(struct module *mod, void *symval, DEF_FIELD_ADDR(symval, input_device_id, ffbit); DEF_FIELD_ADDR(symval, input_device_id, swbit); - sprintf(alias, "input:"); - ADD(alias, "b", flags & INPUT_DEVICE_ID_MATCH_BUS, bustype); ADD(alias, "v", flags & INPUT_DEVICE_ID_MATCH_VENDOR, vendor); ADD(alias, "p", flags & INPUT_DEVICE_ID_MATCH_PRODUCT, product); @@ -827,99 +801,96 @@ static int do_input_entry(struct module *mod, void *symval, sprintf(alias + strlen(alias), "w*"); if (flags & INPUT_DEVICE_ID_MATCH_SWBIT) do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX); - return 1; + + module_alias_printf(mod, false, "input:%s", alias); } -static int do_eisa_entry(struct module *mod, void *symval, - char *alias) +static void do_eisa_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, eisa_device_id, sig); - sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", *sig); - return 1; + module_alias_printf(mod, false, EISA_DEVICE_MODALIAS_FMT "*", *sig); } /* Looks like: parisc:tNhvNrevNsvN */ -static int do_parisc_entry(struct module *mod, void *symval, - char *alias) +static void do_parisc_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, parisc_device_id, hw_type); DEF_FIELD(symval, parisc_device_id, hversion); DEF_FIELD(symval, parisc_device_id, hversion_rev); DEF_FIELD(symval, parisc_device_id, sversion); - strcpy(alias, "parisc:"); ADD(alias, "t", hw_type != PA_HWTYPE_ANY_ID, hw_type); ADD(alias, "hv", hversion != PA_HVERSION_ANY_ID, hversion); ADD(alias, "rev", hversion_rev != PA_HVERSION_REV_ANY_ID, hversion_rev); ADD(alias, "sv", sversion != PA_SVERSION_ANY_ID, sversion); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "parisc:%s", alias); } /* Looks like: sdio:cNvNdN. */ -static int do_sdio_entry(struct module *mod, - void *symval, char *alias) +static void do_sdio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, sdio_device_id, class); DEF_FIELD(symval, sdio_device_id, vendor); DEF_FIELD(symval, sdio_device_id, device); - strcpy(alias, "sdio:"); ADD(alias, "c", class != (__u8)SDIO_ANY_ID, class); ADD(alias, "v", vendor != (__u16)SDIO_ANY_ID, vendor); ADD(alias, "d", device != (__u16)SDIO_ANY_ID, device); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "sdio:%s", alias); } /* Looks like: ssb:vNidNrevN. */ -static int do_ssb_entry(struct module *mod, - void *symval, char *alias) +static void do_ssb_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ssb_device_id, vendor); DEF_FIELD(symval, ssb_device_id, coreid); DEF_FIELD(symval, ssb_device_id, revision); - strcpy(alias, "ssb:"); ADD(alias, "v", vendor != SSB_ANY_VENDOR, vendor); ADD(alias, "id", coreid != SSB_ANY_ID, coreid); ADD(alias, "rev", revision != SSB_ANY_REV, revision); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "ssb:%s", alias); } /* Looks like: bcma:mNidNrevNclN. */ -static int do_bcma_entry(struct module *mod, - void *symval, char *alias) +static void do_bcma_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, bcma_device_id, manuf); DEF_FIELD(symval, bcma_device_id, id); DEF_FIELD(symval, bcma_device_id, rev); DEF_FIELD(symval, bcma_device_id, class); - strcpy(alias, "bcma:"); ADD(alias, "m", manuf != BCMA_ANY_MANUF, manuf); ADD(alias, "id", id != BCMA_ANY_ID, id); ADD(alias, "rev", rev != BCMA_ANY_REV, rev); ADD(alias, "cl", class != BCMA_ANY_CLASS, class); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "bcma:%s", alias); } /* Looks like: virtio:dNvN */ -static int do_virtio_entry(struct module *mod, void *symval, - char *alias) +static void do_virtio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, virtio_device_id, device); DEF_FIELD(symval, virtio_device_id, vendor); - strcpy(alias, "virtio:"); ADD(alias, "d", device != VIRTIO_DEV_ANY_ID, device); ADD(alias, "v", vendor != VIRTIO_DEV_ANY_ID, vendor); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "virtio:%s", alias); } /* @@ -928,8 +899,7 @@ static int do_virtio_entry(struct module *mod, void *symval, * in the name. */ -static int do_vmbus_entry(struct module *mod, void *symval, - char *alias) +static void do_vmbus_entry(struct module *mod, void *symval) { int i; DEF_FIELD_ADDR(symval, hv_vmbus_device_id, guid); @@ -938,68 +908,57 @@ static int do_vmbus_entry(struct module *mod, void *symval, for (i = 0; i < (sizeof(*guid) * 2); i += 2) sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2])); - strcpy(alias, "vmbus:"); - strcat(alias, guid_name); - - return 1; + module_alias_printf(mod, false, "vmbus:%s", guid_name); } /* Looks like: rpmsg:S */ -static int do_rpmsg_entry(struct module *mod, void *symval, - char *alias) +static void do_rpmsg_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, rpmsg_device_id, name); - sprintf(alias, RPMSG_DEVICE_MODALIAS_FMT, *name); - return 1; + module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name); } /* Looks like: i2c:S */ -static int do_i2c_entry(struct module *mod, void *symval, - char *alias) +static void do_i2c_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, i2c_device_id, name); - sprintf(alias, I2C_MODULE_PREFIX "%s", *name); - return 1; + module_alias_printf(mod, false, I2C_MODULE_PREFIX "%s", *name); } -static int do_i3c_entry(struct module *mod, void *symval, - char *alias) +static void do_i3c_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, i3c_device_id, match_flags); DEF_FIELD(symval, i3c_device_id, dcr); DEF_FIELD(symval, i3c_device_id, manuf_id); DEF_FIELD(symval, i3c_device_id, part_id); DEF_FIELD(symval, i3c_device_id, extra_info); - strcpy(alias, "i3c:"); ADD(alias, "dcr", match_flags & I3C_MATCH_DCR, dcr); ADD(alias, "manuf", match_flags & I3C_MATCH_MANUF, manuf_id); ADD(alias, "part", match_flags & I3C_MATCH_PART, part_id); ADD(alias, "ext", match_flags & I3C_MATCH_EXTRA_INFO, extra_info); - return 1; + module_alias_printf(mod, false, "i3c:%s", alias); } -static int do_slim_entry(struct module *mod, void *symval, char *alias) +static void do_slim_entry(struct module *mod, void *symval) { DEF_FIELD(symval, slim_device_id, manf_id); DEF_FIELD(symval, slim_device_id, prod_code); - sprintf(alias, "slim:%x:%x:*", manf_id, prod_code); - - return 1; + module_alias_printf(mod, false, "slim:%x:%x:*", manf_id, prod_code); } /* Looks like: spi:S */ -static int do_spi_entry(struct module *mod, void *symval, - char *alias) +static void do_spi_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, spi_device_id, name); - sprintf(alias, SPI_MODULE_PREFIX "%s", *name); - return 1; + module_alias_printf(mod, false, SPI_MODULE_PREFIX "%s", *name); } static const struct dmifield { @@ -1034,12 +993,11 @@ static void dmi_ascii_filter(char *d, const char *s) } -static int do_dmi_entry(struct module *mod, void *symval, - char *alias) +static void do_dmi_entry(struct module *mod, void *symval) { + char alias[256] = {}; int i, j; DEF_FIELD_ADDR(symval, dmi_system_id, matches); - sprintf(alias, "dmi*"); for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) { for (j = 0; j < 4; j++) { @@ -1054,80 +1012,75 @@ static int do_dmi_entry(struct module *mod, void *symval, } } - strcat(alias, ":"); - return 1; + module_alias_printf(mod, false, "dmi*%s:", alias); } -static int do_platform_entry(struct module *mod, - void *symval, char *alias) +static void do_platform_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, platform_device_id, name); - sprintf(alias, PLATFORM_MODULE_PREFIX "%s", *name); - return 1; + + module_alias_printf(mod, false, PLATFORM_MODULE_PREFIX "%s", *name); } -static int do_mdio_entry(struct module *mod, - void *symval, char *alias) +static void do_mdio_entry(struct module *mod, void *symval) { + char id[33]; int i; DEF_FIELD(symval, mdio_device_id, phy_id); DEF_FIELD(symval, mdio_device_id, phy_id_mask); - alias += sprintf(alias, MDIO_MODULE_PREFIX); - for (i = 0; i < 32; i++) { if (!((phy_id_mask >> (31-i)) & 1)) - *(alias++) = '?'; + id[i] = '?'; else if ((phy_id >> (31-i)) & 1) - *(alias++) = '1'; + id[i] = '1'; else - *(alias++) = '0'; + id[i] = '0'; } /* Terminate the string */ - *alias = 0; + id[32] = '\0'; - return 1; + module_alias_printf(mod, false, MDIO_MODULE_PREFIX "%s", id); } /* Looks like: zorro:iN. */ -static int do_zorro_entry(struct module *mod, void *symval, - char *alias) +static void do_zorro_entry(struct module *mod, void *symval) { + char alias[256] = {}; DEF_FIELD(symval, zorro_device_id, id); - strcpy(alias, "zorro:"); + ADD(alias, "i", id != ZORRO_WILDCARD, id); - return 1; + + module_alias_printf(mod, false, "zorro:%s", alias); } /* looks like: "pnp:dD" */ -static int do_isapnp_entry(struct module *mod, - void *symval, char *alias) +static void do_isapnp_entry(struct module *mod, void *symval) { DEF_FIELD(symval, isapnp_device_id, vendor); DEF_FIELD(symval, isapnp_device_id, function); - sprintf(alias, "pnp:d%c%c%c%x%x%x%x*", + module_alias_printf(mod, false, "pnp:d%c%c%c%x%x%x%x*", 'A' + ((vendor >> 2) & 0x3f) - 1, 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1, 'A' + ((vendor >> 8) & 0x1f) - 1, (function >> 4) & 0x0f, function & 0x0f, (function >> 12) & 0x0f, (function >> 8) & 0x0f); - return 1; } /* Looks like: "ipack:fNvNdN". */ -static int do_ipack_entry(struct module *mod, - void *symval, char *alias) +static void do_ipack_entry(struct module *mod, void *symval) { + char alias[256] = {}; DEF_FIELD(symval, ipack_device_id, format); DEF_FIELD(symval, ipack_device_id, vendor); DEF_FIELD(symval, ipack_device_id, device); - strcpy(alias, "ipack:"); + ADD(alias, "f", format != IPACK_ANY_FORMAT, format); ADD(alias, "v", vendor != IPACK_ANY_ID, vendor); ADD(alias, "d", device != IPACK_ANY_ID, device); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "ipack:%s", alias); } /* @@ -1178,9 +1131,9 @@ static void append_nibble_mask(char **outp, * N is exactly 8 digits, where each is an upper-case hex digit, or * a ? or [] pattern matching exactly one digit. */ -static int do_amba_entry(struct module *mod, - void *symval, char *alias) +static void do_amba_entry(struct module *mod, void *symval) { + char alias[256]; unsigned int digit; char *p = alias; DEF_FIELD(symval, amba_id, id); @@ -1190,13 +1143,12 @@ static int do_amba_entry(struct module *mod, fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: id=0x%08X, mask=0x%08X. Please fix this driver.\n", mod->name, id, mask); - p += sprintf(alias, "amba:d"); for (digit = 0; digit < 8; digit++) append_nibble_mask(&p, (id >> (4 * (7 - digit))) & 0xf, (mask >> (4 * (7 - digit))) & 0xf); - return 1; + module_alias_printf(mod, false, "amba:d%s", alias); } /* @@ -1205,13 +1157,11 @@ static int do_amba_entry(struct module *mod, * N is exactly 2 digits, where each is an upper-case hex digit, or * a ? or [] pattern matching exactly one digit. */ -static int do_mips_cdmm_entry(struct module *mod, - void *symval, char *alias) +static void do_mips_cdmm_entry(struct module *mod, void *symval) { DEF_FIELD(symval, mips_cdmm_device_id, type); - sprintf(alias, "mipscdmm:t%02X*", type); - return 1; + module_alias_printf(mod, false, "mipscdmm:t%02X*", type); } /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,* @@ -1220,137 +1170,130 @@ static int do_mips_cdmm_entry(struct module *mod, * complicated. */ -static int do_x86cpu_entry(struct module *mod, void *symval, - char *alias) +static void do_x86cpu_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, x86_cpu_id, feature); DEF_FIELD(symval, x86_cpu_id, family); DEF_FIELD(symval, x86_cpu_id, model); DEF_FIELD(symval, x86_cpu_id, vendor); - strcpy(alias, "cpu:type:x86,"); ADD(alias, "ven", vendor != X86_VENDOR_ANY, vendor); ADD(alias, "fam", family != X86_FAMILY_ANY, family); ADD(alias, "mod", model != X86_MODEL_ANY, model); strcat(alias, ":feature:*"); if (feature != X86_FEATURE_ANY) sprintf(alias + strlen(alias), "%04X*", feature); - return 1; + + module_alias_printf(mod, false, "cpu:type:x86,%s", alias); } /* LOOKS like cpu:type:*:feature:*FEAT* */ -static int do_cpu_entry(struct module *mod, void *symval, char *alias) +static void do_cpu_entry(struct module *mod, void *symval) { DEF_FIELD(symval, cpu_feature, feature); - sprintf(alias, "cpu:type:*:feature:*%04X*", feature); - return 1; + module_alias_printf(mod, false, "cpu:type:*:feature:*%04X*", feature); } /* Looks like: mei:S:uuid:N:* */ -static int do_mei_entry(struct module *mod, void *symval, - char *alias) +static void do_mei_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD_ADDR(symval, mei_cl_device_id, name); DEF_FIELD_ADDR(symval, mei_cl_device_id, uuid); DEF_FIELD(symval, mei_cl_device_id, version); - sprintf(alias, MEI_CL_MODULE_PREFIX); - sprintf(alias + strlen(alias), "%s:", (*name)[0] ? *name : "*"); add_uuid(alias, *uuid); ADD(alias, ":", version != MEI_CL_VERSION_ANY, version); - strcat(alias, ":*"); - - return 1; + module_alias_printf(mod, false, MEI_CL_MODULE_PREFIX "%s:%s:*", + (*name)[0] ? *name : "*", alias); } /* Looks like: rapidio:vNdNavNadN */ -static int do_rio_entry(struct module *mod, - void *symval, char *alias) +static void do_rio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, rio_device_id, did); DEF_FIELD(symval, rio_device_id, vid); DEF_FIELD(symval, rio_device_id, asm_did); DEF_FIELD(symval, rio_device_id, asm_vid); - strcpy(alias, "rapidio:"); ADD(alias, "v", vid != RIO_ANY_ID, vid); ADD(alias, "d", did != RIO_ANY_ID, did); ADD(alias, "av", asm_vid != RIO_ANY_ID, asm_vid); ADD(alias, "ad", asm_did != RIO_ANY_ID, asm_did); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "rapidio:%s", alias); } /* Looks like: ulpi:vNpN */ -static int do_ulpi_entry(struct module *mod, void *symval, - char *alias) +static void do_ulpi_entry(struct module *mod, void *symval) { DEF_FIELD(symval, ulpi_device_id, vendor); DEF_FIELD(symval, ulpi_device_id, product); - sprintf(alias, "ulpi:v%04xp%04x", vendor, product); - - return 1; + module_alias_printf(mod, false, "ulpi:v%04xp%04x", vendor, product); } /* Looks like: hdaudio:vNrNaN */ -static int do_hda_entry(struct module *mod, void *symval, char *alias) +static void do_hda_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, hda_device_id, vendor_id); DEF_FIELD(symval, hda_device_id, rev_id); DEF_FIELD(symval, hda_device_id, api_version); - strcpy(alias, "hdaudio:"); ADD(alias, "v", vendor_id != 0, vendor_id); ADD(alias, "r", rev_id != 0, rev_id); ADD(alias, "a", api_version != 0, api_version); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "hdaudio:%s", alias); } /* Looks like: sdw:mNpNvNcN */ -static int do_sdw_entry(struct module *mod, void *symval, char *alias) +static void do_sdw_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, sdw_device_id, mfg_id); DEF_FIELD(symval, sdw_device_id, part_id); DEF_FIELD(symval, sdw_device_id, sdw_version); DEF_FIELD(symval, sdw_device_id, class_id); - strcpy(alias, "sdw:"); ADD(alias, "m", mfg_id != 0, mfg_id); ADD(alias, "p", part_id != 0, part_id); ADD(alias, "v", sdw_version != 0, sdw_version); ADD(alias, "c", class_id != 0, class_id); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "sdw:%s", alias); } /* Looks like: fsl-mc:vNdN */ -static int do_fsl_mc_entry(struct module *mod, void *symval, - char *alias) +static void do_fsl_mc_entry(struct module *mod, void *symval) { DEF_FIELD(symval, fsl_mc_device_id, vendor); DEF_FIELD_ADDR(symval, fsl_mc_device_id, obj_type); - sprintf(alias, "fsl-mc:v%08Xd%s", vendor, *obj_type); - return 1; + module_alias_printf(mod, false, "fsl-mc:v%08Xd%s", vendor, *obj_type); } /* Looks like: tbsvc:kSpNvNrN */ -static int do_tbsvc_entry(struct module *mod, void *symval, char *alias) +static void do_tbsvc_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, tb_service_id, match_flags); DEF_FIELD_ADDR(symval, tb_service_id, protocol_key); DEF_FIELD(symval, tb_service_id, protocol_id); DEF_FIELD(symval, tb_service_id, protocol_version); DEF_FIELD(symval, tb_service_id, protocol_revision); - strcpy(alias, "tbsvc:"); if (match_flags & TBSVC_MATCH_PROTOCOL_KEY) sprintf(alias + strlen(alias), "k%s", *protocol_key); else @@ -1361,93 +1304,80 @@ static int do_tbsvc_entry(struct module *mod, void *symval, char *alias) ADD(alias, "r", match_flags & TBSVC_MATCH_PROTOCOL_REVISION, protocol_revision); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "tbsvc:%s", alias); } /* Looks like: typec:idNmN */ -static int do_typec_entry(struct module *mod, void *symval, char *alias) +static void do_typec_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, typec_device_id, svid); DEF_FIELD(symval, typec_device_id, mode); - sprintf(alias, "typec:id%04X", svid); ADD(alias, "m", mode != TYPEC_ANY_MODE, mode); - return 1; + module_alias_printf(mod, false, "typec:id%04X%s", svid, alias); } /* Looks like: tee:uuid */ -static int do_tee_entry(struct module *mod, void *symval, char *alias) +static void do_tee_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, tee_client_device_id, uuid); - sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + module_alias_printf(mod, true, + "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4], uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9], uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14], uuid->b[15]); - - add_wildcard(alias); - return 1; } /* Looks like: wmi:guid */ -static int do_wmi_entry(struct module *mod, void *symval, char *alias) +static void do_wmi_entry(struct module *mod, void *symval) { - int len; DEF_FIELD_ADDR(symval, wmi_device_id, guid_string); if (strlen(*guid_string) != UUID_STRING_LEN) { warn("Invalid WMI device id 'wmi:%s' in '%s'\n", *guid_string, mod->name); - return 0; + return; } - len = snprintf(alias, ALIAS_SIZE, WMI_MODULE_PREFIX "%s", *guid_string); - if (len < 0 || len >= ALIAS_SIZE) { - warn("Could not generate all MODULE_ALIAS's in '%s'\n", - mod->name); - return 0; - } - return 1; + module_alias_printf(mod, false, WMI_MODULE_PREFIX "%s", *guid_string); } /* Looks like: mhi:S */ -static int do_mhi_entry(struct module *mod, void *symval, char *alias) +static void do_mhi_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); - sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan); - return 1; + module_alias_printf(mod, false, MHI_DEVICE_MODALIAS_FMT, *chan); } /* Looks like: mhi_ep:S */ -static int do_mhi_ep_entry(struct module *mod, void *symval, char *alias) +static void do_mhi_ep_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); - sprintf(alias, MHI_EP_DEVICE_MODALIAS_FMT, *chan); - return 1; + module_alias_printf(mod, false, MHI_EP_DEVICE_MODALIAS_FMT, *chan); } /* Looks like: ishtp:{guid} */ -static int do_ishtp_entry(struct module *mod, void *symval, char *alias) +static void do_ishtp_entry(struct module *mod, void *symval) { + char alias[256] = {}; DEF_FIELD_ADDR(symval, ishtp_device_id, guid); - strcpy(alias, ISHTP_MODULE_PREFIX "{"); add_guid(alias, *guid); - strcat(alias, "}"); - return 1; + module_alias_printf(mod, false, ISHTP_MODULE_PREFIX "{%s}", alias); } -static int do_auxiliary_entry(struct module *mod, void *symval, char *alias) +static void do_auxiliary_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, auxiliary_device_id, name); - sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name); - return 1; + module_alias_printf(mod, false, AUXILIARY_MODULE_PREFIX "%s", *name); } /* @@ -1455,8 +1385,10 @@ static int do_auxiliary_entry(struct module *mod, void *symval, char *alias) * * N is exactly 2 digits, where each is an upper-case hex digit. */ -static int do_ssam_entry(struct module *mod, void *symval, char *alias) +static void do_ssam_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ssam_device_id, match_flags); DEF_FIELD(symval, ssam_device_id, domain); DEF_FIELD(symval, ssam_device_id, category); @@ -1464,30 +1396,28 @@ static int do_ssam_entry(struct module *mod, void *symval, char *alias) DEF_FIELD(symval, ssam_device_id, instance); DEF_FIELD(symval, ssam_device_id, function); - sprintf(alias, "ssam:d%02Xc%02X", domain, category); ADD(alias, "t", match_flags & SSAM_MATCH_TARGET, target); ADD(alias, "i", match_flags & SSAM_MATCH_INSTANCE, instance); ADD(alias, "f", match_flags & SSAM_MATCH_FUNCTION, function); - return 1; + module_alias_printf(mod, false, "ssam:d%02Xc%02X%s", + domain, category, alias); } /* Looks like: dfl:tNfN */ -static int do_dfl_entry(struct module *mod, void *symval, char *alias) +static void do_dfl_entry(struct module *mod, void *symval) { DEF_FIELD(symval, dfl_device_id, type); DEF_FIELD(symval, dfl_device_id, feature_id); - sprintf(alias, "dfl:t%04Xf%04X", type, feature_id); - - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "dfl:t%04Xf%04X", type, feature_id); } /* Looks like: cdx:vNdN */ -static int do_cdx_entry(struct module *mod, void *symval, - char *alias) +static void do_cdx_entry(struct module *mod, void *symval) { + char alias[256]; + DEF_FIELD(symval, cdx_device_id, vendor); DEF_FIELD(symval, cdx_device_id, device); DEF_FIELD(symval, cdx_device_id, subvendor); @@ -1506,7 +1436,7 @@ static int do_cdx_entry(struct module *mod, void *symval, default: warn("Unknown CDX driver_override alias %08X\n", override_only); - return 0; + return; } ADD(alias, "v", vendor != CDX_ANY_ID, vendor); @@ -1515,24 +1445,22 @@ static int do_cdx_entry(struct module *mod, void *symval, ADD(alias, "sd", subdevice != CDX_ANY_ID, subdevice); ADD(alias, "c", class_mask == 0xFFFFFF, class); - return 1; + module_alias_printf(mod, false, "%s", alias); } -static int do_vchiq_entry(struct module *mod, void *symval, char *alias) +static void do_vchiq_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, vchiq_device_id, name); - sprintf(alias, "vchiq:%s", *name); - return 1; + module_alias_printf(mod, false, "vchiq:%s", *name); } /* Looks like: coreboot:tN */ -static int do_coreboot_entry(struct module *mod, void *symval, char *alias) +static void do_coreboot_entry(struct module *mod, void *symval) { DEF_FIELD(symval, coreboot_device_id, tag); - sprintf(alias, "coreboot:t%08X", tag); - return 1; + module_alias_printf(mod, false, "coreboot:t%08X", tag); } /* Does namelen bytes of name exactly match the symbol? */ @@ -1547,21 +1475,17 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol) static void do_table(void *symval, unsigned long size, unsigned long id_size, const char *device_id, - int (*do_entry)(struct module *mod, void *symval, char *alias), + void (*do_entry)(struct module *mod, void *symval), struct module *mod) { unsigned int i; - char alias[ALIAS_SIZE]; device_id_check(mod->name, device_id, size, id_size, symval); /* Leave last one: it's the terminator. */ size -= id_size; - for (i = 0; i < size; i += id_size) { - if (do_entry(mod, symval+i, alias)) { - module_alias_printf(mod, false, "%s", alias); - } - } + for (i = 0; i < size; i += id_size) + do_entry(mod, symval + i); } static const struct devtable devtable[] = { -- cgit From a5d8d417e62ab3823a06e1bc08634d737d810e59 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:46 +0900 Subject: modpost: convert do_pnp_card_entries() to a generic handler do_pnp_card_entries() no longer needs to iterate over the pnp_card_device_id array. Convert it to a generic ->do_entry() handler. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 5ef87a6d33f8..00bb3f8f0647 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -651,34 +651,24 @@ static void do_pnp_device_entry(void *symval, unsigned long size, } /* looks like: "pnp:dD" for every device of the card */ -static void do_pnp_card_entries(void *symval, unsigned long size, - struct module *mod) +static void do_pnp_card_entry(struct module *mod, void *symval) { - const unsigned long id_size = SIZE_pnp_card_device_id; - const unsigned int count = (size / id_size)-1; - unsigned int i; - - device_id_check(mod->name, "pnp", size, id_size, symval); - - for (i = 0; i < count; i++) { - unsigned int j; - DEF_FIELD_ADDR(symval + i * id_size, pnp_card_device_id, devs); + DEF_FIELD_ADDR(symval, pnp_card_device_id, devs); - for (j = 0; j < PNP_MAX_DEVICES; j++) { - const char *id = (char *)(*devs)[j].id; - char acpi_id[PNP_ID_LEN]; + for (unsigned int i = 0; i < PNP_MAX_DEVICES; i++) { + const char *id = (char *)(*devs)[i].id; + char acpi_id[PNP_ID_LEN]; - if (!id[0]) - break; + if (!id[0]) + break; - /* add an individual alias for every device entry */ - module_alias_printf(mod, false, "pnp:d%s*", id); + /* fix broken pnp bus lowercasing */ + for (unsigned int j = 0; j < sizeof(acpi_id); j++) + acpi_id[j] = toupper(id[j]); - /* fix broken pnp bus lowercasing */ - for (int k = 0; k < sizeof(acpi_id); k++) - acpi_id[k] = toupper(id[k]); - module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); - } + /* add an individual alias for every device entry */ + module_alias_printf(mod, false, "pnp:d%s*", id); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } } @@ -1541,6 +1531,7 @@ static const struct devtable devtable[] = { {"cdx", SIZE_cdx_device_id, do_cdx_entry}, {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, {"coreboot", SIZE_coreboot_device_id, do_coreboot_entry}, + {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry}, }; /* Create MODULE_ALIAS() statements. @@ -1591,8 +1582,6 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_of_table(symval, sym->st_size, mod); else if (sym_is(name, namelen, "pnp")) do_pnp_device_entry(symval, sym->st_size, mod); - else if (sym_is(name, namelen, "pnp_card")) - do_pnp_card_entries(symval, sym->st_size, mod); else { int i; -- cgit From 600dbaf1e2f0c0b70b2d3e7513a161b884e7718f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:47 +0900 Subject: modpost: convert do_pnp_device_entry() to a generic handler do_pnp_device_entry() no longer needs to iterate over the pnp_device_id array. Convert it to a generic ->do_entry() handler. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 00bb3f8f0647..cacfa0de634b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -627,27 +627,16 @@ static void do_acpi_entry(struct module *mod, void *symval) } /* looks like: "pnp:dD" */ -static void do_pnp_device_entry(void *symval, unsigned long size, - struct module *mod) +static void do_pnp_device_entry(struct module *mod, void *symval) { - const unsigned long id_size = SIZE_pnp_device_id; - const unsigned int count = (size / id_size)-1; - unsigned int i; - - device_id_check(mod->name, "pnp", size, id_size, symval); - - for (i = 0; i < count; i++) { - DEF_FIELD_ADDR(symval + i*id_size, pnp_device_id, id); - char acpi_id[sizeof(*id)]; - int j; - - module_alias_printf(mod, false, "pnp:d%s*", *id); + DEF_FIELD_ADDR(symval, pnp_device_id, id); + char acpi_id[sizeof(*id)]; - /* fix broken pnp bus lowercasing */ - for (j = 0; j < sizeof(acpi_id); j++) - acpi_id[j] = toupper((*id)[j]); - module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); - } + /* fix broken pnp bus lowercasing */ + for (unsigned int i = 0; i < sizeof(acpi_id); i++) + acpi_id[i] = toupper((*id)[i]); + module_alias_printf(mod, false, "pnp:d%s*", *id); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } /* looks like: "pnp:dD" for every device of the card */ @@ -1531,6 +1520,7 @@ static const struct devtable devtable[] = { {"cdx", SIZE_cdx_device_id, do_cdx_entry}, {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, {"coreboot", SIZE_coreboot_device_id, do_coreboot_entry}, + {"pnp", SIZE_pnp_device_id, do_pnp_device_entry}, {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry}, }; @@ -1580,8 +1570,6 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_usb_table(symval, sym->st_size, mod); else if (sym_is(name, namelen, "of")) do_of_table(symval, sym->st_size, mod); - else if (sym_is(name, namelen, "pnp")) - do_pnp_device_entry(symval, sym->st_size, mod); else { int i; -- cgit From c58854c8e0b50c2f30c729b82b92b3fd8cc8f2c1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:48 +0900 Subject: modpost: convert do_of_table() to a generic handler do_of_table() no longer needs to iterate over the of_device_id array. Convert it to a generic ->do_entry() handler. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index cacfa0de634b..7f079a3857b2 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -398,7 +398,7 @@ static void do_usb_table(void *symval, unsigned long size, do_usb_entry_multi(symval + i, mod); } -static void do_of_entry_multi(void *symval, struct module *mod) +static void do_of_entry(struct module *mod, void *symval) { char alias[500]; int len; @@ -424,21 +424,6 @@ static void do_of_entry_multi(void *symval, struct module *mod) module_alias_printf(mod, false, "%sC*", alias); } -static void do_of_table(void *symval, unsigned long size, - struct module *mod) -{ - unsigned int i; - const unsigned long id_size = SIZE_of_device_id; - - device_id_check(mod->name, "of", size, id_size, symval); - - /* Leave last one: it's the terminator. */ - size -= id_size; - - for (i = 0; i < size; i += id_size) - do_of_entry_multi(symval + i, mod); -} - /* Looks like: hid:bNvNpN */ static void do_hid_entry(struct module *mod, void *symval) { @@ -1520,6 +1505,7 @@ static const struct devtable devtable[] = { {"cdx", SIZE_cdx_device_id, do_cdx_entry}, {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, {"coreboot", SIZE_coreboot_device_id, do_coreboot_entry}, + {"of", SIZE_of_device_id, do_of_entry}, {"pnp", SIZE_pnp_device_id, do_pnp_device_entry}, {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry}, }; @@ -1568,8 +1554,6 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, /* First handle the "special" cases */ if (sym_is(name, namelen, "usb")) do_usb_table(symval, sym->st_size, mod); - else if (sym_is(name, namelen, "of")) - do_of_table(symval, sym->st_size, mod); else { int i; -- cgit From abd20428c3f2f8b97a2a0414343faf0ff246a018 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:49 +0900 Subject: modpost: convert do_usb_table() to a generic handler do_usb_table() no longer needs to iterate over the usb_device_id array. Convert it to a generic ->do_entry() handler. This is the last special case. Clean up handle_moddevtable(). Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 7f079a3857b2..7f1bbb46dc65 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -122,7 +122,6 @@ typedef struct { * we handle those differences explicitly below */ #include "../../include/linux/mod_devicetable.h" -/* This array collects all instances that use the generic do_table */ struct devtable { const char *device_id; /* name of table, __mod___*_device_table. */ unsigned long id_size; @@ -318,7 +317,7 @@ static unsigned int incbcd(unsigned int *bcd, return init; } -static void do_usb_entry_multi(void *symval, struct module *mod) +static void do_usb_entry_multi(struct module *mod, void *symval) { unsigned int devlo, devhi; unsigned char chi, clo, max; @@ -383,21 +382,6 @@ static void do_usb_entry_multi(void *symval, struct module *mod) } } -static void do_usb_table(void *symval, unsigned long size, - struct module *mod) -{ - unsigned int i; - const unsigned long id_size = SIZE_usb_device_id; - - device_id_check(mod->name, "usb", size, id_size, symval); - - /* Leave last one: it's the terminator. */ - size -= id_size; - - for (i = 0; i < size; i += id_size) - do_usb_entry_multi(symval + i, mod); -} - static void do_of_entry(struct module *mod, void *symval) { char alias[500]; @@ -1506,6 +1490,7 @@ static const struct devtable devtable[] = { {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, {"coreboot", SIZE_coreboot_device_id, do_coreboot_entry}, {"of", SIZE_of_device_id, do_of_entry}, + {"usb", SIZE_usb_device_id, do_usb_entry_multi}, {"pnp", SIZE_pnp_device_id, do_pnp_device_entry}, {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry}, }; @@ -1551,21 +1536,15 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, symval = sym_get_data(info, sym); } - /* First handle the "special" cases */ - if (sym_is(name, namelen, "usb")) - do_usb_table(symval, sym->st_size, mod); - else { - int i; - - for (i = 0; i < ARRAY_SIZE(devtable); i++) { - const struct devtable *p = &devtable[i]; + for (int i = 0; i < ARRAY_SIZE(devtable); i++) { + const struct devtable *p = &devtable[i]; - if (sym_is(name, namelen, p->device_id)) { - do_table(symval, sym->st_size, p->id_size, - p->device_id, p->do_entry, mod); - break; - } + if (sym_is(name, namelen, p->device_id)) { + do_table(symval, sym->st_size, p->id_size, + p->device_id, p->do_entry, mod); + break; } } + free(zeros); } -- cgit From 9d98038d438d8515473a75a29bc524e9a4a5882a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:50 +0900 Subject: modpost: move strstarts() to modpost.h This macro is useful in file2alias.c as well. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 2 +- scripts/mod/modpost.c | 2 -- scripts/mod/modpost.h | 2 ++ 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 7f1bbb46dc65..541e6a3f95bc 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1515,7 +1515,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, return; /* All our symbols are of form __mod____device_table. */ - if (strncmp(symname, "__mod_", strlen("__mod_"))) + if (!strstarts(symname, "__mod_")) return; name = symname + strlen("__mod_"); namelen = strlen(name); diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1948d69ce2b9..3bbd5efcf3f3 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -341,8 +341,6 @@ static const char *sec_name(const struct elf_info *info, unsigned int secindex) return sech_name(info, &info->sechdrs[secindex]); } -#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) - static struct symbol *sym_add_exported(const char *name, struct module *mod, bool gpl_only, const char *namespace) { diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 52efe0026b34..49848fcbe2a1 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -67,6 +67,8 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) + struct buffer { char *p; int pos; -- cgit From 9a8ace8bb2efa0ca43a77866fa9c835294b1e045 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:51 +0900 Subject: modpost: rename variables in handle_moddevtable() This commit renames the variables in handle_moddevtable() as follows: name -> type namelen -> typelen identifier -> name These changes align with the definition in include/linux/module.h: extern typeof(name) __mod_##type##__##name##_device_table Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 541e6a3f95bc..038b2ab79e11 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1503,8 +1503,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, { void *symval; char *zeros = NULL; - const char *name, *identifier; - unsigned int namelen; + const char *type, *name; + size_t typelen; /* We're looking for a section relative symbol */ if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) @@ -1514,19 +1514,19 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) return; - /* All our symbols are of form __mod____device_table. */ + /* All our symbols are of form __mod____device_table. */ if (!strstarts(symname, "__mod_")) return; - name = symname + strlen("__mod_"); - namelen = strlen(name); - if (namelen < strlen("_device_table")) + type = symname + strlen("__mod_"); + typelen = strlen(type); + if (typelen < strlen("_device_table")) return; - if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) + if (strcmp(type + typelen - strlen("_device_table"), "_device_table")) return; - identifier = strstr(name, "__"); - if (!identifier) + name = strstr(type, "__"); + if (!name) return; - namelen = identifier - name; + typelen = name - type; /* Handle all-NULL symbols allocated into .bss */ if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { @@ -1539,7 +1539,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, for (int i = 0; i < ARRAY_SIZE(devtable); i++) { const struct devtable *p = &devtable[i]; - if (sym_is(name, namelen, p->device_id)) { + if (sym_is(type, typelen, p->device_id)) { do_table(symval, sym->st_size, p->id_size, p->device_id, p->do_entry, mod); break; -- cgit From 054a9cd395a79f4a5595f2cd24542e9bca8723c8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:52 +0900 Subject: modpost: rename alias symbol for MODULE_DEVICE_TABLE() This commit renames the alias symbol, __mod____device_table to __mod_device_table____. This change simplifies the code slightly, as there is no longer a need to check both the prefix and suffix. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 038b2ab79e11..fc4bbeea1268 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -123,7 +123,7 @@ typedef struct { #include "../../include/linux/mod_devicetable.h" struct devtable { - const char *device_id; /* name of table, __mod___*_device_table. */ + const char *device_id; unsigned long id_size; void (*do_entry)(struct module *mod, void *symval); }; @@ -190,7 +190,7 @@ static void device_id_check(const char *modname, const char *device_id, int i; if (size % id_size || size < id_size) { - fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo of the size of section __mod_%s___device_table=%lu.\n" + fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo of the size of section __mod_device_table__%s__=%lu.\n" "Fix definition of struct %s_device_id in mod_devicetable.h\n", modname, device_id, id_size, device_id, size, device_id); } @@ -1505,6 +1505,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, char *zeros = NULL; const char *type, *name; size_t typelen; + static const char *prefix = "__mod_device_table__"; /* We're looking for a section relative symbol */ if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) @@ -1514,15 +1515,11 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) return; - /* All our symbols are of form __mod____device_table. */ - if (!strstarts(symname, "__mod_")) - return; - type = symname + strlen("__mod_"); - typelen = strlen(type); - if (typelen < strlen("_device_table")) - return; - if (strcmp(type + typelen - strlen("_device_table"), "_device_table")) + /* All our symbols are of form __mod_device_table____. */ + if (!strstarts(symname, prefix)) return; + type = symname + strlen(prefix); + name = strstr(type, "__"); if (!name) return; -- cgit From 2b1bd507542a6ec1506a847da8e81fc764a4e707 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:53 +0900 Subject: modpost: improve error messages in device_id_check() The first error message in device_id_check() is obscure and can be misleading because the cause of the error is unlikely to be found in the struct definition in mod_devicetable.h. This type of error occurs when an array is passed to an incorrect type of MODULE_DEVICE_TABLE(). [Example 1] static const struct acpi_device_id foo_ids[] = { { "FOO" }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, foo_ids); Currently, modpost outputs a meaningless suggestion: ERROR: modpost: ...: sizeof(struct of_device_id)=200 is not a modulo of the size of section __mod_device_table__of__=64. Fix definition of struct of_device_id in mod_devicetable.h The root cause here is that MODULE_DEVICE_TABLE(of, ...) is used instead of the correct MODULE_DEVICE_TABLE(acpi, ...). This commit provides a more intuitive error message: ERROR: modpost: ...: type mismatch between foo_ids[] and MODULE_DEVICE_TABLE(of, ...) The second error message, related to a missing terminator, is too verbose. [Example 2] static const struct acpi_device_id foo_ids[] = { { "FOO" }, }; MODULE_DEVICE_TABLE(acpi, foo_ids); The current error message is overly long, and does not pinpoint the incorrect array: ...: struct acpi_device_id is 32 bytes. The last of 1 is: 0x46 0x4f 0x4f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ERROR: modpost: ...: struct acpi_device_id is not terminated with a NULL entry! This commit changes it to a more concise error message, sufficient to identify the incorrect array: ERROR: modpost: ...: foo_ids[] is not terminated with a NULL entry Lastly, this commit squashes device_id_check() into do_table() and changes fatal() into error(), allowing modpost to continue processing other modules. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 55 ++++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 37 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index fc4bbeea1268..5b5745f00eb3 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -176,40 +176,6 @@ static inline void add_guid(char *str, guid_t guid) guid.b[12], guid.b[13], guid.b[14], guid.b[15]); } -/** - * Check that sizeof(device_id type) are consistent with size of section - * in .o file. If in-consistent then userspace and kernel does not agree - * on actual size which is a bug. - * Also verify that the final entry in the table is all zeros. - * Ignore both checks if build host differ from target host and size differs. - **/ -static void device_id_check(const char *modname, const char *device_id, - unsigned long size, unsigned long id_size, - void *symval) -{ - int i; - - if (size % id_size || size < id_size) { - fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo of the size of section __mod_device_table__%s__=%lu.\n" - "Fix definition of struct %s_device_id in mod_devicetable.h\n", - modname, device_id, id_size, device_id, size, device_id); - } - /* Verify last one is a terminator */ - for (i = 0; i < id_size; i++ ) { - if (*(uint8_t*)(symval+size-id_size+i)) { - fprintf(stderr, - "%s: struct %s_device_id is %lu bytes. The last of %lu is:\n", - modname, device_id, id_size, size / id_size); - for (i = 0; i < id_size; i++ ) - fprintf(stderr,"0x%02x ", - *(uint8_t*)(symval+size-id_size+i) ); - fprintf(stderr,"\n"); - fatal("%s: struct %s_device_id is not terminated with a NULL entry!\n", - modname, device_id); - } - } -} - /* USB is special because the bcdDevice can be matched against a numeric range */ /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */ static void do_usb_entry(void *symval, @@ -1420,7 +1386,7 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol) return memcmp(name, symbol, namelen) == 0; } -static void do_table(void *symval, unsigned long size, +static void do_table(const char *name, void *symval, unsigned long size, unsigned long id_size, const char *device_id, void (*do_entry)(struct module *mod, void *symval), @@ -1428,7 +1394,21 @@ static void do_table(void *symval, unsigned long size, { unsigned int i; - device_id_check(mod->name, device_id, size, id_size, symval); + if (size % id_size || size < id_size) { + error("%s: type mismatch between %s[] and MODULE_DEVICE_TABLE(%s, ...)\n", + mod->name, name, device_id); + return; + } + + /* Verify the last entry is a terminator */ + for (i = size - id_size; i < size; i++) { + if (*(uint8_t *)(symval + i)) { + error("%s: %s[] is not terminated with a NULL entry\n", + mod->name, name); + return; + } + } + /* Leave last one: it's the terminator. */ size -= id_size; @@ -1524,6 +1504,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (!name) return; typelen = name - type; + name += strlen("__"); /* Handle all-NULL symbols allocated into .bss */ if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { @@ -1537,7 +1518,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, const struct devtable *p = &devtable[i]; if (sym_is(type, typelen, p->device_id)) { - do_table(symval, sym->st_size, p->id_size, + do_table(name, symval, sym->st_size, p->id_size, p->device_id, p->do_entry, mod); break; } -- cgit From 091aa11a2983cdc608f3978d365f5479e78917d8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 22 Nov 2024 08:22:55 +0900 Subject: genksyms: reduce indentation in export_symbol() Modify this function to return earlier when find_symbol() returns NULL, reducing the level of improve readability. No functional changes are intended. Signed-off-by: Masahiro Yamada --- scripts/genksyms/genksyms.c | 73 +++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 36 deletions(-) (limited to 'scripts') diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index f3901c55df23..07f9b8cfb233 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -632,54 +632,55 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) void export_symbol(const char *name) { struct symbol *sym; + unsigned long crc; + int has_changed = 0; sym = find_symbol(name, SYM_NORMAL, 0); - if (!sym) + if (!sym) { error_with_pos("export undefined symbol %s", name); - else { - unsigned long crc; - int has_changed = 0; + return; + } - if (flag_dump_defs) - fprintf(debugfile, "Export %s == <", name); + if (flag_dump_defs) + fprintf(debugfile, "Export %s == <", name); - expansion_trail = (struct symbol *)-1L; + expansion_trail = (struct symbol *)-1L; - sym->expansion_trail = expansion_trail; - expansion_trail = sym; - crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; + sym->expansion_trail = expansion_trail; + expansion_trail = sym; + crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; - sym = expansion_trail; - while (sym != (struct symbol *)-1L) { - struct symbol *n = sym->expansion_trail; + sym = expansion_trail; + while (sym != (struct symbol *)-1L) { + struct symbol *n = sym->expansion_trail; - if (sym->status != STATUS_UNCHANGED) { - if (!has_changed) { - print_location(); - fprintf(stderr, "%s: %s: modversion " - "changed because of changes " - "in ", flag_preserve ? "error" : - "warning", name); - } else - fprintf(stderr, ", "); - print_type_name(sym->type, sym->name); - if (sym->status == STATUS_DEFINED) - fprintf(stderr, " (became defined)"); - has_changed = 1; - if (flag_preserve) - errors++; + if (sym->status != STATUS_UNCHANGED) { + if (!has_changed) { + print_location(); + fprintf(stderr, + "%s: %s: modversion changed because of changes in ", + flag_preserve ? "error" : "warning", + name); + } else { + fprintf(stderr, ", "); } - sym->expansion_trail = 0; - sym = n; + print_type_name(sym->type, sym->name); + if (sym->status == STATUS_DEFINED) + fprintf(stderr, " (became defined)"); + has_changed = 1; + if (flag_preserve) + errors++; } - if (has_changed) - fprintf(stderr, "\n"); + sym->expansion_trail = 0; + sym = n; + } + if (has_changed) + fprintf(stderr, "\n"); - if (flag_dump_defs) - fputs(">\n", debugfile); + if (flag_dump_defs) + fputs(">\n", debugfile); - printf("#SYMVER %s 0x%08lx\n", name, crc); - } + printf("#SYMVER %s 0x%08lx\n", name, crc); } /*----------------------------------------------------------------------*/ -- cgit From 6b1fabce7313dcd4d95e541dd400ba5748b09b94 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 23 Nov 2024 17:26:45 +0900 Subject: kbuild: deb-pkg: add python3:native to build dependency Python3 is necessary for running some scripts such as drivers/gpu/drm/msm/registers/gen_header.py Both scripts/package/kernel.spec and scripts/package/PKGBUILD already list Python as the build dependency. Do likewise for scripts/package/mkdebian. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/package/mkdebian | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index fc3b7fa709fc..4ffcc70f8e31 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -202,7 +202,7 @@ Build-Depends-Arch: bc, bison, cpio, flex, gcc-${host_gnu} , kmod, libelf-dev:native, libssl-dev:native, libssl-dev , - rsync + python3:native, rsync Homepage: https://www.kernel.org/ Package: $packagename-$version -- cgit From 5eaea85187bf2132d1af916010fa9e26bb63f97f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 23 Nov 2024 17:36:08 +0900 Subject: modpost: replace tdb_hash() with hash_str() Use a helper available in scripts/include/hash.h. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3bbd5efcf3f3..0584cbcdbd2d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -210,19 +211,6 @@ struct symbol { static HASHTABLE_DEFINE(symbol_hashtable, 1U << 10); -/* This is based on the hash algorithm from gdbm, via tdb */ -static inline unsigned int tdb_hash(const char *name) -{ - unsigned value; /* Used to compute the hash value. */ - unsigned i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++) - value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - /** * Allocate a new symbols for use in the hash of exported symbols or * the list of unresolved symbols per module @@ -240,7 +228,7 @@ static struct symbol *alloc_symbol(const char *name) /* For the hash of exported symbols */ static void hash_add_symbol(struct symbol *sym) { - hash_add(symbol_hashtable, &sym->hnode, tdb_hash(sym->name)); + hash_add(symbol_hashtable, &sym->hnode, hash_str(sym->name)); } static void sym_add_unresolved(const char *name, struct module *mod, bool weak) @@ -261,7 +249,7 @@ static struct symbol *sym_find_with_module(const char *name, struct module *mod) if (name[0] == '.') name++; - hash_for_each_possible(symbol_hashtable, s, hnode, tdb_hash(name)) { + hash_for_each_possible(symbol_hashtable, s, hnode, hash_str(name)) { if (strcmp(s->name, name) == 0 && (!mod || s->module == mod)) return s; } -- cgit From 18e9944e56f68423e52505066f79939e7d12a62b Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Sat, 23 Nov 2024 14:33:37 +0100 Subject: kbuild: add dependency from vmlinux to resolve_btfids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resolve_btfids is used by link-vmlinux.sh. In contrast to other configuration options and targets no transitive dependency between resolve_btfids and vmlinux. Add an explicit one. Signed-off-by: Thomas Weißschuh Acked-by: Jiri Olsa Signed-off-by: Masahiro Yamada --- scripts/Makefile.vmlinux | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 997be5dc7bf5..2ecd350e9c43 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -68,6 +68,9 @@ cmd_link_vmlinux = \ targets += vmlinux vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +$(call if_changed_dep,link_vmlinux) +ifdef CONFIG_DEBUG_INFO_BTF +vmlinux: $(RESOLVE_BTFIDS) +endif # module.builtin.ranges # --------------------------------------------------------------------------- -- cgit From e6064da6461f989a357f2e280d7f8d4155267c4c Mon Sep 17 00:00:00 2001 From: Sedat Dilek Date: Tue, 26 Nov 2024 16:58:01 +0100 Subject: kbuild: rename .tmp_vmlinux.kallsyms0.syms to .tmp_vmlinux0.syms Change the naming for consistency. While at this, fix the comments in scripts/link-vmlinux.sh. Signed-off-by: Sedat Dilek Signed-off-by: Masahiro Yamada --- scripts/link-vmlinux.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 53bd4b727e21..139aa4d1215a 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -207,8 +207,8 @@ kallsymso= strip_debug= if is_enabled CONFIG_KALLSYMS; then - true > .tmp_vmlinux.kallsyms0.syms - kallsyms .tmp_vmlinux.kallsyms0.syms .tmp_vmlinux0.kallsyms + true > .tmp_vmlinux0.syms + kallsyms .tmp_vmlinux0.syms .tmp_vmlinux0.kallsyms fi if is_enabled CONFIG_KALLSYMS || is_enabled CONFIG_DEBUG_INFO_BTF; then @@ -235,14 +235,14 @@ if is_enabled CONFIG_KALLSYMS; then # Generate section listing all symbols and add it into vmlinux # It's a four step process: # 0) Generate a dummy __kallsyms with empty symbol list. - # 1) Link .tmp_vmlinux.kallsyms1 so it has all symbols and sections, + # 1) Link .tmp_vmlinux1.kallsyms so it has all symbols and sections, # with a dummy __kallsyms. - # Running kallsyms on that gives us .tmp_kallsyms1.o with + # Running kallsyms on that gives us .tmp_vmlinux1.kallsyms.o with # the right size - # 2) Link .tmp_vmlinux.kallsyms2 so it now has a __kallsyms section of + # 2) Link .tmp_vmlinux2.kallsyms so it now has a __kallsyms section of # the right size, but due to the added section, some # addresses have shifted. - # From here, we generate a correct .tmp_vmlinux.kallsyms2.o + # From here, we generate a correct .tmp_vmlinux2.kallsyms.o # 3) That link may have expanded the kernel image enough that # more linker branch stubs / trampolines had to be added, which # introduces new names, which further expands kallsyms. Do another -- cgit From cdd30ebb1b9f36159d66f088b61aee264e649d7a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 2 Dec 2024 15:59:47 +0100 Subject: module: Convert symbol namespace to string literal Clean up the existing export namespace code along the same lines of commit 33def8498fdd ("treewide: Convert macro and uses of __section(foo) to __section("foo")") and for the same reason, it is not desired for the namespace argument to be a macro expansion itself. Scripted using git grep -l -e MODULE_IMPORT_NS -e EXPORT_SYMBOL_NS | while read file; do awk -i inplace ' /^#define EXPORT_SYMBOL_NS/ { gsub(/__stringify\(ns\)/, "ns"); print; next; } /^#define MODULE_IMPORT_NS/ { gsub(/__stringify\(ns\)/, "ns"); print; next; } /MODULE_IMPORT_NS/ { $0 = gensub(/MODULE_IMPORT_NS\(([^)]*)\)/, "MODULE_IMPORT_NS(\"\\1\")", "g"); } /EXPORT_SYMBOL_NS/ { if ($0 ~ /(EXPORT_SYMBOL_NS[^(]*)\(([^,]+),/) { if ($0 !~ /(EXPORT_SYMBOL_NS[^(]*)\(([^,]+), ([^)]+)\)/ && $0 !~ /(EXPORT_SYMBOL_NS[^(]*)\(\)/ && $0 !~ /^my/) { getline line; gsub(/[[:space:]]*\\$/, ""); gsub(/[[:space:]]/, "", line); $0 = $0 " " line; } $0 = gensub(/(EXPORT_SYMBOL_NS[^(]*)\(([^,]+), ([^)]+)\)/, "\\1(\\2, \"\\3\")", "g"); } } { print }' $file; done Requested-by: Masahiro Yamada Signed-off-by: Peter Zijlstra (Intel) Link: https://mail.google.com/mail/u/2/#inbox/FMfcgzQXKWgMmjdFwwdsfgxzKpVHWPlc Acked-by: Greg KH Signed-off-by: Linus Torvalds --- scripts/coccinelle/misc/add_namespace.cocci | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/misc/add_namespace.cocci b/scripts/coccinelle/misc/add_namespace.cocci index cbf1614163cb..d66c4e3cd946 100644 --- a/scripts/coccinelle/misc/add_namespace.cocci +++ b/scripts/coccinelle/misc/add_namespace.cocci @@ -13,7 +13,7 @@ virtual report declarer name MODULE_IMPORT_NS; identifier virtual.ns; @@ -MODULE_IMPORT_NS(ns); +MODULE_IMPORT_NS("ns"); // Add missing imports, but only adjacent to a MODULE_LICENSE statement. // That ensures we are adding it only to the main module source file. @@ -23,7 +23,7 @@ expression license; identifier virtual.ns; @@ MODULE_LICENSE(license); -+ MODULE_IMPORT_NS(ns); ++ MODULE_IMPORT_NS("ns"); // Dummy rule for report mode that would otherwise be empty and make spatch // fail ("No rules apply.") -- cgit From 62aa6f2ede976dfb3539e59ee55c62cfd3c3faa3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 3 Dec 2024 19:21:05 +0900 Subject: scripts/nsdeps: get 'make nsdeps' working again Since commit cdd30ebb1b9f ("module: Convert symbol namespace to string literal"), when MODULE_IMPORT_NS() is missing, 'make nsdeps' inserts pointless code: MODULE_IMPORT_NS("ns"); Here, "ns" is not a namespace, but the variable in the semantic patch. It must not be quoted. Instead, a string literal must be passed to Coccinelle. Fixes: cdd30ebb1b9f ("module: Convert symbol namespace to string literal") Signed-off-by: Masahiro Yamada Signed-off-by: Linus Torvalds --- scripts/coccinelle/misc/add_namespace.cocci | 4 ++-- scripts/nsdeps | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/misc/add_namespace.cocci b/scripts/coccinelle/misc/add_namespace.cocci index d66c4e3cd946..cbf1614163cb 100644 --- a/scripts/coccinelle/misc/add_namespace.cocci +++ b/scripts/coccinelle/misc/add_namespace.cocci @@ -13,7 +13,7 @@ virtual report declarer name MODULE_IMPORT_NS; identifier virtual.ns; @@ -MODULE_IMPORT_NS("ns"); +MODULE_IMPORT_NS(ns); // Add missing imports, but only adjacent to a MODULE_LICENSE statement. // That ensures we are adding it only to the main module source file. @@ -23,7 +23,7 @@ expression license; identifier virtual.ns; @@ MODULE_LICENSE(license); -+ MODULE_IMPORT_NS("ns"); ++ MODULE_IMPORT_NS(ns); // Dummy rule for report mode that would otherwise be empty and make spatch // fail ("No rules apply.") diff --git a/scripts/nsdeps b/scripts/nsdeps index bab4ec870e50..a3372166ac01 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -21,7 +21,7 @@ fi generate_deps_for_ns() { $SPATCH --very-quiet --in-place --sp-file \ - $srctree/scripts/coccinelle/misc/add_namespace.cocci -D nsdeps -D ns=$1 $2 + $srctree/scripts/coccinelle/misc/add_namespace.cocci -D nsdeps -D ns=\"$1\" $2 } generate_deps() { -- cgit