|
@@ -180,6 +180,7 @@ static int init_rmode(struct kvm *kvm);
|
|
|
static u64 construct_eptp(unsigned long root_hpa);
|
|
|
static void kvm_cpu_vmxon(u64 addr);
|
|
|
static void kvm_cpu_vmxoff(void);
|
|
|
+static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3);
|
|
|
|
|
|
static DEFINE_PER_CPU(struct vmcs *, vmxarea);
|
|
|
static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
|
|
@@ -1866,6 +1867,13 @@ static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
|
|
|
vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & cr0_guest_owned_bits;
|
|
|
}
|
|
|
|
|
|
+static void vmx_decache_cr3(struct kvm_vcpu *vcpu)
|
|
|
+{
|
|
|
+ if (enable_ept && is_paging(vcpu))
|
|
|
+ vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
|
|
|
+ __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail);
|
|
|
+}
|
|
|
+
|
|
|
static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
|
|
|
{
|
|
|
ulong cr4_guest_owned_bits = vcpu->arch.cr4_guest_owned_bits;
|
|
@@ -1909,6 +1917,7 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
|
|
|
unsigned long cr0,
|
|
|
struct kvm_vcpu *vcpu)
|
|
|
{
|
|
|
+ vmx_decache_cr3(vcpu);
|
|
|
if (!(cr0 & X86_CR0_PG)) {
|
|
|
/* From paging/starting to nonpaging */
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
|
|
@@ -3756,11 +3765,6 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
|
|
|
if (vmx->emulation_required && emulate_invalid_guest_state)
|
|
|
return handle_invalid_guest_state(vcpu);
|
|
|
|
|
|
- /* Access CR3 don't cause VMExit in paging mode, so we need
|
|
|
- * to sync with guest real CR3. */
|
|
|
- if (enable_ept && is_paging(vcpu))
|
|
|
- vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
|
|
|
-
|
|
|
if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
|
|
|
vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY;
|
|
|
vcpu->run->fail_entry.hardware_entry_failure_reason
|
|
@@ -4077,7 +4081,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
|
|
);
|
|
|
|
|
|
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
|
|
|
- | (1 << VCPU_EXREG_PDPTR));
|
|
|
+ | (1 << VCPU_EXREG_PDPTR)
|
|
|
+ | (1 << VCPU_EXREG_CR3));
|
|
|
vcpu->arch.regs_dirty = 0;
|
|
|
|
|
|
vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
|
|
@@ -4344,6 +4349,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
|
|
|
.get_cpl = vmx_get_cpl,
|
|
|
.get_cs_db_l_bits = vmx_get_cs_db_l_bits,
|
|
|
.decache_cr0_guest_bits = vmx_decache_cr0_guest_bits,
|
|
|
+ .decache_cr3 = vmx_decache_cr3,
|
|
|
.decache_cr4_guest_bits = vmx_decache_cr4_guest_bits,
|
|
|
.set_cr0 = vmx_set_cr0,
|
|
|
.set_cr3 = vmx_set_cr3,
|