[PATCH v4 09/11] x86/vmscape: Deploy BHB clearing mitigation

Pawan Gupta posted 11 patches 1 week, 4 days ago
There is a newer version of this series
[PATCH v4 09/11] x86/vmscape: Deploy BHB clearing mitigation
Posted by Pawan Gupta 1 week, 4 days ago
IBPB mitigation for VMSCAPE is an overkill on CPUs that are only affected
by the BHI variant of VMSCAPE. On such CPUs, eIBRS already provides
indirect branch isolation between guest and host userspace. However, branch
history from guest may also influence the indirect branches in host
userspace.

To mitigate the BHI aspect, use clear_bhb_loop().

Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
---
 Documentation/admin-guide/hw-vuln/vmscape.rst |  4 ++++
 arch/x86/include/asm/nospec-branch.h          |  2 ++
 arch/x86/kernel/cpu/bugs.c                    | 30 ++++++++++++++++++++-------
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/Documentation/admin-guide/hw-vuln/vmscape.rst b/Documentation/admin-guide/hw-vuln/vmscape.rst
index d9b9a2b6c114c05a7325e5f3c9d42129339b870b..dc63a0bac03d43d1e295de0791dd6497d101f986 100644
--- a/Documentation/admin-guide/hw-vuln/vmscape.rst
+++ b/Documentation/admin-guide/hw-vuln/vmscape.rst
@@ -86,6 +86,10 @@ The possible values in this file are:
    run a potentially malicious guest and issues an IBPB before the first
    exit to userspace after VM-exit.
 
+ * 'Mitigation: Clear BHB before exit to userspace':
+
+   As above, conditional BHB clearing mitigation is enabled.
+
  * 'Mitigation: IBPB on VMEXIT':
 
    IBPB is issued on every VM-exit. This occurs when other mitigations like
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
index 15a2fa8f2f48a066e102263513eff9537ac1d25f..1e8c26c37dbed4256b35101fb41c0e1eb6ef9272 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -388,6 +388,8 @@ extern void write_ibpb(void);
 
 #ifdef CONFIG_X86_64
 extern void clear_bhb_loop(void);
+#else
+static inline void clear_bhb_loop(void) {}
 #endif
 
 extern void (*x86_return_thunk)(void);
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index cbb3341b9a19f835738eda7226323d88b7e41e52..d12c07ccf59479ecf590935607394492c988b2ff 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -109,9 +109,8 @@ DEFINE_PER_CPU(u64, x86_spec_ctrl_current);
 EXPORT_PER_CPU_SYMBOL_GPL(x86_spec_ctrl_current);
 
 /*
- * Set when the CPU has run a potentially malicious guest. An IBPB will
- * be needed to before running userspace. That IBPB will flush the branch
- * predictor content.
+ * Set when the CPU has run a potentially malicious guest. Indicates that a
+ * branch predictor flush is needed before running userspace.
  */
 DEFINE_PER_CPU(bool, x86_predictor_flush_exit_to_user);
 EXPORT_PER_CPU_SYMBOL_GPL(x86_predictor_flush_exit_to_user);
@@ -3200,13 +3199,15 @@ enum vmscape_mitigations {
 	VMSCAPE_MITIGATION_AUTO,
 	VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER,
 	VMSCAPE_MITIGATION_IBPB_ON_VMEXIT,
+	VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER,
 };
 
 static const char * const vmscape_strings[] = {
-	[VMSCAPE_MITIGATION_NONE]		= "Vulnerable",
+	[VMSCAPE_MITIGATION_NONE]			= "Vulnerable",
 	/* [VMSCAPE_MITIGATION_AUTO] */
-	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]	= "Mitigation: IBPB before exit to userspace",
-	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]	= "Mitigation: IBPB on VMEXIT",
+	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]		= "Mitigation: IBPB before exit to userspace",
+	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]		= "Mitigation: IBPB on VMEXIT",
+	[VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER]	= "Mitigation: Clear BHB before exit to userspace",
 };
 
 static enum vmscape_mitigations vmscape_mitigation __ro_after_init =
@@ -3253,8 +3254,19 @@ static void __init vmscape_select_mitigation(void)
 			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
 		break;
 
