linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86/bugs: Restructure ITS mitigation
@ 2025-05-15 13:47 David Kaplan
  2025-05-15 15:16 ` Borislav Petkov
                   ` (3 more replies)
  0 siblings, 4 replies; 18+ messages in thread
From: David Kaplan @ 2025-05-15 13:47 UTC (permalink / raw)
  To: Thomas Gleixner, Borislav Petkov, Peter Zijlstra, Josh Poimboeuf,
	Pawan Gupta, Ingo Molnar, Dave Hansen, x86, H. Peter Anvin
  Cc: linux-kernel

Restructure the ITS mitigation to use select/update/apply functions like
the other mitigations.

There is a particularly complex interaction between ITS and Retbleed as CDT
(Call Depth Tracking) is a mitigation for both, and either its=stuff or
retbleed=stuff will attempt to enable CDT.

retbleed_update_mitigation() runs first and will check the necessary
pre-conditions for CDT if either ITS or Retbleed stuffing is selected.  If
checks pass and ITS stuffing is selected, it will select stuffing for
Retbleed as well.

its_update_mitigation() runs after and will either select stuffing if
retbleed stuffing was enabled, or fall back to the default (aligned thunks)
if stuffing could not be enabled.

Enablement of CDT is done exclusively in retbleed_apply_mitigation().
its_apply_mitigation() is only used to enable aligned thunks.

Signed-off-by: David Kaplan <david.kaplan@amd.com>
---
 arch/x86/kernel/cpu/bugs.c | 167 ++++++++++++++++++++-----------------
 1 file changed, 90 insertions(+), 77 deletions(-)

diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index dd8b50b4ceaa..db26fb5a0a13 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -92,6 +92,8 @@ static void __init bhi_select_mitigation(void);
 static void __init bhi_update_mitigation(void);
 static void __init bhi_apply_mitigation(void);
 static void __init its_select_mitigation(void);
+static void __init its_update_mitigation(void);
+static void __init its_apply_mitigation(void);
 
 /* The base value of the SPEC_CTRL MSR without task-specific bits set */
 u64 x86_spec_ctrl_base;
@@ -235,6 +237,11 @@ void __init cpu_select_mitigations(void)
 	 * spectre_v2=ibrs.
 	 */
 	retbleed_update_mitigation();
+	/*
+	 * its_update_mitigation() depends on spectre_v2_update_mitigation()
+	 * and retbleed_update_mitigation().
+	 */
+	its_update_mitigation();
 
 	/*
 	 * spectre_v2_user_update_mitigation() depends on
@@ -263,6 +270,7 @@ void __init cpu_select_mitigations(void)
 	srbds_apply_mitigation();
 	srso_apply_mitigation();
 	gds_apply_mitigation();
+	its_apply_mitigation();
 	bhi_apply_mitigation();
 }
 
@@ -1125,6 +1133,14 @@ enum retbleed_mitigation {
 	RETBLEED_MITIGATION_STUFF,
 };
 
+enum its_mitigation {
+	ITS_MITIGATION_OFF,
+	ITS_MITIGATION_AUTO,
+	ITS_MITIGATION_VMEXIT_ONLY,
+	ITS_MITIGATION_ALIGNED_THUNKS,
+	ITS_MITIGATION_RETPOLINE_STUFF,
+};
+
 static const char * const retbleed_strings[] = {
 	[RETBLEED_MITIGATION_NONE]	= "Vulnerable",
 	[RETBLEED_MITIGATION_UNRET]	= "Mitigation: untrained return thunk",
@@ -1137,6 +1153,9 @@ static const char * const retbleed_strings[] = {
 static enum retbleed_mitigation retbleed_mitigation __ro_after_init =
 	IS_ENABLED(CONFIG_MITIGATION_RETBLEED) ? RETBLEED_MITIGATION_AUTO : RETBLEED_MITIGATION_NONE;
 
+static enum its_mitigation its_mitigation __ro_after_init =
+	IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_MITIGATION_AUTO : ITS_MITIGATION_OFF;
+
 static int __ro_after_init retbleed_nosmt = false;
 
 static int __init retbleed_parse_cmdline(char *str)
@@ -1242,11 +1261,19 @@ static void __init retbleed_update_mitigation(void)
 	/*
 	 * retbleed=stuff is only allowed on Intel.  If stuffing can't be used
 	 * then a different mitigation will be selected below.
+	 *
+	 * its=stuff will also attempt to enable stuffing.
 	 */
-	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF) {
+	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF ||
+	    its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF) {
 		if (spectre_v2_enabled != SPECTRE_V2_RETPOLINE) {
 			pr_err("WARNING: retbleed=stuff depends on spectre_v2=retpoline\n");
 			retbleed_mitigation = RETBLEED_MITIGATION_AUTO;
+		} else {
+			if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
+				pr_info("Retbleed mitigation updated to stuffing\n");
+
+			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
 		}
 	}
 	/*
@@ -1338,20 +1365,6 @@ static void __init retbleed_apply_mitigation(void)
 #undef pr_fmt
 #define pr_fmt(fmt)     "ITS: " fmt
 
-enum its_mitigation_cmd {
-	ITS_CMD_OFF,
-	ITS_CMD_ON,
-	ITS_CMD_VMEXIT,
-	ITS_CMD_RSB_STUFF,
-};
-
-enum its_mitigation {
-	ITS_MITIGATION_OFF,
-	ITS_MITIGATION_VMEXIT_ONLY,
-	ITS_MITIGATION_ALIGNED_THUNKS,
-	ITS_MITIGATION_RETPOLINE_STUFF,
-};
-
 static const char * const its_strings[] = {
 	[ITS_MITIGATION_OFF]			= "Vulnerable",
 	[ITS_MITIGATION_VMEXIT_ONLY]		= "Mitigation: Vulnerable, KVM: Not affected",
@@ -1359,11 +1372,6 @@ static const char * const its_strings[] = {
 	[ITS_MITIGATION_RETPOLINE_STUFF]	= "Mitigation: Retpolines, Stuffing RSB",
 };
 
-static enum its_mitigation its_mitigation __ro_after_init = ITS_MITIGATION_ALIGNED_THUNKS;
-
-static enum its_mitigation_cmd its_cmd __ro_after_init =
-	IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_CMD_ON : ITS_CMD_OFF;
-
 static int __init its_parse_cmdline(char *str)
 {
 	if (!str)
@@ -1375,16 +1383,16 @@ static int __init its_parse_cmdline(char *str)
 	}
 
 	if (!strcmp(str, "off")) {
-		its_cmd = ITS_CMD_OFF;
+		its_mitigation = ITS_MITIGATION_OFF;
 	} else if (!strcmp(str, "on")) {
-		its_cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 	} else if (!strcmp(str, "force")) {
-		its_cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 		setup_force_cpu_bug(X86_BUG_ITS);
 	} else if (!strcmp(str, "vmexit")) {
-		its_cmd = ITS_CMD_VMEXIT;
+		its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
 	} else if (!strcmp(str, "stuff")) {
-		its_cmd = ITS_CMD_RSB_STUFF;
+		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
 	} else {
 		pr_err("Ignoring unknown indirect_target_selection option (%s).", str);
 	}
@@ -1395,85 +1403,90 @@ early_param("indirect_target_selection", its_parse_cmdline);
 
 static void __init its_select_mitigation(void)
 {
-	enum its_mitigation_cmd cmd = its_cmd;
-
 	if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off()) {
 		its_mitigation = ITS_MITIGATION_OFF;
 		return;
 	}
 
-	/* Retpoline+CDT mitigates ITS, bail out */
-	if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
-	    boot_cpu_has(X86_FEATURE_CALL_DEPTH)) {
-		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
-		goto out;
-	}
+	if (its_mitigation == ITS_MITIGATION_AUTO)
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+
+	if (its_mitigation == ITS_MITIGATION_OFF)
+		return;
 
-	/* Exit early to avoid irrelevant warnings */
-	if (cmd == ITS_CMD_OFF) {
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
-	if (spectre_v2_enabled == SPECTRE_V2_NONE) {
-		pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
 	if (!IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) ||
 	    !IS_ENABLED(CONFIG_MITIGATION_RETHUNK)) {
 		pr_err("WARNING: ITS mitigation depends on retpoline and rethunk support\n");
 		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
+		return;
 	}
+
 	if (IS_ENABLED(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)) {
 		pr_err("WARNING: ITS mitigation is not compatible with CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B\n");
 		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
-	if (boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) {
-		pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
+		return;
 	}
 
-	if (cmd == ITS_CMD_RSB_STUFF &&
-	    (!boot_cpu_has(X86_FEATURE_RETPOLINE) || !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))) {
+	if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
+	    !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING)) {
 		pr_err("RSB stuff mitigation not supported, using default\n");
-		cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 	}
 
-	switch (cmd) {
-	case ITS_CMD_OFF:
+	if (its_mitigation == ITS_MITIGATION_VMEXIT_ONLY &&
+	    !boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY))
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+}
+
+static void __init its_update_mitigation(void)
+{
+	if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off())
+		return;
+
+	switch (spectre_v2_enabled) {
+	case SPECTRE_V2_NONE:
+		pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
 		its_mitigation = ITS_MITIGATION_OFF;
 		break;
-	case ITS_CMD_VMEXIT:
-		if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
-			its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
-			goto out;
-		}
-		fallthrough;
-	case ITS_CMD_ON:
-		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
-		if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
-			setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
-		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
-		set_return_thunk(its_return_thunk);
+	case SPECTRE_V2_RETPOLINE:
+		/* Retpoline+CDT mitigates ITS */
+		if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF)
+			its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
 		break;
-	case ITS_CMD_RSB_STUFF:
-		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
-		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
-		setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH);
-		set_return_thunk(call_depth_return_thunk);
-		if (retbleed_mitigation == RETBLEED_MITIGATION_NONE) {
-			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
-			pr_info("Retbleed mitigation updated to stuffing\n");
-		}
+	case SPECTRE_V2_LFENCE:
+	case SPECTRE_V2_EIBRS_LFENCE:
+		pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
+		its_mitigation = ITS_MITIGATION_OFF;
+		break;
+	default:
 		break;
 	}
-out:
+
+	/*
+	 * retbleed_update_mitigation() will try to do stuffing if its=stuff.
+	 * If it can't, such as if spectre_v2!=retpoline, then fall back to
+	 * aligned thunks.
+	 */
+	if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
+	    retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+
 	pr_info("%s\n", its_strings[its_mitigation]);
 }
 
+static void __init its_apply_mitigation(void)
+{
+	/* its=stuff forces retbleed stuffing and is enabled there. */
+	if (its_mitigation != ITS_MITIGATION_ALIGNED_THUNKS)
+		return;
+
+	if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
+		setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
+
+	setup_force_cpu_cap(X86_FEATURE_RETHUNK);
+	set_return_thunk(its_return_thunk);
+}
+
 #undef pr_fmt
 #define pr_fmt(fmt)     "Spectre V2 : " fmt
 

base-commit: 04bdd560124ec4d02d1d11ee3abc88d51954d7b8
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH] x86/bugs: Restructure ITS mitigation
  2025-05-15 13:47 [PATCH] x86/bugs: Restructure ITS mitigation David Kaplan
@ 2025-05-15 15:16 ` Borislav Petkov
  2025-05-15 21:11 ` Pawan Gupta
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 18+ messages in thread
From: Borislav Petkov @ 2025-05-15 15:16 UTC (permalink / raw)
  To: David Kaplan
  Cc: Thomas Gleixner, Peter Zijlstra, Josh Poimboeuf, Pawan Gupta,
	Ingo Molnar, Dave Hansen, x86, H. Peter Anvin, linux-kernel

