From nobody Mon Jun 8 06:36:53 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D622B3F7ABE; Fri, 5 Jun 2026 12:04:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661046; cv=none; b=SB1L3jGb30OoQgDLDA1FfSjxbu9T27KEmpUtB4gw3S17/DHSYPzSHlN9jm50JKJPFAfeP/cv9/EEnYrY1nMsjAnTVc2b0kJyJO4XhdZ14d25b6dVd80UiF0hFpodQe/nqzduibzDLPIbMaOEKPZKw/4aghAy9LW02FFTsgg0FL4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661046; c=relaxed/simple; bh=EAWSBZHUbvF+BebKTrcH7f4eYwq+NcrjSdvoq/taW5o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZoxM1korA17qvFrTvUJaYFs4MSvLm2X1Fyuh3fDJPPTDdmT9uLDeLh9yI7jgLe01WwgVgCjKbM3Pd1ai4NUQfNuf/gwD7lSUoERtYivgbCySntE2Je1cyqN0fGg60on6XHHK2pcxZPYoZUnNteiQR/mbPSEziOIb4KcoQPXPqPY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=ITRYmA44; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="ITRYmA44" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=pBa18RzXk1ANKaCmnnGIArgni6qzEnHSHRPoGBtodfY=; b=ITRYmA44/zI/GMI+pN0J2KYDDJ BAVFYOAR+cFwwESFEugIvcQd741ieXKFE+BruQdE/POfzyC5gk4pzg5b1pGk4x7ga+vZnbdQPUQgO Me/kj8fqiT6qVlv6wQiVNlYdoXZOMvlhPWMEerpbgQ3lBTGpwaqVunbX2ND+Pvakv1gHTaCx10F6w gjUrt8QzMXov6lDf+xevGM7j78uK+YKsXuBiIa0td9HSq81LXEn38WlXOnPJimHrhHLLZlRWsH5Wk tGOPIZV1njnUw4qWynLnh08/C6MEVJjU3WKDgwirmbn+VgTBe+V7Yt5QqjSae/Ou6q7rOJhhQlhJy GhRd5hGg==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wVTHG-005HGz-1r; Fri, 05 Jun 2026 12:03:54 +0000 From: Breno Leitao Date: Fri, 05 Jun 2026 05:03:32 -0700 Subject: [PATCH v2 1/6] bootconfig: fix NULL-pointer arithmetic in xbc_snprint_cmdline() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260605-bootconfig_using_tools-v2-1-d309f544b5f7@debian.org> References: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> In-Reply-To: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> To: Masami Hiramatsu , Andrew Morton , Nathan Chancellor , paulmck@kernel.org, Nicolas Schier Cc: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3059; i=leitao@debian.org; h=from:subject:message-id; bh=EAWSBZHUbvF+BebKTrcH7f4eYwq+NcrjSdvoq/taW5o=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqIrsf5U0d8IB5M6BXmxOmCe+JLmQ6LX0iXZrj4 IgfUMlBYNuJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaiK7HwAKCRA1o5Of/Hh3 bdbVD/92AKAbzkJE1onq0ANafyihWaN6bWblIBx9O+HhwipD5Ix70DxIhOkWYPcSeeb12ZYdKnq G52xfWd/mZV89ghFZmkFXQWzf1tPGad03mfki4CL0U2onRA75lKqKXmBWUIKm4YApTkZ/T4HV5s Bws9cJ5+1MyGTh7cUm2UDpFGAiL4f20Q9GDEVyQz2DblfHJHCD0ZMQd6ICojxH1GjRALKMBLg5x /ex9HRLGbSLuzg378UNy3hHwFc2AmTCztGjk48y7D9cmHuoWAylWX5bMgeBQyRrAnSLjkfPAPcF 7dvvGWjNC+XNJUp+6fBvA0rzHhZvi7PtMdQ6eMT4r3aQmZ6z0Y0Pp1wV/pI3HfKwOPvmn5Vr75o 55gr191rqw3b2JBV9g9oZCKWPyxpQPY5ol5glqLc3fY9ZJiZ4SjKznkLaDwYg59WmpwPmJQQ8MD RE5pMJX0kfKLZamCwX1MKTGNQhMTNK3amvjj2xdD3xfRbBaba0CMoNMUvde666ms7NKByU9tq3g I6YGTFYrSPO3fxnl9DHo5rm68l4QzEaapHpb2GhiIO7SBEzkRtA4J8k030bJd6Pjowhe2WO5eWs SWJz0zXFpMZ7+WIf21W2+M+xPIx/cxTbk6MyNj3zXp4hgwKF+nexnYaqrKloO9+KSmlX9v4A7oG GfIiD5Htw1n9qBw== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao xbc_snprint_cmdline() is meant to be called twice: first with buf=3DNULL, size=3D0 to probe the rendered length, then with a real buffer to fill it (the standard snprintf() two-pass pattern). The probe call makes the function compute "buf + size" (NULL + 0) and, on every iteration, advance "buf +=3D ret" from that NULL base and pass the result back into snprintf(). Pointer arithmetic on a NULL pointer is undefined behavior. It is harmless in the in-kernel callers today, but the follow-up patches run this same code in the userspace tools/bootconfig parser at kernel build time, where host UBSan / FORTIFY_SOURCE abort the build. Track a running written length (size_t) instead of mutating @buf, and only form "buf + len" when @buf is non-NULL. snprintf(NULL, 0, ...) is itself well defined and returns the would-be length, so the two-pass "probe then fill" usage returns identical byte counts. Signed-off-by: Breno Leitao --- lib/bootconfig.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/bootconfig.c b/lib/bootconfig.c index f445b7703fdd..2ed9ee3dc81c 100644 --- a/lib/bootconfig.c +++ b/lib/bootconfig.c @@ -427,10 +427,18 @@ static char xbc_namebuf[XBC_KEYLEN_MAX] __initdata; int __init xbc_snprint_cmdline(char *buf, size_t size, struct xbc_node *ro= ot) { struct xbc_node *knode, *vnode; - char *end =3D buf + size; const char *val, *q; + size_t len =3D 0; int ret; =20 + /* + * Track the running written length rather than advancing @buf, so we + * never form "buf + size" or "buf +=3D ret" while @buf is NULL (the + * size-probe call passes buf=3DNULL, size=3D0). NULL pointer arithmetic + * is undefined behavior and trips host UBSan / FORTIFY_SOURCE when + * this renderer runs at kernel build time. snprintf(NULL, 0, ...) + * itself is well defined and returns the would-be length. + */ xbc_node_for_each_key_value(root, knode, val) { ret =3D xbc_node_compose_key_after(root, knode, xbc_namebuf, XBC_KEYLEN_MAX); @@ -439,10 +447,11 @@ int __init xbc_snprint_cmdline(char *buf, size_t size= , struct xbc_node *root) =20 vnode =3D xbc_node_get_child(knode); if (!vnode) { - ret =3D snprintf(buf, rest(buf, end), "%s ", xbc_namebuf); + ret =3D snprintf(buf ? buf + len : NULL, rest(len, size), + "%s ", xbc_namebuf); if (ret < 0) return ret; - buf +=3D ret; + len +=3D ret; continue; } xbc_array_for_each_value(vnode, val) { @@ -452,15 +461,15 @@ int __init xbc_snprint_cmdline(char *buf, size_t size= , struct xbc_node *root) * whitespace. */ q =3D strpbrk(val, " \t\r\n") ? "\"" : ""; - ret =3D snprintf(buf, rest(buf, end), "%s=3D%s%s%s ", - xbc_namebuf, q, val, q); + ret =3D snprintf(buf ? buf + len : NULL, rest(len, size), + "%s=3D%s%s%s ", xbc_namebuf, q, val, q); if (ret < 0) return ret; - buf +=3D ret; + len +=3D ret; } } =20 - return buf - (end - size); + return len; } #undef rest =20 --=20 2.53.0-Meta From nobody Mon Jun 8 06:36:53 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D101B3B71D0; Fri, 5 Jun 2026 12:04:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661047; cv=none; b=rv+KoZByOy0I+itOJvjuzJ45wzLvNaUJ0xqInzxAhDbyKcZU5dgcM+VDJYvPB6qbzAI8Z8ZVEoRWtrhuyYlUsBtZ9LUtCIMV8LZy/jTQaPmPXkLNJS3Wz549v4xvaFuBm53FJiDKS4wQumIytTL93pLfjiq7P8eb5JkIABEcLhQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661047; c=relaxed/simple; bh=BXM/BFTpXoNCSM4CwFdmj+8+KMuxV3hQSRoT1Izhr7c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bHV5E8FmVcK/guaNu0etbWojcw1DZUTQlEHNY6hG9iDzOnQsVqN0NnUMfb04M4SLF/9YMrAQewZSG+DD8FCPaIEcf8OGUnAyquvPhqrxvCMbkZwqYNSgfZoLaS8xrd2xM3yLseC2fIYxpvRr8zbuJ7stHdcP0UDLRfYok8jempE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=nygw1lug; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="nygw1lug" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=YgzIlvI5ADPZKpxArpAL5pQC0m+dtwWvGtJdhHuopts=; b=nygw1lugL1LkfbD3y977OiGZQQ 5Vtj9DLyXl70In7mDoEgs/znfVA4arJnbuSg9dnsY/yy/VzWVaqG7xm2khPwsGqJ/sf20LwRFxpno TNoUwaRX7rKPsYbvaLiC+odi5ti444Ocq6wsJfRuOwDmS4PsR+rBfk7ZkCT3aH9jRtw3ooP8aFPgZ Qr5JMLRDSqCifCqsU1nzlJeX+et34Q7A0n9cGJODSYRrKYaR2rb6vMPToJn2RtuE07MTwU7oJYzTp IZ2pATY8pfb4EYoEyRl4FNZ9hIJbi2T4g4w4oaQZCcBSZkc+e0iLRYKwCpRnd7Rw6K9UbfInqapCl T/RUlJ3g==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wVTHL-005HHU-1I; Fri, 05 Jun 2026 12:03:59 +0000 From: Breno Leitao Date: Fri, 05 Jun 2026 05:03:33 -0700 Subject: [PATCH v2 2/6] bootconfig: render descendant keys when xbc_snprint_cmdline() root has a value Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260605-bootconfig_using_tools-v2-2-d309f544b5f7@debian.org> References: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> In-Reply-To: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> To: Masami Hiramatsu , Andrew Morton , Nathan Chancellor , paulmck@kernel.org, Nicolas Schier Cc: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2222; i=leitao@debian.org; h=from:subject:message-id; bh=BXM/BFTpXoNCSM4CwFdmj+8+KMuxV3hQSRoT1Izhr7c=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqIrsfRax59+wfTKP/O7+/5PyZwhSzfjN4RSWfM Ik0wn+jiTKJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaiK7HwAKCRA1o5Of/Hh3 bUv/D/9Tt0I9Rwc1PXTI+uDSz9VNHFCyjd8vhaaA+AfUGmFjRMT9J2r8k0r3ilhjXvt1/Wf/vNb zd6Sd98nqYxRtA8HjD6CVHrw0ehp+pgQL/hn6kMdrgL2OJEQAr+b7aIZVmhLHned0t8LXAmuZa2 2Ey7tezfvrqXuIgptRU3z/O5JExY38mckaQzlMcf7XPJoTI0BQDIeBlMUzf72OyDJqku4CMf2Oz vPnnZE45wif0s7zCTPXVK7FsBnT21fCExJPkoyTiPniq5YJOu97GH1C6CuDLWrRq2JvNGpqtho+ jF5S4DU/zzKlaFzeQJQevG1sYsAKUG1aG2tDkZ+DnDzdQrL2SMs2hO2DH4D2AUwf43WXWrW1CVN tQYyLxH4xABMZzZOQwQNTVy0Iu0NKt5ExZGMQoGm5eCL+NRHWqULs4fHTvVUZvfZBY1nTkIXhWr 9K+5DOJ4RsDzr3oTH4x/CX2dCBpS2llh5ZW+alU58HE7KWRUIi3Rv+wigwmLeOAb8LuoHBCwM3z gBphTZ33/zBiX4+7ITfBIfH1EvGbDJ2OB6FalIuupxwphHqiwdTLKG81daFBJmaBGol0fjQlhcX uivO5DMHFF8HTYtaHALaSvG1BTMIcYl9yjCSjWe13grgIXycc6sBYsOgEVbtxvqDwEtTUYtsuf0 dKgmgfg4Hs97d7w== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao xbc_node_for_each_key_value() walks to the first leaf under @root, and when @root is itself a leaf it yields @root. That happens not only for an empty "kernel {}" subtree, but also when @root carries both a value and subkeys, e.g. kernel =3D x kernel.foo =3D bar Here @root ("kernel") is a leaf because its first child is the value node "x", so the iterator returns @root first. Feeding @root back into xbc_node_compose_key_after(root, root) returns -EINVAL, which the only in-kernel caller papers over with a "len <=3D 0" check -- but the follow-up tools/bootconfig -C user propagates the error and turns such a bootconfig into a build failure. Worse, short-circuiting the whole call on a leaf @root would silently drop the valid "kernel.foo =3D bar" descendant that the pre-existing code rendered. Skip @root inside the loop instead of bailing out: the value-only entry is dropped (it is rendered through the "kernel" cmdline path, not here), while real descendant keys are still emitted. An entirely empty subtree now renders nothing and returns 0 rather than -EINVAL, matching the "nothing to render is not an error" semantics expected by the new build-time caller. Signed-off-by: Breno Leitao --- lib/bootconfig.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/bootconfig.c b/lib/bootconfig.c index 2ed9ee3dc81c..926094d97397 100644 --- a/lib/bootconfig.c +++ b/lib/bootconfig.c @@ -440,6 +440,17 @@ int __init xbc_snprint_cmdline(char *buf, size_t size,= struct xbc_node *root) * itself is well defined and returns the would-be length. */ xbc_node_for_each_key_value(root, knode, val) { + /* + * An empty or value-only @root (e.g. "kernel {}" or + * "kernel =3D x", possibly alongside "kernel.foo =3D bar") + * yields @root itself here. Skip it: composing a key for it + * would fail with -EINVAL, yet any real descendant keys must + * still be rendered. An entirely empty subtree then renders + * nothing and returns 0 rather than an error. + */ + if (knode =3D=3D root) + continue; + ret =3D xbc_node_compose_key_after(root, knode, xbc_namebuf, XBC_KEYLEN_MAX); if (ret < 0) --=20 2.53.0-Meta From nobody Mon Jun 8 06:36:53 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D0E604DA52D; Fri, 5 Jun 2026 12:04:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661055; cv=none; b=dl0RGd/Z8r/ZI+P0I/o+HaIM1JuM/5z3TbtwHvBOTKa7yjEbbFNqmxiJRk8uNWKkXQKbuVmNbROFtvFBow5Kxij4xsk1LSTMBuugv1DvXAVV4GPBzENyxqpnPFIdcPir0pElfIHIFIS/bs9N0v1RJJIwMJKVbnodRwpfpxVKzUU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661055; c=relaxed/simple; bh=slLPjII/YYzG8uebXxPO38rsAzJDoPShfAb4TX0Ty4M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gdenGdR6lP5tn4s6IQsn7aKpWHXc647xF+Z6N65M2JSnDtHUWv/ArNhUduYD2EhF2q2iNy3kwf1n6CKtvWM775l0Qr3mlu/7EvIO4LfMNPwa4viPg3PcDB5W2Lg2R3L5coSbfMjScrmjcA5bqbx7T1fdklXqRvtrYWcg8dm/vkQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=HluiurCM; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="HluiurCM" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=e63u8cSxbTOG7MttvCLiPj4HQCGd9eSdxjzMr9CX6+k=; b=HluiurCM54u2wnPXLfX3693ZWx 0FfPL2vvT0HIn27MrsoFt5Vgf8IaU3EeIckPZPcdHBomszKtbq4fnhadWJBDIikub6w3rLHDlp9li L9TGG5mLmBF9lkxCCahZYwclz08YNEi/ugVNLcSsIfzUW9t7l6OMscOIvxL07KqSAKNnxoGHs+nqf 4yejuqGw4SahmJUutGLYCuFGZxItBZqDVxC2SP535QTYMfcIZHKuJxeP2IRKU7wXWJ4AljT8bznK6 lYGlXnwD1yu3DdOmyO5hXYwe54Ji7N/CPTZHmhC3tszRexjXeP17G6xGf7vCe0VVrGlTqq2D6rTDI GD4ZEc0w==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wVTHQ-005HHe-0Z; Fri, 05 Jun 2026 12:04:04 +0000 From: Breno Leitao Date: Fri, 05 Jun 2026 05:03:34 -0700 Subject: [PATCH v2 3/6] bootconfig: render embedded bootconfig as a kernel cmdline at build time Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260605-bootconfig_using_tools-v2-3-d309f544b5f7@debian.org> References: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> In-Reply-To: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> To: Masami Hiramatsu , Andrew Morton , Nathan Chancellor , paulmck@kernel.org, Nicolas Schier Cc: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=8534; i=leitao@debian.org; h=from:subject:message-id; bh=slLPjII/YYzG8uebXxPO38rsAzJDoPShfAb4TX0Ty4M=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqIrsfqRtONrPL2He67b5vF/k4jg6tn6E77z0HL nVR8BGWXy2JAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaiK7HwAKCRA1o5Of/Hh3 bY5HD/9d5AVwTDHIcWRGcGeDYJD5KuJokOSliR6/5n1YAomaz4KFV368LMzj5QlOxEP015zk+ap c68w5hMNZ7rMPoMPbOW0bi009x26ucoBfxslaANZI5FR+rk2dToKnUKWcFRPZFb1jIvZPGtAaN3 LtSiQc2FUKGCMToDp5Pv5tRZ5iWfYAwykHuG1nLzT6ydN7gW3Pt8pt3ebTSQSYeUr24GzokRP79 LR1Pm5gmVMd9xK2suNKwcDMq4bg9znIpRqA9KFdUX2pre2nGLdxRVZmVZnSih7aeTMggF4QftzI wLaN1oGNIVghxoZq8DAb7LvgBEovRYmiag2TFRnf+r8mnSTGFkLMtQOTraSLfMj03/+KRvzaP9L gFcEjUCO+aP504TAHigpymCJ+wGx1GSIVrqQSrcaJZgl8P8qgRka7cYvNkGdS0ZqoWsqi+e7Cin XnRZKoxU32Qr4Z9NZD6zCpowzwUzJkbHeNCC6+dS5aNHVkCSu25vwTjK638D0na9bQrvTqEbbO0 8MsBvW6Jxq78H52KYSTDQHROVZ5Uodu8TtNJkUhoNZ+dY0wwzCgqCuiiHrMmr6MHKoUUh3cuRUf ewyt2xkRnC9GKFWj3LwXc+OcuFjqREIMXLhBzy4wf9QgG0FqGgYMSl87JQ6il5Xu+ZBtF3eOJQT ZF8X45zUp8pdIpg== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao Add the build-time pipeline that renders the "kernel" subtree of CONFIG_BOOT_CONFIG_EMBED_FILE into a flat cmdline string and stashes it in .init.rodata as embedded_kernel_cmdline[]. A follow-up patch adds the runtime helper that prepends this string to boot_command_line during early architecture setup so parse_early_param() sees the values. The build wires up: tools/bootconfig -C kernel - userspace tool already shared with lib/bootconfig.c, used here in -C mode to render a bootconfig file to a cmdline lib/embedded-cmdline.S - .incbin's the rendered text plus a NUL (listed under the EXTRA BOOT CONFIG MAINTAINERS entry) lib/Makefile rule - runs tools/bootconfig at build time Makefile prepare dep - ensures tools/bootconfig is built first, same pattern as tools/objtool and tools/bpf/resolve_btfids Drop the test target from tools/bootconfig/Makefile's default 'all' recipe so that hooking the binary into the kernel build does not run test-bootconfig.sh on every prepare. The tests stay available as 'make -C tools/bootconfig test', matching the convention of tools/objtool and tools/bpf/resolve_btfids whose 'all' targets only build the binary. Require BOOT_CONFIG_EMBED_FILE to be non-empty before the new option can be enabled, otherwise tools/bootconfig -C runs against an empty file and prints a parse error on every kernel build. The feature gates on CONFIG_ARCH_SUPPORTS_CMDLINE_FROM_BOOTCONFIG, a silent symbol arches select once they've wired the prepend call into setup_arch(). No arch selects it in this patch, so the user-visible CONFIG_BOOT_CONFIG_EMBED_CMDLINE is not yet enableable; when an arch later opts in, the runtime behavior is added by the follow-up patches. tools/bootconfig is compiled with $(HOSTCC), not $(CC): Kbuild exports CC as the target cross-compiler, but the prepare hook runs the tool on the build host, so $(CC) would produce a binary that fails to exec ("Exec format error") under ARCH=3D... cross builds. This mirrors tools/objtool and tools/bpf/resolve_btfids. embedded-cmdline.S places the rendered string in .init.rodata with the "a" (allocatable, read-only) flag and %progbits, not "aw": the data is never written at runtime, so it must not land in a writable section. A follow-up patch wires the build-time tools/bootconfig into the top-level clean target. Signed-off-by: Breno Leitao --- MAINTAINERS | 1 + Makefile | 5 +++++ init/Kconfig | 33 +++++++++++++++++++++++++++++++++ lib/Makefile | 16 ++++++++++++++++ lib/embedded-cmdline.S | 16 ++++++++++++++++ tools/bootconfig/Makefile | 8 ++++++-- 6 files changed, 77 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 4087b67bbc69..fb9314cbe344 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9845,6 +9845,7 @@ F: fs/proc/bootconfig.c F: include/linux/bootconfig.h F: lib/bootconfig-data.S F: lib/bootconfig.c +F: lib/embedded-cmdline.S F: tools/bootconfig/* F: tools/bootconfig/scripts/* =20 diff --git a/Makefile b/Makefile index d59f703f9797..e95992959f44 100644 --- a/Makefile +++ b/Makefile @@ -1543,6 +1543,11 @@ prepare: tools/bpf/resolve_btfids endif endif =20 +# tools/bootconfig renders the embedded bootconfig into a cmdline at build= time. +ifdef CONFIG_BOOT_CONFIG_EMBED_CMDLINE +prepare: tools/bootconfig +endif + # The tools build system is not a part of Kbuild and tends to introduce # its own unique issues. If you need to integrate a new tool into Kbuild, # please consider locating that tool outside the tools/ tree and using the diff --git a/init/Kconfig b/init/Kconfig index ca35184532dc..5f491a5ac4b8 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1569,6 +1569,39 @@ config BOOT_CONFIG_EMBED_FILE This bootconfig will be used if there is no initrd or no other bootconfig in the initrd. =20 +config ARCH_SUPPORTS_CMDLINE_FROM_BOOTCONFIG + bool + help + Selected by architectures whose setup_arch() prepends the + build-time-rendered embedded bootconfig cmdline to + boot_command_line before parse_early_param() runs. + +config BOOT_CONFIG_EMBED_CMDLINE + bool "Render embedded bootconfig as kernel cmdline at build time" + depends on BOOT_CONFIG_EMBED + depends on BOOT_CONFIG_EMBED_FILE !=3D "" + depends on ARCH_SUPPORTS_CMDLINE_FROM_BOOTCONFIG + default n + help + Render the "kernel" subtree of the embedded bootconfig file into a + flat cmdline string at kernel build time and prepend it to + boot_command_line during early architecture setup. This makes + early_param() handlers (e.g. mem=3D, earlycon=3D, loglevel=3D) see the + values supplied via the embedded bootconfig. + + The runtime bootconfig parser is unaffected, so tree-structured + consumers such as ftrace boot-time tracing keep working. + + Note: when an initrd also carries a bootconfig, its "kernel" + subtree is still parsed at runtime, but the embedded "kernel" + keys remain in boot_command_line for parse_early_param() and + end up later than the initrd keys in saved_command_line, so + parse_args() last-wins favors the embedded values. If you need + initrd to override embedded kernel.* keys, leave this option + off. + + If unsure, say N. + config CMDLINE_LOG_WRAP_IDEAL_LEN int "Length to try to wrap the cmdline when logged at boot" default 1021 diff --git a/lib/Makefile b/lib/Makefile index 6e72d2c1cce7..9de0ac7732a2 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -273,6 +273,22 @@ filechk_defbconf =3D cat $(or $(real-prereqs), /dev/nu= ll) $(obj)/default.bconf: $(CONFIG_BOOT_CONFIG_EMBED_FILE) FORCE $(call filechk,defbconf) =20 +obj-$(CONFIG_BOOT_CONFIG_EMBED_CMDLINE) +=3D embedded-cmdline.o +$(obj)/embedded-cmdline.o: $(obj)/embedded_cmdline.bin + +# Render the bootconfig "kernel" subtree to a flat cmdline string using +# the userspace tools/bootconfig parser (-C mode). The runtime prepend +# helper enforces COMMAND_LINE_SIZE at boot, so no build-time size +# check is performed here (COMMAND_LINE_SIZE is an arch header +# constant, not a Kconfig value). +quiet_cmd_render_cmdline =3D BCONF2C $@ + cmd_render_cmdline =3D \ + $(objtree)/tools/bootconfig/bootconfig -C $< > $@ + +targets +=3D embedded_cmdline.bin +$(obj)/embedded_cmdline.bin: $(obj)/default.bconf $(objtree)/tools/bootcon= fig/bootconfig FORCE + $(call if_changed,render_cmdline) + obj-$(CONFIG_RBTREE_TEST) +=3D rbtree_test.o obj-$(CONFIG_INTERVAL_TREE_TEST) +=3D interval_tree_test.o =20 diff --git a/lib/embedded-cmdline.S b/lib/embedded-cmdline.S new file mode 100644 index 000000000000..740d7ad2dc01 --- /dev/null +++ b/lib/embedded-cmdline.S @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Embed the build-time-rendered bootconfig "kernel" subtree as a flat + * cmdline string. setup_arch() prepends this to boot_command_line on + * architectures that select ARCH_SUPPORTS_CMDLINE_FROM_BOOTCONFIG. + * + * Copyright (c) 2026 Meta Platforms, Inc. and affiliates + * Copyright (c) 2026 Breno Leitao + */ + .section .init.rodata, "a", %progbits + .global embedded_kernel_cmdline +embedded_kernel_cmdline: + .incbin "lib/embedded_cmdline.bin" + .byte 0 + .global embedded_kernel_cmdline_end +embedded_kernel_cmdline_end: diff --git a/tools/bootconfig/Makefile b/tools/bootconfig/Makefile index 90eb47c9d8de..aa75a7828685 100644 --- a/tools/bootconfig/Makefile +++ b/tools/bootconfig/Makefile @@ -15,10 +15,14 @@ override CFLAGS +=3D -Wall -g -I$(CURDIR)/include ALL_TARGETS :=3D bootconfig ALL_PROGRAMS :=3D $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) =20 -all: $(ALL_PROGRAMS) test +all: $(ALL_PROGRAMS) =20 +# bootconfig is a build host tool: Kbuild's prepare hook runs it on the +# build machine to render the embedded cmdline, so always compile it with +# $(HOSTCC). Using $(CC) would cross-compile it under ARCH=3D... builds and +# fail to exec on the host ("Exec format error"). $(OUTPUT)bootconfig: main.c include/linux/bootconfig.h $(LIBSRC) - $(CC) $(filter %.c,$^) $(CFLAGS) $(LDFLAGS) -o $@ + $(HOSTCC) $(filter %.c,$^) $(CFLAGS) $(LDFLAGS) -o $@ =20 test: $(ALL_PROGRAMS) test-bootconfig.sh ./test-bootconfig.sh $(OUTPUT) --=20 2.53.0-Meta From nobody Mon Jun 8 06:36:53 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D89EF3EEAC5; Fri, 5 Jun 2026 12:04:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661056; cv=none; b=EbZUFFvnUlHVol7ZUsCnZ4TswHpCpcvfBdmPh7VEbIjcnqsldCaSFzcsG/qk2ESkl1TQCC745IzTf4xHqEZ+lyf5ONInhqQBAPZUFrL8E17gtdJacVeuBR8OcscIXSt5xBIBtIWYY+WBpff7rMFJOrEycuw80il0EjSViJ1dENQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661056; c=relaxed/simple; bh=QLtaJ8xc8uG16z0i8uI3fpxi0eetpfLb5x4494AfSyQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DxIiqH3pupA7MNL8bUWO5M+Rb6Y60/y9UtZWeQ1qXZZ1uwvOHHdKDourQBOT5VGjcPEzsjuQmIsrXwFnh6iNv+A1kmoau+CgarorVbuWfiBBnhJ8+nKrqsbmPsthZV/0qpPvKnLoZ51GpvhWzjPD/9/CB5TpO2JMfARSTQV5c4c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=bF9GNMsg; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="bF9GNMsg" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=uNGt7UQ3hKDQDW7phHSPCK/n9FxMsmhzMnjI9+EEnR4=; b=bF9GNMsg7Sjj0FgHOYeGX7P+jI 05CT4VUcUipogCEPXXr+x1HIw+8a+HfCC8krQ1M4biJNJFXw5dtytXGwnZ8G0p4STXAWsn3Ohn9cv 7/QDJGLlJ2vUefAYUVVEbdv8ZLM0fBLvmeqldxHbrLxsZIbLczuxi8kmgQWDgFoSUPGr5sydjhbh1 XfOLsRgK/cbhdbiOuaARiXYDseDQgd4F1pv7hqpmixhKpSPR5DIsuxmDm28lZQ4WVruNsNOgHb/oK outIjLchPaEUpTcSvs8eSPZyKAcSOLR6yTUKstrG0JTM4YC+CeWH2QwCm2vpCwcHjcMb9ON4EGjUx E6gATjiw==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wVTHV-005HHq-04; Fri, 05 Jun 2026 12:04:09 +0000 From: Breno Leitao Date: Fri, 05 Jun 2026 05:03:35 -0700 Subject: [PATCH v2 4/6] bootconfig: clean build-time tools/bootconfig from make clean Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260605-bootconfig_using_tools-v2-4-d309f544b5f7@debian.org> References: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> In-Reply-To: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> To: Masami Hiramatsu , Andrew Morton , Nathan Chancellor , paulmck@kernel.org, Nicolas Schier Cc: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2499; i=leitao@debian.org; h=from:subject:message-id; bh=QLtaJ8xc8uG16z0i8uI3fpxi0eetpfLb5x4494AfSyQ=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqIrsf3KruBR3AMGJpK5qF9EPKPRwFk2Xw0fXVk hYKWyo3o0qJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaiK7HwAKCRA1o5Of/Hh3 bct2D/9U++USHEnCfjBrk8dUfTq93Fc6wLeWcTew4PC6KL9uwfroetoOIO5GcxKejFqoj/I5uS9 P2iVOqgX+MkqNEsZdLnEK9IrBQjr18egxMZkUzvFUXAadxa2i3TZz2kkYvTVYBXSFH4jjb5Nyzj UEHBNP6EAGr5fP9Gf+SMFbX7aarcBkDAgcmJdsyI4iZQiCr9w0gQf4YAhg2bCGHkuFZAqrjaujD xeBroPeWtz0+p4aSYhb7YbV20+AbCTvil9pV2jQ4YIvdiqoIlAqlJn97ipn+b4OlEzvqu9YYEWD Qw7MQX+xPqWXFgLuZOtb6yDuwFvmk4qiUgktxXhQ+otDL1Zy1Q6Umr4KLSJTHZ40XtOatfMEc7k rpSn5aJ5KpOLcP52bjXCfSQNOVey4LRtxvz86UdOzjbt5Hv332OCEF5EaHIbvV6ANtb9Mraac62 09/A0pqzhtlFOrxQmaLF83CnoeU9jBvr70jArgyqnJAw2uSdXTJuP7g+SRMb/KJVUE797hWLqcU p/b6mpyzrbLaRlADF8z8BkVZiBeMA0XKYWYmah98CB4GHfasKUNNzzHU49q4NgJLqnaHBhx/bqx nU2IOIH11Jxalgl8m2U+7Tivpb3dMhwGmZk+fJS5WjSWgpc/+/tRcgt3kL5Vtee+edaTpTwbqVX bA5Uj/62nU8Er6g== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao The previous patch builds tools/bootconfig during 'make prepare' to render the embedded bootconfig cmdline, but nothing removes it on 'make clean', leaving the compiled tool and its objects behind. Wire a bootconfig_clean hook into the top-level clean target so the compiled tool and its objects are removed by make clean, matching the prepare-wired tools/objtool and tools/bpf/resolve_btfids. The hook runs tools/bootconfig's Makefile via $(MAKE), which the kernel build invokes with -rR (MAKEFLAGS +=3D -rR). -rR drops the built-in $(RM) variable, so the existing "$(RM) -f ..." clean recipe would expand to a bare "-f ..." and fail. Spell the recipe with a literal "rm -f" so it keeps working both standalone and when invoked from Kbuild. Signed-off-by: Breno Leitao --- Makefile | 13 ++++++++++++- tools/bootconfig/Makefile | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e95992959f44..4f31222ff1d1 100644 --- a/Makefile +++ b/Makefile @@ -1574,6 +1574,17 @@ ifneq ($(wildcard $(objtool_O)),) $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=3D$(objtool_O) srctree=3D$= (abs_srctree) $(patsubst objtool_%,%,$@) endif =20 +PHONY +=3D bootconfig_clean + +bootconfig_O =3D $(abspath $(objtree))/tools/bootconfig + +# tools/bootconfig is only built (via the prepare hook above) when +# CONFIG_BOOT_CONFIG_EMBED_CMDLINE is set; skip its clean otherwise. +bootconfig_clean: +ifneq ($(wildcard $(bootconfig_O)),) + $(Q)$(MAKE) -sC $(srctree)/tools/bootconfig O=3D$(bootconfig_O) clean +endif + tools/: FORCE $(Q)mkdir -p $(objtree)/tools $(Q)$(MAKE) O=3D$(abspath $(objtree)) subdir=3Dtools -C $(srctree)/tools/ @@ -1743,7 +1754,7 @@ vmlinuxclean: $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean) =20 -clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean +clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean bootconfi= g_clean =20 # mrproper - Delete all generated files, including .config # diff --git a/tools/bootconfig/Makefile b/tools/bootconfig/Makefile index aa75a7828685..86f1a4e64f04 100644 --- a/tools/bootconfig/Makefile +++ b/tools/bootconfig/Makefile @@ -31,4 +31,4 @@ install: $(ALL_PROGRAMS) install $(OUTPUT)bootconfig $(DESTDIR)$(bindir) =20 clean: - $(RM) -f $(OUTPUT)*.o $(ALL_PROGRAMS) + rm -f $(OUTPUT)*.o $(ALL_PROGRAMS) --=20 2.53.0-Meta From nobody Mon Jun 8 06:36:53 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 620EE4DA551; Fri, 5 Jun 2026 12:04:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661061; cv=none; b=FwMv3uqqGlb5xtozd4mImGBqJdWBUQ41wfMVUBZYBAEnew+RspVggeE14G7GgA+OI72xGXP4A/3evWs6+thBl7X2NcGl6OFHJQ5xF/qbeLjiPVeH5SMiPofDAkGKKeYBt4LdFBuPXMWwyoCy85V4bqdGUI5QDyl0icujAJyn18M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661061; c=relaxed/simple; bh=HphAVP8d1EmlWPiq3Xm6Fy1H9xBvQSlS+8N330xZBQs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BfM26NL85LBB3f7Nc0xYj9379oti3TrtLRGPS/YTxEwBS0QkzbsrXgvi4cPEy025yNDmEWz/94K9knz7sQHtZ0zJfx4tWaKplAuK+RyWjXYcReXa0v2rsnZSal90t6P2xQ81jG86EqQS2kSW13KvB9h4Cfr7nnmYHSbdKLENK6U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=AZoEa8We; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="AZoEa8We" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=76ZX8FMuSby1II008hNX9DM5CqfyvtNrG2xvmlC+9pU=; b=AZoEa8Weoz14vD4VAaQdiFQYCn ztnmyPsU7BjmKNRBdINixUtG7low2FjLCQ2f/ZyiMj3EDiRnHt3c1oTp6F1ydSXE/31JEfcWGq/+u N66soHE9J08gbAZ10pK7dCGNiwJKeVrNd3w354yKOJXurfJ1zXPa8W6Th3bxKjC2YT+4oncaop9CG 8Hoci4YMlSFBQ04lMurU2SZ5GS4TICGDoD0yMUkkZkCeB0KdRwuBX72GO4g+HBtxYLjqINNUMFsif B9H5fLkrIr0q6xLQVTI8rbTWV2GsMh9IsJG+ZO9AJDM3omR/g9eE/UAixTxV+yFrkSgpRC/j00lV6 f7nUqmBQ==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wVTHZ-005HI2-2O; Fri, 05 Jun 2026 12:04:14 +0000 From: Breno Leitao Date: Fri, 05 Jun 2026 05:03:36 -0700 Subject: [PATCH v2 5/6] bootconfig: add xbc_prepend_embedded_cmdline() helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260605-bootconfig_using_tools-v2-5-d309f544b5f7@debian.org> References: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> In-Reply-To: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> To: Masami Hiramatsu , Andrew Morton , Nathan Chancellor , paulmck@kernel.org, Nicolas Schier Cc: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5585; i=leitao@debian.org; h=from:subject:message-id; bh=HphAVP8d1EmlWPiq3Xm6Fy1H9xBvQSlS+8N330xZBQs=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqIrsfXOwGNzV0u+KYBTP6M7Fn32x9v2PFRu2Ol cp3dDYnaHyJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaiK7HwAKCRA1o5Of/Hh3 bSiMD/4tASADVfGP3XbFFOX7ZP8sYoUF8gF3eApu/TPj4gIJvlfYsGS5mF+wfK/kKoq6zpmQBBt DUL4lv6AH2EYV8Pseo+GQ7weaBqR/yO7k02Yit4kiAcMqotT+5O60lWt1V1HhBLPeTWCzfLwiPH JPhqaMG4Y1yevAoyNID2ay1YStBv2MF2hstG4czZwN7W3OQB5zZoZ/bzhdJhvzddQMQ05kpXxHY DOw6yNdEwnfnCVZ0N9kG49hVPZYc1qZ+XBPNRFujUSKQAjrK9aSVH9HcP1WLOR/mKly+nwKtGQ/ 2oNPdcadrLFRs4nynR1SLO5IwavtJ6Ak62Sx8+rdcS0O6/y5aqE4eSzyoHjzWonAUybO1zenoqA sVZ5v06y+dDBpjFOd3Ev6uiq6VFoNMUvOHDRJuM0GcwhDP8d7g16qjKa2M4XuzpmkXa0G3NJeZg lHiKWVp/tIeJo+7mSdoZeqiEziBE02K2jVX9l/roGaW5iZYe5hy5j6l1a3H4ym4njVDbzJtIGC9 aP6cLeLOejQTNRIVWcgeA/h/pM7Pg8LYl7+RWq1FKa75usSk9itAHnyjcJRDF2vo5/QqMmuCA6m lsfMHOhbktS0icdeKr0Mr/QM5CYh+xQToAXD3YFGnerAs/irv0NFGU4eCa7LL0U2VEiVZQikaQS dExEUCS6yK2bccA== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao Add a helper that prepends the build-time-rendered embedded bootconfig "kernel" subtree (embedded_kernel_cmdline[] from embedded-cmdline.S) to a cmdline buffer with a separating space. Architectures call this from setup_arch() before parse_early_param() so early_param() handlers (mem=3D, earlycon=3D, loglevel=3D, ...) see values supplied via the embedded bootconfig. The in-place prepend (shift the existing string right, then drop the embedded string in front) is factored into a small str_prepend() helper. On overflow the helper logs an error and leaves the cmdline untouched rather than panicking. Booting without the embedded values is better than refusing to boot, and the error tells the user why their embedded keys are missing. The helper records whether it actually prepended, exposed via xbc_embedded_cmdline_applied(). setup_boot_config() uses this to decide whether the runtime "kernel" render would duplicate keys already folded into boot_command_line. When CONFIG_BOOT_CONFIG_EMBED_CMDLINE=3Dn, the public declaration in resolves to a no-op stub so callers compile unchanged. Signed-off-by: Breno Leitao --- include/linux/bootconfig.h | 9 ++++++ lib/bootconfig.c | 78 ++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 87 insertions(+) diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h index 1c7f3b74ffcf..c186137f87ac 100644 --- a/include/linux/bootconfig.h +++ b/include/linux/bootconfig.h @@ -308,4 +308,13 @@ static inline const char *xbc_get_embedded_bootconfig(= size_t *size) } #endif =20 +/* Build-time-rendered bootconfig cmdline prepended in setup_arch() */ +#ifdef CONFIG_BOOT_CONFIG_EMBED_CMDLINE +void __init xbc_prepend_embedded_cmdline(char *dst, size_t size); +bool __init xbc_embedded_cmdline_applied(void); +#else +static inline void xbc_prepend_embedded_cmdline(char *dst, size_t size) { } +static inline bool xbc_embedded_cmdline_applied(void) { return false; } +#endif + #endif diff --git a/lib/bootconfig.c b/lib/bootconfig.c index 926094d97397..f66be0b2dc24 100644 --- a/lib/bootconfig.c +++ b/lib/bootconfig.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,83 @@ const char * __init xbc_get_embedded_bootconfig(size_t *= size) return (*size) ? embedded_bootconfig_data : NULL; } #endif + +#ifdef CONFIG_BOOT_CONFIG_EMBED_CMDLINE +/* embedded_kernel_cmdline is defined in embedded-cmdline.S */ +extern __visible const char embedded_kernel_cmdline[]; +extern __visible const char embedded_kernel_cmdline_end[]; + +/* Set once the embedded cmdline has actually been prepended. */ +static bool xbc_cmdline_applied __initdata; + +/* + * str_prepend() - Prepend @src in front of the string in @dst, in place + * @dst: NUL-terminated destination buffer, currently @dst_len bytes long + * @dst_len: length of the current @dst string (excluding its NUL) + * @src: bytes to prepend (not NUL-terminated) + * @src_len: number of bytes from @src to prepend + * + * The caller must guarantee @dst has room for src_len + dst_len + 1 bytes. + * Moving dst_len + 1 bytes carries @dst's NUL terminator too, so an empty + * @dst needs no special case. + */ +static void __init str_prepend(char *dst, size_t dst_len, + const char *src, size_t src_len) +{ + memmove(dst + src_len, dst, dst_len + 1); + memcpy(dst, src, src_len); +} + +/** + * xbc_prepend_embedded_cmdline() - Prepend embedded bootconfig cmdline + * @dst: cmdline buffer to prepend into (must already contain a NUL byte) + * @size: total capacity of @dst in bytes + * + * Prepend the build-time-rendered "kernel" subtree of the embedded + * bootconfig to @dst. The rendered string already ends with a single + * space (the xbc_snprint_cmdline() invariant), which serves as the + * separator between the embedded keys and any existing content of @dst. + * On overflow, log an error and leave @dst untouched rather than + * silently truncating: booting without the embedded values is better + * than refusing to boot, and the error message tells the user why + * their embedded keys are missing. + * + * Intended to be called from setup_arch() before parse_early_param() so + * that early_param() handlers see the embedded values. + */ +void __init xbc_prepend_embedded_cmdline(char *dst, size_t size) +{ + size_t embed_len =3D embedded_kernel_cmdline_end - embedded_kernel_cmdlin= e; + size_t dst_len; + + if (!size || embed_len <=3D 1) /* trailing NUL only */ + return; + embed_len--; /* exclude trailing NUL byte */ + + dst_len =3D strnlen(dst, size); + if (embed_len + dst_len + 1 > size) { + pr_err("embedded bootconfig cmdline (%zu bytes) does not fit in COMMAND_= LINE_SIZE with %zu bytes already used; ignoring embedded values\n", + embed_len, dst_len); + return; + } + + str_prepend(dst, dst_len, embedded_kernel_cmdline, embed_len); + xbc_cmdline_applied =3D true; +} + +/** + * xbc_embedded_cmdline_applied() - Did the embedded cmdline get prepended? + * + * Return true if xbc_prepend_embedded_cmdline() actually prepended the + * embedded "kernel" subtree. setup_boot_config() uses this to avoid + * rendering the same keys a second time. + */ +bool __init xbc_embedded_cmdline_applied(void) +{ + return xbc_cmdline_applied; +} +#endif + #endif =20 /* --=20 2.53.0-Meta From nobody Mon Jun 8 06:36:53 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E5B1F4DBD7D; Fri, 5 Jun 2026 12:04:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661067; cv=none; b=upW0bksFExjZR7czdmMw6ee8Xewd0OnPVr+2ct/wxxJgVB94XpjO0mV7czA2cxtA2c3/ZGJZwi4rETdPsVhOzfCCbqDlJNz53+sj1jYa7w6NR8Kp1Vqy9/Z3HJOGMQO7vDA6mq96xn5zrzRe55oxNyRMR7YxpYW7Iw5SmqC4nTU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780661067; c=relaxed/simple; bh=I0OdXy6FEp71NFvv+bDXTFaDIxx23MCYNaRhxq58Q2o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bICO0T05Y7mrdsIZKMhlhTpQcP7mFT/vSFmvJlUsPsjo/4T4zIO7QJnTWaPsiCkrQ1BbB1ccYo3UKphzDXcQW0EXuGetr0ImYJIMvXio2bx0CRoJRtsBjpCr+TSiMBsSMCTOrXM2hye/5bq037Jg4GMLbrE35w74jI51NkW+5ss= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=dE3hoo0v; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="dE3hoo0v" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=B1K18S07Behr2dPLcs6pjimCBF6grfM9DcwV9KSISms=; b=dE3hoo0vU5ci/tgSCdMkGb/lVZ 7e5kk04dHiMyj76oF/XNlbWtiYSpkQ4uLBnKOvQXtb4UtvB4T3ETHDkLzdeEo6Z2iODCy1wXAhozs Mf2qNhRG+MPrWjU/HY+st55PvhvSSw8lvyR1pAaZjoK+xtEdfz59Io2bid6nqFviRCFwg0V4uwZPn K6Co0rlonE+6Gjc+eSTUed0i4ZEoI1GDe8vHs6vkXhM+5jSWqLwbI0z75MGckHsi2LaT+UDCz86BV +tg+AS1rdxnClQkgS+hHjvSryqxGZvA3E5P5/ZmzYC5R/5IeuTMNiQFk6xdVyN/WHnMLD8OHxTCKX q1yamxcw==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wVTHe-005HIJ-1Y; Fri, 05 Jun 2026 12:04:18 +0000 From: Breno Leitao Date: Fri, 05 Jun 2026 05:03:37 -0700 Subject: [PATCH v2 6/6] x86/setup: prepend embedded bootconfig cmdline before parse_early_param Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260605-bootconfig_using_tools-v2-6-d309f544b5f7@debian.org> References: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> In-Reply-To: <20260605-bootconfig_using_tools-v2-0-d309f544b5f7@debian.org> To: Masami Hiramatsu , Andrew Morton , Nathan Chancellor , paulmck@kernel.org, Nicolas Schier Cc: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5839; i=leitao@debian.org; h=from:subject:message-id; bh=I0OdXy6FEp71NFvv+bDXTFaDIxx23MCYNaRhxq58Q2o=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqIrsfTYkPu/ZtQ/7DE3oaO0MeQE1sA/iBzYZ3B tYHw/cM5ICJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaiK7HwAKCRA1o5Of/Hh3 bUzhD/4/OsdRyuXYsOrgKzNmWGdy9klHFtbGxXvat9iO6TvOSy7uqndACjJbkl7G5AtpbhKr5kG 6L/0MFbBzIoqPrSI8zdYWMPDr26Tv+T9l40KviV7/mTOc9M+RWgeV2//DDi90dIm8KiyHwfhOLK +gnrMrsSCtDv+vkak/AqJdbfr96j5rj0g1sM4Q2HUPnCSgd0LB9hV/PAgO2OO0Q/4Pg345HCR0z LOBI2uWx8rK4oFiI2f9UeA2gqzeKobWM2LWYp/0mmLZRuGvbyl7emavW+O9uLReeRIgBcMCXv78 VHmNbHu4xONHdR55viiGH/RQOajHT9Fs+VmqNB+RRzq04G/hdiLC+dV0ZwQyOiEg/kbhNJVactS w6z+kPEX+VlxwVAPJoIHnHyF4N061IDl34B3bpe/T9kRTpB8C/xl1OOeLqCyeXDVnWhcd5vOh0s ux4Nufdx7YMZCJHPehOq+WxuhVUvhxVjYKAvDD6jRaie6TaF2T707MakEmy8uXAnHA5euyL27U+ nhWe5G7GXyAjgaq8jDoT1kAoCoqRsvW766VSJ7xnZ9mr42ulmPI9n4TEFCznqFz8+DdBTssxXTY URxlPPgm7K9D1fccN0k9DKICWOctwc8UlOnFMtcbjJqIgMf/PkXbGsY8gJV5Ow8p5PyNhXbw6vC j+QHC4RkPv73vfQ== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao Call xbc_prepend_embedded_cmdline() in setup_arch() right after the CONFIG_CMDLINE merge and before strscpy(command_line, ...) so the build-time-rendered embedded bootconfig "kernel" subtree is part of boot_command_line by the time parse_early_param() runs. early_param() handlers (mem=3D, earlycon=3D, loglevel=3D, ...) now see values supplied via CONFIG_BOOT_CONFIG_EMBED_FILE without parsing bootconfig at runtime. Gate the prepend on the bootconfig opt-in: only fold in the embedded kernel.* keys when "bootconfig" is present on the command line, or CONFIG_BOOT_CONFIG_FORCE is set. Applying the embedded cmdline unconditionally would (a) diverge from how embedded init.* keys are treated and (b) break fail-safe recovery: a malformed embedded console=3D/mem=3D could panic the boot with no way for the admin to disable it by dropping "bootconfig" from the bootloader cmdline. cmdline_find_option_bool() runs before parse_early_param(), so the gate is cheap and correctly ordered. Select ARCH_SUPPORTS_CMDLINE_FROM_BOOTCONFIG so the user-visible CONFIG_BOOT_CONFIG_EMBED_CMDLINE option becomes selectable on x86. With this select in place, setup_boot_config() in init/main.c would otherwise render the embedded "kernel" subtree a second time via xbc_make_cmdline("kernel") into extra_command_line, duplicating every embedded kernel.* key in saved_command_line and making accumulating handlers (console=3D, earlycon=3D, ...) register the same value twice. Skip that render only when xbc_prepend_embedded_cmdline() actually prepended the keys, reported by xbc_embedded_cmdline_applied(). Keying the skip on the prepend itself, rather than re-deriving the opt-in, keeps the two paths consistent even when setup_arch() and the runtime parser detect "bootconfig" differently (e.g. "bootconfig=3D1"): the keys are then rendered at runtime instead of being dropped. Signed-off-by: Breno Leitao --- arch/x86/Kconfig | 1 + arch/x86/kernel/setup.c | 16 ++++++++++++++++ init/main.c | 18 +++++++++++++++--- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f24810015234..f839795692b4 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -126,6 +126,7 @@ config X86 select ARCH_SUPPORTS_NUMA_BALANCING if X86_64 select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <=3D 4096 select ARCH_SUPPORTS_CFI if X86_64 + select ARCH_SUPPORTS_CMDLINE_FROM_BOOTCONFIG select ARCH_USES_CFI_TRAPS if X86_64 && CFI select ARCH_SUPPORTS_LTO_CLANG select ARCH_SUPPORTS_LTO_CLANG_THIN diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 46882ce79c3a..26a82a41f44c 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -6,6 +6,7 @@ * parts of early kernel initialization. */ #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -924,6 +926,20 @@ void __init setup_arch(char **cmdline_p) builtin_cmdline_added =3D true; #endif =20 + /* + * Honor the same opt-in as the runtime bootconfig parser: only fold + * the embedded kernel.* keys into the cmdline when "bootconfig" is + * present on the command line (or CONFIG_BOOT_CONFIG_FORCE is set). + * This keeps fail-safe recovery working -- dropping "bootconfig" from + * the bootloader cmdline disables the embedded keys -- so a malformed + * embedded console=3D/mem=3D cannot brick a boot with no way out. It also + * matches setup_boot_config(), which bails out under the same + * condition before parsing the embedded bootconfig at runtime. + */ + if (IS_ENABLED(CONFIG_BOOT_CONFIG_FORCE) || + cmdline_find_option_bool(boot_command_line, "bootconfig")) + xbc_prepend_embedded_cmdline(boot_command_line, COMMAND_LINE_SIZE); + strscpy(command_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p =3D command_line; =20 diff --git a/init/main.c b/init/main.c index e363232b428b..567f641a5731 100644 --- a/init/main.c +++ b/init/main.c @@ -378,12 +378,15 @@ static void __init setup_boot_config(void) int pos, ret; size_t size; char *err; + bool from_embedded =3D false; =20 /* Cut out the bootconfig data even if we have no bootconfig option */ data =3D get_boot_config_from_initrd(&size); /* If there is no bootconfig in initrd, try embedded one. */ - if (!data) + if (!data) { data =3D xbc_get_embedded_bootconfig(&size); + from_embedded =3D true; + } =20 strscpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); err =3D parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL, @@ -421,8 +424,17 @@ static void __init setup_boot_config(void) } else { xbc_get_info(&ret, NULL); pr_info("Load bootconfig: %ld bytes %d nodes\n", (long)size, ret); - /* keys starting with "kernel." are passed via cmdline */ - extra_command_line =3D xbc_make_cmdline("kernel"); + /* + * keys starting with "kernel." are passed via cmdline. When + * this bootconfig came from the embedded source and + * setup_arch() already prepended the rendered "kernel" subtree + * to boot_command_line, rendering again here would duplicate + * the keys in saved_command_line and make accumulating handlers + * (console=3D, earlycon=3D, ...) re-register the same value. Skip + * only when the prepend really happened. + */ + if (!from_embedded || !xbc_embedded_cmdline_applied()) + extra_command_line =3D xbc_make_cmdline("kernel"); /* Also, "init." keys are init arguments */ extra_init_args =3D xbc_make_cmdline("init"); } --=20 2.53.0-Meta