| From 656ec4a4928a3db7d16e5cb9bce351a478cfd3d5 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= <rkrcmar@redhat.com> |
| Date: Mon, 2 Nov 2015 22:20:00 +0100 |
| Subject: KVM: VMX: fix SMEP and SMAP without EPT |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= <rkrcmar@redhat.com> |
| |
| commit 656ec4a4928a3db7d16e5cb9bce351a478cfd3d5 upstream. |
| |
| 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> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/kvm/vmx.c | 19 ++++++++++--------- |
| 1 file changed, 10 insertions(+), 9 deletions(-) |
| |
| --- a/arch/x86/kvm/vmx.c |
| +++ b/arch/x86/kvm/vmx.c |
| @@ -3644,20 +3644,21 @@ static int vmx_set_cr4(struct kvm_vcpu * |
| if (!is_paging(vcpu)) { |
| hw_cr4 &= ~X86_CR4_PAE; |
| hw_cr4 |= X86_CR4_PSE; |
| - /* |
| - * SMEP/SMAP is disabled if CPU is in non-paging mode |
| - * in hardware. However KVM always uses paging mode to |
| - * emulate guest non-paging mode with TDP. |
| - * To emulate this behavior, SMEP/SMAP needs to be |
| - * manually disabled when guest switches to non-paging |
| - * mode. |
| - */ |
| - hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP); |
| } else if (!(cr4 & X86_CR4_PAE)) { |
| hw_cr4 &= ~X86_CR4_PAE; |
| } |
| } |
| |
| + if (!enable_unrestricted_guest && !is_paging(vcpu)) |
| + /* |
| + * SMEP/SMAP is disabled if CPU is in non-paging mode in |
| + * hardware. However KVM always uses paging mode without |
| + * unrestricted guest. |
| + * To emulate this behavior, SMEP/SMAP needs to be manually |
| + * disabled when guest switches to non-paging mode. |
| + */ |
| + hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP); |
| + |
| vmcs_writel(CR4_READ_SHADOW, cr4); |
| vmcs_writel(GUEST_CR4, hw_cr4); |
| return 0; |