On Thu, May 15, 2025 at 08:47:56AM -0500, David Kaplan wrote:
> @@ -1242,11 +1261,19 @@ static void __init retbleed_update_mitigation(void)
>  	/*
>  	 * retbleed=stuff is only allowed on Intel.  If stuffing can't be used
>  	 * then a different mitigation will be selected below.
> +	 *
> +	 * its=stuff will also attempt to enable stuffing.
>  	 */
> -	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF) {
> +	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF ||
> +	    its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF) {
>  		if (spectre_v2_enabled != SPECTRE_V2_RETPOLINE) {
>  			pr_err("WARNING: retbleed=stuff depends on spectre_v2=retpoline\n");
>  			retbleed_mitigation = RETBLEED_MITIGATION_AUTO;
> +		} else {
> +			if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
> +				pr_info("Retbleed mitigation updated to stuffing\n");

I've seen this patch offlist already so only one thing about this here above
which is already there in the current tree.

Let's zap it. One can see to what the retbleed mitigation was updated by other
means. No need to add more spaghetti to the code.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] x86/bugs: Restructure ITS mitigation
  2025-05-15 13:47 [PATCH] x86/bugs: Restructure ITS mitigation David Kaplan
  2025-05-15 15:16 ` Borislav Petkov
@ 2025-05-15 21:11 ` Pawan Gupta
  2025-05-15 21:15   ` Kaplan, David
  2025-05-15 23:52 ` Pawan Gupta
  2025-05-16 19:32 ` [PATCH v2] " David Kaplan
  3 siblings, 1 reply; 18+ messages in thread
From: Pawan Gupta @ 2025-05-15 21:11 UTC (permalink / raw)
  To: David Kaplan
  Cc: Thomas Gleixner, Borislav Petkov, Peter Zijlstra, Josh Poimboeuf,
	Ingo Molnar, Dave Hansen, x86, H. Peter Anvin, linux-kernel

On Thu, May 15, 2025 at 08:47:56AM -0500, David Kaplan wrote:
...
> +static void __init its_apply_mitigation(void)
> +{
> +	/* its=stuff forces retbleed stuffing and is enabled there. */
> +	if (its_mitigation != ITS_MITIGATION_ALIGNED_THUNKS)
> +		return;
> +
> +	if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
> +		setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
> +
> +	setup_force_cpu_cap(X86_FEATURE_RETHUNK);
> +	set_return_thunk(its_return_thunk);
> +}
> +
>  #undef pr_fmt
>  #define pr_fmt(fmt)     "Spectre V2 : " fmt
>  
> 
> base-commit: 04bdd560124ec4d02d1d11ee3abc88d51954d7b8

I am having trouble applying this patch to upstream and tip/master. I can't
seem to find this base-commit in Linus's or tip tree. Please let me know
what am I missing?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH] x86/bugs: Restructure ITS mitigation
  2025-05-15 21:11 ` Pawan Gupta
@ 2025-05-15 21:15   ` Kaplan, David
  2025-05-15 22:02     ` Pawan Gupta
  0 siblings, 1 reply; 18+ messages in thread
From: Kaplan, David @ 2025-05-15 21:15 UTC (permalink / raw)
  To: Pawan Gupta
  Cc: Thomas Gleixner, Borislav Petkov, Peter Zijlstra, Josh Poimboeuf,
	Ingo Molnar, Dave Hansen, x86@kernel.org, H. Peter Anvin,
	linux-kernel@vger.kernel.org

[AMD Official Use Only - AMD Internal Distribution Only]

> -----Original Message-----
> From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
> Sent: Thursday, May 15, 2025 4:12 PM
> To: Kaplan, David <David.Kaplan@amd.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>; Borislav Petkov <bp@alien8.de>; Peter
> Zijlstra <peterz@infradead.org>; Josh Poimboeuf <jpoimboe@kernel.org>; Ingo
> Molnar <mingo@redhat.com>; Dave Hansen <dave.hansen@linux.intel.com>;
> x86@kernel.org; H. Peter Anvin <hpa@zytor.com>; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH] x86/bugs: Restructure ITS mitigation
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> On Thu, May 15, 2025 at 08:47:56AM -0500, David Kaplan wrote:
> ...
> > +static void __init its_apply_mitigation(void) {
> > +     /* its=stuff forces retbleed stuffing and is enabled there. */
> > +     if (its_mitigation != ITS_MITIGATION_ALIGNED_THUNKS)
> > +             return;
> > +
> > +     if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
> > +             setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
> > +
> > +     setup_force_cpu_cap(X86_FEATURE_RETHUNK);
> > +     set_return_thunk(its_return_thunk);
> > +}
> > +
> >  #undef pr_fmt
> >  #define pr_fmt(fmt)     "Spectre V2 : " fmt
> >
> >
> > base-commit: 04bdd560124ec4d02d1d11ee3abc88d51954d7b8
>
> I am having trouble applying this patch to upstream and tip/master. I can't seem to
> find this base-commit in Linus's or tip tree. Please let me know what am I missing?

Hmm.  I was working off origin/master on tip.  This was the base commit in my git log from this morning:

commit 04bdd560124ec4d02d1d11ee3abc88d51954d7b8 (origin/master, origin/HEAD)
Merge: 61e94712bb24 e59236b5a09e
Author: Ingo Molnar <mingo@kernel.org>
Date:   Thu May 15 10:16:23 2025 +0200

Not sure if something happened to it since?  Or is there something else I can provide to help?

--David Kaplan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] x86/bugs: Restructure ITS mitigation
  2025-05-15 21:15   ` Kaplan, David
@ 2025-05-15 22:02     ` Pawan Gupta
  2025-05-16 14:56       ` Borislav Petkov
  0 siblings, 1 reply; 18+ messages in thread
From: Pawan Gupta @ 2025-05-15 22:02 UTC (permalink / raw)
  To: Kaplan, David
  Cc: Thomas Gleixner, Borislav Petkov, Peter Zijlstra, Josh Poimboeuf,
	Ingo Molnar, Dave Hansen, x86@kernel.org, H. Peter Anvin,
	linux-kernel@vger.kernel.org

On Thu, May 15, 2025 at 09:15:59PM +0000, Kaplan, David wrote:
> [AMD Official Use Only - AMD Internal Distribution Only]
> 
> > -----Original Message-----
> > From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
> > Sent: Thursday, May 15, 2025 4:12 PM
> > To: Kaplan, David <David.Kaplan@amd.com>
> > Cc: Thomas Gleixner <tglx@linutronix.de>; Borislav Petkov <bp@alien8.de>; Peter
> > Zijlstra <peterz@infradead.org>; Josh Poimboeuf <jpoimboe@kernel.org>; Ingo
> > Molnar <mingo@redhat.com>; Dave Hansen <dave.hansen@linux.intel.com>;
> > x86@kernel.org; H. Peter Anvin <hpa@zytor.com>; linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH] x86/bugs: Restructure ITS mitigation
> >
> > Caution: This message originated from an External Source. Use proper caution
> > when opening attachments, clicking links, or responding.
> >
> >
> > On Thu, May 15, 2025 at 08:47:56AM -0500, David Kaplan wrote:
> > ...
> > > +static void __init its_apply_mitigation(void) {
> > > +     /* its=stuff forces retbleed stuffing and is enabled there. */
> > > +     if (its_mitigation != ITS_MITIGATION_ALIGNED_THUNKS)
> > > +             return;
> > > +
> > > +     if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
> > > +             setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
> > > +
> > > +     setup_force_cpu_cap(X86_FEATURE_RETHUNK);
> > > +     set_return_thunk(its_return_thunk);
> > > +}
> > > +
> > >  #undef pr_fmt
> > >  #define pr_fmt(fmt)     "Spectre V2 : " fmt
> > >
> > >
> > > base-commit: 04bdd560124ec4d02d1d11ee3abc88d51954d7b8
> >
> > I am having trouble applying this patch to upstream and tip/master. I can't seem to
> > find this base-commit in Linus's or tip tree. Please let me know what am I missing?
> 
> Hmm.  I was working off origin/master on tip.  This was the base commit in my git log from this morning:
> 
> commit 04bdd560124ec4d02d1d11ee3abc88d51954d7b8 (origin/master, origin/HEAD)
> Merge: 61e94712bb24 e59236b5a09e
> Author: Ingo Molnar <mingo@kernel.org>
> Date:   Thu May 15 10:16:23 2025 +0200
> 
> Not sure if something happened to it since?

Likely yes. I am getting:

	Notice: this object is not reachable from any branch.

when I go to this link:

https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit?id=04bdd560124ec4d02d1d11ee3abc88d51954d7b8

> Or is there something else I can provide to help?

No, I am able to apply now. Earlier my b4 based script failed because it
couldn't find the base-commit. It works when I am apply manually, sorry to
bother you.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] x86/bugs: Restructure ITS mitigation
  2025-05-15 13:47 [PATCH] x86/bugs: Restructure ITS mitigation David Kaplan
  2025-05-15 15:16 ` Borislav Petkov
  2025-05-15 21:11 ` Pawan Gupta
@ 2025-05-15 23:52 ` Pawan Gupta
  2025-05-16 15:06   ` Kaplan, David
  2025-05-16 19:32 ` [PATCH v2] " David Kaplan
  3 siblings, 1 reply; 18+ messages in thread
From: Pawan Gupta @ 2025-05-15 23:52 UTC (permalink / raw)
  To: David Kaplan
  Cc: Thomas Gleixner, Borislav Petkov, Peter Zijlstra, Josh Poimboeuf,
	Ingo Molnar, Dave Hansen, x86, H. Peter Anvin, linux-kernel

