• Masahiro Yamada's avatar
    kconfig: fix missing choice values in auto.conf · 8e2442a5
    Masahiro Yamada authored
    Since commit 00c864f8 ("kconfig: allow all config targets to write
    auto.conf if missing"), Kconfig creates include/config/auto.conf in the
    defconfig stage when it is missing.
    
    Joonas Kylmälä reported incorrect auto.conf generation under some
    circumstances.
    
    To reproduce it, apply the following diff:
    
    |  --- a/arch/arm/configs/imx_v6_v7_defconfig
    |  +++ b/arch/arm/configs/imx_v6_v7_defconfig
    |  @@ -345,14 +345,7 @@ CONFIG_USB_CONFIGFS_F_MIDI=y
    |   CONFIG_USB_CONFIGFS_F_HID=y
    |   CONFIG_USB_CONFIGFS_F_UVC=y
    |   CONFIG_USB_CONFIGFS_F_PRINTER=y
    |  -CONFIG_USB_ZERO=m
    |  -CONFIG_USB_AUDIO=m
    |  -CONFIG_USB_ETH=m
    |  -CONFIG_USB_G_NCM=m
    |  -CONFIG_USB_GADGETFS=m
    |  -CONFIG_USB_FUNCTIONFS=m
    |  -CONFIG_USB_MASS_STORAGE=m
    |  -CONFIG_USB_G_SERIAL=m
    |  +CONFIG_USB_FUNCTIONFS=y
    |   CONFIG_MMC=y
    |   CONFIG_MMC_SDHCI=y
    |   CONFIG_MMC_SDHCI_PLTFM=y
    
    And then, run:
    
    $ make ARCH=arm mrproper imx_v6_v7_defconfig
    
    You will see CONFIG_USB_FUNCTIONFS=y is correctly contained in the
    .config, but not in the auto.conf.
    
    Please note drivers/usb/gadget/legacy/Kconfig is included from a choice
    block in drivers/usb/gadget/Kconfig. So USB_FUNCTIONFS is a choice value.
    
    This is probably a similar situation described in commit beaaddb6
    ("kconfig: tests: test defconfig when two choices interact").
    
    When sym_calc_choice() is called, the choice symbol forgets the
    SYMBOL_DEF_USER unless all of its choice values are explicitly set by
    the user.
    
    The choice symbol is given just one chance to recall it because
    set_all_choice_values() is called if SYMBOL_NEED_SET_CHOICE_VALUES
    is set.
    
    When sym_calc_choice() is called again, the choice symbol forgets it
    forever, since SYMBOL_NEED_SET_CHOICE_VALUES is a one-time aid.
    Hence, we cannot call sym_clear_all_valid() again and again.
    
    It is crazy to repeat set and unset of internal flags. However, we
    cannot simply get rid of "sym->flags &= flags | ~SYMBOL_DEF_USER;"
    Doing so would re-introduce the problem solved by commit 5d09598d
    ("kconfig: fix new choices being skipped upon config update").
    
    To work around the issue, conf_write_autoconf() stopped calling
    sym_clear_all_valid().
    
    conf_write() must be changed accordingly. Currently, it clears
    SYMBOL_WRITE after the symbol is written into the .config file. This
    is needed to prevent it from writing the same symbol multiple times in
    case the symbol is declared in two or more locations. I added the new
    flag SYMBOL_WRITTEN, to track the symbols that have been written.
    
    Anyway, this is a cheesy workaround in order to suppress the issue
    as far as defconfig is concerned.
    
    Handling of choices is totally broken. sym_clear_all_valid() is called
    every time a user touches a symbol from the GUI interface. To reproduce
    it, just add a new symbol drivers/usb/gadget/legacy/Kconfig, then touch
    around unrelated symbols from menuconfig. USB_FUNCTIONFS will disappear
    from the .config file.
    
    I added the Fixes tag since it is more fatal than before. But, this
    has been broken since long long time before, and still it is.
    We should take a closer look to fix this correctly somehow.
    
    Fixes: 00c864f8 ("kconfig: allow all config targets to write auto.conf if missing")
    Cc: linux-stable <stable@vger.kernel.org> # 4.19+
    Reported-by: default avatarJoonas Kylmälä <joonas.kylmala@iki.fi>
    Signed-off-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
    Tested-by: default avatarJoonas Kylmälä <joonas.kylmala@iki.fi>
    8e2442a5
confdata.c 27.7 KB