summaryrefslogtreecommitdiffstats
path: root/drivers/kvm/mmu.c
diff options
context:
space:
mode:
authorAvi Kivity2007-10-28 17:48:59 +0100
committerAvi Kivity2008-01-30 16:52:57 +0100
commit3067714cf59bd4a6dbf788b709485bc62c1ff845 (patch)
tree4cdfba475258886666150e638568e6ad5e8c0e2f /drivers/kvm/mmu.c
parentKVM: x86 emulator: don't depend on cr2 for mov abs emulation (diff)
downloadkernel-qcow2-linux-3067714cf59bd4a6dbf788b709485bc62c1ff845.tar.gz
kernel-qcow2-linux-3067714cf59bd4a6dbf788b709485bc62c1ff845.tar.xz
kernel-qcow2-linux-3067714cf59bd4a6dbf788b709485bc62c1ff845.zip
KVM: Move page fault processing to common code
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>
Diffstat (limited to 'drivers/kvm/mmu.c')
-rw-r--r--drivers/kvm/mmu.c36
1 files changed, 36 insertions, 0 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)
}
}
+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;