On Thu, May 15, 2025 at 08:47:56AM -0500, David Kaplan wrote:
> Restructure the ITS mitigation to use select/update/apply functions like
> the other mitigations.
> 
> There is a particularly complex interaction between ITS and Retbleed as CDT
> (Call Depth Tracking) is a mitigation for both, and either its=stuff or
> retbleed=stuff will attempt to enable CDT.
> 
> retbleed_update_mitigation() runs first and will check the necessary
> pre-conditions for CDT if either ITS or Retbleed stuffing is selected.  If
> checks pass and ITS stuffing is selected, it will select stuffing for
> Retbleed as well.
> 
> its_update_mitigation() runs after and will either select stuffing if
> retbleed stuffing was enabled, or fall back to the default (aligned thunks)
> if stuffing could not be enabled.
> 
> Enablement of CDT is done exclusively in retbleed_apply_mitigation().
> its_apply_mitigation() is only used to enable aligned thunks.
> 
> Signed-off-by: David Kaplan <david.kaplan@amd.com>
> ---
>  arch/x86/kernel/cpu/bugs.c | 167 ++++++++++++++++++++-----------------
>  1 file changed, 90 insertions(+), 77 deletions(-)
> 
> diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
> index dd8b50b4ceaa..db26fb5a0a13 100644
> --- a/arch/x86/kernel/cpu/bugs.c
> +++ b/arch/x86/kernel/cpu/bugs.c
> @@ -92,6 +92,8 @@ static void __init bhi_select_mitigation(void);
>  static void __init bhi_update_mitigation(void);
>  static void __init bhi_apply_mitigation(void);
>  static void __init its_select_mitigation(void);
> +static void __init its_update_mitigation(void);
> +static void __init its_apply_mitigation(void);
>  
>  /* The base value of the SPEC_CTRL MSR without task-specific bits set */
>  u64 x86_spec_ctrl_base;
> @@ -235,6 +237,11 @@ void __init cpu_select_mitigations(void)
>  	 * spectre_v2=ibrs.
>  	 */
>  	retbleed_update_mitigation();
> +	/*
> +	 * its_update_mitigation() depends on spectre_v2_update_mitigation()
> +	 * and retbleed_update_mitigation().
> +	 */
> +	its_update_mitigation();
>  
>  	/*
>  	 * spectre_v2_user_update_mitigation() depends on
> @@ -263,6 +270,7 @@ void __init cpu_select_mitigations(void)
>  	srbds_apply_mitigation();
>  	srso_apply_mitigation();
>  	gds_apply_mitigation();
> +	its_apply_mitigation();
>  	bhi_apply_mitigation();
>  }
>  
> @@ -1125,6 +1133,14 @@ enum retbleed_mitigation {
>  	RETBLEED_MITIGATION_STUFF,
>  };
>  
> +enum its_mitigation {
> +	ITS_MITIGATION_OFF,
> +	ITS_MITIGATION_AUTO,
> +	ITS_MITIGATION_VMEXIT_ONLY,
> +	ITS_MITIGATION_ALIGNED_THUNKS,
> +	ITS_MITIGATION_RETPOLINE_STUFF,
> +};

This is in between retbleed declarations, I would suggest to move this
before retbleed mitigation starts.

enum its_mitigation {
        ITS_MITIGATION_OFF,
        ITS_MITIGATION_AUTO,
        ITS_MITIGATION_VMEXIT_ONLY,
        ITS_MITIGATION_ALIGNED_THUNKS,
        ITS_MITIGATION_RETPOLINE_STUFF,
};

static enum its_mitigation its_mitigation __ro_after_init =
        IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_MITIGATION_AUTO : ITS_MITIGATION_OFF;

#undef pr_fmt
#define pr_fmt(fmt)     "RETBleed: " fmt

enum retbleed_mitigation {

>  static const char * const retbleed_strings[] = {
>  	[RETBLEED_MITIGATION_NONE]	= "Vulnerable",
>  	[RETBLEED_MITIGATION_UNRET]	= "Mitigation: untrained return thunk",
> @@ -1137,6 +1153,9 @@ static const char * const retbleed_strings[] = {
>  static enum retbleed_mitigation retbleed_mitigation __ro_after_init =
>  	IS_ENABLED(CONFIG_MITIGATION_RETBLEED) ? RETBLEED_MITIGATION_AUTO : RETBLEED_MITIGATION_NONE;
>  
> +static enum its_mitigation its_mitigation __ro_after_init =
> +	IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_MITIGATION_AUTO : ITS_MITIGATION_OFF;

Ditto.

>  static int __ro_after_init retbleed_nosmt = false;
>  
>  static int __init retbleed_parse_cmdline(char *str)
> @@ -1242,11 +1261,19 @@ static void __init retbleed_update_mitigation(void)
>  	/*
>  	 * retbleed=stuff is only allowed on Intel.  If stuffing can't be used
>  	 * then a different mitigation will be selected below.
> +	 *
> +	 * its=stuff will also attempt to enable stuffing.
>  	 */
> -	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF) {
> +	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF ||
> +	    its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF) {
>  		if (spectre_v2_enabled != SPECTRE_V2_RETPOLINE) {

SPECTRE_V2_EIBRS_RETPOLINE also enables retpoline.

>  			pr_err("WARNING: retbleed=stuff depends on spectre_v2=retpoline\n");

This can be updated to:

  			pr_err("WARNING: retbleed=stuff depends on retpoline\n");

>  			retbleed_mitigation = RETBLEED_MITIGATION_AUTO;
> +		} else {
> +			if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
> +				pr_info("Retbleed mitigation updated to stuffing\n");
> +
> +			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
>  		}
>  	}
>  	/*
> @@ -1338,20 +1365,6 @@ static void __init retbleed_apply_mitigation(void)
>  #undef pr_fmt
>  #define pr_fmt(fmt)     "ITS: " fmt
>  
> -enum its_mitigation_cmd {
> -	ITS_CMD_OFF,
> -	ITS_CMD_ON,
> -	ITS_CMD_VMEXIT,
> -	ITS_CMD_RSB_STUFF,
> -};
> -
> -enum its_mitigation {
> -	ITS_MITIGATION_OFF,
> -	ITS_MITIGATION_VMEXIT_ONLY,
> -	ITS_MITIGATION_ALIGNED_THUNKS,
> -	ITS_MITIGATION_RETPOLINE_STUFF,
> -};
> -
>  static const char * const its_strings[] = {
>  	[ITS_MITIGATION_OFF]			= "Vulnerable",
>  	[ITS_MITIGATION_VMEXIT_ONLY]		= "Mitigation: Vulnerable, KVM: Not affected",
> @@ -1359,11 +1372,6 @@ static const char * const its_strings[] = {
>  	[ITS_MITIGATION_RETPOLINE_STUFF]	= "Mitigation: Retpolines, Stuffing RSB",
>  };
>  
> -static enum its_mitigation its_mitigation __ro_after_init = ITS_MITIGATION_ALIGNED_THUNKS;
> -
> -static enum its_mitigation_cmd its_cmd __ro_after_init =
> -	IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_CMD_ON : ITS_CMD_OFF;
> -
>  static int __init its_parse_cmdline(char *str)
>  {
>  	if (!str)
> @@ -1375,16 +1383,16 @@ static int __init its_parse_cmdline(char *str)
>  	}
>  
>  	if (!strcmp(str, "off")) {
> -		its_cmd = ITS_CMD_OFF;
> +		its_mitigation = ITS_MITIGATION_OFF;
>  	} else if (!strcmp(str, "on")) {
> -		its_cmd = ITS_CMD_ON;
> +		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
>  	} else if (!strcmp(str, "force")) {
> -		its_cmd = ITS_CMD_ON;
> +		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
>  		setup_force_cpu_bug(X86_BUG_ITS);
>  	} else if (!strcmp(str, "vmexit")) {
> -		its_cmd = ITS_CMD_VMEXIT;
> +		its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
>  	} else if (!strcmp(str, "stuff")) {
> -		its_cmd = ITS_CMD_RSB_STUFF;
> +		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
>  	} else {
>  		pr_err("Ignoring unknown indirect_target_selection option (%s).", str);
>  	}
> @@ -1395,85 +1403,90 @@ early_param("indirect_target_selection", its_parse_cmdline);
>  
>  static void __init its_select_mitigation(void)
>  {
> -	enum its_mitigation_cmd cmd = its_cmd;
> -
>  	if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off()) {
>  		its_mitigation = ITS_MITIGATION_OFF;
>  		return;
>  	}
>  
> -	/* Retpoline+CDT mitigates ITS, bail out */
> -	if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
> -	    boot_cpu_has(X86_FEATURE_CALL_DEPTH)) {
> -		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
> -		goto out;
> -	}
> +	if (its_mitigation == ITS_MITIGATION_AUTO)
> +		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
> +
> +	if (its_mitigation == ITS_MITIGATION_OFF)
> +		return;
>  
> -	/* Exit early to avoid irrelevant warnings */
> -	if (cmd == ITS_CMD_OFF) {
> -		its_mitigation = ITS_MITIGATION_OFF;
> -		goto out;
> -	}
> -	if (spectre_v2_enabled == SPECTRE_V2_NONE) {
> -		pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
> -		its_mitigation = ITS_MITIGATION_OFF;
> -		goto out;
> -	}
>  	if (!IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) ||
>  	    !IS_ENABLED(CONFIG_MITIGATION_RETHUNK)) {
>  		pr_err("WARNING: ITS mitigation depends on retpoline and rethunk support\n");
>  		its_mitigation = ITS_MITIGATION_OFF;
> -		goto out;
> +		return;
>  	}
> +
>  	if (IS_ENABLED(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)) {
>  		pr_err("WARNING: ITS mitigation is not compatible with CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B\n");
>  		its_mitigation = ITS_MITIGATION_OFF;
> -		goto out;
> -	}
> -	if (boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) {
> -		pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
> -		its_mitigation = ITS_MITIGATION_OFF;
> -		goto out;
> +		return;
>  	}
>  
> -	if (cmd == ITS_CMD_RSB_STUFF &&
> -	    (!boot_cpu_has(X86_FEATURE_RETPOLINE) || !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))) {
> +	if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
> +	    !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING)) {
>  		pr_err("RSB stuff mitigation not supported, using default\n");
> -		cmd = ITS_CMD_ON;
> +		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;

This and ...

>  	}
>  
> -	switch (cmd) {
> -	case ITS_CMD_OFF:
> +	if (its_mitigation == ITS_MITIGATION_VMEXIT_ONLY &&
> +	    !boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY))
> +		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;

... this are essentially resetting the mitigation to default. This will be
more clear if you could change the mitigation to ITS_MITIGATION_AUTO here,
and at the end have:

	if (its_mitigation == ITS_MITIGATION_AUTO)
		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
> +
> +}
> +
> +static void __init its_update_mitigation(void)
> +{
> +	if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off())
> +		return;
> +
> +	switch (spectre_v2_enabled) {
> +	case SPECTRE_V2_NONE:
> +		pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
>  		its_mitigation = ITS_MITIGATION_OFF;
>  		break;
> -	case ITS_CMD_VMEXIT:
> -		if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
> -			its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
> -			goto out;
> -		}
> -		fallthrough;
> -	case ITS_CMD_ON:
> -		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
> -		if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
> -			setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
> -		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
> -		set_return_thunk(its_return_thunk);
> +	case SPECTRE_V2_RETPOLINE:

Also SPECTRE_V2_EIBRS_RETPOLINE.

> +		/* Retpoline+CDT mitigates ITS */
> +		if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF)



> +			its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
>  		break;
> -	case ITS_CMD_RSB_STUFF:
> -		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
> -		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
> -		setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH);
> -		set_return_thunk(call_depth_return_thunk);
> -		if (retbleed_mitigation == RETBLEED_MITIGATION_NONE) {
> -			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
> -			pr_info("Retbleed mitigation updated to stuffing\n");
> -		}
> +	case SPECTRE_V2_LFENCE:
> +	case SPECTRE_V2_EIBRS_LFENCE:
> +		pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
> +		its_mitigation = ITS_MITIGATION_OFF;
> +		break;
> +	default:
>  		break;
>  	}
> -out:
> +
> +	/*
> +	 * retbleed_update_mitigation() will try to do stuffing if its=stuff.
> +	 * If it can't, such as if spectre_v2!=retpoline, then fall back to
> +	 * aligned thunks.
> +	 */
> +	if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
> +	    retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
> +		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;

The =stuff mitigation depends on retpoline, not really on retbleed.
Shouldn't this be handled in the switch (spectre_v2_enabled) above?

>  	pr_info("%s\n", its_strings[its_mitigation]);
>  }
>  
> +static void __init its_apply_mitigation(void)
> +{
> +	/* its=stuff forces retbleed stuffing and is enabled there. */

Oh, this is why you are depending on retbleed_mitigation above, this part is
a bit confusing.

Will think about it more later, trying to have a couple of days off.

> +	if (its_mitigation != ITS_MITIGATION_ALIGNED_THUNKS)
> +		return;
> +
> +	if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
> +		setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
> +
> +	setup_force_cpu_cap(X86_FEATURE_RETHUNK);
> +	set_return_thunk(its_return_thunk);
> +}

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] x86/bugs: Restructure ITS mitigation
  2025-05-15 22:02     ` Pawan Gupta
@ 2025-05-16 14:56       ` Borislav Petkov
  0 siblings, 0 replies; 18+ messages in thread
From: Borislav Petkov @ 2025-05-16 14:56 UTC (permalink / raw)
  To: Pawan Gupta
  Cc: Kaplan, David, Thomas Gleixner, Peter Zijlstra, Josh Poimboeuf,
	Ingo Molnar, Dave Hansen, x86@kernel.org, H. Peter Anvin,
	linux-kernel@vger.kernel.org

On Thu, May 15, 2025 at 03:02:43PM -0700, Pawan Gupta wrote:
> No, I am able to apply now. Earlier my b4 based script failed because it
> couldn't find the base-commit. It works when I am apply manually, sorry to
> bother you.