+	case VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER:
+		if (!boot_cpu_has(X86_FEATURE_BHI_CTRL))
+			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
+		break;
 	case VMSCAPE_MITIGATION_AUTO:
-		if (boot_cpu_has(X86_FEATURE_IBPB))
+		/*
+		 * CPUs with BHI_CTRL(ADL and newer) can avoid the IBPB and use BHB
+		 * clear sequence. These CPUs are only vulnerable to the BHI variant
+		 * of the VMSCAPE attack and does not require an IBPB flush.
+		 */
+		if (boot_cpu_has(X86_FEATURE_BHI_CTRL))
+			vmscape_mitigation = VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER;
+		else if (boot_cpu_has(X86_FEATURE_IBPB))
 			vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER;
 		else
 			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
@@ -3278,6 +3290,9 @@ static void __init vmscape_apply_mitigation(void)
 {
 	if (vmscape_mitigation == VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER)
 		static_call_update(vmscape_predictor_flush, write_ibpb);
+	else if (vmscape_mitigation == VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER &&
+		 IS_ENABLED(CONFIG_X86_64))
+		static_call_update(vmscape_predictor_flush, clear_bhb_loop);
 }
 
 #undef pr_fmt
@@ -3369,6 +3384,7 @@ void cpu_bugs_smt_update(void)
 		break;
 	case VMSCAPE_MITIGATION_IBPB_ON_VMEXIT:
 	case VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER:
+	case VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER:
 		/*
 		 * Hypervisors can be attacked across-threads, warn for SMT when
 		 * STIBP is not already enabled system-wide.

-- 
2.34.1
Re: [PATCH v4 09/11] x86/vmscape: Deploy BHB clearing mitigation
Posted by Nikolay Borisov 1 week, 3 days ago

On 11/20/25 08:19, Pawan Gupta wrote:
> IBPB mitigation for VMSCAPE is an overkill on CPUs that are only affected
> by the BHI variant of VMSCAPE. On such CPUs, eIBRS already provides
> indirect branch isolation between guest and host userspace. However, branch
> history from guest may also influence the indirect branches in host
> userspace.
> 
> To mitigate the BHI aspect, use clear_bhb_loop().
> 
> Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
> ---
>   Documentation/admin-guide/hw-vuln/vmscape.rst |  4 ++++
>   arch/x86/include/asm/nospec-branch.h          |  2 ++
>   arch/x86/kernel/cpu/bugs.c                    | 30 ++++++++++++++++++++-------
>   3 files changed, 29 insertions(+), 7 deletions(-)
> 
> diff --git a/Documentation/admin-guide/hw-vuln/vmscape.rst b/Documentation/admin-guide/hw-vuln/vmscape.rst
> index d9b9a2b6c114c05a7325e5f3c9d42129339b870b..dc63a0bac03d43d1e295de0791dd6497d101f986 100644
> --- a/Documentation/admin-guide/hw-vuln/vmscape.rst
> +++ b/Documentation/admin-guide/hw-vuln/vmscape.rst
> @@ -86,6 +86,10 @@ The possible values in this file are:
>      run a potentially malicious guest and issues an IBPB before the first
>      exit to userspace after VM-exit.
>   
> + * 'Mitigation: Clear BHB before exit to userspace':
> +
> +   As above, conditional BHB clearing mitigation is enabled.
> +
>    * 'Mitigation: IBPB on VMEXIT':
>   
>      IBPB is issued on every VM-exit. This occurs when other mitigations like
> diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
> index 15a2fa8f2f48a066e102263513eff9537ac1d25f..1e8c26c37dbed4256b35101fb41c0e1eb6ef9272 100644
> --- a/arch/x86/include/asm/nospec-branch.h
> +++ b/arch/x86/include/asm/nospec-branch.h
> @@ -388,6 +388,8 @@ extern void write_ibpb(void);
>   
>   #ifdef CONFIG_X86_64
>   extern void clear_bhb_loop(void);
> +#else
> +static inline void clear_bhb_loop(void) {}
>   #endif
>   
>   extern void (*x86_return_thunk)(void);
> diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
> index cbb3341b9a19f835738eda7226323d88b7e41e52..d12c07ccf59479ecf590935607394492c988b2ff 100644
> --- a/arch/x86/kernel/cpu/bugs.c
> +++ b/arch/x86/kernel/cpu/bugs.c
> @@ -109,9 +109,8 @@ DEFINE_PER_CPU(u64, x86_spec_ctrl_current);
>   EXPORT_PER_CPU_SYMBOL_GPL(x86_spec_ctrl_current);
>   
>   /*
> - * Set when the CPU has run a potentially malicious guest. An IBPB will
> - * be needed to before running userspace. That IBPB will flush the branch
> - * predictor content.
> + * Set when the CPU has run a potentially malicious guest. Indicates that a
> + * branch predictor flush is needed before running userspace.
>    */
>   DEFINE_PER_CPU(bool, x86_predictor_flush_exit_to_user);
>   EXPORT_PER_CPU_SYMBOL_GPL(x86_predictor_flush_exit_to_user);
> @@ -3200,13 +3199,15 @@ enum vmscape_mitigations {
>   	VMSCAPE_MITIGATION_AUTO,
>   	VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER,
>   	VMSCAPE_MITIGATION_IBPB_ON_VMEXIT,
> +	VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER,
>   };
>   
>   static const char * const vmscape_strings[] = {
> -	[VMSCAPE_MITIGATION_NONE]		= "Vulnerable",
> +	[VMSCAPE_MITIGATION_NONE]			= "Vulnerable",
>   	/* [VMSCAPE_MITIGATION_AUTO] */
> -	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]	= "Mitigation: IBPB before exit to userspace",
> -	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]	= "Mitigation: IBPB on VMEXIT",
> +	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]		= "Mitigation: IBPB before exit to userspace",
> +	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]		= "Mitigation: IBPB on VMEXIT",
> +	[VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER]	= "Mitigation: Clear BHB before exit to userspace",
>   };
>   
>   static enum vmscape_mitigations vmscape_mitigation __ro_after_init =
> @@ -3253,8 +3254,19 @@ static void __init vmscape_select_mitigation(void)
>   			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
>   		break;
>   
> +	case VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER:
> +		if (!boot_cpu_has(X86_FEATURE_BHI_CTRL))
> +			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
> +		break;

