From mboxrd@z Thu Jan 1 00:00:00 1970 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 7DE603E3C68; Wed, 17 Jun 2026 11:24:12 +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=1781695460; cv=none; b=KDQF5rU+l/oGdTDZqkZCRt1T0SRaaxPCJEPjF8cJ/As70D8UiBqm7HAJJeyheWlwucL+0DK63Fc8mPqopqdi7PJjMeP+ruPyHXD9UAeNbkbW205ErqXrvHuOX+kdThDz7iheWolQaoTR+j/ItfOU9iWAr8BZOnwCkt4VuRQSc8c= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781695460; c=relaxed/simple; bh=WGe0fIn8r73770CCOkOPS7Vw12cXZpASEoN86LMa/eI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DehUTimRSSqWFJjuENJ+70/krgrLweEN3AJKOs+vql+YCjiLhd5iaqpK+d4dD+CrcHZdAB+iaoIjp/GSbwYS8OIgKuxlLZtGZizfCETWfritU9WhbtXBMoAsMIvp0pH+y6Pb7BiQD9U38sDM7WFUBEleqUFcf6WzmNM+3fHMZWw= 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=N7hnL2US; 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="N7hnL2US" 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=l1fgs5/vY8CfUicrClnJtUp43P8Rg6yybujnLQdR3HY=; b=N7hnL2US5Rhh2cKeCul1OT/O0Z BAPEsjfS8Ki5f9tZCP8s5WGHuB5itxIy9OwbcSDTrdnWCgyENhBzmv0HMU6fJrN0Qpzg1XU/h/myb X2WKCTAEOjIVyMqguSXtpMjNQazy9sM5Q+uKdO9Eq/O6ID6TivxmLABnb9f9FlAWekuA0JpA2uitQ FfVO1BzPrg+5yx2nohyEF4ifdqzMXTB0rDaggvGLUuTNIukedeFizYyh8XAl8OKEQ2RTxulpdo08R 753b9fuG9Yru71ki0W9cY9yXlNmc1wJtbiExAK5q3I4Mhkrg/RRIuQYIuZpzgmg3A/Pw7S+nG689s cqDIttPg==; 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 1wZoNN-00EaGI-1q; Wed, 17 Jun 2026 11:24:09 +0000 From: Breno Leitao Date: Wed, 17 Jun 2026 04:23:37 -0700 Subject: [PATCH v5 5/7] bootconfig: add xbc_prepend_embedded_cmdline() helper Precedence: bulk X-Mailing-List: linux-trace-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260617-bootconfig_using_tools-v5-5-fd589a9cc5e3@debian.org> References: <20260617-bootconfig_using_tools-v5-0-fd589a9cc5e3@debian.org> In-Reply-To: <20260617-bootconfig_using_tools-v5-0-fd589a9cc5e3@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=5589; i=leitao@debian.org; h=from:subject:message-id; bh=WGe0fIn8r73770CCOkOPS7Vw12cXZpASEoN86LMa/eI=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqMoO706OqoRN9TjSzwYk6G3/xUu3PpuGJyomly IE2njRqCjqJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCajKDuwAKCRA1o5Of/Hh3 bebcD/45KwEkp5UJDIZb1CgmuGRGkKeh56Q9waC79Kiiq3KZv8V3UmsJ3/DiQU4CvVM52O0Wrg6 +sdsLB4jaIu9Xa1RfQjtDYmjdTFTFd2plRds4O2LAbYrLpAk8VHfGRIpNq2ZTPxkVp/oEYvCTWm BAJc9QH7zMJuRq7movTOoa02jNZI6ZXYtOvpKmx+rbqQX0bKznWcmP+fRxnU9hmXJc/heaeKl4x Xr3cUdJGvDBh4w3BL8gYad3pKjorsZ6F0gdeZ46RtbPgGtuvCUnqTl7QOGFqVSEHiKjm6XS19Bc vDtxnRx/wQwGb99nI2m42t6IpqL70ehJY+YjpBfgz9xbXBEvM3aQyN+x7Sdl3/tG3STOvPCmDex cuigakYdHBunl7BX2EiKfzyP80AGT0ByNUgJlQOab5baJkuCJOLR0MoA2rYUdpqb6b+eE3dgj5n hpGwtUS8G6sq1g7j69EswbRFC8USGDDUk3SCwplhn+K5sqY24xxbw0vf8vBwEdFGOhhc0njjif9 lAHrHcytOkn54FFK2bEwSevU1lhrMFW4IuYsX94YOqVVcucC/fFRl6BNe21emrilCdVOSetsIUB 2XZAj0r3MXh0iI/2lvXQEBRlNhm9GSM+aDHqI8DtivByr81w5qBKOUuq0ORBDB4PxmiLvu3wdwS sE1EIr64sIjltyg== 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=, earlycon=, loglevel=, ...) 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=n, 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 1c7f3b74ffcf3..c186137f87ac5 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 +/* 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 926094d97397e..f66be0b2dc241 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 = embedded_kernel_cmdline_end - embedded_kernel_cmdline; + size_t dst_len; + + if (!size || embed_len <= 1) /* trailing NUL only */ + return; + embed_len--; /* exclude trailing NUL byte */ + + dst_len = 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 = 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 /* -- 2.53.0-Meta