Yah, tip/master changes very often and gets regenerated so the top-most commit
is gone. Just apply manually.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH] x86/bugs: Restructure ITS mitigation
  2025-05-15 23:52 ` Pawan Gupta
@ 2025-05-16 15:06   ` Kaplan, David
  2025-05-19 23:51     ` Pawan Gupta
  0 siblings, 1 reply; 18+ messages in thread
From: Kaplan, David @ 2025-05-16 15:06 UTC (permalink / raw)
  To: Pawan Gupta
  Cc: Thomas Gleixner, Borislav Petkov, Peter Zijlstra, Josh Poimboeuf,
	Ingo Molnar, Dave Hansen, x86@kernel.org, H. Peter Anvin,
	linux-kernel@vger.kernel.org

[AMD Official Use Only - AMD Internal Distribution Only]

> -----Original Message-----
> From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
> Sent: Thursday, May 15, 2025 6:52 PM
> To: Kaplan, David <David.Kaplan@amd.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>; Borislav Petkov <bp@alien8.de>;
> Peter Zijlstra <peterz@infradead.org>; Josh Poimboeuf <jpoimboe@kernel.org>;
> Ingo Molnar <mingo@redhat.com>; Dave Hansen
> <dave.hansen@linux.intel.com>; x86@kernel.org; H. Peter Anvin
> <hpa@zytor.com>; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH] x86/bugs: Restructure ITS mitigation
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> On Thu, May 15, 2025 at 08:47:56AM -0500, David Kaplan wrote:
> > Restructure the ITS mitigation to use select/update/apply functions
> > like the other mitigations.
> >
> > There is a particularly complex interaction between ITS and Retbleed
> > as CDT (Call Depth Tracking) is a mitigation for both, and either
> > its=stuff or retbleed=stuff will attempt to enable CDT.
> >
> > retbleed_update_mitigation() runs first and will check the necessary
> > pre-conditions for CDT if either ITS or Retbleed stuffing is selected.
> > If checks pass and ITS stuffing is selected, it will select stuffing
> > for Retbleed as well.
> >
> > its_update_mitigation() runs after and will either select stuffing if
> > retbleed stuffing was enabled, or fall back to the default (aligned
> > thunks) if stuffing could not be enabled.
> >
> > Enablement of CDT is done exclusively in retbleed_apply_mitigation().
> > its_apply_mitigation() is only used to enable aligned thunks.
> >
> > Signed-off-by: David Kaplan <david.kaplan@amd.com>
> >
> > @@ -1125,6 +1133,14 @@ enum retbleed_mitigation {
> >       RETBLEED_MITIGATION_STUFF,
> >  };
> >
> > +enum its_mitigation {
> > +     ITS_MITIGATION_OFF,
> > +     ITS_MITIGATION_AUTO,
> > +     ITS_MITIGATION_VMEXIT_ONLY,
> > +     ITS_MITIGATION_ALIGNED_THUNKS,
> > +     ITS_MITIGATION_RETPOLINE_STUFF,
> > +};
>
> This is in between retbleed declarations, I would suggest to move this before
> retbleed mitigation starts.

Ok

>
> enum its_mitigation {
>         ITS_MITIGATION_OFF,
>         ITS_MITIGATION_AUTO,
>         ITS_MITIGATION_VMEXIT_ONLY,
>         ITS_MITIGATION_ALIGNED_THUNKS,
>         ITS_MITIGATION_RETPOLINE_STUFF,
> };
>
> static enum its_mitigation its_mitigation __ro_after_init =
>         IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_MITIGATION_AUTO :
> ITS_MITIGATION_OFF;
>
> #undef pr_fmt
> #define pr_fmt(fmt)     "RETBleed: " fmt
>
> enum retbleed_mitigation {
>
> >  static const char * const retbleed_strings[] = {
> >       [RETBLEED_MITIGATION_NONE]      = "Vulnerable",
> >       [RETBLEED_MITIGATION_UNRET]     = "Mitigation: untrained return thunk",
> > @@ -1137,6 +1153,9 @@ static const char * const retbleed_strings[] = {
> > static enum retbleed_mitigation retbleed_mitigation __ro_after_init =
> >       IS_ENABLED(CONFIG_MITIGATION_RETBLEED) ?
> > RETBLEED_MITIGATION_AUTO : RETBLEED_MITIGATION_NONE;
> >
> > +static enum its_mitigation its_mitigation __ro_after_init =
> > +     IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_MITIGATION_AUTO :
> > +ITS_MITIGATION_OFF;
>
> Ditto.
>
> >  static int __ro_after_init retbleed_nosmt = false;
> >
> >  static int __init retbleed_parse_cmdline(char *str) @@ -1242,11
> > +1261,19 @@ static void __init retbleed_update_mitigation(void)
> >       /*
> >        * retbleed=stuff is only allowed on Intel.  If stuffing can't be used
> >        * then a different mitigation will be selected below.
> > +      *
> > +      * its=stuff will also attempt to enable stuffing.
> >        */
> > -     if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF) {
> > +     if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF ||
> > +         its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF) {
> >               if (spectre_v2_enabled != SPECTRE_V2_RETPOLINE) {
>
> SPECTRE_V2_EIBRS_RETPOLINE also enables retpoline.
>
> >                       pr_err("WARNING: retbleed=stuff depends on
> > spectre_v2=retpoline\n");
>
> This can be updated to:
>
>                         pr_err("WARNING: retbleed=stuff depends on retpoline\n");
>

Yeah, I noticed that too.  But the existing upstream code (before my re-write) was also only checking spectre_v2_enabled == SPECTRE_V2_RETPOLINE in retbleed_select_mitigation().

So it seems like CDT previously wasn't supported with spectre_v2=eibrs,retpoline.

If we want to change that, I suggest doing it in a separate patch.


> >       }
> >
> > -     if (cmd == ITS_CMD_RSB_STUFF &&
> > -         (!boot_cpu_has(X86_FEATURE_RETPOLINE) ||
> !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))) {
> > +     if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
> > +         !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING)) {
> >               pr_err("RSB stuff mitigation not supported, using default\n");
> > -             cmd = ITS_CMD_ON;
> > +             its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
>
> This and ...
>
> >       }
> >
> > -     switch (cmd) {
> > -     case ITS_CMD_OFF:
> > +     if (its_mitigation == ITS_MITIGATION_VMEXIT_ONLY &&
> > +         !boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY))
> > +             its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
>
> ... this are essentially resetting the mitigation to default. This will be more clear if
> you could change the mitigation to ITS_MITIGATION_AUTO here, and at the end
> have:
>
>         if (its_mitigation == ITS_MITIGATION_AUTO)
>                 its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;

The point of AUTO is really to say that no cmdline option was specified.  This is relevant for my attack vector patches because AUTO means "defer to the enabled attack vectors".

In the attack vector series, AUTO is checked early in the select function and the mitigation will be disabled if needed.  If it is needed, the default mitigation is chosen.

In the current code without attack vectors, AUTO just always means pick the default, but is really a preparatory thing for the attack vector support.

The code you highlighted deals with cases where an explicit cmdline option was specified asking for mitigation, but it can't be done.  Falling back to the default option is fine, but calling it AUTO I think would be confusing because AUTO (in the next patch series) means "defer to the attack vectors".  So I would prefer to leave the code as-is.


> > +
> > +}
> > +
> > +static void __init its_update_mitigation(void) {
> > +     if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off())
> > +             return;
> > +
> > +     switch (spectre_v2_enabled) {
> > +     case SPECTRE_V2_NONE:
> > +             pr_err("WARNING: Spectre-v2 mitigation is off, disabling
> > + ITS\n");
> >               its_mitigation = ITS_MITIGATION_OFF;
> >               break;
> > -     case ITS_CMD_VMEXIT:
> > -             if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
> > -                     its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
> > -                     goto out;
> > -             }
> > -             fallthrough;
> > -     case ITS_CMD_ON:
> > -             its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
> > -             if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
> > -                     setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
> > -             setup_force_cpu_cap(X86_FEATURE_RETHUNK);
> > -             set_return_thunk(its_return_thunk);
> > +     case SPECTRE_V2_RETPOLINE:
>
> Also SPECTRE_V2_EIBRS_RETPOLINE.

See above.

>
> > +             /* Retpoline+CDT mitigates ITS */
> > +             if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF)
>
>
>
> > +                     its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
> >               break;
> > -     case ITS_CMD_RSB_STUFF:
> > -             its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
> > -             setup_force_cpu_cap(X86_FEATURE_RETHUNK);
> > -             setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH);
> > -             set_return_thunk(call_depth_return_thunk);
> > -             if (retbleed_mitigation == RETBLEED_MITIGATION_NONE) {
> > -                     retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
> > -                     pr_info("Retbleed mitigation updated to stuffing\n");
> > -             }
> > +     case SPECTRE_V2_LFENCE:
> > +     case SPECTRE_V2_EIBRS_LFENCE:
> > +             pr_err("WARNING: ITS mitigation is not compatible with lfence
> mitigation\n");
> > +             its_mitigation = ITS_MITIGATION_OFF;
> > +             break;
> > +     default:
> >               break;
> >       }
> > -out:
> > +
> > +     /*
> > +      * retbleed_update_mitigation() will try to do stuffing if its=stuff.
> > +      * If it can't, such as if spectre_v2!=retpoline, then fall back to
> > +      * aligned thunks.
> > +      */
> > +     if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
> > +         retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
> > +             its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
>
> The =stuff mitigation depends on retpoline, not really on retbleed.
> Shouldn't this be handled in the switch (spectre_v2_enabled) above?
>
> >       pr_info("%s\n", its_strings[its_mitigation]);  }
> >
> > +static void __init its_apply_mitigation(void) {
> > +     /* its=stuff forces retbleed stuffing and is enabled there. */
>
> Oh, this is why you are depending on retbleed_mitigation above, this part is a bit
> confusing.
>
> Will think about it more later, trying to have a couple of days off.

It is a bit confusing, no argument there.  And why I spent most of the commit log trying to explain it :)

I do prefer this way of handling it though compared to the existing code.  The existing code would *change* retbleed_mitigation in its_select_mitigation() which I think is very confusing.  I believe the rule for these functions should be that xxx_mitigation is only ever modified in the xxx_select_mitigation() and xxx_update_mitigation() functions.

If there's another idea though (or a place where a comment might help), let me know.

Thanks --David Kaplan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2] x86/bugs: Restructure ITS mitigation
  2025-05-15 13:47 [PATCH] x86/bugs: Restructure ITS mitigation David Kaplan
                   ` (2 preceding siblings ...)
  2025-05-15 23:52 ` Pawan Gupta
@ 2025-05-16 19:32 ` David Kaplan
  2025-05-16 22:47   ` Dave Hansen
                     ` (3 more replies)
  3 siblings, 4 replies; 18+ messages in thread
From: David Kaplan @ 2025-05-16 19:32 UTC (permalink / raw)
  To: Thomas Gleixner, Borislav Petkov, Peter Zijlstra, Josh Poimboeuf,
	Pawan Gupta, Ingo Molnar, Dave Hansen, x86, H. Peter Anvin
  Cc: linux-kernel

Restructure the ITS mitigation to use select/update/apply functions like
the other mitigations.

There is a particularly complex interaction between ITS and Retbleed as CDT
(Call Depth Tracking) is a mitigation for both, and either its=stuff or
retbleed=stuff will attempt to enable CDT.

retbleed_update_mitigation() runs first and will check the necessary
pre-conditions for CDT if either ITS or Retbleed stuffing is selected.  If
checks pass and ITS stuffing is selected, it will select stuffing for
Retbleed as well.

its_update_mitigation() runs after and will either select stuffing if
retbleed stuffing was enabled, or fall back to the default (aligned thunks)
if stuffing could not be enabled.

Enablement of CDT is done exclusively in retbleed_apply_mitigation().
its_apply_mitigation() is only used to enable aligned thunks.

Changes since v1:
   - Moved ITS enum definition before retbleed logic

Signed-off-by: David Kaplan <david.kaplan@amd.com>
---
 arch/x86/kernel/cpu/bugs.c | 167 ++++++++++++++++++++-----------------
 1 file changed, 90 insertions(+), 77 deletions(-)

diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index d1a03ffd4b9d..3d5796d25f78 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -92,6 +92,8 @@ static void __init bhi_select_mitigation(void);
 static void __init bhi_update_mitigation(void);
 static void __init bhi_apply_mitigation(void);
 static void __init its_select_mitigation(void);
+static void __init its_update_mitigation(void);
+static void __init its_apply_mitigation(void);
 
 /* The base value of the SPEC_CTRL MSR without task-specific bits set */
 u64 x86_spec_ctrl_base;
@@ -235,6 +237,11 @@ void __init cpu_select_mitigations(void)
 	 * spectre_v2=ibrs.
 	 */
 	retbleed_update_mitigation();
+	/*
+	 * its_update_mitigation() depends on spectre_v2_update_mitigation()
+	 * and retbleed_update_mitigation().
+	 */
+	its_update_mitigation();
 
 	/*
 	 * spectre_v2_user_update_mitigation() depends on
@@ -263,6 +270,7 @@ void __init cpu_select_mitigations(void)
 	srbds_apply_mitigation();
 	srso_apply_mitigation();
 	gds_apply_mitigation();
+	its_apply_mitigation();
 	bhi_apply_mitigation();
 }
 
@@ -1115,6 +1123,17 @@ enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = SPECTRE_V2_NONE;
 #undef pr_fmt
 #define pr_fmt(fmt)     "RETBleed: " fmt
 
+enum its_mitigation {
+	ITS_MITIGATION_OFF,
+	ITS_MITIGATION_AUTO,
+	ITS_MITIGATION_VMEXIT_ONLY,
+	ITS_MITIGATION_ALIGNED_THUNKS,
+	ITS_MITIGATION_RETPOLINE_STUFF,
+};
+
+static enum its_mitigation its_mitigation __ro_after_init =
+	IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_MITIGATION_AUTO : ITS_MITIGATION_OFF;
+
 enum retbleed_mitigation {
 	RETBLEED_MITIGATION_NONE,
 	RETBLEED_MITIGATION_AUTO,
@@ -1242,11 +1261,19 @@ static void __init retbleed_update_mitigation(void)
 	/*
 	 * retbleed=stuff is only allowed on Intel.  If stuffing can't be used
 	 * then a different mitigation will be selected below.
+	 *
+	 * its=stuff will also attempt to enable stuffing.
 	 */
