All of lore.kernel.org
 help / color / mirror / Atom feed
From: KarimAllah Ahmed <karahmed@amazon.com>
To: Jim Mattson <jmattson@google.com>, KarimAllah Ahmed <karahmed@amazon.de>
Cc: kvm list <kvm@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	"the arch/x86 maintainers" <x86@kernel.org>,
	Asit Mallick <asit.k.mallick@intel.com>,
	Arjan Van De Ven <arjan.van.de.ven@intel.com>,
	Dave Hansen <dave.hansen@intel.com>,
	Andi Kleen <ak@linux.intel.com>,
	"Andrea Arcangeli" <aarcange@redhat.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Tim Chen <tim.c.chen@linux.intel.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Dan Williams <dan.j.williams@intel.com>,
	Jun Nakajima <jun.nakajima@intel.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	David Woodhouse <dwmw@amazon.co.uk>,
	Greg KH <gregkh@linuxfoundation.org>,
	Andy Lutomirski <luto@kernel.org>,
	Ashok Raj <ashok.raj@intel.com>
Subject: Re: [PATCH v3 4/4] KVM: VMX: Allow direct access to MSR_IA32_SPEC_CTRL
Date: Tue, 30 Jan 2018 22:00:54 +0100	[thread overview]
Message-ID: <43859417-ae76-ed1f-eb4f-8a84a35998fc@amazon.com> (raw)
In-Reply-To: <CALMp9eSmjkJR466C6QuudsFNjEvmyn1hBoK8zUh9EGRNSoMu9Q@mail.gmail.com>

