Re: [PATCH v3 20/35] x86/bugs: Define attack vectors

Pawan Gupta
2025-02-27T03:50:51Z

On Wed, Feb 26, 2025 at 05:23:29PM -0800, Josh Poimboeuf wrote:
> On Wed, Feb 26, 2025 at 04:35:28PM -0800, Pawan Gupta wrote:
> > On Wed, Feb 26, 2025 at 03:44:40PM -0800, Josh Poimboeuf wrote:
> > > On Wed, Feb 26, 2025 at 02:13:24PM -0800, Pawan Gupta wrote:
> > > > On Wed, Feb 26, 2025 at 09:03:58PM +0000, Kaplan, David wrote:
> > > > > > Extending =auto to take attack vectors is going to be tricky, because it already
> > > > > > takes ",nosmt" which would conflict with ",no_cross_thread".
> > > > > >
> > > > > > How about we keep =off, and =auto as is, and add:
> > > > > >
> > > > > > mitigations=selective,no_user_kernel,no_cross_thread,...
> > > > > >
> > > > > > Requiring the user to explicitly select attack vectors to disable (rather than to
> > > > > > enable). This would be more verbose, but it would be clear that the user is explicitly
> > > > > > selecting attack vectors to disable. Also, if a new attack vector gets added in future,
> > > > > > it would be mitigated by default, without requiring the world to change their cmdline.
> > > > >
> > > > > I kind of like that.
> > >
> > > While it might be true that we don't necessarily need both opt-in and
> > > opt-out options...
> > >
> > > I'm missing the point of the "selective" thing vs just
> > > "auto,no_whatever"?
> >
> > That was my first thought, but then I realized that in "auto,nosmt" nosmt
> > is the opposite of disabling the mitigation. It would be cleaner to have
> > "=selective,no_whatever" which is self-explanatory.
>
> The "auto,nosmt,no_whatever" is indeed a bit confusing because of the
> opposite meanings of the word "no", but least it sort of makes some
> kind of sense if you consider the existing "auto,nosmt" option to be the
> starting point.
>
> And we could document it from that perspective: start with "auto" or
> "auto,smt" and then optionally append the ",no_*" options for the vectors
> you want to disable.
>
> IMO "selective" doesn't seem very self-explanatory, it says nothing to
> indicate "opting out of defaults", in fact it sounds to me more like
> opting in. At least with "auto,no_whatever" it's more clear that it
> starts with the defaults and subtracts from there.

Thats fair. I certainly don't want to be adding new option if we are
willing to live with some minor quirks with auto,nosmt.

Like, should the order in which nosmt appears after =auto matter? IOW,
"=auto,no_foo,nosmt" would be equivalent to "=auto,nosmt,no_foo"? I believe
they should be treated the same.

Arches that don't support attack vectors, but support smt, should treat
"=auto,no_foo,nosmt" as "=auto,nosmt".

So as to treat nosmt as any other attack vector, CPU_MITIGATIONS_AUTO_NOSMT
should go away. I am thinking we can modify cpu_mitigations_auto_nosmt() to
check for smt attack vector:

---
diff --git a/kernel/cpu.c b/kernel/cpu.c
index b605334f8ee6..6ddbee6a0b6b 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -3193,22 +3193,27 @@ void __init boot_cpu_hotplug_init(void)
enum cpu_mitigations {
CPU_MITIGATIONS_OFF,
CPU_MITIGATIONS_AUTO,
- CPU_MITIGATIONS_AUTO_NOSMT,
};

+#define MITIGATE_SMT BIT(0)
+#define MITIGATE_USER_KERNEL BIT(1)
+#define MITIGATE_USER_USER BIT(2)
+#define MITIGATE_GUEST_HOST BIT(3)
+
static enum cpu_mitigations cpu_mitigations __ro_after_init = CPU_MITIGATIONS_AUTO;
+static unsigned int cpu_attack_vectors __ro_after_init = ~0;

static int __init mitigations_parse_cmdline(char *arg)
{
- if (!strcmp(arg, "off"))
+ if (!strcmp(arg, "off")) {
cpu_mitigations = CPU_MITIGATIONS_OFF;
- else if (!strcmp(arg, "auto"))
+ } else if (strstr(arg, "auto")) {
cpu_mitigations = CPU_MITIGATIONS_AUTO;
- else if (!strcmp(arg, "auto,nosmt"))
- cpu_mitigations = CPU_MITIGATIONS_AUTO_NOSMT;
- else
+ cpu_attack_vectors = parse_cpu_attack_vectors(arg);
+ } else {
pr_crit("Unsupported mitigations=%s, system may still be vulnerable\n",
arg);
+ }

return 0;
}
@@ -3223,7 +3228,7 @@ EXPORT_SYMBOL_GPL(cpu_mitigations_off);
/* mitigations=auto,nosmt */
bool cpu_mitigations_auto_nosmt(void)
{
- return cpu_mitigations == CPU_MITIGATIONS_AUTO_NOSMT;
+ return (cpu_mitigations == CPU_MITIGATIONS_AUTO) && (cpu_attack_vectors & MITIGATE_SMT);
}
EXPORT_SYMBOL_GPL(cpu_mitigations_auto_nosmt);
#else