aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/mmu.c36
-rw-r--r--drivers/kvm/svm.c33
-rw-r--r--drivers/kvm/vmx.c29
-rw-r--r--drivers/kvm/x86.h6
4 files changed, 39 insertions, 65 deletions
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index d9c5950cfae1..ace3cb86214b 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -1347,6 +1347,42 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
1347 } 1347 }
1348} 1348}
1349 1349
1350int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code)
1351{
1352 int r;
1353 enum emulation_result er;
1354
1355 mutex_lock(&vcpu->kvm->lock);
1356 r = vcpu->mmu.page_fault(vcpu, cr2, error_code);
1357 if (r < 0)
1358 goto out;
1359
1360 if (!r) {
1361 r = 1;
1362 goto out;
1363 }
1364
1365 er = emulate_instruction(vcpu, vcpu->run, cr2, error_code, 0);
1366 mutex_unlock(&vcpu->kvm->lock);
1367
1368 switch (er) {
1369 case EMULATE_DONE:
1370 return 1;
1371 case EMULATE_DO_MMIO:
1372 ++vcpu->stat.mmio_exits;
1373 return 0;
1374 case EMULATE_FAIL:
1375 kvm_report_emulation_failure(vcpu, "pagetable");
1376 return 1;
1377 default:
1378 BUG();
1379 }
1380out:
1381 mutex_unlock(&vcpu->kvm->lock);
1382 return r;
1383}
1384EXPORT_SYMBOL_GPL(kvm_mmu_page_fault);
1385
1350static void free_mmu_pages(struct kvm_vcpu *vcpu) 1386static void free_mmu_pages(struct kvm_vcpu *vcpu)
1351{ 1387{
1352 struct kvm_mmu_page *page; 1388 struct kvm_mmu_page *page;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index fe2a5e8b0524..97863f8fd001 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -933,45 +933,14 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
933 struct kvm *kvm = svm->vcpu.kvm; 933 struct kvm *kvm = svm->vcpu.kvm;
934 u64 fault_address; 934 u64 fault_address;
935 u32 error_code; 935 u32 error_code;
936 enum emulation_result er;
937 int r;
938 936
939 if (!irqchip_in_kernel(kvm) && 937 if (!irqchip_in_kernel(kvm) &&
940 is_external_interrupt(exit_int_info)) 938 is_external_interrupt(exit_int_info))
941 push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK); 939 push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK);
942 940
943 mutex_lock(&kvm->lock);
944
945 fault_address = svm->vmcb->control.exit_info_2; 941 fault_address = svm->vmcb->control.exit_info_2;
946 error_code = svm->vmcb->control.exit_info_1; 942 error_code = svm->vmcb->control.exit_info_1;
947 r = kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); 943 return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
948 if (r < 0) {
949 mutex_unlock(&kvm->lock);
950 return r;
951 }
952 if (!r) {
953 mutex_unlock(&kvm->lock);
954 return 1;
955 }
956 er = emulate_instruction(&svm->vcpu, kvm_run, fault_address,
957 error_code, 0);
958 mutex_unlock(&kvm->lock);
959
960 switch (er) {
961 case EMULATE_DONE:
962 return 1;
963 case EMULATE_DO_MMIO:
964 ++svm->vcpu.stat.mmio_exits;
965 return 0;
966 case EMULATE_FAIL:
967 kvm_report_emulation_failure(&svm->vcpu, "pagetable");
968 break;
969 default:
970 BUG();
971 }
972
973 kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
974 return 0;
975} 944}
976 945
977static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 946static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 2d7d638d72d0..7fe834cb0d81 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1796,7 +1796,6 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1796 unsigned long cr2, rip; 1796 unsigned long cr2, rip;
1797 u32 vect_info; 1797 u32 vect_info;
1798 enum emulation_result er; 1798 enum emulation_result er;
1799 int r;
1800 1799
1801 vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); 1800 vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
1802 intr_info = vmcs_read32(VM_EXIT_INTR_INFO); 1801 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
@@ -1834,33 +1833,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1834 error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE); 1833 error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
1835 if (is_page_fault(intr_info)) { 1834 if (is_page_fault(intr_info)) {
1836 cr2 = vmcs_readl(EXIT_QUALIFICATION); 1835 cr2 = vmcs_readl(EXIT_QUALIFICATION);
1837 1836 return kvm_mmu_page_fault(vcpu, cr2, error_code);
1838 mutex_lock(&vcpu->kvm->lock);
1839 r = kvm_mmu_page_fault(vcpu, cr2, error_code);
1840 if (r < 0) {
1841 mutex_unlock(&vcpu->kvm->lock);
1842 return r;
1843 }
1844 if (!r) {
1845 mutex_unlock(&vcpu->kvm->lock);
1846 return 1;
1847 }
1848
1849 er = emulate_instruction(vcpu, kvm_run, cr2, error_code, 0);
1850 mutex_unlock(&vcpu->kvm->lock);
1851
1852 switch (er) {
1853 case EMULATE_DONE:
1854 return 1;
1855 case EMULATE_DO_MMIO:
1856 ++vcpu->stat.mmio_exits;
1857 return 0;
1858 case EMULATE_FAIL:
1859 kvm_report_emulation_failure(vcpu, "pagetable");
1860 break;
1861 default:
1862 BUG();
1863 }
1864 } 1837 }
1865 1838
1866 if (vcpu->rmode.active && 1839 if (vcpu->rmode.active &&
diff --git a/drivers/kvm/x86.h b/drivers/kvm/x86.h
index 01452b552db3..20da8e9751c0 100644
--- a/drivers/kvm/x86.h
+++ b/drivers/kvm/x86.h
@@ -85,11 +85,7 @@ struct kvm_vcpu {
85 struct x86_emulate_ctxt emulate_ctxt; 85 struct x86_emulate_ctxt emulate_ctxt;
86}; 86};
87 87
88static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, 88int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code);
89 u32 error_code)
90{
91 return vcpu->mmu.page_fault(vcpu, gva, error_code);
92}
93 89
94static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) 90static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
95{ 91{