On 01/30/2018 06:49 PM, Jim Mattson wrote:
> On Mon, Jan 29, 2018 at 4:10 PM, KarimAllah Ahmed <karahmed@amazon.de> wrote:
>> [ Based on a patch from Ashok Raj <ashok.raj@intel.com> ]
>>
>> Add direct access to MSR_IA32_SPEC_CTRL for guests. This is needed for
>> guests that will only mitigate Spectre V2 through IBRS+IBPB and will not
>> be using a retpoline+IBPB based approach.
>>
>> To avoid the overhead of atomically saving and restoring the
>> MSR_IA32_SPEC_CTRL for guests that do not actually use the MSR, only
>> add_atomic_switch_msr when a non-zero is written to it.
>>
>> No attempt is made to handle STIBP here, intentionally. Filtering STIBP
>> may be added in a future patch, which may require trapping all writes
>> if we don't want to pass it through directly to the guest.
>>
>> [dwmw2: Clean up CPUID bits, save/restore manually, handle reset]
>>
>> Cc: Asit Mallick <asit.k.mallick@intel.com>
>> Cc: Arjan Van De Ven <arjan.van.de.ven@intel.com>
>> Cc: Dave Hansen <dave.hansen@intel.com>
>> Cc: Andi Kleen <ak@linux.intel.com>
>> Cc: Andrea Arcangeli <aarcange@redhat.com>
>> Cc: Linus Torvalds <torvalds@linux-foundation.org>
>> Cc: Tim Chen <tim.c.chen@linux.intel.com>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Dan Williams <dan.j.williams@intel.com>
>> Cc: Jun Nakajima <jun.nakajima@intel.com>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> Cc: David Woodhouse <dwmw@amazon.co.uk>
>> Cc: Greg KH <gregkh@linuxfoundation.org>
>> Cc: Andy Lutomirski <luto@kernel.org>
>> Cc: Ashok Raj <ashok.raj@intel.com>
>> Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
>> Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
>> ---
>> v2:
>> - remove 'host_spec_ctrl' in favor of only a comment (dwmw@).
>> - special case writing '0' in SPEC_CTRL to avoid confusing live-migration
>>    when the instance never used the MSR (dwmw@).
>> - depend on X86_FEATURE_IBRS instead of X86_FEATURE_SPEC_CTRL (dwmw@).
>> - add MSR_IA32_SPEC_CTRL to the list of MSRs to save (dropped it by accident).
>> v3:
>> - Save/restore manually
>> - Fix CPUID handling
>> - Fix a copy & paste error in the name of SPEC_CTRL MSR in
>>    disable_intercept.
>> - support !cpu_has_vmx_msr_bitmap()
>> ---
>>   arch/x86/kvm/cpuid.c |  7 +++++--
>>   arch/x86/kvm/vmx.c   | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>   arch/x86/kvm/x86.c   |  2 +-
>>   3 files changed, 65 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
>> index 1909635..662d0c0 100644
>> --- a/arch/x86/kvm/cpuid.c
>> +++ b/arch/x86/kvm/cpuid.c
>> @@ -394,7 +394,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
>>
>>          /* cpuid 7.0.edx*/
>>          const u32 kvm_cpuid_7_0_edx_x86_features =
>> -               F(AVX512_4VNNIW) | F(AVX512_4FMAPS) | F(ARCH_CAPABILITIES);
>> +               F(AVX512_4VNNIW) | F(AVX512_4FMAPS) | F(SPEC_CTRL) |
>> +               F(ARCH_CAPABILITIES);
>>
>>          /* all calls to cpuid_count() should be made on the same cpu */
>>          get_cpu();
>> @@ -630,9 +631,11 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
>>                          g_phys_as = phys_as;
>>                  entry->eax = g_phys_as | (virt_as << 8);
>>                  entry->edx = 0;
>> -               /* IBPB isn't necessarily present in hardware cpuid */
>> +               /* IBRS and IBPB aren't necessarily present in hardware cpuid */
>>                  if (boot_cpu_has(X86_FEATURE_IBPB))
>>                          entry->ebx |= F(IBPB);
>> +               if (boot_cpu_has(X86_FEATURE_IBRS))
>> +                       entry->ebx |= F(IBRS);
>>                  entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features;
>>                  cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX);
>>                  break;
>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>> index 798a00b..9ac9747 100644
>> --- a/arch/x86/kvm/vmx.c
>> +++ b/arch/x86/kvm/vmx.c
>> @@ -582,6 +582,8 @@ struct vcpu_vmx {
>>          u64                   msr_guest_kernel_gs_base;
>>   #endif
>>          u64                   arch_capabilities;
>> +       u64                   spec_ctrl;
>> +       bool                  save_spec_ctrl_on_exit;
>>
>>          u32 vm_entry_controls_shadow;
>>          u32 vm_exit_controls_shadow;
>> @@ -922,6 +924,8 @@ static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);
>>   static bool nested_vmx_is_page_fault_vmexit(struct vmcs12 *vmcs12,
>>                                              u16 error_code);
>>   static void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu);
>> +static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
>> +                                                         u32 msr, int type);
>>
>>   static DEFINE_PER_CPU(struct vmcs *, vmxarea);
>>   static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
>> @@ -3226,6 +3230,13 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>          case MSR_IA32_TSC:
>>                  msr_info->data = guest_read_tsc(vcpu);
>>                  break;
>> +       case MSR_IA32_SPEC_CTRL:
>> +               if (!msr_info->host_initiated &&
>> +                   !guest_cpuid_has(vcpu, X86_FEATURE_IBRS))
>> +                       return 1;
>> +
>> +               msr_info->data = to_vmx(vcpu)->spec_ctrl;
>> +               break;
>>          case MSR_IA32_ARCH_CAPABILITIES:
>>                  if (!msr_info->host_initiated &&
>>                      !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_CAPABILITIES))
>> @@ -3339,6 +3350,31 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>          case MSR_IA32_TSC:
>>                  kvm_write_tsc(vcpu, msr_info);
>>                  break;
>> +       case MSR_IA32_SPEC_CTRL:
>> +               if (!msr_info->host_initiated &&
>> +                   !guest_cpuid_has(vcpu, X86_FEATURE_IBRS))
>> +                       return 1;
>> +
>> +               /* The STIBP bit doesn't fault even if it's not advertised */
>> +               if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP))
>> +                       return 1;
>> +
>> +               vmx->spec_ctrl = data;
>> +
>> +               /*
>> +                * When it's written (to non-zero) for the first time, pass
>> +                * it through. This means we don't have to take the perf
>> +                * hit of saving it on vmexit for the common case of guests
>> +                * that don't use it.
>> +                */
>> +               if (cpu_has_vmx_msr_bitmap() && data &&
>> +                   !vmx->save_spec_ctrl_on_exit) {
>> +                       vmx->save_spec_ctrl_on_exit = true;
>> +                       vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap,
>> +                                                     MSR_IA32_SPEC_CTRL,
>> +                                                     MSR_TYPE_RW);
>> +               }
> 
> This code seems to assume that L1 is currently active. What if L2 is
> currently active?

Ooops! I did not think at all about nested :)

This should be addressed now, I hope:

http://git.infradead.org/linux-retpoline.git/commitdiff/f7f0cbba3e0cffcee050a8a5a9597a162d57e572

I have not tested it yet though.

