From nobody Fri Oct 2 11:42:16 2026 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 65F9C3932DC for ; Sat, 1 Aug 2026 14:52:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785595976; cv=none; b=BbsvDjqYfQvnuw6V6pqgFac0+1F8OIMSvDhPwwXQG13p8nqZsSbI5cDVAo8beF9a2A0VagVDylKn7SfwlaqDcPCp+gKl1a68kZPPEdD31ecpL8/P2tq9NhddwajMx4/eEIs/+Pe9gRLCG/isi0/6vrJLMV9cGMzxIZ9i5LRESTk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785595976; c=relaxed/simple; bh=Vttuw5du2HyON+new+LEsXAblA6lU3qKSJM0dWQzcok=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=gU72rv7BFPXBJalPLDOXkhU+p19gMEWo7Np193UM3aCEGKLH3+yID13MxAgRwinVEZuA2oLnSu7b0cSIOR1CgnA7PVsyt785Q0DZMl9d5Pj+opyywMTY6IETReNhWO6zPSx6tgqE7FubYMkPSSvvbOeCoQIdln19SDoGQ12wHqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IJe02nxj; arc=none smtp.client-ip=209.85.128.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IJe02nxj" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-4980dc26022so2999165e9.1 for ; Sat, 01 Aug 2026 07:52:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785595969; x=1786200769; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:sender:from:to:cc:subject:date:message-id:reply-to :content-type; bh=0uL7BQNezkocW6jWA2Bv2TxHluVpydRqBfpvgiVgWdA=; b=IJe02nxjVeuq7r2jqNbET0jDbmwzWMqXRuLec9McVsvS4JiKP+wARBN6bWrSRoG9iy v5UO9JwoMvofcV6JifXG+Aiy82dYXVUxZoooIydCuXPnf2mAKsmC1lpBVgFHDYl9ertK T4Rwlj6mY2S7eZ8u2dB/CXrAhIYO5heDEc+ncMM4qgmBGFVKAgrqzppx7MjnMEHzlp5R xeUWG55EzovI/xp+zO2N5ymddg4JLZC19mtCuEBvKXjyxsxI+zQLfEGjQy2ZpfieHzE5 XkNMDOlIaSf82JF5TI5RRB+NaIIHMnIpAKnSp3R0b+TdauDgWKDWrV81+2+u7rzLtPxj e6DA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785595969; x=1786200769; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:sender:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=0uL7BQNezkocW6jWA2Bv2TxHluVpydRqBfpvgiVgWdA=; b=cIHPDEpex+KDvyRRK38W+7o9V/7MBGiHtmmz9zwFRgzdXrpmTx4F1zs1w8u910eZHr WWVvT5MHTnQ8788XRLMA1u+AyIm0UK/thucprt5LS7ozvc8uLsrTSlO3fE+CX5XetPeB lZHaYg6YbC047YtOy/KmHNdmIwsJOzLJcLLQ81LBB1jQOk9296XH6bjk+r2IrVHqxx5i E4xnDjIa0gBaZuc4Yd6A7390Ou2qdqKxF2g/mVkSjCOe3kl4pGwrLdEwXfPkIlgvzXdb WC+LBLOszAb4mKWSSGASds3J5ckWJwtvfoSj8ERXzJnss67HBJzKP0wpHOqi88leK++D pwrw== X-Forwarded-Encrypted: i=1; AHgh+RqewDx81RM46uPkfXoQ4PQcGLb8BYPsAtFpgyk7uZF0d2ELqZ5DFShSZifmqGZTbEIbOAb/wfAsKI3I9Do=@vger.kernel.org X-Gm-Message-State: AOJu0YwOzjUCx1L25Ri8Kbn8A166K3Duwtyof2pTKizfS02ksvxMwENN xZTXouqWCEF4Ecu+yaV7ubJomwE+s4xQ4is9ylvvA8/KmPYZGA0ZtMma X-Gm-Gg: AR+sD10YX3tJi4Xi6fdNHfTvYLl2/4/smeJPko8/olU+bHbyNxz46aaH9nn/yTjvJyN 4GX8x7OQQWDE/mC3vronxOHIH5phVCThatP8JsdkrEmLSVTbKg2+mFOepM03H37KwGKeF1bN7O6 fJHVsafeI83838CW9Hcn9Jl6opoYH9ab+BFRqhRe19Nyh2pUP6P9aX9yxCkNObEzWx+0vrWglab 31w7GWL1xCXnu7XxBB728xc9rXA1ipgIM6w24746dC49/tpIRqZBMI+eNe6KV5V0FI6arEGksSz 9t+rVMercjfSycHP57Cap7gSSgrmQfyMCgKbJxyxJCccD9UeeeHXgCWJYq0Xc081zBdiL5M7ihM Z5DS6MjmCwtD5d7cTfrLtimXDyPpwA0T5RTUnOKO66JuWf56D4P26sk0hjkG/KAPCbscuNQjeO0 jU48TIu05b5XEPz30QCNoDNOdrxYnoqu5zIrXiYNK3bNEP4R+ahbXVFXF9y8X/w1wDrmqtYn+l2 fi8uiCld09cehaRsKgn+H6p1jfA8Rt1AOuAQnrY8CL0EzkKLrFb X-Received: by 2002:a05:600c:4f84:b0:496:bbcb:b0bb with SMTP id 5b1f17b1804b1-4980c674e31mr58378605e9.18.1785595969102; Sat, 01 Aug 2026 07:52:49 -0700 (PDT) Received: from nixos-office (195-23-151-163.net.novis.pt. [195.23.151.163]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49808199a68sm42880765e9.4.2026.08.01.07.52.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Aug 2026 07:52:48 -0700 (PDT) Sender: Julian Braha From: Julian Braha To: nathan@kernel.org, nsc@kernel.org, kees@kernel.org Cc: xry111@xry111.site, hyc.lee@gmail.com, jeffbai@aosc.io, vegard.nossum@oracle.com, rdunlap@infradead.org, grahamr@qti.qualcomm.com, nico@fluxnic.net, masahiroy@kernel.org, linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, Julian Braha Subject: [PATCH v2] kconfig: fix submenu rendering of negative dependencies Date: Sat, 1 Aug 2026 15:52:38 +0100 Message-ID: <20260801145238.2140291-1-julianbraha@gmail.com> X-Mailer: git-send-email 2.55.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Kconfig frontend should render options that depend on a previous option in the submenu of that previous option. But currently, this breaks for negative dependencies. For example, option FOO may be rendered in the submenu of option BAR, despite FOO actually depending on !BAR. Let's fix this ironic rendering by modifying Kconfig to explicitly check negative dependencies. I've only tested locally on x86, but as far as I can tell, this only changes how 2 options are rendered in the menu: 1. NTFS3_FS, no longer in the NTFS_FS submenu, and 2. MTD_BLOCK_RO, no longer in the MTD_BLOCK submenu. Tested-by: Nathan Chancellor Reported-by: Xi Ruoyao Closes: https://lore.kernel.org/all/cbe95c15d2760f6fce8eaf207c969ce8fd3703a= a.camel@xry111.site/ Assisted-by: Claude:claude-4.8-opus Signed-off-by: Julian Braha Reviewed-by: Nicolas Schier Tested-by: Nicolas Schier --- Changes since v1: - made commit message self-contained - moved the issue link to the trailers - add Nathan's tested-by and Xi's reported-by tags=20 Link to v1: https://lore.kernel.org/all/20260721193028.313342-1-julianbraha@gmail.com/ --- scripts/kconfig/expr.c | 33 +++++++++++++++++++++++++++++++++ scripts/kconfig/expr.h | 1 + scripts/kconfig/menu.c | 10 ++++++++++ 3 files changed, 44 insertions(+) diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 16f92c4a775a..2b91d16bf14f 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -738,6 +738,39 @@ bool expr_contains_symbol(struct expr *dep, struct sym= bol *sym) return false; } =20 +/* + * Check if the expression references 'sym' in a way that is satisfiable + * with 'sym' disabled, e.g.'sym!=3Dy'. + * + * Expects that expr_transform() was already called on 'expr'. + */ +bool expr_contains_symbol_negated(struct expr *dep, struct symbol *sym) +{ + if (!dep) + return false; + + switch (dep->type) { + case E_AND: + case E_OR: + return expr_contains_symbol_negated(dep->left.expr, sym) || + expr_contains_symbol_negated(dep->right.expr, sym); + case E_NOT: + return dep->left.expr->type =3D=3D E_SYMBOL && + dep->left.expr->left.sym =3D=3D sym; + case E_EQUAL: + /* sym=3Dn */ + return dep->left.sym =3D=3D sym && dep->right.sym =3D=3D &symbol_no; + case E_UNEQUAL: + /* sym!=3Dy, sym!=3Dm */ + return dep->left.sym =3D=3D sym && + (dep->right.sym =3D=3D &symbol_yes || + dep->right.sym =3D=3D &symbol_mod); + default: + break; + } + return false; +} + bool expr_depends_symbol(struct expr *dep, struct symbol *sym) { if (!dep) diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index fa3823a97d72..b580f9fa0f29 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -307,6 +307,7 @@ tristate expr_calc_value(struct expr *e); struct expr *expr_eliminate_dups(struct expr *e); struct expr *expr_transform(struct expr *e); bool expr_contains_symbol(struct expr *dep, struct symbol *sym); +bool expr_contains_symbol_negated(struct expr *dep, struct symbol *sym); bool expr_depends_symbol(struct expr *dep, struct symbol *sym); struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struc= t symbol *sym); =20 diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index b2d8d4e11e07..9c079e92a9ed 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -428,9 +428,19 @@ static void _menu_finalize(struct menu *parent, bool i= nside_choice) if (!expr_contains_symbol(dep, sym)) /* No dependency, quit */ break; + /* + * Note that it's actually possible to depend on both + * 'SYM!=3Dy' and 'SYM=3Dy', so we need to first check if + * it's a positive dependency before checking if it's + * a negative dependency. See example: + * 'SFC && MTD && !(SFC=3Dy && MTD=3Dm)' + */ if (expr_depends_symbol(dep, sym)) /* Absolute dependency, put in submenu */ goto next; + if (expr_contains_symbol_negated(dep, sym)) + /* Negative dependency, quit */ + break; =20 /* * Also consider it a dependency on sym if our --=20 2.55.0