Message ID | 1432154485-10504-1-git-send-email-liang.z.li@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 20/05/2015 22:41, Liang Li wrote: > The MPX feature requires eager KVM FPU restore support. We have verified > that MPX cannot work correctly with the current lazy KVM FPU restore > mechanism. Eager KVM FPU restore should be enabled if the MPX feature is > exposed to VM. > > Signed-off-by: Liang Li <liang.z.li@intel.com> > Signed-off-by: Yang Zhang <yang.z.zhang@intel.com> > --- > arch/x86/include/asm/kvm_host.h | 1 + > arch/x86/kvm/cpuid.c | 4 ++++ > arch/x86/kvm/cpuid.h | 8 ++++++++ > arch/x86/kvm/vmx.c | 5 +++++ > arch/x86/kvm/x86.c | 3 ++- > 5 files changed, 20 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index e61c3a4..4cb39d4 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -401,6 +401,7 @@ struct kvm_vcpu_arch { > struct kvm_mmu_memory_cache mmu_page_header_cache; > > struct fpu guest_fpu; > + bool eager_fpu; > u64 xcr0; > u64 guest_supported_xcr0; > u32 guest_xstate_size; > diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c > index 59b69f6..5ac5e4d 100644 > --- a/arch/x86/kvm/cpuid.c > +++ b/arch/x86/kvm/cpuid.c > @@ -95,6 +95,10 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) > if (best && (best->eax & (F(XSAVES) | F(XSAVEC)))) > best->ebx = xstate_required_size(vcpu->arch.xcr0, true); > > + if (guest_cpuid_has_mpx(vcpu)) > + vcpu->arch.eager_fpu = true; > + else > + vcpu->arch.eager_fpu = false; > /* > * The existing code assumes virtual address is 48-bit in the canonical > * address checks; exit if it is ever changed. > diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h > index c3b1ad9..496b369 100644 > --- a/arch/x86/kvm/cpuid.h > +++ b/arch/x86/kvm/cpuid.h > @@ -117,4 +117,12 @@ static inline bool guest_cpuid_has_rtm(struct kvm_vcpu *vcpu) > best = kvm_find_cpuid_entry(vcpu, 7, 0); > return best && (best->ebx & bit(X86_FEATURE_RTM)); > } > + > +static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu) > +{ > + struct kvm_cpuid_entry2 *best; > + > + best = kvm_find_cpuid_entry(vcpu, 7, 0); > + return best && (best->ebx & bit(X86_FEATURE_MPX)); > +} > #endif > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index f7b6168..7082151 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -8445,6 +8445,11 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) > goto free_vmcs; > } > > + /* > + * activate fpu here is okay, because it will be deactivated soon if the > + * lazy fpu restore mode is used. > + */ > + vmx_fpu_activate(&vmx->vcpu); > return &vmx->vcpu; > > free_vmcs: > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 5f38188..4d9f8e9 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -7060,7 +7060,8 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) > fpu_save_init(&vcpu->arch.guest_fpu); > __kernel_fpu_end(); > ++vcpu->stat.fpu_reload; > - kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu); > + if (!vcpu->arch.eager_fpu) > + kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu); > trace_kvm_fpu(0); > } > > Thanks, applied to kvm/master. Paolo -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index e61c3a4..4cb39d4 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -401,6 +401,7 @@ struct kvm_vcpu_arch { struct kvm_mmu_memory_cache mmu_page_header_cache; struct fpu guest_fpu; + bool eager_fpu; u64 xcr0; u64 guest_supported_xcr0; u32 guest_xstate_size; diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 59b69f6..5ac5e4d 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -95,6 +95,10 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) if (best && (best->eax & (F(XSAVES) | F(XSAVEC)))) best->ebx = xstate_required_size(vcpu->arch.xcr0, true); + if (guest_cpuid_has_mpx(vcpu)) + vcpu->arch.eager_fpu = true; + else + vcpu->arch.eager_fpu = false; /* * The existing code assumes virtual address is 48-bit in the canonical * address checks; exit if it is ever changed. diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index c3b1ad9..496b369 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -117,4 +117,12 @@ static inline bool guest_cpuid_has_rtm(struct kvm_vcpu *vcpu) best = kvm_find_cpuid_entry(vcpu, 7, 0); return best && (best->ebx & bit(X86_FEATURE_RTM)); } + +static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu) +{ + struct kvm_cpuid_entry2 *best; + + best = kvm_find_cpuid_entry(vcpu, 7, 0); + return best && (best->ebx & bit(X86_FEATURE_MPX)); +} #endif diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f7b6168..7082151 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -8445,6 +8445,11 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) goto free_vmcs; } + /* + * activate fpu here is okay, because it will be deactivated soon if the + * lazy fpu restore mode is used. + */ + vmx_fpu_activate(&vmx->vcpu); return &vmx->vcpu; free_vmcs: diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5f38188..4d9f8e9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7060,7 +7060,8 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) fpu_save_init(&vcpu->arch.guest_fpu); __kernel_fpu_end(); ++vcpu->stat.fpu_reload; - kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu); + if (!vcpu->arch.eager_fpu) + kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu); trace_kvm_fpu(0); }