Am I missing something or this case can never execute because 
VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER is only ever set if mitigation 
is VMSCAPE_MITIGATION_AUTO in the below branch? Perhaps just remove it? 
This just shows how confusing the logic for choosing the mitigations has 
become....



>   	case VMSCAPE_MITIGATION_AUTO:
> -		if (boot_cpu_has(X86_FEATURE_IBPB))
> +		/*
> +		 * CPUs with BHI_CTRL(ADL and newer) can avoid the IBPB and use BHB
> +		 * clear sequence. These CPUs are only vulnerable to the BHI variant
> +		 * of the VMSCAPE attack and does not require an IBPB flush.
> +		 */
> +		if (boot_cpu_has(X86_FEATURE_BHI_CTRL))
> +			vmscape_mitigation = VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER;
> +		else if (boot_cpu_has(X86_FEATURE_IBPB))
>   			vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER;
>   		else
>   			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;


<snip>
Re: [PATCH v4 09/11] x86/vmscape: Deploy BHB clearing mitigation
Posted by Pawan Gupta 1 week, 3 days ago
On Fri, Nov 21, 2025 at 04:23:56PM +0200, Nikolay Borisov wrote:
> 
> 
> On 11/20/25 08:19, Pawan Gupta wrote:
> > IBPB mitigation for VMSCAPE is an overkill on CPUs that are only affected
> > by the BHI variant of VMSCAPE. On such CPUs, eIBRS already provides
> > indirect branch isolation between guest and host userspace. However, branch
> > history from guest may also influence the indirect branches in host
> > userspace.
> > 
> > To mitigate the BHI aspect, use clear_bhb_loop().
> > 
> > Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
> > ---
> >   Documentation/admin-guide/hw-vuln/vmscape.rst |  4 ++++
> >   arch/x86/include/asm/nospec-branch.h          |  2 ++
> >   arch/x86/kernel/cpu/bugs.c                    | 30 ++++++++++++++++++++-------
> >   3 files changed, 29 insertions(+), 7 deletions(-)
> > 
> > diff --git a/Documentation/admin-guide/hw-vuln/vmscape.rst b/Documentation/admin-guide/hw-vuln/vmscape.rst
> > index d9b9a2b6c114c05a7325e5f3c9d42129339b870b..dc63a0bac03d43d1e295de0791dd6497d101f986 100644
> > --- a/Documentation/admin-guide/hw-vuln/vmscape.rst
> > +++ b/Documentation/admin-guide/hw-vuln/vmscape.rst
> > @@ -86,6 +86,10 @@ The possible values in this file are:
> >      run a potentially malicious guest and issues an IBPB before the first
> >      exit to userspace after VM-exit.
> > + * 'Mitigation: Clear BHB before exit to userspace':
> > +
> > +   As above, conditional BHB clearing mitigation is enabled.
> > +
> >    * 'Mitigation: IBPB on VMEXIT':
> >      IBPB is issued on every VM-exit. This occurs when other mitigations like
> > diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
> > index 15a2fa8f2f48a066e102263513eff9537ac1d25f..1e8c26c37dbed4256b35101fb41c0e1eb6ef9272 100644
> > --- a/arch/x86/include/asm/nospec-branch.h
> > +++ b/arch/x86/include/asm/nospec-branch.h
> > @@ -388,6 +388,8 @@ extern void write_ibpb(void);
> >   #ifdef CONFIG_X86_64
> >   extern void clear_bhb_loop(void);
> > +#else
> > +static inline void clear_bhb_loop(void) {}
> >   #endif
> >   extern void (*x86_return_thunk)(void);
> > diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
> > index cbb3341b9a19f835738eda7226323d88b7e41e52..d12c07ccf59479ecf590935607394492c988b2ff 100644
> > --- a/arch/x86/kernel/cpu/bugs.c
> > +++ b/arch/x86/kernel/cpu/bugs.c
> > @@ -109,9 +109,8 @@ DEFINE_PER_CPU(u64, x86_spec_ctrl_current);
> >   EXPORT_PER_CPU_SYMBOL_GPL(x86_spec_ctrl_current);
> >   /*
> > - * Set when the CPU has run a potentially malicious guest. An IBPB will
> > - * be needed to before running userspace. That IBPB will flush the branch
> > - * predictor content.
> > + * Set when the CPU has run a potentially malicious guest. Indicates that a
> > + * branch predictor flush is needed before running userspace.
> >    */
> >   DEFINE_PER_CPU(bool, x86_predictor_flush_exit_to_user);
> >   EXPORT_PER_CPU_SYMBOL_GPL(x86_predictor_flush_exit_to_user);
> > @@ -3200,13 +3199,15 @@ enum vmscape_mitigations {
> >   	VMSCAPE_MITIGATION_AUTO,
> >   	VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER,
> >   	VMSCAPE_MITIGATION_IBPB_ON_VMEXIT,
> > +	VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER,
> >   };
> >   static const char * const vmscape_strings[] = {
> > -	[VMSCAPE_MITIGATION_NONE]		= "Vulnerable",
> > +	[VMSCAPE_MITIGATION_NONE]			= "Vulnerable",
> >   	/* [VMSCAPE_MITIGATION_AUTO] */
> > -	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]	= "Mitigation: IBPB before exit to userspace",
> > -	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]	= "Mitigation: IBPB on VMEXIT",
> > +	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]		= "Mitigation: IBPB before exit to userspace",
> > +	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]		= "Mitigation: IBPB on VMEXIT",
> > +	[VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER]	= "Mitigation: Clear BHB before exit to userspace",
> >   };
> >   static enum vmscape_mitigations vmscape_mitigation __ro_after_init =
> > @@ -3253,8 +3254,19 @@ static void __init vmscape_select_mitigation(void)
> >   			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
> >   		break;
> > +	case VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER:
> > +		if (!boot_cpu_has(X86_FEATURE_BHI_CTRL))
> > +			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
> > +		break;
> 
> Am I missing something or this case can never execute because
> VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER is only ever set if mitigation is
> VMSCAPE_MITIGATION_AUTO in the below branch? Perhaps just remove it? This
> just shows how confusing the logic for choosing the mitigations has
> become....