-	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF) {
+	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF ||
+	    its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF) {
 		if (spectre_v2_enabled != SPECTRE_V2_RETPOLINE) {
 			pr_err("WARNING: retbleed=stuff depends on spectre_v2=retpoline\n");
 			retbleed_mitigation = RETBLEED_MITIGATION_AUTO;
+		} else {
+			if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
+				pr_info("Retbleed mitigation updated to stuffing\n");
+
+			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
 		}
 	}
 	/*
@@ -1338,20 +1365,6 @@ static void __init retbleed_apply_mitigation(void)
 #undef pr_fmt
 #define pr_fmt(fmt)     "ITS: " fmt
 
-enum its_mitigation_cmd {
-	ITS_CMD_OFF,
-	ITS_CMD_ON,
-	ITS_CMD_VMEXIT,
-	ITS_CMD_RSB_STUFF,
-};
-
-enum its_mitigation {
-	ITS_MITIGATION_OFF,
-	ITS_MITIGATION_VMEXIT_ONLY,
-	ITS_MITIGATION_ALIGNED_THUNKS,
-	ITS_MITIGATION_RETPOLINE_STUFF,
-};
-
 static const char * const its_strings[] = {
 	[ITS_MITIGATION_OFF]			= "Vulnerable",
 	[ITS_MITIGATION_VMEXIT_ONLY]		= "Mitigation: Vulnerable, KVM: Not affected",
@@ -1359,11 +1372,6 @@ static const char * const its_strings[] = {
 	[ITS_MITIGATION_RETPOLINE_STUFF]	= "Mitigation: Retpolines, Stuffing RSB",
 };
 
-static enum its_mitigation its_mitigation __ro_after_init = ITS_MITIGATION_ALIGNED_THUNKS;
-
-static enum its_mitigation_cmd its_cmd __ro_after_init =
-	IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_CMD_ON : ITS_CMD_OFF;
-
 static int __init its_parse_cmdline(char *str)
 {
 	if (!str)
@@ -1375,16 +1383,16 @@ static int __init its_parse_cmdline(char *str)
 	}
 
 	if (!strcmp(str, "off")) {
-		its_cmd = ITS_CMD_OFF;
+		its_mitigation = ITS_MITIGATION_OFF;
 	} else if (!strcmp(str, "on")) {
-		its_cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 	} else if (!strcmp(str, "force")) {
-		its_cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 		setup_force_cpu_bug(X86_BUG_ITS);
 	} else if (!strcmp(str, "vmexit")) {
-		its_cmd = ITS_CMD_VMEXIT;
+		its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
 	} else if (!strcmp(str, "stuff")) {
-		its_cmd = ITS_CMD_RSB_STUFF;
+		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
 	} else {
 		pr_err("Ignoring unknown indirect_target_selection option (%s).", str);
 	}
@@ -1395,85 +1403,90 @@ early_param("indirect_target_selection", its_parse_cmdline);
 
 static void __init its_select_mitigation(void)
 {
-	enum its_mitigation_cmd cmd = its_cmd;
-
 	if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off()) {
 		its_mitigation = ITS_MITIGATION_OFF;
 		return;
 	}
 
-	/* Retpoline+CDT mitigates ITS, bail out */
-	if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
-	    boot_cpu_has(X86_FEATURE_CALL_DEPTH)) {
-		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
-		goto out;
-	}
+	if (its_mitigation == ITS_MITIGATION_AUTO)
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+
+	if (its_mitigation == ITS_MITIGATION_OFF)
+		return;
 
-	/* Exit early to avoid irrelevant warnings */
-	if (cmd == ITS_CMD_OFF) {
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
-	if (spectre_v2_enabled == SPECTRE_V2_NONE) {
-		pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
 	if (!IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) ||
 	    !IS_ENABLED(CONFIG_MITIGATION_RETHUNK)) {
 		pr_err("WARNING: ITS mitigation depends on retpoline and rethunk support\n");
 		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
+		return;
 	}
+
 	if (IS_ENABLED(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)) {
 		pr_err("WARNING: ITS mitigation is not compatible with CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B\n");
 		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
-	if (boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) {
-		pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
+		return;
 	}
 
-	if (cmd == ITS_CMD_RSB_STUFF &&
-	    (!boot_cpu_has(X86_FEATURE_RETPOLINE) || !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))) {
+	if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
+	    !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING)) {
 		pr_err("RSB stuff mitigation not supported, using default\n");
-		cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 	}
 
-	switch (cmd) {
-	case ITS_CMD_OFF:
+	if (its_mitigation == ITS_MITIGATION_VMEXIT_ONLY &&
+	    !boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY))
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+}
+
+static void __init its_update_mitigation(void)
+{
+	if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off())
+		return;
+
+	switch (spectre_v2_enabled) {
+	case SPECTRE_V2_NONE:
+		pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
 		its_mitigation = ITS_MITIGATION_OFF;
 		break;
-	case ITS_CMD_VMEXIT:
-		if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
-			its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
-			goto out;
-		}
-		fallthrough;
-	case ITS_CMD_ON:
-		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
-		if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
-			setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
-		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
-		set_return_thunk(its_return_thunk);
+	case SPECTRE_V2_RETPOLINE:
+		/* Retpoline+CDT mitigates ITS */
+		if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF)
+			its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
 		break;
-	case ITS_CMD_RSB_STUFF:
-		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
-		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
-		setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH);
-		set_return_thunk(call_depth_return_thunk);
-		if (retbleed_mitigation == RETBLEED_MITIGATION_NONE) {
-			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
-			pr_info("Retbleed mitigation updated to stuffing\n");
-		}
+	case SPECTRE_V2_LFENCE:
+	case SPECTRE_V2_EIBRS_LFENCE:
+		pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
+		its_mitigation = ITS_MITIGATION_OFF;
+		break;
+	default:
 		break;
 	}
-out:
+
+	/*
+	 * retbleed_update_mitigation() will try to do stuffing if its=stuff.
+	 * If it can't, such as if spectre_v2!=retpoline, then fall back to
+	 * aligned thunks.
+	 */
+	if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
+	    retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+
 	pr_info("%s\n", its_strings[its_mitigation]);
 }
 
+static void __init its_apply_mitigation(void)
+{
+	/* its=stuff forces retbleed stuffing and is enabled there. */
+	if (its_mitigation != ITS_MITIGATION_ALIGNED_THUNKS)
+		return;
+
+	if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
+		setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
+
+	setup_force_cpu_cap(X86_FEATURE_RETHUNK);
+	set_return_thunk(its_return_thunk);
+}
+
 #undef pr_fmt
 #define pr_fmt(fmt)     "Spectre V2 : " fmt
 

base-commit: 9162d2f2aab03400a773d9e8078f8c19e1f53228
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] x86/bugs: Restructure ITS mitigation
  2025-05-16 19:32 ` [PATCH v2] " David Kaplan
@ 2025-05-16 22:47   ` Dave Hansen
  2025-05-17 13:19     ` Ingo Molnar
  2025-05-17 13:25     ` Borislav Petkov
  2025-05-20 16:32   ` Pawan Gupta
                     ` (2 subsequent siblings)
  3 siblings, 2 replies; 18+ messages in thread
From: Dave Hansen @ 2025-05-16 22:47 UTC (permalink / raw)
  To: David Kaplan, Thomas Gleixner, Borislav Petkov, Peter Zijlstra,
	Josh Poimboeuf, Pawan Gupta, Ingo Molnar, Dave Hansen, x86,
	H. Peter Anvin
  Cc: linux-kernel

On 5/16/25 12:32, David Kaplan wrote:
> Restructure the ITS mitigation to use select/update/apply functions like
> the other mitigations.
> 
> There is a particularly complex interaction between ITS and Retbleed as CDT
> (Call Depth Tracking) is a mitigation for both, and either its=stuff or
> retbleed=stuff will attempt to enable CDT.
> 
> retbleed_update_mitigation() runs first and will check the necessary
> pre-conditions for CDT if either ITS or Retbleed stuffing is selected.  If
> checks pass and ITS stuffing is selected, it will select stuffing for
> Retbleed as well.
> 
> its_update_mitigation() runs after and will either select stuffing if
> retbleed stuffing was enabled, or fall back to the default (aligned thunks)
> if stuffing could not be enabled.
> 
> Enablement of CDT is done exclusively in retbleed_apply_mitigation().
> its_apply_mitigation() is only used to enable aligned thunks.

This seems to be explaining what is going on, but there isn't a clear
problem that this is fixing.

Why does this need restructuring?


>  	if (!strcmp(str, "off")) {
> -		its_cmd = ITS_CMD_OFF;
> +		its_mitigation = ITS_MITIGATION_OFF;
>  	} else if (!strcmp(str, "on")) {
> -		its_cmd = ITS_CMD_ON;
> +		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
>  	} else if (!strcmp(str, "force")) {
> -		its_cmd = ITS_CMD_ON;
> +		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
>  		setup_force_cpu_bug(X86_BUG_ITS);
>  	} else if (!strcmp(str, "vmexit")) {
> -		its_cmd = ITS_CMD_VMEXIT;
> +		its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
>  	} else if (!strcmp(str, "stuff")) {
> -		its_cmd = ITS_CMD_RSB_STUFF;
> +		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
>  	} else {
>  		pr_err("Ignoring unknown indirect_target_selection option (%s).", str);
>  	}

There seems to be a mix of command-line parsing functions that have a
separate 'foo_cmd' from 'foo_mitigation'. What's the reasoning behind
converting this one?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] x86/bugs: Restructure ITS mitigation
  2025-05-16 22:47   ` Dave Hansen
@ 2025-05-17 13:19     ` Ingo Molnar
  2025-05-17 13:25     ` Borislav Petkov
  1 sibling, 0 replies; 18+ messages in thread
From: Ingo Molnar @ 2025-05-17 13:19 UTC (permalink / raw)
  To: Dave Hansen
  Cc: David Kaplan, Thomas Gleixner, Borislav Petkov, Peter Zijlstra,
	Josh Poimboeuf, Pawan Gupta, Ingo Molnar, Dave Hansen, x86,
	H. Peter Anvin, linux-kernel


* Dave Hansen <dave.hansen@intel.com> wrote:

> On 5/16/25 12:32, David Kaplan wrote:
> > Restructure the ITS mitigation to use select/update/apply functions like
> > the other mitigations.
> > 
> > There is a particularly complex interaction between ITS and Retbleed as CDT
> > (Call Depth Tracking) is a mitigation for both, and either its=stuff or
> > retbleed=stuff will attempt to enable CDT.
> > 
> > retbleed_update_mitigation() runs first and will check the necessary
> > pre-conditions for CDT if either ITS or Retbleed stuffing is selected.  If
> > checks pass and ITS stuffing is selected, it will select stuffing for
> > Retbleed as well.
> > 
> > its_update_mitigation() runs after and will either select stuffing if
> > retbleed stuffing was enabled, or fall back to the default (aligned thunks)
> > if stuffing could not be enabled.
> > 
> > Enablement of CDT is done exclusively in retbleed_apply_mitigation().
> > its_apply_mitigation() is only used to enable aligned thunks.
> 
> This seems to be explaining what is going on, but there isn't a clear
> problem that this is fixing.
> 
> Why does this need restructuring?

All other mitigations have the following methods:

  static void __init bhi_select_mitigation(void);
  static void __init bhi_update_mitigation(void);
  static void __init bhi_apply_mitigation(void);

(The _update() method is optional.)

Except the freshly added ITS mitigation breaks this pattern, which has 
all this functionality in a single function:

  static void __init its_select_mitigation(void);

David's patch refactors the recently added ITS code to follow the 
existing pattern of all the other mitigation methods:

  static void __init its_select_mitigation(void);
  static void __init its_update_mitigation(void);
  static void __init its_apply_mitigation(void);

This makes it easier to read if you know the other mitigations already, 
and makes it easier to maintain going forward.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] x86/bugs: Restructure ITS mitigation
  2025-05-16 22:47   ` Dave Hansen
  2025-05-17 13:19     ` Ingo Molnar
@ 2025-05-17 13:25     ` Borislav Petkov
  1 sibling, 0 replies; 18+ messages in thread
From: Borislav Petkov @ 2025-05-17 13:25 UTC (permalink / raw)
  To: Dave Hansen
  Cc: David Kaplan, Thomas Gleixner, Peter Zijlstra, Josh Poimboeuf,
	Pawan Gupta, Ingo Molnar, Dave Hansen, x86, H. Peter Anvin,
	linux-kernel

On Fri, May 16, 2025 at 03:47:26PM -0700, Dave Hansen wrote:
> This seems to be explaining what is going on, but there isn't a clear
> problem that this is fixing.
> 
> Why does this need restructuring?

Yeah, we're splitting how the whole mitigations gunk gets determined and we're
adding the capability to mitigate whole attack vectors instead of controlling
single mitigations:

