From patchwork Thu Mar 9 03:13:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sky Liu X-Patchwork-Id: 9612265 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1DD8A602B4 for ; Thu, 9 Mar 2017 03:16:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3E35284E9 for ; Thu, 9 Mar 2017 03:16:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E8BA928632; Thu, 9 Mar 2017 03:16:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.6 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EAE4A284E9 for ; Thu, 9 Mar 2017 03:16:11 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cloWO-0006GG-KV; Thu, 09 Mar 2017 03:13:44 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cloWN-0006GA-Ji for xen-devel@lists.xenproject.org; Thu, 09 Mar 2017 03:13:43 +0000 Received: from [85.158.139.211] by server-6.bemta-5.messagelabs.com id CA/86-16497-668C0C85; Thu, 09 Mar 2017 03:13:42 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprCIsWRWlGSWpSXmKPExsVyMfTAId3UEwc iDLa/0rT4vmUykwOjx+EPV1gCGKNYM/OS8isSWDN2fehmK3jqW7GpkbWBcZZtFyMXh5DAdEaJ pp0/WUAcFoFLLBJz9mxjAnEkBN6xSNzofg3kcAI5MRJTd3UzQ9hVEtN3T2YHsYUElCWmr/zBD jWKSeJd/3pGkASbgIbE2ikH2UBsEQEliXurJoNNZRZ4yygx69kDsCJhAX+JMxcfg9ksAqoSnR O3gm3jFbCUaH39iR1im7zEok0zWCYw8i1gZFjFqF6cWlSWWqRrrJdUlJmeUZKbmJmja2hgqpe bWlycmJ6ak5hUrJecn7uJERgqDECwg3HvP6dDjJIcTEqivAYBByKE+JLyUyozEosz4otKc1KL DzHKcHAoSfAqHQfKCRalpqdWpGXmAIMWJi3BwaMkwpsEkuYtLkjMLc5Mh0idYrTkeHBq1xsmj lsNe4Dkp/7Db5iEWPLy81KlxHnDQBoEQBoySvPgxsEi6xKjrJQwLyPQgUI8BalFuZklqPKvGM U5GJWEeVVBpvBk5pXAbX0FdBAT0EHarntBDipJREhJNTBOdFwdO9f6B1P0vRPdGq1Fj5KLTaq 0IpXDPWfLH/0w3VZ8etnDhfr9Orp72ZqyvrGxcz84I1q/LDGRNefpykdxLvtvHzHbf7flzmpF m3jzoF9ivfXhyioP7915f+fhuhzZmzWnnNbE+zVXvjZp/Rt8SPTLotAJs874JUZobNAUaI+Y8 yzQfpUSS3FGoqEWc1FxIgBb/zjNpwIAAA== X-Env-Sender: blackskygg@gmail.com X-Msg-Ref: server-6.tower-206.messagelabs.com!1489029220!88334544!1 X-Originating-IP: [209.85.192.194] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 18784 invoked from network); 9 Mar 2017 03:13:41 -0000 Received: from mail-pf0-f194.google.com (HELO mail-pf0-f194.google.com) (209.85.192.194) by server-6.tower-206.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 9 Mar 2017 03:13:41 -0000 Received: by mail-pf0-f194.google.com with SMTP id 67so5714745pfg.2 for ; Wed, 08 Mar 2017 19:13:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=QXRZT1/05Y0gd3Et3UNbH5oiz61jkEkpzGiclDzji3I=; b=ZirTSWVqe8FC3qeOFh4uYtmBvn3zsVqRnRAgsYGLSJ74cTJl5hYXRXFkKJRfl60iOC KQJzyGyyt+u/qDCXpRT0tr7VT7mHlldpEqi88GUx2j9sHvlJ43IsVB8IWaZ17OljLwvc pSXCaSfBIO+vaKiG82G3aOIexgbaekHPghcfIzR6p1zQcfHwjKbGUJ4xSxjR3BoWKExl 25gU0bvYzsED5LuKxi01jgdv1yC89Rev/zCseWNjr5ab8fguOUQR/RAz6GRjP6uebncm dKr+4v/eIgm+K25jrzrzHFgR8v80/WVi+fthgN41fQrhp3fWqirZz43tsHVKL0QP9xNc jp+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=QXRZT1/05Y0gd3Et3UNbH5oiz61jkEkpzGiclDzji3I=; b=bD4TBpyb9mkiW1NxJSZVzLNvRPWzcialJRDj1hfQILmefGHVjy0emuc0XEA6o0h1r2 reG+jP0rlGPst0ojmnTV/U5fLgWMOmMLXIV2zkEwAI83dLY2QLIjp6MNDCSSx9PwxfEC OvwFRZ4ahr3rVv1pZTz3KXR538vU+LZakWk2IE/rImEk6+fVRwk8KmNsdoNNpZqN0OcW Zb4OpthvSals2C2KBr0IQmqRIZ0Kt+mu888I4u0DkpBz4X3p1URrdoJlz0GJSbVoCKM2 /XlBRHsHcahr5dkprBKs1POE8JVJZ4SS68lrofwJo/odl/oZ/FeWg5tsPLYr+Dz6BU+O FC+g== X-Gm-Message-State: AMke39kIzf6nlqn5Yj1CkNVkA4K+zgKPajR0BXxY0J9KgqZN9p08UAoh93cBPU5EJLusqA== X-Received: by 10.84.216.81 with SMTP id f17mr13664016plj.170.1489029219537; Wed, 08 Mar 2017 19:13:39 -0800 (PST) Received: from localhost.localdomain ([2001:250:4000:4191:42e2:30ff:feff:2235]) by smtp.gmail.com with ESMTPSA id 80sm8632165pfy.67.2017.03.08.19.13.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Mar 2017 19:13:37 -0800 (PST) From: Zhongze Liu To: xen-devel@lists.xenproject.org Date: Thu, 9 Mar 2017 11:13:21 +0800 Message-Id: <20170309031321.19355-1-blackskygg@gmail.com> X-Mailer: git-send-email 2.12.0 Cc: Stefano Stabellini , Zhongze Liu , Andrew Cooper , Doug Goldstein , Julien Grall , Jan Beulich Subject: [Xen-devel] [PATCH v4] xen: Allow a default compiled-in command line using Kconfig X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Added 2 new config entries in common/Kconfig: CMDLINE and CMDLINE_OVERRIDE Modified the interface common/kernel.c:cmdline_parse(). The 2 new entries allow an embedded command line to be compiled in the hypervisor.This allows downstreams to set their defaults without modifying the source code all over the place. Also probably useful for the embedded space. (See Also: https://xenproject.atlassian.net/browse/XEN-41) If CMDLINE is set, the cmdline_parse() routine will append the bootloader command line to this string, forming the complete command line before parsing. This order of concatenation implies that if any non-cumulative options are set in both the built-in and bootloader command line, only the ones in the latter will take effect. And if CMDLINE_OVERRIDE is set to y, the whole bootloader command line will be ignored, which will be useful to work around broken bootloaders. Since some architectures (e.g. x86) allow optional dom0 options to appear after " -- " in the command line. cmdline_parse() was modified to handle these dom0 options if the caller request it to do so, and thus architectures supporting this feature don't need to handle them in their setup.c's anymore. Signed-off-by: Zhongze Liu --- Changed since v3: * Remove the CMDLINE_BOOL option. * Make the option CMDLINE_OVERRIDE depend on EXPERT = "y". * Move the CMDLINE-related code from various /xen/$(ARCH)/setup.c's to common/kernel.c:cmdline_parse(). * Dealing with the optional dom0 options in cmdline_parse(). * Remove some pointless initializers. * Remove unnecessary #ifdef-ary's --- xen/arch/arm/setup.c | 6 ++--- xen/arch/x86/setup.c | 23 +++++----------- xen/common/Kconfig | 24 +++++++++++++++++ xen/common/kernel.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++----- xen/include/xen/lib.h | 2 +- 5 files changed, 103 insertions(+), 26 deletions(-) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 92a2de6b70..a5ecdbb54a 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -705,7 +705,7 @@ void __init start_xen(unsigned long boot_phys_offset, size_t fdt_size; int cpus, i; paddr_t xen_paddr; - const char *cmdline; + const char *cmdline, *complete_cmdline; struct bootmodule *xen_bootmodule; struct domain *dom0; struct xen_arch_domainconfig config; @@ -730,8 +730,8 @@ void __init start_xen(unsigned long boot_phys_offset, fdt_size = boot_fdt_info(device_tree_flattened, fdt_paddr); cmdline = boot_fdt_cmdline(device_tree_flattened); - printk("Command line: %s\n", cmdline); - cmdline_parse(cmdline); + complete_cmdline = cmdline_parse(cmdline, NULL, 0); + printk("Command line: %s\n", complete_cmdline); /* Register Xen's load address as a boot module. */ xen_bootmodule = add_boot_module(BOOTMOD_XEN, diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index dab67d5491..dc65d8f389 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -639,7 +639,9 @@ static char * __init cmdline_cook(char *p, const char *loader_name) void __init noreturn __start_xen(unsigned long mbi_p) { char *memmap_type = NULL; - char *cmdline, *kextra, *loader; + char *cmdline, *loader; + const char *complete_cmdline; + static char __initdata kextra[MAX_GUEST_CMDLINE]; unsigned int initrdidx, domcr_flags = DOMCRF_s3_integrity; multiboot_info_t *mbi = __va(mbi_p); module_t *mod = (module_t *)__va(mbi->mods_addr); @@ -679,18 +681,7 @@ void __init noreturn __start_xen(unsigned long mbi_p) cmdline = cmdline_cook((mbi->flags & MBI_CMDLINE) ? __va(mbi->cmdline) : NULL, loader); - if ( (kextra = strstr(cmdline, " -- ")) != NULL ) - { - /* - * Options after ' -- ' separator belong to dom0. - * 1. Orphan dom0's options from Xen's command line. - * 2. Skip all but final leading space from dom0's options. - */ - *kextra = '\0'; - kextra += 3; - while ( kextra[1] == ' ' ) kextra++; - } - cmdline_parse(cmdline); + complete_cmdline = cmdline_parse(cmdline, kextra, sizeof(kextra)); /* Must be after command line argument parsing and before * allocing any xenheap structures wanted in lower memory. */ @@ -713,7 +704,7 @@ void __init noreturn __start_xen(unsigned long mbi_p) printk("Bootloader: %s\n", loader); - printk("Command line: %s\n", cmdline); + printk("Command line: %s\n", complete_cmdline); printk("Video information:\n"); @@ -1566,14 +1557,14 @@ void __init noreturn __start_xen(unsigned long mbi_p) /* Grab the DOM0 command line. */ cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL); - if ( (cmdline != NULL) || (kextra != NULL) ) + if ( (cmdline != NULL) || strlen(kextra) ) { static char __initdata dom0_cmdline[MAX_GUEST_CMDLINE]; cmdline = cmdline_cook(cmdline, loader); safe_strcpy(dom0_cmdline, cmdline); - if ( kextra != NULL ) + if ( strlen(kextra) ) /* kextra always includes exactly one leading space. */ safe_strcat(dom0_cmdline, kextra); diff --git a/xen/common/Kconfig b/xen/common/Kconfig index f2ecbc43d6..d7288abdcc 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -237,4 +237,28 @@ config FAST_SYMBOL_LOOKUP The only user of this is Live patching. If unsure, say Y. + +config CMDLINE + string "Built-in hypervisor command string" + default "" + ---help--- + Enter arguments here that should be compiled into the hypervisor + image and used at boot time. If the bootloader provides a + command line at boot time, it is appended to this string to + form the full hypervisor command line, when the system boots. + So if the same command line option is not cumulative, + and was set both in this string and in the bootloader command line, + only the latter (i.e. the one in the bootloader command line), + will take effect. + +config CMDLINE_OVERRIDE + bool "Built-in command line overrides bootloader arguments" + default n + depends on EXPERT = "y" + ---help--- + Set this option to 'Y' to have the hypervisor ignore the bootloader + command line, and use ONLY the built-in command line. + + This is used to work around broken bootloaders. This should + be set to 'N' under normal conditions. endmenu diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 4b87c60845..77544be948 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -22,7 +22,7 @@ enum system_state system_state = SYS_STATE_early_boot; -xen_commandline_t saved_cmdline; +xen_commandline_t saved_cmdline = CONFIG_CMDLINE; static void __init assign_integer_param( const struct kernel_param *param, uint64_t val) @@ -46,17 +46,77 @@ static void __init assign_integer_param( } } -void __init cmdline_parse(const char *cmdline) +/* + * Extracts dom0 options from the @cmdline. + * Options after ' -- ' separator belong to dom0. + * 1. Orphan dom0's options from Xen's command line. + * 2. Skip all but final leading space from dom0's options. + * 3. Append dom0's options to kextra. + */ +static void __init gather_dom0_options( + char *cmdline, char *kextra, size_t kextra_len) +{ + char *p; + + if ( (p = strstr(cmdline, " -- ")) != NULL ) + { + *p = '\0'; + p += 3; + while ( p[1] == ' ' ) + p++; + + strlcat(kextra, p, kextra_len); + } +} + +/** + * cmdline_parse - parses the command line options. + * + * @cmdline: the command line to be parsed. + * @kextra: if not NULL, this will be filled with the optional dom0 options. + * (some architecture allows dom0 options to appear after " -- " in + * the cmdline); if set to NULL, the function won't seek for dom0 + * options. + * @kextra_len: length of @kextra, ignored if @kextra is NULL. + * + * If CONFIG_CMDLINE is set, @cmdline will be appended to CONFIG_CMDLINE + * to form the complete cmdline before parsing, and the optional dom0 options + * will also be concatenated in the same order before we put them in @kextra. + * But if CONFIG_CMDLINE_OVERRIDE is set to y, the whole bootloader command + * line will be ignored. + * The fucntion retruns the complete command line with the optional dom0 + * options stripped out. + */ +const char* __init cmdline_parse( + const char *cmdline, char *kextra, size_t kextra_len) { char opt[100], *optval, *optkey, *q; - const char *p = cmdline; + const char *p = saved_cmdline; const struct kernel_param *param; int bool_assert; - if ( cmdline == NULL ) - return; + if ( kextra != NULL ) + kextra[0] = '\0'; - safe_strcpy(saved_cmdline, cmdline); + if ( strlen(saved_cmdline) ) + { + if ( kextra != NULL ) + gather_dom0_options(saved_cmdline, kextra, kextra_len); + safe_strcat(saved_cmdline, " "); + } + +#ifndef CONFIG_CMDLINE_OVERRIDE + if ( cmdline != NULL ) + { + safe_strcat(saved_cmdline, cmdline); + if ( kextra != NULL ) + gather_dom0_options(saved_cmdline, kextra, kextra_len); + } +#endif + + if ( !strlen(saved_cmdline) ) + /* Nothing to parse. */ + return saved_cmdline; for ( ; ; ) { @@ -145,6 +205,8 @@ void __init cmdline_parse(const char *cmdline) } } } + + return saved_cmdline; } int __init parse_bool(const char *s) diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index 995a85a7db..33e5fbfe20 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -70,7 +70,7 @@ struct domain; -void cmdline_parse(const char *cmdline); +const char *cmdline_parse(const char *cmdline, char *kextra, size_t kextra_len); int parse_bool(const char *s); /*#define DEBUG_TRACE_DUMP*/