diff options
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 |