diff options
-rw-r--r-- | arch/x86/kvm/vmx.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ea0e1d5ebe70..752465f98bfd 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1547,10 +1547,6 @@ static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) | |||
1547 | static void ept_load_pdptrs(struct kvm_vcpu *vcpu) | 1547 | static void ept_load_pdptrs(struct kvm_vcpu *vcpu) |
1548 | { | 1548 | { |
1549 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { | 1549 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { |
1550 | if (!load_pdptrs(vcpu, vcpu->arch.cr3)) { | ||
1551 | printk(KERN_ERR "EPT: Fail to load pdptrs!\n"); | ||
1552 | return; | ||
1553 | } | ||
1554 | vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]); | 1550 | vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]); |
1555 | vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]); | 1551 | vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]); |
1556 | vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]); | 1552 | vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]); |
@@ -1558,6 +1554,16 @@ static void ept_load_pdptrs(struct kvm_vcpu *vcpu) | |||
1558 | } | 1554 | } |
1559 | } | 1555 | } |
1560 | 1556 | ||
1557 | static void ept_save_pdptrs(struct kvm_vcpu *vcpu) | ||
1558 | { | ||
1559 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { | ||
1560 | vcpu->arch.pdptrs[0] = vmcs_read64(GUEST_PDPTR0); | ||
1561 | vcpu->arch.pdptrs[1] = vmcs_read64(GUEST_PDPTR1); | ||
1562 | vcpu->arch.pdptrs[2] = vmcs_read64(GUEST_PDPTR2); | ||
1563 | vcpu->arch.pdptrs[3] = vmcs_read64(GUEST_PDPTR3); | ||
1564 | } | ||
1565 | } | ||
1566 | |||
1561 | static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); | 1567 | static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); |
1562 | 1568 | ||
1563 | static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, | 1569 | static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, |
@@ -1651,7 +1657,6 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
1651 | if (enable_ept) { | 1657 | if (enable_ept) { |
1652 | eptp = construct_eptp(cr3); | 1658 | eptp = construct_eptp(cr3); |
1653 | vmcs_write64(EPT_POINTER, eptp); | 1659 | vmcs_write64(EPT_POINTER, eptp); |
1654 | ept_load_pdptrs(vcpu); | ||
1655 | guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 : | 1660 | guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 : |
1656 | VMX_EPT_IDENTITY_PAGETABLE_ADDR; | 1661 | VMX_EPT_IDENTITY_PAGETABLE_ADDR; |
1657 | } | 1662 | } |
@@ -3252,7 +3257,7 @@ static int vmx_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
3252 | * to sync with guest real CR3. */ | 3257 | * to sync with guest real CR3. */ |
3253 | if (enable_ept && is_paging(vcpu)) { | 3258 | if (enable_ept && is_paging(vcpu)) { |
3254 | vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); | 3259 | vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); |
3255 | ept_load_pdptrs(vcpu); | 3260 | ept_save_pdptrs(vcpu); |
3256 | } | 3261 | } |
3257 | 3262 | ||
3258 | if (unlikely(vmx->fail)) { | 3263 | if (unlikely(vmx->fail)) { |
@@ -3437,6 +3442,10 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
3437 | { | 3442 | { |
3438 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 3443 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
3439 | 3444 | ||
3445 | if (enable_ept && is_paging(vcpu)) { | ||
3446 | vmcs_writel(GUEST_CR3, vcpu->arch.cr3); | ||
3447 | ept_load_pdptrs(vcpu); | ||
3448 | } | ||
3440 | /* Record the guest's net vcpu time for enforced NMI injections. */ | 3449 | /* Record the guest's net vcpu time for enforced NMI injections. */ |
3441 | if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked)) | 3450 | if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked)) |
3442 | vmx->entry_time = ktime_get(); | 3451 | vmx->entry_time = ktime_get(); |