The goal was not make any assumptions on what vmscape_parse_cmdline() can
and cannot set. If you feel strongly about it, I can remove this case.

> >   	case VMSCAPE_MITIGATION_AUTO:
> > -		if (boot_cpu_has(X86_FEATURE_IBPB))
> > +		/*
> > +		 * CPUs with BHI_CTRL(ADL and newer) can avoid the IBPB and use BHB
> > +		 * clear sequence. These CPUs are only vulnerable to the BHI variant
> > +		 * of the VMSCAPE attack and does not require an IBPB flush.
> > +		 */
> > +		if (boot_cpu_has(X86_FEATURE_BHI_CTRL))
> > +			vmscape_mitigation = VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER;
> > +		else if (boot_cpu_has(X86_FEATURE_IBPB))
> >   			vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER;
> >   		else
> >   			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
> 
> 
> <snip>
>
Re: [PATCH v4 09/11] x86/vmscape: Deploy BHB clearing mitigation
Posted by Nikolay Borisov 1 week, 3 days ago

On 11/21/25 20:41, Pawan Gupta wrote:
> On Fri, Nov 21, 2025 at 04:23:56PM +0200, Nikolay Borisov wrote:
>>
>>
>> On 11/20/25 08:19, Pawan Gupta wrote:
>>> IBPB mitigation for VMSCAPE is an overkill on CPUs that are only affected
>>> by the BHI variant of VMSCAPE. On such CPUs, eIBRS already provides
>>> indirect branch isolation between guest and host userspace. However, branch
>>> history from guest may also influence the indirect branches in host
>>> userspace.
>>>
>>> To mitigate the BHI aspect, use clear_bhb_loop().
>>>
>>> Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
>>> ---
>>>    Documentation/admin-guide/hw-vuln/vmscape.rst |  4 ++++
>>>    arch/x86/include/asm/nospec-branch.h          |  2 ++
>>>    arch/x86/kernel/cpu/bugs.c                    | 30 ++++++++++++++++++++-------
>>>    3 files changed, 29 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/Documentation/admin-guide/hw-vuln/vmscape.rst b/Documentation/admin-guide/hw-vuln/vmscape.rst
>>> index d9b9a2b6c114c05a7325e5f3c9d42129339b870b..dc63a0bac03d43d1e295de0791dd6497d101f986 100644
>>> --- a/Documentation/admin-guide/hw-vuln/vmscape.rst
>>> +++ b/Documentation/admin-guide/hw-vuln/vmscape.rst
>>> @@ -86,6 +86,10 @@ The possible values in this file are:
>>>       run a potentially malicious guest and issues an IBPB before the first
>>>       exit to userspace after VM-exit.
>>> + * 'Mitigation: Clear BHB before exit to userspace':
>>> +
>>> +   As above, conditional BHB clearing mitigation is enabled.
>>> +
>>>     * 'Mitigation: IBPB on VMEXIT':
>>>       IBPB is issued on every VM-exit. This occurs when other mitigations like
>>> diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
>>> index 15a2fa8f2f48a066e102263513eff9537ac1d25f..1e8c26c37dbed4256b35101fb41c0e1eb6ef9272 100644
>>> --- a/arch/x86/include/asm/nospec-branch.h
>>> +++ b/arch/x86/include/asm/nospec-branch.h
>>> @@ -388,6 +388,8 @@ extern void write_ibpb(void);
>>>    #ifdef CONFIG_X86_64
>>>    extern void clear_bhb_loop(void);
>>> +#else
>>> +static inline void clear_bhb_loop(void) {}
>>>    #endif
>>>    extern void (*x86_return_thunk)(void);
>>> diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
>>> index cbb3341b9a19f835738eda7226323d88b7e41e52..d12c07ccf59479ecf590935607394492c988b2ff 100644
>>> --- a/arch/x86/kernel/cpu/bugs.c
>>> +++ b/arch/x86/kernel/cpu/bugs.c
>>> @@ -109,9 +109,8 @@ DEFINE_PER_CPU(u64, x86_spec_ctrl_current);
>>>    EXPORT_PER_CPU_SYMBOL_GPL(x86_spec_ctrl_current);
>>>    /*
>>> - * Set when the CPU has run a potentially malicious guest. An IBPB will
>>> - * be needed to before running userspace. That IBPB will flush the branch
>>> - * predictor content.
>>> + * Set when the CPU has run a potentially malicious guest. Indicates that a
>>> + * branch predictor flush is needed before running userspace.
>>>     */
>>>    DEFINE_PER_CPU(bool, x86_predictor_flush_exit_to_user);
>>>    EXPORT_PER_CPU_SYMBOL_GPL(x86_predictor_flush_exit_to_user);
>>> @@ -3200,13 +3199,15 @@ enum vmscape_mitigations {
>>>    	VMSCAPE_MITIGATION_AUTO,
>>>    	VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER,
>>>    	VMSCAPE_MITIGATION_IBPB_ON_VMEXIT,
>>> +	VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER,
>>>    };
>>>    static const char * const vmscape_strings[] = {
>>> -	[VMSCAPE_MITIGATION_NONE]		= "Vulnerable",
>>> +	[VMSCAPE_MITIGATION_NONE]			= "Vulnerable",
>>>    	/* [VMSCAPE_MITIGATION_AUTO] */
>>> -	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]	= "Mitigation: IBPB before exit to userspace",
>>> -	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]	= "Mitigation: IBPB on VMEXIT",
>>> +	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]		= "Mitigation: IBPB before exit to userspace",
>>> +	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]		= "Mitigation: IBPB on VMEXIT",
>>> +	[VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER]	= "Mitigation: Clear BHB before exit to userspace",
>>>    };
>>>    static enum vmscape_mitigations vmscape_mitigation __ro_after_init =
>>> @@ -3253,8 +3254,19 @@ static void __init vmscape_select_mitigation(void)
>>>    			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
>>>    		break;
>>> +	case VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER:
>>> +		if (!boot_cpu_has(X86_FEATURE_BHI_CTRL))
>>> +			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
>>> +		break;
>>
>> Am I missing something or this case can never execute because
>> VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER is only ever set if mitigation is
>> VMSCAPE_MITIGATION_AUTO in the below branch? Perhaps just remove it? This
>> just shows how confusing the logic for choosing the mitigations has
>> become....
> 
> The goal was not make any assumptions on what vmscape_parse_cmdline() can
> and cannot set. If you feel strongly about it, I can remove this case.

 From where I'm standing bugs.c is already rather hairy even after 
