From: Daniel Sneddon <daniel.sneddon@linux.intel.com>
To: Jim Mattson <jmattson@google.com>,
Suraj Jitindar Singh <surajjs@amazon.com>
Cc: kvm@vger.kernel.org, sjitindarsingh@gmail.com,
linux-kernel@vger.kernel.org, x86@kernel.org, tglx@linutronix.de,
mingo@redhat.com, bp@suse.de, dave.hansen@linux.intel.com,
seanjc@google.com, pbonzini@redhat.com, peterz@infradead.org,
jpoimboe@kernel.org, pawan.kumar.gupta@linux.intel.com,
benh@kernel.crashing.org, stable@vger.kernel.org
Subject: Re: [PATCH] x86/speculation: Mitigate eIBRS PBRSB predictions with WRMSR
Date: Wed, 5 Oct 2022 17:26:37 -0700 [thread overview]
Message-ID: <684c8ef6-bf69-e31e-fb3e-d3beca52fd15@linux.intel.com> (raw)
In-Reply-To: <CALMp9eThzv+5UBPtm77nvD_b48hHD7O1QLni7a+x9zAPicFk4Q@mail.gmail.com>
On 10/5/22 16:46, Jim Mattson wrote:
> On Wed, Oct 5, 2022 at 3:03 PM Suraj Jitindar Singh <surajjs@amazon.com> wrote:
>>
>> tl;dr: The existing mitigation for eIBRS PBRSB predictions uses an INT3 to
>> ensure a call instruction retires before a following unbalanced RET. Replace
>> this with a WRMSR serialising instruction which has a lower performance
>> penalty.
>>
>> == Background ==
>>
>> eIBRS (enhanced indirect branch restricted speculation) is used to prevent
>> predictor addresses from one privilege domain from being used for prediction
>> in a higher privilege domain.
>>
>> == Problem ==
>>
>> On processors with eIBRS protections there can be a case where upon VM exit
>> a guest address may be used as an RSB prediction for an unbalanced RET if a
>> CALL instruction hasn't yet been retired. This is termed PBRSB (Post-Barrier
>> Return Stack Buffer).
>>
>> A mitigation for this was introduced in:
>> (2b1299322016731d56807aa49254a5ea3080b6b3 x86/speculation: Add RSB VM Exit protections)
>>
>> This mitigation [1] has a ~1% performance impact on VM exit compared to without
>> it [2].
>>
>> == Solution ==
>>
>> The WRMSR instruction can be used as a speculation barrier and a serialising
>> instruction. Use this on the VM exit path instead to ensure that a CALL
>> instruction (in this case the call to vmx_spec_ctrl_restore_host) has retired
>> before the prediction of a following unbalanced RET.
>>
>> This mitigation [3] has a negligible performance impact.
>>
>> == Testing ==
>>
>> Run the outl_to_kernel kvm-unit-tests test 200 times per configuration which
>> counts the cycles for an exit to kernel mode.
>>
>> [1] With existing mitigation:
>> Average: 2026 cycles
>> [2] With no mitigation:
>> Average: 2008 cycles
>> [3] With proposed mitigation:
>> Average: 2008 cycles
>>
>> Signed-off-by: Suraj Jitindar Singh <surajjs@amazon.com>
>> Cc: stable@vger.kernel.org
>> ---
>> arch/x86/include/asm/nospec-branch.h | 7 +++----
>> arch/x86/kvm/vmx/vmenter.S | 3 +--
>> arch/x86/kvm/vmx/vmx.c | 5 +++++
>> 3 files changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
>> index c936ce9f0c47..e5723e024b47 100644
>> --- a/arch/x86/include/asm/nospec-branch.h
>> +++ b/arch/x86/include/asm/nospec-branch.h
>> @@ -159,10 +159,9 @@
>> * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP
>> * monstrosity above, manually.
>> */
>> -.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2=ALT_NOT(X86_FEATURE_ALWAYS)
>> - ALTERNATIVE_2 "jmp .Lskip_rsb_\@", \
>> - __stringify(__FILL_RETURN_BUFFER(\reg,\nr)), \ftr, \
>> - __stringify(__FILL_ONE_RETURN), \ftr2
>> +.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req
>> + ALTERNATIVE "jmp .Lskip_rsb_\@", \
>> + __stringify(__FILL_RETURN_BUFFER(\reg,\nr)), \ftr
>>
>> .Lskip_rsb_\@:
>> .endm
>> diff --git a/arch/x86/kvm/vmx/vmenter.S b/arch/x86/kvm/vmx/vmenter.S
>> index 6de96b943804..eb82797bd7bf 100644
>> --- a/arch/x86/kvm/vmx/vmenter.S
>> +++ b/arch/x86/kvm/vmx/vmenter.S
>> @@ -231,8 +231,7 @@ SYM_INNER_LABEL(vmx_vmexit, SYM_L_GLOBAL)
>> * single call to retire, before the first unbalanced RET.
>> */
>>
>> - FILL_RETURN_BUFFER %_ASM_CX, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT,\
>> - X86_FEATURE_RSB_VMEXIT_LITE
>> + FILL_RETURN_BUFFER %_ASM_CX, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT
>>
>>
>> pop %_ASM_ARG2 /* @flags */
>> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
>> index c9b49a09e6b5..fdcd8e10c2ab 100644
>> --- a/arch/x86/kvm/vmx/vmx.c
>> +++ b/arch/x86/kvm/vmx/vmx.c
>> @@ -7049,8 +7049,13 @@ void noinstr vmx_spec_ctrl_restore_host(struct vcpu_vmx *vmx,
>> * For legacy IBRS, the IBRS bit always needs to be written after
>> * transitioning from a less privileged predictor mode, regardless of
>> * whether the guest/host values differ.
>> + *
>> + * For eIBRS affected by Post Barrier RSB Predictions a serialising
>> + * instruction (wrmsr) must be executed to ensure a call instruction has
>> + * retired before the prediction of a following unbalanced ret.
>> */
>> if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS) ||
>> + cpu_feature_enabled(X86_FEATURE_RSB_VMEXIT_LITE) ||
>> vmx->spec_ctrl != hostval)
>> native_wrmsrl(MSR_IA32_SPEC_CTRL, hostval);
>
> Better, I think, would be to leave the condition alone and put an
> LFENCE on the 'else' path:
>
> if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS) ||
> vmx->spec_ctrl != hostval)
> native_wrmsrl(MSR_IA32_SPEC_CTRL, hostval);
> else
> rmb();
>
> When the guest and host have different IA32_SPEC_CTRL values, you get
> the serialization from the WRMSR. Otherwise, you get it from the
> cheaper LFENCE.
In this case systems that don't suffer from PBRSB (i.e. don've have
X86_FEATURE_RSB_VMEXIT_LITE set) would be doing a barrier for no reason. We're
just trading performance on vulnerable systems for a performance hit on systems
that aren't vulnerable.
>
> This is still more convoluted than having the mitigation in one place.
Agreed.
next prev parent reply other threads:[~2022-10-06 0:26 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-05 22:02 [PATCH] x86/speculation: Mitigate eIBRS PBRSB predictions with WRMSR Suraj Jitindar Singh
2022-10-05 22:29 ` Jim Mattson
2022-10-06 8:25 ` David Laight
2022-10-06 20:27 ` pawan.kumar.gupta
2022-10-05 23:24 ` Jim Mattson
2022-10-05 23:45 ` Pawan Gupta
2022-10-05 23:46 ` Jim Mattson
2022-10-06 0:26 ` Daniel Sneddon [this message]
2022-10-06 1:28 ` Jim Mattson
2022-10-06 8:18 ` Peter Zijlstra
2022-10-06 2:42 ` Andrew Cooper
2022-10-07 1:44 ` pawan.kumar.gupta
2022-10-07 1:54 ` Pawan Gupta
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=684c8ef6-bf69-e31e-fb3e-d3beca52fd15@linux.intel.com \
--to=daniel.sneddon@linux.intel.com \
--cc=benh@kernel.crashing.org \
--cc=bp@suse.de \
--cc=dave.hansen@linux.intel.com \
--cc=jmattson@google.com \
--cc=jpoimboe@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pawan.kumar.gupta@linux.intel.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=seanjc@google.com \
--cc=sjitindarsingh@gmail.com \
--cc=stable@vger.kernel.org \
--cc=surajjs@amazon.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.