/*
 * Speculation Vulnerability Handling
 *
 * Each vulnerability is handled with the following functions:
 *   <vuln>_select_mitigation() -- Selects a mitigation to use.  This should
 *                                 take into account all relevant command line
 *                                 options.
 *   <vuln>_update_mitigation() -- This is called after all vulnerabilities have
 *                                 selected a mitigation, in case the selection
 *                                 may want to change based on other choices
 *                                 made.  This function is optional.
 *   <vuln>_apply_mitigation() -- Enable the selected mitigation.
 *
 * The compile-time mitigation in all cases should be AUTO.  An explicit
 * command-line option can override AUTO.  If no such option is
 * provided, <vuln>_select_mitigation() will override AUTO to the best
 * mitigation option.
 */

Full details here:

https://lore.kernel.org/r/20250509162839.3057217-2-david.kaplan@amd.com

> There seems to be a mix of command-line parsing functions that have a
> separate 'foo_cmd' from 'foo_mitigation'. What's the reasoning behind
> converting this one?

We've been doing them with cmds first and then based on the cmd, we select the
mitigation. But we don't really need the cmds - we can simply mitigation
variable.

I'm thinking as a future cleanup we'll get rid of all cmds.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] x86/bugs: Restructure ITS mitigation
  2025-05-16 15:06   ` Kaplan, David
@ 2025-05-19 23:51     ` Pawan Gupta
  0 siblings, 0 replies; 18+ messages in thread
From: Pawan Gupta @ 2025-05-19 23:51 UTC (permalink / raw)
  To: Kaplan, David
  Cc: Thomas Gleixner, Borislav Petkov, Peter Zijlstra, Josh Poimboeuf,
	Ingo Molnar, Dave Hansen, x86@kernel.org, H. Peter Anvin,
	linux-kernel@vger.kernel.org

On Fri, May 16, 2025 at 03:06:26PM +0000, Kaplan, David wrote:
> > > +1261,19 @@ static void __init retbleed_update_mitigation(void)
> > >       /*
> > >        * retbleed=stuff is only allowed on Intel.  If stuffing can't be used
> > >        * then a different mitigation will be selected below.
> > > +      *
> > > +      * its=stuff will also attempt to enable stuffing.
> > >        */
> > > -     if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF) {
> > > +     if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF ||
> > > +         its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF) {
> > >               if (spectre_v2_enabled != SPECTRE_V2_RETPOLINE) {
> >
> > SPECTRE_V2_EIBRS_RETPOLINE also enables retpoline.
> >
> > >                       pr_err("WARNING: retbleed=stuff depends on
> > > spectre_v2=retpoline\n");
> >
> > This can be updated to:
> >
> >                         pr_err("WARNING: retbleed=stuff depends on retpoline\n");
> >
> 
> Yeah, I noticed that too.  But the existing upstream code (before my
> re-write) was also only checking spectre_v2_enabled == SPECTRE_V2_RETPOLINE
> in retbleed_select_mitigation(). So it seems like CDT previously wasn't
> supported with spectre_v2=eibrs,retpoline.

Thats because there was no need for CDT when eIBRS was enabled, until ITS.
The current upstream ITS mitigation behavior is to allow CDT with eIBRS.
This restructuring is changing that as ITS now relies on retbleed
mitigation, but retbleed_update_mitigation() is refusing to enable CDT when
eIBRS is enabled.

> If we want to change that, I suggest doing it in a separate patch.
> > >       }
> > >
> > > -     if (cmd == ITS_CMD_RSB_STUFF &&
> > > -         (!boot_cpu_has(X86_FEATURE_RETPOLINE) ||
> > !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))) {
> > > +     if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
> > > +         !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING)) {
> > >               pr_err("RSB stuff mitigation not supported, using default\n");
> > > -             cmd = ITS_CMD_ON;
> > > +             its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
> >
> > This and ...
> >
> > >       }
> > >
> > > -     switch (cmd) {
> > > -     case ITS_CMD_OFF:
> > > +     if (its_mitigation == ITS_MITIGATION_VMEXIT_ONLY &&
> > > +         !boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY))
> > > +             its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
> >
> > ... this are essentially resetting the mitigation to default. This will be more clear if
> > you could change the mitigation to ITS_MITIGATION_AUTO here, and at the end
> > have:
> >
> >         if (its_mitigation == ITS_MITIGATION_AUTO)
> >                 its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
> 
> The point of AUTO is really to say that no cmdline option was specified.
> This is relevant for my attack vector patches because AUTO means "defer
> to the enabled attack vectors".
> 
> In the attack vector series, AUTO is checked early in the select function
> and the mitigation will be disabled if needed.  If it is needed, the
> default mitigation is chosen.

Okay, I see your point. But it is debatable whether not selecting a
mitigation (which is auto) is equivalent to selecting an invalid mitigation
which then falls back to the default (also equivalent to auto).

> In the current code without attack vectors, AUTO just always means pick
> the default, but is really a preparatory thing for the attack vector
> support.
> 
> The code you highlighted deals with cases where an explicit cmdline
> option was specified asking for mitigation, but it can't be done.
> Falling back to the default option is fine, but calling it AUTO I think
> would be confusing because AUTO (in the next patch series) means "defer
> to the attack vectors".  So I would prefer to leave the code as-is.

In the other series can we make this subtlity more clear with:

enum its_mitigation {
        ITS_MITIGATION_OFF,
        ITS_MITIGATION_AUTO,
        ITS_MITIGATION_VECTOR_BASED = ITS_MITIGATION_AUTO,
	...
};

> > > +
> > > +}
> > > +
> > > +static void __init its_update_mitigation(void) {
> > > +     if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off())
> > > +             return;
> > > +
> > > +     switch (spectre_v2_enabled) {
> > > +     case SPECTRE_V2_NONE:
> > > +             pr_err("WARNING: Spectre-v2 mitigation is off, disabling
> > > + ITS\n");
> > >               its_mitigation = ITS_MITIGATION_OFF;
> > >               break;
> > > -     case ITS_CMD_VMEXIT:
> > > -             if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
> > > -                     its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
> > > -                     goto out;
> > > -             }
> > > -             fallthrough;
> > > -     case ITS_CMD_ON:
> > > -             its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
> > > -             if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
> > > -                     setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
> > > -             setup_force_cpu_cap(X86_FEATURE_RETHUNK);
> > > -             set_return_thunk(its_return_thunk);
> > > +     case SPECTRE_V2_RETPOLINE:
> >
> > Also SPECTRE_V2_EIBRS_RETPOLINE.
> 
> See above.
> 
> >
> > > +             /* Retpoline+CDT mitigates ITS */
> > > +             if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF)
> >
> >
> >
> > > +                     its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
> > >               break;
> > > -     case ITS_CMD_RSB_STUFF:
> > > -             its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
> > > -             setup_force_cpu_cap(X86_FEATURE_RETHUNK);
> > > -             setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH);
> > > -             set_return_thunk(call_depth_return_thunk);
> > > -             if (retbleed_mitigation == RETBLEED_MITIGATION_NONE) {
> > > -                     retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
> > > -                     pr_info("Retbleed mitigation updated to stuffing\n");
> > > -             }
> > > +     case SPECTRE_V2_LFENCE:
> > > +     case SPECTRE_V2_EIBRS_LFENCE:
> > > +             pr_err("WARNING: ITS mitigation is not compatible with lfence
> > mitigation\n");
> > > +             its_mitigation = ITS_MITIGATION_OFF;
> > > +             break;
> > > +     default:
> > >               break;
> > >       }
> > > -out:
> > > +
> > > +     /*
> > > +      * retbleed_update_mitigation() will try to do stuffing if its=stuff.
> > > +      * If it can't, such as if spectre_v2!=retpoline, then fall back to
> > > +      * aligned thunks.
> > > +      */
> > > +     if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
> > > +         retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
> > > +             its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
> >
> > The =stuff mitigation depends on retpoline, not really on retbleed.
> > Shouldn't this be handled in the switch (spectre_v2_enabled) above?
> >
> > >       pr_info("%s\n", its_strings[its_mitigation]);  }
> > >
> > > +static void __init its_apply_mitigation(void) {
> > > +     /* its=stuff forces retbleed stuffing and is enabled there. */
> >
> > Oh, this is why you are depending on retbleed_mitigation above, this part is a bit
> > confusing.
> >
> > Will think about it more later, trying to have a couple of days off.
> 
> It is a bit confusing, no argument there.  And why I spent most of the
> commit log trying to explain it :)
> 
> I do prefer this way of handling it though compared to the existing code.
> The existing code would *change* retbleed_mitigation in
> its_select_mitigation() which I think is very confusing.  I believe the
> rule for these functions should be that xxx_mitigation is only ever
> modified in the xxx_select_mitigation() and xxx_update_mitigation()
> functions.
> 
> If there's another idea though (or a place where a comment might help),
> let me know.

One way to handle intersection between two mitigations is via a common
function that each mitigation can call. Something on the lines of
set_return_thunk().

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] x86/bugs: Restructure ITS mitigation
  2025-05-16 19:32 ` [PATCH v2] " David Kaplan
  2025-05-16 22:47   ` Dave Hansen
@ 2025-05-20 16:32   ` Pawan Gupta
  2025-05-20 16:48     ` Borislav Petkov
  2025-05-20 16:54   ` [tip: x86/core] " tip-bot2 for David Kaplan
  2025-05-21  6:56   ` tip-bot2 for David Kaplan
  3 siblings, 1 reply; 18+ messages in thread
From: Pawan Gupta @ 2025-05-20 16:32 UTC (permalink / raw)
  To: David Kaplan
  Cc: Thomas Gleixner, Borislav Petkov, Peter Zijlstra, Josh Poimboeuf,
	Ingo Molnar, Dave Hansen, x86, H. Peter Anvin, linux-kernel

On Fri, May 16, 2025 at 02:32:11PM -0500, David Kaplan wrote:
> Restructure the ITS mitigation to use select/update/apply functions like
> the other mitigations.
> 
> There is a particularly complex interaction between ITS and Retbleed as CDT
> (Call Depth Tracking) is a mitigation for both, and either its=stuff or
> retbleed=stuff will attempt to enable CDT.
> 
> retbleed_update_mitigation() runs first and will check the necessary
> pre-conditions for CDT if either ITS or Retbleed stuffing is selected.  If
> checks pass and ITS stuffing is selected, it will select stuffing for
> Retbleed as well.
> 
> its_update_mitigation() runs after and will either select stuffing if
> retbleed stuffing was enabled, or fall back to the default (aligned thunks)
> if stuffing could not be enabled.
> 
> Enablement of CDT is done exclusively in retbleed_apply_mitigation().
> its_apply_mitigation() is only used to enable aligned thunks.
> 
> Changes since v1:
>    - Moved ITS enum definition before retbleed logic
> 
> Signed-off-by: David Kaplan <david.kaplan@amd.com>
> ---
>  arch/x86/kernel/cpu/bugs.c | 167 ++++++++++++++++++++-----------------
...
> @@ -1338,20 +1365,6 @@ static void __init retbleed_apply_mitigation(void)
>  #undef pr_fmt
>  #define pr_fmt(fmt)     "ITS: " fmt
>  
> -enum its_mitigation_cmd {
> -	ITS_CMD_OFF,
> -	ITS_CMD_ON,
> -	ITS_CMD_VMEXIT,
> -	ITS_CMD_RSB_STUFF,
> -};
> -
> -enum its_mitigation {
> -	ITS_MITIGATION_OFF,
> -	ITS_MITIGATION_VMEXIT_ONLY,
> -	ITS_MITIGATION_ALIGNED_THUNKS,
> -	ITS_MITIGATION_RETPOLINE_STUFF,
> -};
> -
>  static const char * const its_strings[] = {
>  	[ITS_MITIGATION_OFF]			= "Vulnerable",

Index 1 (which is now ITS_MITIGATION_AUTO) is missing. I understand AUTO is
a temporary state, and it may not be necessary to define a string for it.
But, assigning an empty string, or an error message would make this obvious
for a future reader.

>  	[ITS_MITIGATION_VMEXIT_ONLY]		= "Mitigation: Vulnerable, KVM: Not affected",
> @@ -1359,11 +1372,6 @@ static const char * const its_strings[] = {
>  	[ITS_MITIGATION_RETPOLINE_STUFF]	= "Mitigation: Retpolines, Stuffing RSB",
>  };

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] x86/bugs: Restructure ITS mitigation
  2025-05-20 16:32   ` Pawan Gupta
@ 2025-05-20 16:48     ` Borislav Petkov
  2025-05-20 16:57       ` Pawan Gupta
  0 siblings, 1 reply; 18+ messages in thread
From: Borislav Petkov @ 2025-05-20 16:48 UTC (permalink / raw)
  To: Pawan Gupta
  Cc: David Kaplan, Thomas Gleixner, Peter Zijlstra, Josh Poimboeuf,
	Ingo Molnar, Dave Hansen, x86, H. Peter Anvin, linux-kernel

On Tue, May 20, 2025 at 09:32:21AM -0700, Pawan Gupta wrote:
> Index 1 (which is now ITS_MITIGATION_AUTO) is missing. I understand AUTO is
> a temporary state, and it may not be necessary to define a string for it.
> But, assigning an empty string, or an error message would make this obvious
> for a future reader.

Yeah, this AUTO gets overwritten and the other AUTOs don't have strings too.

We can fix that after the MW if you think it is important but from what
I looked, all the AUTO settings get overwritten as AUTO means, user didn't
make any decision here so it is left to the kernel to make it.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [tip: x86/core] x86/bugs: Restructure ITS mitigation
  2025-05-16 19:32 ` [PATCH v2] " David Kaplan
  2025-05-16 22:47   ` Dave Hansen
  2025-05-20 16:32   ` Pawan Gupta
