KVM: Move page fault processing to common code
authorAvi Kivity <avi@qumranet.com>
Sun, 28 Oct 2007 16:48:59 +0000 (18:48 +0200)
committerAvi Kivity <avi@qumranet.com>
Wed, 30 Jan 2008 15:52:57 +0000 (17:52 +0200)
The code that dispatches the page fault and emulates if we failed to map
is duplicated across vmx and svm.  Merge it to simplify further bugfixing.

Signed-off-by: Avi Kivity <avi@qumranet.com>
drivers/kvm/mmu.c
drivers/kvm/svm.c
drivers/kvm/vmx.c
drivers/kvm/x86.h

index d9c5950cfae1ed812a4b98a29aaae698d661d376..ace3cb86214b2979aaad93b580f6b20088c24154 100644 (file)
@@ -1347,6 +1347,42 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
        }
 }
 
+int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code)
+{
+       int r;
+       enum emulation_result er;
+
+       mutex_lock(&vcpu->kvm->lock);
+       r = vcpu->mmu.page_fault(vcpu, cr2, error_code);
+       if (r < 0)
+               goto out;
+
+       if (!r) {
+               r = 1;
+               goto out;
+       }
+
+       er = emulate_instruction(vcpu, vcpu->run, cr2, error_code, 0);
+       mutex_unlock(&vcpu->kvm->lock);
+
+       switch (er) {
+       case EMULATE_DONE:
+               return 1;
+       case EMULATE_DO_MMIO:
+               ++vcpu->stat.mmio_exits;
+               return 0;
+       case EMULATE_FAIL:
+               kvm_report_emulation_failure(vcpu, "pagetable");
+               return 1;
+       default:
+               BUG();
+       }
+out:
+       mutex_unlock(&vcpu->kvm->lock);
+       return r;
+}
+EXPORT_SYMBOL_GPL(kvm_mmu_page_fault);
+
 static void free_mmu_pages(struct kvm_vcpu *vcpu)
 {
        struct kvm_mmu_page *page;
index fe2a5e8b0524a995b20d176c9b0486bae6989ece..97863f8fd0018672c10f10a1273982f6d242cff2 100644 (file)
@@ -933,45 +933,14 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
        struct kvm *kvm = svm->vcpu.kvm;
        u64 fault_address;
        u32 error_code;
-       enum emulation_result er;
-       int r;
 
        if (!irqchip_in_kernel(kvm) &&
                is_external_interrupt(exit_int_info))
                push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK);
 
-       mutex_lock(&kvm->lock);
-
        fault_address  = svm->vmcb->control.exit_info_2;
        error_code = svm->vmcb->control.exit_info_1;
-       r = kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
-       if (r < 0) {
-               mutex_unlock(&kvm->lock);
-               return r;
-       }
-       if (!r) {
-               mutex_unlock(&kvm->lock);
-               return 1;
-       }
-       er = emulate_instruction(&svm->vcpu, kvm_run, fault_address,
-                                error_code, 0);
-       mutex_unlock(&kvm->lock);
-
-       switch (er) {
-       case EMULATE_DONE:
-               return 1;
-       case EMULATE_DO_MMIO:
-               ++svm->vcpu.stat.mmio_exits;
-               return 0;
-       case EMULATE_FAIL:
-               kvm_report_emulation_failure(&svm->vcpu, "pagetable");
-               break;
-       default:
-               BUG();
-       }
-
-       kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
-       return 0;
+       return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
 }
 
 static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
index 2d7d638d72d0e17358bc7959a5f235dbac509eae..7fe834cb0d81a276cdda7e699f111751098a10f1 100644 (file)
@@ -1796,7 +1796,6 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        unsigned long cr2, rip;
        u32 vect_info;
        enum emulation_result er;
-       int r;
 
        vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
        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)
                error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
        if (is_page_fault(intr_info)) {
                cr2 = vmcs_readl(EXIT_QUALIFICATION);
-
-               mutex_lock(&vcpu->kvm->lock);
-               r = kvm_mmu_page_fault(vcpu, cr2, error_code);
-               if (r < 0) {
-                       mutex_unlock(&vcpu->kvm->lock);
-                       return r;
-               }
-               if (!r) {
-                       mutex_unlock(&vcpu->kvm->lock);
-                       return 1;
-               }
-
-               er = emulate_instruction(vcpu, kvm_run, cr2, error_code, 0);
-               mutex_unlock(&vcpu->kvm->lock);
-
-               switch (er) {
-               case EMULATE_DONE:
-                       return 1;
-               case EMULATE_DO_MMIO:
-                       ++vcpu->stat.mmio_exits;
-                       return 0;
-               case EMULATE_FAIL:
-                       kvm_report_emulation_failure(vcpu, "pagetable");
-                       break;
-               default:
-                       BUG();
-               }
+               return kvm_mmu_page_fault(vcpu, cr2, error_code);
        }
 
        if (vcpu->rmode.active &&
index 01452b552db317b8b1e84b0c322a36a13a085450..20da8e9751c07bd95bdea56bcda917f5c603ef2e 100644 (file)
@@ -85,11 +85,7 @@ struct kvm_vcpu {
        struct x86_emulate_ctxt emulate_ctxt;
 };
 
-static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
-                                    u32 error_code)
-{
-       return vcpu->mmu.page_fault(vcpu, gva, error_code);
-}
+int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code);
 
 static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
 {