|
@@ -1662,8 +1662,14 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
|
|
|
vmx->guest_msrs[efer_offset].mask = ~ignore_bits;
|
|
|
|
|
|
clear_atomic_switch_msr(vmx, MSR_EFER);
|
|
|
- /* On ept, can't emulate nx, and must switch nx atomically */
|
|
|
- if (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX)) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * On EPT, we can't emulate NX, so we must switch EFER atomically.
|
|
|
+ * On CPUs that support "load IA32_EFER", always switch EFER
|
|
|
+ * atomically, since it's faster than switching it manually.
|
|
|
+ */
|
|
|
+ if (cpu_has_load_ia32_efer ||
|
|
|
+ (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) {
|
|
|
guest_efer = vmx->vcpu.arch.efer;
|
|
|
if (!(guest_efer & EFER_LMA))
|
|
|
guest_efer &= ~EFER_LME;
|