multiple rounds of cleanups and brushups, if we can remove code - I'll 
be up for it. At the very least  in the commit message you can 
explicitly mention that you handle every case on-principle, and you 
expect that some of it is dead code. Still, I think the best code is the 
one which doesn't exist  and you won't have to worry about it.

<snip>
Re: [PATCH v4 09/11] x86/vmscape: Deploy BHB clearing mitigation
Posted by Pawan Gupta 1 week, 3 days ago
On Fri, Nov 21, 2025 at 08:53:38PM +0200, Nikolay Borisov wrote:
> 
> 
> On 11/21/25 20:41, Pawan Gupta wrote:
> > On Fri, Nov 21, 2025 at 04:23:56PM +0200, Nikolay Borisov wrote:
> > > 
> > > 
> > > On 11/20/25 08:19, Pawan Gupta wrote:
> > > > IBPB mitigation for VMSCAPE is an overkill on CPUs that are only affected
> > > > by the BHI variant of VMSCAPE. On such CPUs, eIBRS already provides
> > > > indirect branch isolation between guest and host userspace. However, branch
> > > > history from guest may also influence the indirect branches in host
> > > > userspace.
> > > > 
> > > > To mitigate the BHI aspect, use clear_bhb_loop().
> > > > 
> > > > Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
> > > > ---
> > > >    Documentation/admin-guide/hw-vuln/vmscape.rst |  4 ++++
> > > >    arch/x86/include/asm/nospec-branch.h          |  2 ++
> > > >    arch/x86/kernel/cpu/bugs.c                    | 30 ++++++++++++++++++++-------
> > > >    3 files changed, 29 insertions(+), 7 deletions(-)
> > > > 
> > > > diff --git a/Documentation/admin-guide/hw-vuln/vmscape.rst b/Documentation/admin-guide/hw-vuln/vmscape.rst
> > > > index d9b9a2b6c114c05a7325e5f3c9d42129339b870b..dc63a0bac03d43d1e295de0791dd6497d101f986 100644
> > > > --- a/Documentation/admin-guide/hw-vuln/vmscape.rst
> > > > +++ b/Documentation/admin-guide/hw-vuln/vmscape.rst
> > > > @@ -86,6 +86,10 @@ The possible values in this file are:
> > > >       run a potentially malicious guest and issues an IBPB before the first
> > > >       exit to userspace after VM-exit.
> > > > + * 'Mitigation: Clear BHB before exit to userspace':
> > > > +
> > > > +   As above, conditional BHB clearing mitigation is enabled.
> > > > +
> > > >     * 'Mitigation: IBPB on VMEXIT':
> > > >       IBPB is issued on every VM-exit. This occurs when other mitigations like
> > > > diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
> > > > index 15a2fa8f2f48a066e102263513eff9537ac1d25f..1e8c26c37dbed4256b35101fb41c0e1eb6ef9272 100644
> > > > --- a/arch/x86/include/asm/nospec-branch.h
> > > > +++ b/arch/x86/include/asm/nospec-branch.h
> > > > @@ -388,6 +388,8 @@ extern void write_ibpb(void);
> > > >    #ifdef CONFIG_X86_64
> > > >    extern void clear_bhb_loop(void);
> > > > +#else
> > > > +static inline void clear_bhb_loop(void) {}
> > > >    #endif
> > > >    extern void (*x86_return_thunk)(void);
> > > > diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
> > > > index cbb3341b9a19f835738eda7226323d88b7e41e52..d12c07ccf59479ecf590935607394492c988b2ff 100644
> > > > --- a/arch/x86/kernel/cpu/bugs.c
> > > > +++ b/arch/x86/kernel/cpu/bugs.c
> > > > @@ -109,9 +109,8 @@ DEFINE_PER_CPU(u64, x86_spec_ctrl_current);
> > > >    EXPORT_PER_CPU_SYMBOL_GPL(x86_spec_ctrl_current);
> > > >    /*
> > > > - * Set when the CPU has run a potentially malicious guest. An IBPB will
> > > > - * be needed to before running userspace. That IBPB will flush the branch
> > > > - * predictor content.
> > > > + * Set when the CPU has run a potentially malicious guest. Indicates that a
> > > > + * branch predictor flush is needed before running userspace.
> > > >     */
> > > >    DEFINE_PER_CPU(bool, x86_predictor_flush_exit_to_user);
> > > >    EXPORT_PER_CPU_SYMBOL_GPL(x86_predictor_flush_exit_to_user);
> > > > @@ -3200,13 +3199,15 @@ enum vmscape_mitigations {
> > > >    	VMSCAPE_MITIGATION_AUTO,
> > > >    	VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER,
> > > >    	VMSCAPE_MITIGATION_IBPB_ON_VMEXIT,
> > > > +	VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER,
> > > >    };
> > > >    static const char * const vmscape_strings[] = {
> > > > -	[VMSCAPE_MITIGATION_NONE]		= "Vulnerable",
> > > > +	[VMSCAPE_MITIGATION_NONE]			= "Vulnerable",
> > > >    	/* [VMSCAPE_MITIGATION_AUTO] */
> > > > -	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]	= "Mitigation: IBPB before exit to userspace",
> > > > -	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]	= "Mitigation: IBPB on VMEXIT",
> > > > +	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]		= "Mitigation: IBPB before exit to userspace",
> > > > +	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]		= "Mitigation: IBPB on VMEXIT",
> > > > +	[VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER]	= "Mitigation: Clear BHB before exit to userspace",
> > > >    };
> > > >    static enum vmscape_mitigations vmscape_mitigation __ro_after_init =
> > > > @@ -3253,8 +3254,19 @@ static void __init vmscape_select_mitigation(void)
> > > >    			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
> > > >    		break;
> > > > +	case VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER:
> > > > +		if (!boot_cpu_has(X86_FEATURE_BHI_CTRL))
> > > > +			vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
> > > > +		break;
> > > 
> > > Am I missing something or this case can never execute because
> > > VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER is only ever set if mitigation is
> > > VMSCAPE_MITIGATION_AUTO in the below branch? Perhaps just remove it? This
> > > just shows how confusing the logic for choosing the mitigations has
> > > become....
> > 
> > The goal was not make any assumptions on what vmscape_parse_cmdline() can
> > and cannot set. If you feel strongly about it, I can remove this case.
> 
> From where I'm standing bugs.c is already rather hairy even after multiple
> rounds of cleanups and brushups, if we can remove code - I'll be up for it.
> At the very least  in the commit message you can explicitly mention that you
> handle every case on-principle, and you expect that some of it is dead code.
> Still, I think the best code is the one which doesn't exist  and you won't
> have to worry about it.

