diff options
author | Avi Kivity <avi@redhat.com> | 2010-04-28 09:42:29 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-19 04:36:32 -0400 |
commit | 84ad33ef5dbc12665ad42ee07a2daed473d3ec54 (patch) | |
tree | 1adcc15df88e869c528ec0715504adec78a6c046 /arch/x86 | |
parent | 61d2ef2ce3e0161bedf5d2867f546a8df77fa9bc (diff) |
KVM: VMX: Atomically switch efer if EPT && !EFER.NX
When EPT is enabled, we cannot emulate EFER.NX=0 through the shadow page
tables. This causes accesses through ptes with bit 63 set to succeed instead
of failing a reserved bit check.
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kvm/vmx.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ae22dcf17211..c4f3955c64e0 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -678,6 +678,17 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) | |||
678 | guest_efer |= host_efer & ignore_bits; | 678 | guest_efer |= host_efer & ignore_bits; |
679 | vmx->guest_msrs[efer_offset].data = guest_efer; | 679 | vmx->guest_msrs[efer_offset].data = guest_efer; |
680 | vmx->guest_msrs[efer_offset].mask = ~ignore_bits; | 680 | vmx->guest_msrs[efer_offset].mask = ~ignore_bits; |
681 | |||
682 | clear_atomic_switch_msr(vmx, MSR_EFER); | ||
683 | /* On ept, can't emulate nx, and must switch nx atomically */ | ||
684 | if (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX)) { | ||
685 | guest_efer = vmx->vcpu.arch.efer; | ||
686 | if (!(guest_efer & EFER_LMA)) | ||
687 | guest_efer &= ~EFER_LME; | ||
688 | add_atomic_switch_msr(vmx, MSR_EFER, guest_efer, host_efer); | ||
689 | return false; | ||
690 | } | ||
691 | |||
681 | return true; | 692 | return true; |
682 | } | 693 | } |
683 | 694 | ||
@@ -1734,6 +1745,7 @@ static void exit_lmode(struct kvm_vcpu *vcpu) | |||
1734 | vmcs_write32(VM_ENTRY_CONTROLS, | 1745 | vmcs_write32(VM_ENTRY_CONTROLS, |
1735 | vmcs_read32(VM_ENTRY_CONTROLS) | 1746 | vmcs_read32(VM_ENTRY_CONTROLS) |
1736 | & ~VM_ENTRY_IA32E_MODE); | 1747 | & ~VM_ENTRY_IA32E_MODE); |
1748 | vmx_set_efer(vcpu, vcpu->arch.efer); | ||
1737 | } | 1749 | } |
1738 | 1750 | ||
1739 | #endif | 1751 | #endif |