diff options
-rw-r--r-- | drivers/kvm/mmu.c | 36 | ||||
-rw-r--r-- | drivers/kvm/svm.c | 33 | ||||
-rw-r--r-- | drivers/kvm/vmx.c | 29 | ||||
-rw-r--r-- | drivers/kvm/x86.h | 6 |
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 | ||
1350 | int 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 | } | ||
1380 | out: | ||
1381 | mutex_unlock(&vcpu->kvm->lock); | ||
1382 | return r; | ||
1383 | } | ||
1384 | EXPORT_SYMBOL_GPL(kvm_mmu_page_fault); | ||
1385 | |||
1350 | static void free_mmu_pages(struct kvm_vcpu *vcpu) | 1386 | static 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 | ||
977 | static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 946 | static 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 | ||
88 | static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, | 88 | int 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 | ||
94 | static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) | 90 | static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) |
95 | { | 91 | { |