Makes sense. I will get rid of those cases.
Re: [PATCH v4 09/11] x86/vmscape: Deploy BHB clearing mitigation
Posted by Nikolay Borisov 1 week, 3 days ago

On 11/20/25 08:19, Pawan Gupta wrote:
> IBPB mitigation for VMSCAPE is an overkill on CPUs that are only affected
> by the BHI variant of VMSCAPE. On such CPUs, eIBRS already provides
> indirect branch isolation between guest and host userspace. However, branch
> history from guest may also influence the indirect branches in host
> userspace.
> 
> To mitigate the BHI aspect, use clear_bhb_loop().
> 
> Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>

<snip>

> @@ -3278,6 +3290,9 @@ static void __init vmscape_apply_mitigation(void)
>   {
>   	if (vmscape_mitigation == VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER)
>   		static_call_update(vmscape_predictor_flush, write_ibpb);
> +	else if (vmscape_mitigation == VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER &&
> +		 IS_ENABLED(CONFIG_X86_64))

why the x86_64 dependency ?


> +		static_call_update(vmscape_predictor_flush, clear_bhb_loop);
>   }
>   
>   #undef pr_fmt
> @@ -3369,6 +3384,7 @@ void cpu_bugs_smt_update(void)
>   		break;
>   	case VMSCAPE_MITIGATION_IBPB_ON_VMEXIT:
>   	case VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER:
> +	case VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER:
>   		/*
>   		 * Hypervisors can be attacked across-threads, warn for SMT when
>   		 * STIBP is not already enabled system-wide.
>
Re: [PATCH v4 09/11] x86/vmscape: Deploy BHB clearing mitigation
Posted by Pawan Gupta 1 week, 3 days ago
On Fri, Nov 21, 2025 at 04:18:09PM +0200, Nikolay Borisov wrote:
> 
> 
> On 11/20/25 08:19, Pawan Gupta wrote:
> > IBPB mitigation for VMSCAPE is an overkill on CPUs that are only affected
> > by the BHI variant of VMSCAPE. On such CPUs, eIBRS already provides
> > indirect branch isolation between guest and host userspace. However, branch
> > history from guest may also influence the indirect branches in host
> > userspace.
> > 
> > To mitigate the BHI aspect, use clear_bhb_loop().
> > 
> > Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
> 
> <snip>
> 
> > @@ -3278,6 +3290,9 @@ static void __init vmscape_apply_mitigation(void)
> >   {
> >   	if (vmscape_mitigation == VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER)
> >   		static_call_update(vmscape_predictor_flush, write_ibpb);
> > +	else if (vmscape_mitigation == VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER &&
> > +		 IS_ENABLED(CONFIG_X86_64))
> 
> why the x86_64 dependency ?

BHI sequence mitigation is only supported in 64-bit mode. I will add a
comment. Looking at it again, I realized that 64-bit check should be in
vmscape_select_mitigation(), otherwise we report incorrectly on 32-bit.

> > +		static_call_update(vmscape_predictor_flush, clear_bhb_loop);
> >   }
> >   #undef pr_fmt
> > @@ -3369,6 +3384,7 @@ void cpu_bugs_smt_update(void)
> >   		break;
> >   	case VMSCAPE_MITIGATION_IBPB_ON_VMEXIT:
> >   	case VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER:
> > +	case VMSCAPE_MITIGATION_BHB_CLEAR_EXIT_TO_USER:
> >   		/*
> >   		 * Hypervisors can be attacked across-threads, warn for SMT when
> >   		 * STIBP is not already enabled system-wide.
> > 
>