Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87ab5f14 authored by Arvind Sankar's avatar Arvind Sankar Committed by Greg Kroah-Hartman
Browse files

x86/fpu: Allow multiple bits in clearcpuid= parameter



[ Upstream commit 0a4bb5e5507a585532cc413125b921c8546fc39f ]

Commit

  0c2a3913 ("x86/fpu: Parse clearcpuid= as early XSAVE argument")

changed clearcpuid parsing from __setup() to cmdline_find_option().
While the __setup() function would have been called for each clearcpuid=
parameter on the command line, cmdline_find_option() will only return
the last one, so the change effectively made it impossible to disable
more than one bit.

Allow a comma-separated list of bit numbers as the argument for
clearcpuid to allow multiple bits to be disabled again. Log the bits
being disabled for informational purposes.

Also fix the check on the return value of cmdline_find_option(). It
returns -1 when the option is not found, so testing as a boolean is
incorrect.

Fixes: 0c2a3913 ("x86/fpu: Parse clearcpuid= as early XSAVE argument")
Signed-off-by: default avatarArvind Sankar <nivedita@alum.mit.edu>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20200907213919.2423441-1-nivedita@alum.mit.edu


Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent dc0e1c91
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -558,7 +558,7 @@
			loops can be debugged more effectively on production
			systems.

	clearcpuid=BITNUM [X86]
	clearcpuid=BITNUM[,BITNUM...] [X86]
			Disable CPUID feature X for the kernel. See
			arch/x86/include/asm/cpufeatures.h for the valid bit
			numbers. Note the Linux specific bits are not necessarily
+22 −8
Original line number Diff line number Diff line
@@ -249,9 +249,9 @@ static void __init fpu__init_system_ctx_switch(void)
 */
static void __init fpu__init_parse_early_param(void)
{
	char arg[32];
	char arg[128];
	char *argptr = arg;
	int bit;
	int arglen, res, bit;

	if (cmdline_find_option_bool(boot_command_line, "no387"))
		setup_clear_cpu_cap(X86_FEATURE_FPU);
@@ -271,13 +271,27 @@ static void __init fpu__init_parse_early_param(void)
	if (cmdline_find_option_bool(boot_command_line, "noxsaves"))
		setup_clear_cpu_cap(X86_FEATURE_XSAVES);

	if (cmdline_find_option(boot_command_line, "clearcpuid", arg,
				sizeof(arg)) &&
	    get_option(&argptr, &bit) &&
	    bit >= 0 &&
	    bit < NCAPINTS * 32)
	arglen = cmdline_find_option(boot_command_line, "clearcpuid", arg, sizeof(arg));
	if (arglen <= 0)
		return;

	pr_info("Clearing CPUID bits:");
	do {
		res = get_option(&argptr, &bit);
		if (res == 0 || res == 3)
			break;

		/* If the argument was too long, the last bit may be cut off */
		if (res == 1 && arglen >= sizeof(arg))
			break;

		if (bit >= 0 && bit < NCAPINTS * 32) {
			pr_cont(" " X86_CAP_FMT, x86_cap_flag(bit));
			setup_clear_cpu_cap(bit);
		}
	} while (res == 2);
	pr_cont("\n");
}

/*
 * Called on the boot CPU once per system bootup, to set up the initial