aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/vmx.c21
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)
1547static void ept_load_pdptrs(struct kvm_vcpu *vcpu) 1547static 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
1557static 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
1561static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); 1567static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
1562 1568
1563static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, 1569static 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();