@ 2025-05-20 16:54   ` tip-bot2 for David Kaplan
  2025-05-21  6:56   ` tip-bot2 for David Kaplan
  3 siblings, 0 replies; 18+ messages in thread
From: tip-bot2 for David Kaplan @ 2025-05-20 16:54 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: David Kaplan, Borislav Petkov (AMD), x86, linux-kernel

The following commit has been merged into the x86/core branch of tip:

Commit-ID:     8c57ca583ebfe879f99007d10c8f2b66baa18422
Gitweb:        https://git.kernel.org/tip/8c57ca583ebfe879f99007d10c8f2b66baa18422
Author:        David Kaplan <david.kaplan@amd.com>
AuthorDate:    Fri, 16 May 2025 14:32:11 -05:00
Committer:     Borislav Petkov (AMD) <bp@alien8.de>
CommitterDate: Tue, 20 May 2025 18:42:06 +02:00

x86/bugs: Restructure ITS mitigation

Restructure the ITS mitigation to use select/update/apply functions like
the other mitigations.

There is a particularly complex interaction between ITS and Retbleed as CDT
(Call Depth Tracking) is a mitigation for both, and either its=stuff or
retbleed=stuff will attempt to enable CDT.

retbleed_update_mitigation() runs first and will check the necessary
pre-conditions for CDT if either ITS or Retbleed stuffing is selected.  If
checks pass and ITS stuffing is selected, it will select stuffing for
Retbleed as well.

its_update_mitigation() runs after and will either select stuffing if
retbleed stuffing was enabled, or fall back to the default (aligned thunks)
if stuffing could not be enabled.

Enablement of CDT is done exclusively in retbleed_apply_mitigation().
its_apply_mitigation() is only used to enable aligned thunks.

Signed-off-by: David Kaplan <david.kaplan@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/20250516193212.128782-1-david.kaplan@amd.com
---
 arch/x86/kernel/cpu/bugs.c | 167 +++++++++++++++++++-----------------
 1 file changed, 90 insertions(+), 77 deletions(-)

diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index d1a03ff..3d5796d 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -92,6 +92,8 @@ static void __init bhi_select_mitigation(void);
 static void __init bhi_update_mitigation(void);
 static void __init bhi_apply_mitigation(void);
 static void __init its_select_mitigation(void);
+static void __init its_update_mitigation(void);
+static void __init its_apply_mitigation(void);
 
 /* The base value of the SPEC_CTRL MSR without task-specific bits set */
 u64 x86_spec_ctrl_base;
@@ -235,6 +237,11 @@ void __init cpu_select_mitigations(void)
 	 * spectre_v2=ibrs.
 	 */
 	retbleed_update_mitigation();
+	/*
+	 * its_update_mitigation() depends on spectre_v2_update_mitigation()
+	 * and retbleed_update_mitigation().
+	 */
+	its_update_mitigation();
 
 	/*
 	 * spectre_v2_user_update_mitigation() depends on
@@ -263,6 +270,7 @@ void __init cpu_select_mitigations(void)
 	srbds_apply_mitigation();
 	srso_apply_mitigation();
 	gds_apply_mitigation();
+	its_apply_mitigation();
 	bhi_apply_mitigation();
 }
 
@@ -1115,6 +1123,17 @@ enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = SPECTRE_V2_NONE;
 #undef pr_fmt
 #define pr_fmt(fmt)     "RETBleed: " fmt
 
+enum its_mitigation {
+	ITS_MITIGATION_OFF,
+	ITS_MITIGATION_AUTO,
+	ITS_MITIGATION_VMEXIT_ONLY,
+	ITS_MITIGATION_ALIGNED_THUNKS,
+	ITS_MITIGATION_RETPOLINE_STUFF,
+};
+
+static enum its_mitigation its_mitigation __ro_after_init =
+	IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_MITIGATION_AUTO : ITS_MITIGATION_OFF;
+
 enum retbleed_mitigation {
 	RETBLEED_MITIGATION_NONE,
 	RETBLEED_MITIGATION_AUTO,
@@ -1242,11 +1261,19 @@ static void __init retbleed_update_mitigation(void)
 	/*
 	 * retbleed=stuff is only allowed on Intel.  If stuffing can't be used
 	 * then a different mitigation will be selected below.
+	 *
+	 * its=stuff will also attempt to enable stuffing.
 	 */
-	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF) {
+	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF ||
+	    its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF) {
 		if (spectre_v2_enabled != SPECTRE_V2_RETPOLINE) {
 			pr_err("WARNING: retbleed=stuff depends on spectre_v2=retpoline\n");
 			retbleed_mitigation = RETBLEED_MITIGATION_AUTO;
+		} else {
+			if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
+				pr_info("Retbleed mitigation updated to stuffing\n");
+
+			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
 		}
 	}
 	/*
@@ -1338,20 +1365,6 @@ static void __init retbleed_apply_mitigation(void)
 #undef pr_fmt
 #define pr_fmt(fmt)     "ITS: " fmt
 
-enum its_mitigation_cmd {
-	ITS_CMD_OFF,
-	ITS_CMD_ON,
-	ITS_CMD_VMEXIT,
-	ITS_CMD_RSB_STUFF,
-};
-
-enum its_mitigation {
-	ITS_MITIGATION_OFF,
-	ITS_MITIGATION_VMEXIT_ONLY,
-	ITS_MITIGATION_ALIGNED_THUNKS,
-	ITS_MITIGATION_RETPOLINE_STUFF,
-};
-
 static const char * const its_strings[] = {
 	[ITS_MITIGATION_OFF]			= "Vulnerable",
 	[ITS_MITIGATION_VMEXIT_ONLY]		= "Mitigation: Vulnerable, KVM: Not affected",
@@ -1359,11 +1372,6 @@ static const char * const its_strings[] = {
 	[ITS_MITIGATION_RETPOLINE_STUFF]	= "Mitigation: Retpolines, Stuffing RSB",
 };
 
-static enum its_mitigation its_mitigation __ro_after_init = ITS_MITIGATION_ALIGNED_THUNKS;
-
-static enum its_mitigation_cmd its_cmd __ro_after_init =
-	IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_CMD_ON : ITS_CMD_OFF;
-
 static int __init its_parse_cmdline(char *str)
 {
 	if (!str)
@@ -1375,16 +1383,16 @@ static int __init its_parse_cmdline(char *str)
 	}
 
 	if (!strcmp(str, "off")) {
-		its_cmd = ITS_CMD_OFF;
+		its_mitigation = ITS_MITIGATION_OFF;
 	} else if (!strcmp(str, "on")) {
-		its_cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 	} else if (!strcmp(str, "force")) {
-		its_cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 		setup_force_cpu_bug(X86_BUG_ITS);
 	} else if (!strcmp(str, "vmexit")) {
-		its_cmd = ITS_CMD_VMEXIT;
+		its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
 	} else if (!strcmp(str, "stuff")) {
-		its_cmd = ITS_CMD_RSB_STUFF;
+		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
 	} else {
 		pr_err("Ignoring unknown indirect_target_selection option (%s).", str);
 	}
@@ -1395,85 +1403,90 @@ early_param("indirect_target_selection", its_parse_cmdline);
 
 static void __init its_select_mitigation(void)
 {
-	enum its_mitigation_cmd cmd = its_cmd;
-
 	if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off()) {
 		its_mitigation = ITS_MITIGATION_OFF;
 		return;
 	}
 
-	/* Retpoline+CDT mitigates ITS, bail out */
-	if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
-	    boot_cpu_has(X86_FEATURE_CALL_DEPTH)) {
-		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
-		goto out;
-	}
+	if (its_mitigation == ITS_MITIGATION_AUTO)
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+
+	if (its_mitigation == ITS_MITIGATION_OFF)
+		return;
 
-	/* Exit early to avoid irrelevant warnings */
-	if (cmd == ITS_CMD_OFF) {
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
-	if (spectre_v2_enabled == SPECTRE_V2_NONE) {
-		pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
 	if (!IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) ||
 	    !IS_ENABLED(CONFIG_MITIGATION_RETHUNK)) {
 		pr_err("WARNING: ITS mitigation depends on retpoline and rethunk support\n");
 		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
+		return;
 	}
+
 	if (IS_ENABLED(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)) {
 		pr_err("WARNING: ITS mitigation is not compatible with CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B\n");
 		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
-	if (boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) {
-		pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
+		return;
 	}
 
-	if (cmd == ITS_CMD_RSB_STUFF &&
-	    (!boot_cpu_has(X86_FEATURE_RETPOLINE) || !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))) {
+	if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
+	    !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING)) {
 		pr_err("RSB stuff mitigation not supported, using default\n");
-		cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 	}
 
-	switch (cmd) {
-	case ITS_CMD_OFF:
+	if (its_mitigation == ITS_MITIGATION_VMEXIT_ONLY &&
+	    !boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY))
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+}
+
+static void __init its_update_mitigation(void)
+{
+	if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off())
+		return;
+
+	switch (spectre_v2_enabled) {
+	case SPECTRE_V2_NONE:
+		pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
 		its_mitigation = ITS_MITIGATION_OFF;
 		break;
-	case ITS_CMD_VMEXIT:
-		if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
-			its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
-			goto out;
-		}
-		fallthrough;
-	case ITS_CMD_ON:
-		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
-		if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
-			setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
-		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
-		set_return_thunk(its_return_thunk);
+	case SPECTRE_V2_RETPOLINE:
+		/* Retpoline+CDT mitigates ITS */
+		if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF)
+			its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
 		break;
-	case ITS_CMD_RSB_STUFF:
-		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
-		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
-		setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH);
-		set_return_thunk(call_depth_return_thunk);
-		if (retbleed_mitigation == RETBLEED_MITIGATION_NONE) {
-			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
-			pr_info("Retbleed mitigation updated to stuffing\n");
-		}
+	case SPECTRE_V2_LFENCE:
+	case SPECTRE_V2_EIBRS_LFENCE:
+		pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
+		its_mitigation = ITS_MITIGATION_OFF;
+		break;
+	default:
 		break;
 	}
-out:
+
+	/*
+	 * retbleed_update_mitigation() will try to do stuffing if its=stuff.
+	 * If it can't, such as if spectre_v2!=retpoline, then fall back to
+	 * aligned thunks.
+	 */
+	if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
+	    retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+
 	pr_info("%s\n", its_strings[its_mitigation]);
 }
 
+static void __init its_apply_mitigation(void)
+{
+	/* its=stuff forces retbleed stuffing and is enabled there. */
+	if (its_mitigation != ITS_MITIGATION_ALIGNED_THUNKS)
+		return;
+
+	if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
+		setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
+
+	setup_force_cpu_cap(X86_FEATURE_RETHUNK);
+	set_return_thunk(its_return_thunk);
+}
+
 #undef pr_fmt
 #define pr_fmt(fmt)     "Spectre V2 : " fmt
 

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] x86/bugs: Restructure ITS mitigation
  2025-05-20 16:48     ` Borislav Petkov
@ 2025-05-20 16:57       ` Pawan Gupta
  0 siblings, 0 replies; 18+ messages in thread
From: Pawan Gupta @ 2025-05-20 16:57 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: David Kaplan, Thomas Gleixner, Peter Zijlstra, Josh Poimboeuf,
	Ingo Molnar, Dave Hansen, x86, H. Peter Anvin, linux-kernel

On Tue, May 20, 2025 at 06:48:26PM +0200, Borislav Petkov wrote:
> On Tue, May 20, 2025 at 09:32:21AM -0700, Pawan Gupta wrote:
> > Index 1 (which is now ITS_MITIGATION_AUTO) is missing. I understand AUTO is
> > a temporary state, and it may not be necessary to define a string for it.
> > But, assigning an empty string, or an error message would make this obvious
> > for a future reader.
> 
> Yeah, this AUTO gets overwritten and the other AUTOs don't have strings too.
> 
> We can fix that after the MW if you think it is important but from what
> I looked, all the AUTO settings get overwritten as AUTO means, user didn't
> make any decision here so it is left to the kernel to make it.

As long as AUTO setting is overwritten it is fine.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [tip: x86/core] x86/bugs: Restructure ITS mitigation
  2025-05-16 19:32 ` [PATCH v2] " David Kaplan
                     ` (2 preceding siblings ...)
  2025-05-20 16:54   ` [tip: x86/core] " tip-bot2 for David Kaplan
@ 2025-05-21  6:56   ` tip-bot2 for David Kaplan
  3 siblings, 0 replies; 18+ messages in thread
From: tip-bot2 for David Kaplan @ 2025-05-21  6:56 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: David Kaplan, Borislav Petkov (AMD), Ingo Molnar, x86,
	linux-kernel

The following commit has been merged into the x86/core branch of tip:

Commit-ID:     61ab72c2c6bf24f28b3dbfd3126e984d5afa8424
Gitweb:        https://git.kernel.org/tip/61ab72c2c6bf24f28b3dbfd3126e984d5afa8424
Author:        David Kaplan <david.kaplan@amd.com>
AuthorDate:    Fri, 16 May 2025 14:32:11 -05:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Wed, 21 May 2025 08:45:27 +02:00

x86/bugs: Restructure ITS mitigation

Restructure the ITS mitigation to use select/update/apply functions like
the other mitigations.

There is a particularly complex interaction between ITS and Retbleed as CDT
(Call Depth Tracking) is a mitigation for both, and either its=stuff or
retbleed=stuff will attempt to enable CDT.

retbleed_update_mitigation() runs first and will check the necessary
pre-conditions for CDT if either ITS or Retbleed stuffing is selected.  If
checks pass and ITS stuffing is selected, it will select stuffing for
Retbleed as well.

its_update_mitigation() runs after and will either select stuffing if
retbleed stuffing was enabled, or fall back to the default (aligned thunks)
if stuffing could not be enabled.

Enablement of CDT is done exclusively in retbleed_apply_mitigation().
its_apply_mitigation() is only used to enable aligned thunks.

Signed-off-by: David Kaplan <david.kaplan@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/20250516193212.128782-1-david.kaplan@amd.com
---
 arch/x86/kernel/cpu/bugs.c | 167 +++++++++++++++++++-----------------
 1 file changed, 90 insertions(+), 77 deletions(-)

diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index d1a03ff..3d5796d 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -92,6 +92,8 @@ static void __init bhi_select_mitigation(void);
 static void __init bhi_update_mitigation(void);
 static void __init bhi_apply_mitigation(void);
 static void __init its_select_mitigation(void);
+static void __init its_update_mitigation(void);
+static void __init its_apply_mitigation(void);
 
 /* The base value of the SPEC_CTRL MSR without task-specific bits set */
 u64 x86_spec_ctrl_base;
@@ -235,6 +237,11 @@ void __init cpu_select_mitigations(void)
 	 * spectre_v2=ibrs.
 	 */
 	retbleed_update_mitigation();
+	/*
+	 * its_update_mitigation() depends on spectre_v2_update_mitigation()
+	 * and retbleed_update_mitigation().
+	 */
+	its_update_mitigation();
 
 	/*
 	 * spectre_v2_user_update_mitigation() depends on
@@ -263,6 +270,7 @@ void __init cpu_select_mitigations(void)
 	srbds_apply_mitigation();
 	srso_apply_mitigation();
 	gds_apply_mitigation();
+	its_apply_mitigation();
 	bhi_apply_mitigation();
 }
 
@@ -1115,6 +1123,17 @@ enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = SPECTRE_V2_NONE;
 #undef pr_fmt
 #define pr_fmt(fmt)     "RETBleed: " fmt
 
+enum its_mitigation {
+	ITS_MITIGATION_OFF,
+	ITS_MITIGATION_AUTO,
+	ITS_MITIGATION_VMEXIT_ONLY,
+	ITS_MITIGATION_ALIGNED_THUNKS,
+	ITS_MITIGATION_RETPOLINE_STUFF,
+};
+
+static enum its_mitigation its_mitigation __ro_after_init =
+	IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_MITIGATION_AUTO : ITS_MITIGATION_OFF;
+
 enum retbleed_mitigation {
 	RETBLEED_MITIGATION_NONE,
 	RETBLEED_MITIGATION_AUTO,
@@ -1242,11 +1261,19 @@ static void __init retbleed_update_mitigation(void)
 	/*
 	 * retbleed=stuff is only allowed on Intel.  If stuffing can't be used
 	 * then a different mitigation will be selected below.
+	 *
+	 * its=stuff will also attempt to enable stuffing.
 	 */
-	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF) {
+	if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF ||
+	    its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF) {
 		if (spectre_v2_enabled != SPECTRE_V2_RETPOLINE) {
 			pr_err("WARNING: retbleed=stuff depends on spectre_v2=retpoline\n");
 			retbleed_mitigation = RETBLEED_MITIGATION_AUTO;
+		} else {
+			if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
+				pr_info("Retbleed mitigation updated to stuffing\n");
+
+			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
 		}
 	}
 	/*
@@ -1338,20 +1365,6 @@ static void __init retbleed_apply_mitigation(void)
 #undef pr_fmt
 #define pr_fmt(fmt)     "ITS: " fmt
 
-enum its_mitigation_cmd {
-	ITS_CMD_OFF,
-	ITS_CMD_ON,
-	ITS_CMD_VMEXIT,
-	ITS_CMD_RSB_STUFF,
-};
-
-enum its_mitigation {
-	ITS_MITIGATION_OFF,
-	ITS_MITIGATION_VMEXIT_ONLY,
-	ITS_MITIGATION_ALIGNED_THUNKS,
-	ITS_MITIGATION_RETPOLINE_STUFF,
-};
-
 static const char * const its_strings[] = {
 	[ITS_MITIGATION_OFF]			= "Vulnerable",
 	[ITS_MITIGATION_VMEXIT_ONLY]		= "Mitigation: Vulnerable, KVM: Not affected",
@@ -1359,11 +1372,6 @@ static const char * const its_strings[] = {
 	[ITS_MITIGATION_RETPOLINE_STUFF]	= "Mitigation: Retpolines, Stuffing RSB",
 };
 
-static enum its_mitigation its_mitigation __ro_after_init = ITS_MITIGATION_ALIGNED_THUNKS;
-
-static enum its_mitigation_cmd its_cmd __ro_after_init =
-	IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_CMD_ON : ITS_CMD_OFF;
-
 static int __init its_parse_cmdline(char *str)
 {
 	if (!str)
@@ -1375,16 +1383,16 @@ static int __init its_parse_cmdline(char *str)
 	}
 
 	if (!strcmp(str, "off")) {
-		its_cmd = ITS_CMD_OFF;
+		its_mitigation = ITS_MITIGATION_OFF;
 	} else if (!strcmp(str, "on")) {
-		its_cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 	} else if (!strcmp(str, "force")) {
-		its_cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 		setup_force_cpu_bug(X86_BUG_ITS);
 	} else if (!strcmp(str, "vmexit")) {
-		its_cmd = ITS_CMD_VMEXIT;
+		its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
 	} else if (!strcmp(str, "stuff")) {
-		its_cmd = ITS_CMD_RSB_STUFF;
+		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
 	} else {
 		pr_err("Ignoring unknown indirect_target_selection option (%s).", str);
 	}
@@ -1395,85 +1403,90 @@ early_param("indirect_target_selection", its_parse_cmdline);
 
 static void __init its_select_mitigation(void)
 {
-	enum its_mitigation_cmd cmd = its_cmd;
-
 	if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off()) {
 		its_mitigation = ITS_MITIGATION_OFF;
 		return;
 	}
 
-	/* Retpoline+CDT mitigates ITS, bail out */
-	if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
-	    boot_cpu_has(X86_FEATURE_CALL_DEPTH)) {
-		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
-		goto out;
-	}
+	if (its_mitigation == ITS_MITIGATION_AUTO)
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+
+	if (its_mitigation == ITS_MITIGATION_OFF)
+		return;
 
-	/* Exit early to avoid irrelevant warnings */
-	if (cmd == ITS_CMD_OFF) {
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
-	if (spectre_v2_enabled == SPECTRE_V2_NONE) {
-		pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
 	if (!IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) ||
 	    !IS_ENABLED(CONFIG_MITIGATION_RETHUNK)) {
 		pr_err("WARNING: ITS mitigation depends on retpoline and rethunk support\n");
 		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
+		return;
 	}
+
 	if (IS_ENABLED(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)) {
 		pr_err("WARNING: ITS mitigation is not compatible with CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B\n");
 		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
-	}
-	if (boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) {
-		pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
-		its_mitigation = ITS_MITIGATION_OFF;
-		goto out;
+		return;
 	}
 
-	if (cmd == ITS_CMD_RSB_STUFF &&
-	    (!boot_cpu_has(X86_FEATURE_RETPOLINE) || !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))) {
+	if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
+	    !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING)) {
 		pr_err("RSB stuff mitigation not supported, using default\n");
-		cmd = ITS_CMD_ON;
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 	}
 
-	switch (cmd) {
-	case ITS_CMD_OFF:
+	if (its_mitigation == ITS_MITIGATION_VMEXIT_ONLY &&
+	    !boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY))
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+}
+
+static void __init its_update_mitigation(void)
+{
+	if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off())
+		return;
+
+	switch (spectre_v2_enabled) {
+	case SPECTRE_V2_NONE:
+		pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
 		its_mitigation = ITS_MITIGATION_OFF;
 		break;
-	case ITS_CMD_VMEXIT:
-		if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
-			its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
-			goto out;
-		}
-		fallthrough;
-	case ITS_CMD_ON:
-		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
-		if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
-			setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
-		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
-		set_return_thunk(its_return_thunk);
+	case SPECTRE_V2_RETPOLINE:
+		/* Retpoline+CDT mitigates ITS */
+		if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF)
+			its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
 		break;
-	case ITS_CMD_RSB_STUFF:
-		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
-		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
-		setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH);
-		set_return_thunk(call_depth_return_thunk);
-		if (retbleed_mitigation == RETBLEED_MITIGATION_NONE) {
-			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
-			pr_info("Retbleed mitigation updated to stuffing\n");
-		}
+	case SPECTRE_V2_LFENCE:
+	case SPECTRE_V2_EIBRS_LFENCE:
+		pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
+		its_mitigation = ITS_MITIGATION_OFF;
+		break;
+	default:
 		break;
 	}
-out:
+
+	/*
+	 * retbleed_update_mitigation() will try to do stuffing if its=stuff.
+	 * If it can't, such as if spectre_v2!=retpoline, then fall back to
+	 * aligned thunks.
+	 */
+	if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
+	    retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
+		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
+
 	pr_info("%s\n", its_strings[its_mitigation]);
 }
 
+static void __init its_apply_mitigation(void)
+{
+	/* its=stuff forces retbleed stuffing and is enabled there. */
+	if (its_mitigation != ITS_MITIGATION_ALIGNED_THUNKS)
+		return;
+
+	if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
+		setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
+
+	setup_force_cpu_cap(X86_FEATURE_RETHUNK);
+	set_return_thunk(its_return_thunk);
+}
+
 #undef pr_fmt
 #define pr_fmt(fmt)     "Spectre V2 : " fmt
 

^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2025-05-21  6:56 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-15 13:47 [PATCH] x86/bugs: Restructure ITS mitigation David Kaplan
2025-05-15 15:16 ` Borislav Petkov
2025-05-15 21:11 ` Pawan Gupta
2025-05-15 21:15   ` Kaplan, David
2025-05-15 22:02     ` Pawan Gupta
2025-05-16 14:56       ` Borislav Petkov
2025-05-15 23:52 ` Pawan Gupta
2025-05-16 15:06   ` Kaplan, David
2025-05-19 23:51     ` Pawan Gupta
2025-05-16 19:32 ` [PATCH v2] " David Kaplan
2025-05-16 22:47   ` Dave Hansen
2025-05-17 13:19     ` Ingo Molnar
2025-05-17 13:25     ` Borislav Petkov
2025-05-20 16:32   ` Pawan Gupta
2025-05-20 16:48     ` Borislav Petkov
2025-05-20 16:57       ` Pawan Gupta
2025-05-20 16:54   ` [tip: x86/core] " tip-bot2 for David Kaplan
2025-05-21  6:56   ` tip-bot2 for David Kaplan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).