[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20241119-force-cpu-bug-v1-1-2aa31c6c1ccf@google.com>
Date: Tue, 19 Nov 2024 18:43:57 +0000
From: Brendan Jackman <jackmanb@...gle.com>
To: Jonathan Corbet <corbet@....net>, Thomas Gleixner <tglx@...utronix.de>, Ingo Molnar <mingo@...hat.com>,
Borislav Petkov <bp@...en8.de>, Dave Hansen <dave.hansen@...ux.intel.com>, x86@...nel.org,
"H. Peter Anvin" <hpa@...or.com>, Peter Zijlstra <peterz@...radead.org>
Cc: linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org,
Brendan Jackman <jackmanb@...gle.com>
Subject: [PATCH] x86/bugs: Add force_cpu_bug= cmdline param
Sometimes it can be very useful to run CPU vulnerability mitigations on
systems where they aren't known to mitigate any real-world
vulnerabilities. This can be handy for mundane reasons like "I wanna
debug this on the machine that quickly", but also for research reasons:
while some mitigations are focussed on individual vulns and uarches,
others are fairly general, and it's strategically useful to have an idea
how they'd perform on systems where we don't currently need them.
As evidence for this being useful, a flag specifically for Retbleed was
added in commit 5c9a92dec323 ("x86/bugs: Add retbleed=force").
It's a bit unfortunate that we have to do this by bug instead of by
mitigation. However, we don't have clear identifiers for the mitigations
that we do, so I don't think it's practical to do better here than "you
can pretend you're on a vulnerable CPU - now go and read the docs for
the per-vuln cmdline params to figure out how to run the mitigation you
want".
Being an early_param() means we get to do this before identify_cpu() and
cpu_select_mitigations(). But it's possible there's still other types of
bugs that get setup earlier and might miss this override...
I've only tested this by booting a QEMU guest and checking /proc/cpuinfo.
Signed-off-by: Brendan Jackman <jackmanb@...gle.com>
---
Documentation/admin-guide/kernel-parameters.txt | 6 ++++
arch/x86/kernel/cpu/common.c | 40 +++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index d401577b5a6ace87d250d9b1cc200691c6a0ed4e..260267a6d555076735fda09d171c918e6412b6e1 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1559,6 +1559,12 @@
floppy= [HW]
See Documentation/admin-guide/blockdev/floppy.rst.
+ force_cpu_bug= [X86,EARLY]
+ Force the kernel to assume the CPU is affected by the
+ given bug, regardless of its built-in information about
+ individual models. Comma-separated list of the names of
+ vulnerabilities that would appear in /proc/cpuinfo.
+
forcepae [X86-32]
Forcefully enable Physical Address Extension (PAE).
Many Pentium M systems disable PAE but may have a
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index f43bb974fc66d7b21ad52c64da22694ccc274187..b86b0200a5bf0de692f07d4ffef50ba7c360975d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1318,6 +1318,10 @@ static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr)
return cpu_matches(cpu_vuln_blacklist, RFDS);
}
+/*
+ * This sets up what we _really_ think the CPU has. The user might override this
+ * later via force_cpu_bug.
+ */
static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
{
u64 x86_arch_cap_msr = x86_read_arch_cap_msr();
@@ -1462,6 +1466,42 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
setup_force_cpu_bug(X86_BUG_L1TF);
}
+static int __init force_cpu_bug_parse_cmdline(char *str)
+{
+ if (!str)
+ return -EINVAL;
+
+ while (str) {
+ char *next = strchr(str, ',');
+ int i;
+
+ if (next) {
+ *next = 0;
+ next++;
+ }
+
+ /*
+ * Linear search because there aren't many bugs (well, at least
+ * not for the definition of "many" that is relevant here...).
+ *
+ * Some configs have no gaps so we could stop at the first NULL,
+ * but it isn't worth the ifdeffery.
+ */
+ for (i = 0; i < ARRAY_SIZE(x86_bug_flags); i++) {
+ if (x86_bug_flags[i] && !strcmp(str, x86_bug_flags[i])) {
+ setup_force_cpu_bug(X86_BUG(i));
+ goto found;
+ }
+ }
+ pr_err("Ignoring unknown force_cpu_bug= option (%s).", str);
+found:
+ str = next;
+ }
+
+ return 0;
+}
+early_param("force_cpu_bug", force_cpu_bug_parse_cmdline);
+
/*
* The NOPL instruction is supposed to exist on all CPUs of family >= 6;
* unfortunately, that's not true in practice because of early VIA
---
base-commit: adc218676eef25575469234709c2d87185ca223a
change-id: 20241119-force-cpu-bug-94a08ab0239f
Best regards,
--
Brendan Jackman <jackmanb@...gle.com>
Powered by blists - more mailing lists