[PATCH 3/7] x86/bugs: Fix BHI handling of RRSBA

Josh Poimboeuf posted 7 patches 1 year, 10 months ago
[PATCH 3/7] x86/bugs: Fix BHI handling of RRSBA
Posted by Josh Poimboeuf 1 year, 10 months ago
The ARCH_CAP_RRSBA check isn't correct: RRSBA may have already been
disabled by the Spectre v2 mitigation (or can otherwise be disabled by
the BHI mitigation itself if needed).  In that case retpolines are fine.

Fixes: ec9404e40e8f ("x86/bhi: Add BHI mitigation knob")
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 arch/x86/kernel/cpu/bugs.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 27d6d64eeec3..0755600d5d18 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -1538,20 +1538,25 @@ static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void)
 	return SPECTRE_V2_RETPOLINE;
 }
 
+static bool __ro_after_init rrsba_disabled;
+
 /* Disable in-kernel use of non-RSB RET predictors */
 static void __init spec_ctrl_disable_kernel_rrsba(void)
 {
-	u64 ia32_cap;
+	if (rrsba_disabled)
+		return;
+
+	if (!(ia32_cap & ARCH_CAP_RRSBA)) {
+		rrsba_disabled = true;
+		return;
+	}
 
 	if (!boot_cpu_has(X86_FEATURE_RRSBA_CTRL))
 		return;
 
-	ia32_cap = x86_read_arch_cap_msr();
-
-	if (ia32_cap & ARCH_CAP_RRSBA) {
-		x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S;
-		update_spec_ctrl(x86_spec_ctrl_base);
-	}
+	x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S;
+	update_spec_ctrl(x86_spec_ctrl_base);
+	rrsba_disabled = true;
 }
 
 static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_mitigation mode)
@@ -1652,9 +1657,11 @@ static void __init bhi_select_mitigation(void)
 		return;
 
 	/* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */
-	if (cpu_feature_enabled(X86_FEATURE_RETPOLINE) &&
-	    !(x86_read_arch_cap_msr() & ARCH_CAP_RRSBA))
-		return;
+	if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) {
+		spec_ctrl_disable_kernel_rrsba();
+		if (rrsba_disabled)
+			return;
+	}
 
 	if (spec_ctrl_bhi_dis())
 		return;
@@ -2809,8 +2816,7 @@ static const char * const spectre_bhi_state(void)
 		return "; BHI: BHI_DIS_S";
 	else if  (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP))
 		return "; BHI: SW loop, KVM: SW loop";
-	else if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
-		 !(ia32_cap & ARCH_CAP_RRSBA))
+	else if (boot_cpu_has(X86_FEATURE_RETPOLINE) && rrsba_disabled)
 		return "; BHI: Retpoline";
 	else if  (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT))
 		return "; BHI: Syscall hardening, KVM: SW loop";
-- 
2.44.0
Re: [PATCH 3/7] x86/bugs: Fix BHI handling of RRSBA
Posted by Andrew Cooper 1 year, 10 months ago
On 11/04/2024 6:40 am, Josh Poimboeuf wrote:
> The ARCH_CAP_RRSBA check isn't correct: RRSBA may have already been
> disabled by the Spectre v2 mitigation (or can otherwise be disabled by
> the BHI mitigation itself if needed).  In that case retpolines are fine.
>
> Fixes: ec9404e40e8f ("x86/bhi: Add BHI mitigation knob")
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> ---
>  arch/x86/kernel/cpu/bugs.c | 30 ++++++++++++++++++------------
>  1 file changed, 18 insertions(+), 12 deletions(-)
>
> diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
> index 27d6d64eeec3..0755600d5d18 100644
> --- a/arch/x86/kernel/cpu/bugs.c
> +++ b/arch/x86/kernel/cpu/bugs.c
> @@ -1538,20 +1538,25 @@ static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void)
>  	return SPECTRE_V2_RETPOLINE;
>  }
>  
> +static bool __ro_after_init rrsba_disabled;
> +
>  /* Disable in-kernel use of non-RSB RET predictors */
>  static void __init spec_ctrl_disable_kernel_rrsba(void)
>  {
> -	u64 ia32_cap;
> +	if (rrsba_disabled)
> +		return;
> +
> +	if (!(ia32_cap & ARCH_CAP_RRSBA)) {
> +		rrsba_disabled = true;
> +		return;
> +	}

You'll take this path if you have out-of-date microcode.

RRSBA is only enumerated from September last year, IIRC.  (Definitely
from this point on some CPUs.)

When RRSBA was introduced, I was under the (false) impression that all
eIBRS systems suffered RRSBA, but it turns out that select parts
(ICX,TGL,RKL) are non-RRSBA despite not having RRSBA_CTRL.

~Andrew
Re: [PATCH 3/7] x86/bugs: Fix BHI handling of RRSBA
Posted by Josh Poimboeuf 1 year, 10 months ago
On Thu, Apr 11, 2024 at 11:02:42AM +0100, Andrew Cooper wrote:
> >  /* Disable in-kernel use of non-RSB RET predictors */
> >  static void __init spec_ctrl_disable_kernel_rrsba(void)
> >  {
> > -	u64 ia32_cap;
> > +	if (rrsba_disabled)
> > +		return;
> > +
> > +	if (!(ia32_cap & ARCH_CAP_RRSBA)) {
> > +		rrsba_disabled = true;
> > +		return;
> > +	}
> 
> You'll take this path if you have out-of-date microcode.
> 
> RRSBA is only enumerated from September last year, IIRC.  (Definitely
> from this point on some CPUs.)
> 
> When RRSBA was introduced, I was under the (false) impression that all
> eIBRS systems suffered RRSBA, but it turns out that select parts
> (ICX,TGL,RKL) are non-RRSBA despite not having RRSBA_CTRL.

Hm, so the original code here had this problem too, right?

	if (cpu_feature_enabled(X86_FEATURE_RETPOLINE) &&
	    !(x86_read_arch_cap_msr() & ARCH_CAP_RRSBA))
		return;

At this point I'm having a hard time caring about 7 months out-of-date
microcode, but is there a reasonable way to check for that?

-- 
Josh