From: Dave Hansen <dave@sr71.net>
To: x86@kernel.org
Cc: linux-kernel@vger.kernel.org, Dave Hansen <dave@sr71.net>,
dave.hansen@linux.intel.com, bp@suse.de, hpa@zytor.com,
fenghua.yu@intel.com, yu-cheng.yu@intel.com
Subject: [PATCH 5/5] x86: test early command-line code
Date: Tue, 22 Dec 2015 14:52:44 -0800 [thread overview]
Message-ID: <20151222225244.C64747AF@viggo.jf.intel.com> (raw)
In-Reply-To: <20151222225237.08CDE5F1@viggo.jf.intel.com>
From: Dave Hansen <dave.hansen@linux.intel.com>
Here are some simple tests for the early command-line code. It
had way more bugs than it should have, so let's make sure they
never pop up again.
Note, there are a few failures in here now. We will fix those
up in the next few patches.
This is complete overkill for this code, but I had to do it to
convince myself that I wasn't making it any worse.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: linux-kernel@vger.kernel.org
Cc: fenghua.yu@intel.com
Cc: yu-cheng.yu@intel.com
---
b/arch/x86/Kconfig.debug | 7 ++
b/arch/x86/kernel/check.c | 1
b/arch/x86/kernel/setup.c | 9 +++
b/arch/x86/lib/cmdline.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 138 insertions(+), 1 deletion(-)
diff -puN arch/x86/Kconfig.debug~x86-early-command-line-test arch/x86/Kconfig.debug
--- a/arch/x86/Kconfig.debug~x86-early-command-line-test 2015-12-22 11:57:01.229266152 -0800
+++ b/arch/x86/Kconfig.debug 2015-12-22 11:57:01.238266557 -0800
@@ -400,4 +400,11 @@ config PUNIT_ATOM_DEBUG
The current power state can be read from
/sys/kernel/debug/punit_atom/dev_power_state
+config X86_TEST_EARLY_CMDLINE
+ bool "Early command line runtime tests"
+ ---help---
+ This creates some test command-lines and tries to parse
+ a bunch of options from them. The overhead is small both
+ at boot and increased text/data sizes.
+
endmenu
diff -puN arch/x86/kernel/check.c~x86-early-command-line-test arch/x86/kernel/check.c
--- a/arch/x86/kernel/check.c~x86-early-command-line-test 2015-12-22 11:57:01.230266197 -0800
+++ b/arch/x86/kernel/check.c 2015-12-22 11:57:01.239266602 -0800
@@ -164,4 +164,3 @@ static int start_periodic_check_for_corr
return 0;
}
device_initcall(start_periodic_check_for_corruption);
-
diff -puN arch/x86/lib/cmdline.c~x86-early-command-line-test arch/x86/lib/cmdline.c
--- a/arch/x86/lib/cmdline.c~x86-early-command-line-test 2015-12-22 11:57:01.232266287 -0800
+++ b/arch/x86/lib/cmdline.c 2015-12-22 11:57:01.239266602 -0800
@@ -4,6 +4,7 @@
*
* Misc librarized functions for cmdline poking.
*/
+#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ctype.h>
@@ -108,3 +109,124 @@ int cmdline_find_option_bool(const char
return __cmdline_find_option_bool(cmdline, COMMAND_LINE_SIZE,
option);
}
+
+#ifdef CONFIG_X86_TEST_EARLY_CMDLINE
+
+static int __cmdtest(char *cmdline, int str_size, char *option,
+ int expected_result, int do_shrink)
+{
+ int ret;
+ int null_terminate;
+ /* Results are 1-based, so bias back down by 1 */
+ int option_end = expected_result + strlen(option) - 1;
+ int shrink_max = 0;
+
+ if (cmdline && do_shrink)
+ shrink_max = strlen(cmdline);
+ /*
+ * The option was not found. If it was not found in the
+ * *full* command-line, it should never be found in any
+ * *part* of the command-line.
+ */
+ for (null_terminate = 0; null_terminate <= 1; null_terminate++) {
+ int shrink_by;
+ for (shrink_by = 0; shrink_by < shrink_max; shrink_by++) {
+ int str_size_tst = str_size - shrink_by;
+ char tmp = cmdline[str_size_tst];
+
+ /*
+ * Do not run tests that would truncate
+ * over the expected option
+ */
+ if (str_size_tst <= option_end)
+ continue;
+
+ if (null_terminate)
+ cmdline[str_size_tst] = '\0';
+ ret = __cmdline_find_option_bool(cmdline, str_size_tst,
+ option);
+ if (null_terminate)
+ cmdline[str_size_tst] = tmp;
+
+ if (ret == expected_result)
+ continue;
+ pr_err("failed cmdline test ('%s', %d, '%s') == %d "
+ "nulld: %d got: %d\n",
+ cmdline, str_size_tst, option,
+ expected_result, null_terminate,
+ ret);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#define cmdtest(cmdline, option, result) \
+ WARN_ON(__cmdtest(cmdline, sizeof(cmdline), option, result, 1))
+
+#define cmdtest_noshrink(cmdline, option, result) \
+ WARN_ON(__cmdtest(cmdline, sizeof(cmdline), option, result, 0))
+
+char cmdline1[] = "CALL me Ishmael ";
+char cmdline2[] = "Whenever I find myself growing grim about the mouth ";
+char cmdline3[] = "grow growing ";
+int test_early_cmdline(void)
+{
+ /* NULL command-line: */
+ WARN_ON(__cmdline_find_option_bool(NULL, 22, "Ishmael") != -1);
+ /* zero-length command-line: */
+ cmdtest("", "Ishmael", 0);
+
+ /* Find words at each of 3 positions: start, middle, end */
+ cmdtest(cmdline1, "CALL", 1);
+ cmdtest(cmdline1, "me", 6);
+ cmdtest(cmdline1, "Ishmael", 9);
+
+ /*
+ * Fail to find strings that all occur in the cmdline,
+ * but not as full words
+ */
+ /*
+ * If "option" is _present_ in "cmdline" as the start of a
+ * word, like cmdline="foo bar" and we pass in option="b",
+ * when we shrink cmdline to "foo b", it will match. So,
+ * skip shrink tests for those.
+ */
+ cmdtest_noshrink(cmdline1, "m", 0);
+ cmdtest(cmdline1, "e", 0);
+ cmdtest(cmdline1, "C", 0);
+ cmdtest(cmdline1, "l", 0);
+ cmdtest_noshrink(cmdline1, "Ishmae", 0);
+ cmdtest(cmdline1, "mael", 0);
+ /*
+ * Look for strings that do not occur, but match until
+ * close to the end of cmdline
+ */
+ cmdtest_noshrink(cmdline1, "Ishmae", 0);
+ cmdtest(cmdline1, "Ishmaels", 0);
+ cmdtest(cmdline1, "maels", 0);
+
+ /*
+ * Look for full words that do not occur in a different
+ * cmdline
+ */
+ cmdtest(cmdline2, "CALL", 0);
+ cmdtest(cmdline2, "me", 0);
+ cmdtest(cmdline2, "Ishmael", 0);
+ /*
+ * Look for full words which do occur in cmdline2
+ */
+ cmdtest(cmdline2, "Whenever", 1);
+ cmdtest(cmdline2, "growing", 24);
+ cmdtest(cmdline2, "grim", 32);
+ cmdtest(cmdline2, "mouth", 47);
+
+ /*
+ * Catch the bug where if we match a partial word and
+ * then have a space, we do not match the _next_ word.
+ */
+ cmdtest(cmdline3, "grow", 1);
+ cmdtest(cmdline3, "growing", 6);
+ return 0;
+}
+#endif /* CONFIG_X86_TEST_EARLY_CMDLINE */
diff -puN arch/x86/kernel/setup.c~x86-early-command-line-test arch/x86/kernel/setup.c
--- a/arch/x86/kernel/setup.c~x86-early-command-line-test 2015-12-22 11:57:01.233266332 -0800
+++ b/arch/x86/kernel/setup.c 2015-12-22 11:57:01.239266602 -0800
@@ -1282,3 +1282,12 @@ static int __init register_kernel_offset
return 0;
}
__initcall(register_kernel_offset_dumper);
+
+/*
+ * This code is in lib/ and we do not link initcalls from there.
+ * Stash it here instead.
+ */
+#ifdef CONFIG_X86_TEST_EARLY_CMDLINE
+int test_early_cmdline(void);
+late_initcall(test_early_cmdline);
+#endif /* CONFIG_X86_TEST_EARLY_CMDLINE */
_
next prev parent reply other threads:[~2015-12-22 22:52 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-22 22:52 [PATCH 0/5] x86: early command-line parsing fixes / tests (v2) Dave Hansen
2015-12-22 22:52 ` [PATCH 1/5] x86: fix early command-line parsing when matching at end Dave Hansen
2016-01-05 18:35 ` Borislav Petkov
2016-01-05 18:51 ` Dave Hansen
2016-01-06 17:10 ` Borislav Petkov
2016-01-06 17:57 ` Dave Hansen
2016-01-06 18:14 ` Borislav Petkov
2016-02-03 11:34 ` [tip:x86/boot] x86/boot: Fix " tip-bot for Dave Hansen
2015-12-22 22:52 ` [PATCH 2/5] x86: fix early command-line parsing, when partial word match Dave Hansen
2016-02-03 11:35 ` [tip:x86/boot] x86/boot: Fix early command-line parsing when partial word matches tip-bot for Dave Hansen
2015-12-22 22:52 ` [PATCH 3/5] x86: simplify early command line parsing Dave Hansen
2016-01-06 17:10 ` Borislav Petkov
2016-01-06 17:35 ` Dave Hansen
2016-01-06 17:37 ` Dave Hansen
2016-01-06 17:48 ` Borislav Petkov
2016-02-03 11:35 ` [tip:x86/boot] x86/boot: Simplify " tip-bot for Dave Hansen
2015-12-22 22:52 ` [PATCH 4/5] x86: pass in size to early cmdline parsing Dave Hansen
2016-02-03 11:36 ` [tip:x86/boot] x86/boot: Pass " tip-bot for Dave Hansen
2015-12-22 22:52 ` Dave Hansen [this message]
2016-01-27 12:28 ` [PATCH 5/5] x86: test early command-line code Borislav Petkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20151222225244.C64747AF@viggo.jf.intel.com \
--to=dave@sr71.net \
--cc=bp@suse.de \
--cc=dave.hansen@linux.intel.com \
--cc=fenghua.yu@intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=x86@kernel.org \
--cc=yu-cheng.yu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox