All of lore.kernel.org
 help / color / mirror / Atom feed
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 */
_

  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.