diff --git a/core/cpu.c b/core/cpu.c index 595071a9..050cc169 100644 --- a/core/cpu.c +++ b/core/cpu.c @@ -624,8 +624,7 @@ void load_vmcs_common(struct vcpu_t *vcpu) vmx(vcpu, exc_bitmap) = vmx(vcpu, exc_bitmap_base) = vmread( vcpu, VMX_EXCEPTION_BITMAP); - vmx(vcpu, entry_ctls) = vmx(vcpu, entry_ctls_base) = vmread( - vcpu, VMX_ENTRY_CONTROLS); + vmx(vcpu, entry_ctls) = vmread(vcpu, VMX_ENTRY_CONTROLS); vmx(vcpu, exit_ctls) = vmx(vcpu, exit_ctls_base) = vmread( vcpu, VMX_EXIT_CONTROLS); diff --git a/core/include/vcpu.h b/core/include/vcpu.h index a873942b..c81349b7 100644 --- a/core/include/vcpu.h +++ b/core/include/vcpu.h @@ -72,7 +72,6 @@ struct vcpu_vmx_data { uint32_t pin_ctls_base; uint32_t pcpu_ctls_base; uint32_t scpu_ctls_base; - uint32_t entry_ctls_base; uint32_t exc_bitmap_base; uint32_t exit_ctls_base; diff --git a/core/vcpu.c b/core/vcpu.c index 2ee7bb65..652b7645 100644 --- a/core/vcpu.c +++ b/core/vcpu.c @@ -1900,7 +1900,7 @@ static void vmwrite_cr(struct vcpu_t *vcpu) struct vcpu_state_t *state = vcpu->state; struct per_cpu_data *cpu = current_cpu_data(); - uint32_t entry_ctls = vmx(vcpu, entry_ctls_base); + uint32_t entry_ctls = vmx(vcpu, entry_ctls); uint32_t pcpu_ctls = vmx(vcpu, pcpu_ctls_base); uint32_t scpu_ctls = vmx(vcpu, scpu_ctls_base); uint32_t exc_bitmap = vmx(vcpu, exc_bitmap_base); @@ -2017,16 +2017,10 @@ static void vmwrite_cr(struct vcpu_t *vcpu) if ((state->_cr4 & CR4_PAE) && (state->_cr0 & CR0_PG) && (state->_cr0 & CR0_PE)) { entry_ctls |= ENTRY_CONTROL_LOAD_EFER; - vmx(vcpu, entry_ctls) |= ENTRY_CONTROL_LOAD_EFER; } else { entry_ctls &= ~ENTRY_CONTROL_LOAD_EFER; - vmx(vcpu, entry_ctls) &= ~ENTRY_CONTROL_LOAD_EFER; } - vmwrite_efer(vcpu); - if (state->_efer & IA32_EFER_LMA) { - entry_ctls |= ENTRY_CONTROL_LONG_MODE_GUEST; - } if (pcpu_ctls != vmx(vcpu, pcpu_ctls)) { vmx(vcpu, pcpu_ctls) = pcpu_ctls; vcpu->pcpu_ctls_dirty = 1; @@ -2041,6 +2035,8 @@ static void vmwrite_cr(struct vcpu_t *vcpu) if (entry_ctls != vmx(vcpu, entry_ctls)) { vmwrite(vcpu, VMX_ENTRY_CONTROLS, vmx(vcpu, entry_ctls) = entry_ctls); } + + vmwrite_efer(vcpu); } static void vcpu_enter_fpu_state(struct vcpu_t *vcpu) @@ -3489,14 +3485,14 @@ static int handle_msr_read(struct vcpu_t *vcpu, uint32_t msr, uint64_t *val) static void vmwrite_efer(struct vcpu_t *vcpu) { struct vcpu_state_t *state = vcpu->state; + uint32_t entry_ctls = vmx(vcpu, entry_ctls); if ((state->_cr0 & CR0_PG) && (state->_efer & IA32_EFER_LME)) { state->_efer |= IA32_EFER_LMA; - - vmwrite(vcpu, VMX_ENTRY_CONTROLS, vmread(vcpu, VMX_ENTRY_CONTROLS) | - ENTRY_CONTROL_LONG_MODE_GUEST); + entry_ctls |= ENTRY_CONTROL_LONG_MODE_GUEST; } else { state->_efer &= ~IA32_EFER_LMA; + entry_ctls &= ~ENTRY_CONTROL_LONG_MODE_GUEST; } if (vmx(vcpu, entry_ctls) & ENTRY_CONTROL_LOAD_EFER) { @@ -3508,6 +3504,10 @@ static void vmwrite_efer(struct vcpu_t *vcpu) vmwrite(vcpu, GUEST_EFER, guest_efer); } + + if (entry_ctls != vmx(vcpu, entry_ctls)) { + vmwrite(vcpu, VMX_ENTRY_CONTROLS, vmx(vcpu, entry_ctls) = entry_ctls); + } } static int misc_msr_write(struct vcpu_t *vcpu, uint32_t msr, uint64_t val)