kconfig: fix infinite loop in sym_calc_choice()
Since commitf79dc03fe6
("kconfig: refactor choice value calculation"), Kconfig for ARCH=powerpc may result in an infinite loop. This occurs because there are two entries for POWERPC64_CPU in a choice block. If the same symbol appears twice in a choice block, the ->choice_link node is added twice to ->choice_members, resulting a corrupted linked list. A simple test case is: choice prompt "choice" config A bool "A" config B bool "B 1" config B bool "B 2" endchoice Running 'make defconfig' results in an infinite loop. One solution is to replace the current two entries: config POWERPC64_CPU bool "Generic (POWER5 and PowerPC 970 and above)" depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN select PPC_64S_HASH_MMU config POWERPC64_CPU bool "Generic (POWER8 and above)" depends on PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN select ARCH_HAS_FAST_MULTIPLIER select PPC_64S_HASH_MMU select PPC_HAS_LBARX_LHARX with the following single entry: config POWERPC64_CPU bool "Generic 64 bit powerpc" depends on PPC_BOOK3S_64 select ARCH_HAS_FAST_MULTIPLIER if CPU_LITTLE_ENDIAN select PPC_64S_HASH_MMU select PPC_HAS_LBARX_LHARX if CPU_LITTLE_ENDIAN In my opinion, the latter looks cleaner, but PowerPC maintainers may prefer to display different prompts depending on CPU_LITTLE_ENDIAN. For now, this commit fixes the issue in Kconfig, restoring the original behavior. I will reconsider whether such a use case is worth supporting. Fixes:f79dc03fe6
("kconfig: refactor choice value calculation") Reported-by: Marco Bonelli <marco@mebeim.net> Closes: https://lore.kernel.org/all/1763151587.3581913.1727224126288@privateemail.com/ Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
This commit is contained in:
parent
7fb1d1e038
commit
4d46b5b623
@ -159,8 +159,14 @@ config_stmt: config_entry_start config_option_list
|
|||||||
yynerrs++;
|
yynerrs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_add_tail(¤t_entry->sym->choice_link,
|
/*
|
||||||
¤t_choice->choice_members);
|
* If the same symbol appears twice in a choice block, the list
|
||||||
|
* node would be added twice, leading to a broken linked list.
|
||||||
|
* list_empty() ensures that this symbol has not yet added.
|
||||||
|
*/
|
||||||
|
if (list_empty(¤t_entry->sym->choice_link))
|
||||||
|
list_add_tail(¤t_entry->sym->choice_link,
|
||||||
|
¤t_choice->choice_members);
|
||||||
}
|
}
|
||||||
|
|
||||||
printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
|
printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
|
||||||
|
Loading…
Reference in New Issue
Block a user