aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRadim Krčmář <rkrcmar@redhat.com>2015-11-02 16:20:00 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2015-11-04 10:24:37 -0500
commit656ec4a4928a3db7d16e5cb9bce351a478cfd3d5 (patch)
tree2eadec89b6429d14d08171e99b0ba8e684e8d054
parent8a22f234a81ab4d1de5d948c3478608f08a9b844 (diff)
KVM: VMX: fix SMEP and SMAP without EPT
The comment in code had it mostly right, but we enable paging for emulated real mode regardless of EPT. Without EPT (which implies emulated real mode), secondary VCPUs won't start unless we disable SM[AE]P when the guest doesn't use paging. Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/vmx.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 4d0aa31a42ba..2ac116417583 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3788,20 +3788,21 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
3788 if (!is_paging(vcpu)) { 3788 if (!is_paging(vcpu)) {
3789 hw_cr4 &= ~X86_CR4_PAE; 3789 hw_cr4 &= ~X86_CR4_PAE;
3790 hw_cr4 |= X86_CR4_PSE; 3790 hw_cr4 |= X86_CR4_PSE;
3791 /*
3792 * SMEP/SMAP is disabled if CPU is in non-paging mode
3793 * in hardware. However KVM always uses paging mode to
3794 * emulate guest non-paging mode with TDP.
3795 * To emulate this behavior, SMEP/SMAP needs to be
3796 * manually disabled when guest switches to non-paging
3797 * mode.
3798 */
3799 hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP);
3800 } else if (!(cr4 & X86_CR4_PAE)) { 3791 } else if (!(cr4 & X86_CR4_PAE)) {
3801 hw_cr4 &= ~X86_CR4_PAE; 3792 hw_cr4 &= ~X86_CR4_PAE;
3802 } 3793 }
3803 } 3794 }
3804 3795
3796 if (!enable_unrestricted_guest && !is_paging(vcpu))
3797 /*
3798 * SMEP/SMAP is disabled if CPU is in non-paging mode in
3799 * hardware. However KVM always uses paging mode without
3800 * unrestricted guest.
3801 * To emulate this behavior, SMEP/SMAP needs to be manually
3802 * disabled when guest switches to non-paging mode.
3803 */
3804 hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP);
3805
3805 vmcs_writel(CR4_READ_SHADOW, cr4); 3806 vmcs_writel(CR4_READ_SHADOW, cr4);
3806 vmcs_writel(GUEST_CR4, hw_cr4); 3807 vmcs_writel(GUEST_CR4, hw_cr4);
3807 return 0; 3808 return 0;