> 
>> +               break;
>>          case MSR_IA32_PRED_CMD:
>>                  if (!msr_info->host_initiated &&
>>                      !guest_cpuid_has(vcpu, X86_FEATURE_IBPB))
>> @@ -5644,6 +5680,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>>          u64 cr0;
>>
>>          vmx->rmode.vm86_active = 0;
>> +       vmx->spec_ctrl = 0;
>>
>>          vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val();
>>          kvm_set_cr8(vcpu, 0);
>> @@ -9314,6 +9351,15 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
>>
>>          vmx_arm_hv_timer(vcpu);
>>
>> +       /*
>> +        * If this vCPU has touched SPEC_CTRL, restore the guest's value if
>> +        * it's non-zero. Since vmentry is serialising on affected CPUs, there
>> +        * is no need to worry about the conditional branch over the wrmsr
>> +        * being speculatively taken.
>> +        */
>> +       if (vmx->spec_ctrl)
>> +               wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
>> +
>>          vmx->__launched = vmx->loaded_vmcs->launched;
>>          asm(
>>                  /* Store host registers */
>> @@ -9420,6 +9466,19 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
>>   #endif
>>                );
>>
>> +       /*
>> +        * We do not use IBRS in the kernel. If this vCPU has used the
>> +        * SPEC_CTRL MSR it may have left it on; save the value and
>> +        * turn it off. This is much more efficient than blindly adding
>> +        * it to the atomic save/restore list. Especially as the former
>> +        * (Saving guest MSRs on vmexit) doesn't even exist in KVM.
>> +        */
>> +       if (vmx->save_spec_ctrl_on_exit)
>> +               rdmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
>> +
>> +       if (vmx->spec_ctrl)
>> +               wrmsrl(MSR_IA32_SPEC_CTRL, 0);
>> +
>>          /* Eliminate branch target predictions from guest mode */
>>          vmexit_fill_RSB();
>>
>> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
>> index 8e889dc..fc9724c 100644
>> --- a/arch/x86/kvm/x86.c
>> +++ b/arch/x86/kvm/x86.c
>> @@ -1006,7 +1006,7 @@ static u32 msrs_to_save[] = {
>>   #endif
>>          MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
>>          MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX,
>> -       MSR_IA32_ARCH_CAPABILITIES
>> +       MSR_IA32_SPEC_CTRL, MSR_IA32_ARCH_CAPABILITIES
>>   };
>>
>>   static unsigned num_msrs_to_save;
>> --
>> 2.7.4
>>
> 
Amazon Development Center Germany GmbH
Berlin - Dresden - Aachen
main office: Krausenstr. 38, 10117 Berlin
Geschaeftsfuehrer: Dr. Ralf Herbrich, Christian Schlaeger
Ust-ID: DE289237879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B

  reply	other threads:[~2018-01-30 21:00 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-30  0:10 [PATCH v3 0/4] KVM: Expose speculation control feature to guests KarimAllah Ahmed
2018-01-30  0:10 ` KarimAllah Ahmed
2018-01-30  0:10 ` [PATCH v3 1/4] KVM: x86: Update the reverse_cpuid list to include CPUID_7_EDX KarimAllah Ahmed
2018-01-30 23:17   ` Paolo Bonzini
2018-01-30  0:10 ` [PATCH v3 2/4] KVM: x86: Add IBPB support KarimAllah Ahmed
2018-01-30 14:22   ` Tom Lendacky
2018-01-30 14:36     ` David Woodhouse
2018-01-30 17:19   ` Jim Mattson
2018-01-30 17:43     ` David Woodhouse
2018-01-30  0:10 ` [PATCH v3 3/4] KVM: VMX: Emulate MSR_IA32_ARCH_CAPABILITIES KarimAllah Ahmed
2018-01-30  0:22   ` Raj, Ashok
2018-01-30  0:25     ` KarimAllah Ahmed
2018-01-30 23:21       ` Paolo Bonzini
2018-01-30  0:10 ` [PATCH v3 4/4] KVM: VMX: Allow direct access to MSR_IA32_SPEC_CTRL KarimAllah Ahmed
2018-01-30 17:49   ` Jim Mattson
2018-01-30 21:00     ` KarimAllah Ahmed [this message]
2018-01-30 22:49       ` Jim Mattson
2018-01-30 23:32         ` Paolo Bonzini
2018-01-30 23:50         ` KarimAllah Ahmed
2018-01-31  0:16           ` Jim Mattson
2018-01-31  0:19           ` Paolo Bonzini
2018-01-31  0:27             ` Jim Mattson
2018-01-31  0:52               ` KarimAllah Ahmed
2018-01-31  0:56               ` Paolo Bonzini
2018-01-30  9:00 ` [PATCH v3 0/4] KVM: Expose speculation control feature to guests David Woodhouse
2018-01-30  9:00   ` David Woodhouse
2018-01-30  9:32   ` KarimAllah Ahmed
2018-01-30  9:32     ` KarimAllah Ahmed
2018-01-30 23:36   ` Paolo Bonzini
2018-01-30 23:36     ` Paolo Bonzini
2018-01-30 23:48     ` Raj, Ashok
2018-01-30 23:48       ` Raj, Ashok
2018-01-31  0:16       ` Paolo Bonzini
2018-01-31  0:16         ` Paolo Bonzini
2018-01-31  0:26         ` David Woodhouse
2018-01-31  0:26           ` David Woodhouse
2018-01-31  6:54         ` Dave Hansen
2018-01-31  6:54           ` Dave Hansen

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=43859417-ae76-ed1f-eb4f-8a84a35998fc@amazon.com \
    --to=karahmed@amazon.com \
    --cc=aarcange@redhat.com \
    --cc=ak@linux.intel.com \
    --cc=arjan.van.de.ven@intel.com \
    --cc=ashok.raj@intel.com \
    --cc=asit.k.mallick@intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=dwmw@amazon.co.uk \
    --cc=gregkh@linuxfoundation.org \
    --cc=jmattson@google.com \
    --cc=jun.nakajima@intel.com \
    --cc=karahmed@amazon.de \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=tim.c.chen@linux.intel.com \
    --cc=torvalds@linux-foundation.org \
    --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.