]> err.no Git - linux-2.6/blobdiff - drivers/kvm/svm.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6
[linux-2.6] / drivers / kvm / svm.c
index 99250011a47137b17ff3132afe88f50829b28d60..7397bfbbcb1cec356bd91826f4455d2728b2b75d 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/highmem.h>
+#include <linux/profile.h>
 #include <asm/desc.h>
 
 #include "kvm_svm.h"
@@ -852,6 +853,7 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        u64 fault_address;
        u32 error_code;
        enum emulation_result er;
+       int r;
 
        if (is_external_interrupt(exit_int_info))
                push_irq(vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK);
@@ -860,7 +862,12 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 
        fault_address  = vcpu->svm->vmcb->control.exit_info_2;
        error_code = vcpu->svm->vmcb->control.exit_info_1;
-       if (!kvm_mmu_page_fault(vcpu, fault_address, error_code)) {
+       r = kvm_mmu_page_fault(vcpu, fault_address, error_code);
+       if (r < 0) {
+               spin_unlock(&vcpu->kvm->lock);
+               return r;
+       }
+       if (!r) {
                spin_unlock(&vcpu->kvm->lock);
                return 1;
        }
@@ -1200,8 +1207,7 @@ static int interrupt_window_interception(struct kvm_vcpu *vcpu,
         * possible
         */
        if (kvm_run->request_interrupt_window &&
-           !vcpu->irq_summary &&
-           (vcpu->svm->vmcb->save.rflags & X86_EFLAGS_IF)) {
+           !vcpu->irq_summary) {
                ++kvm_stat.irq_window_exits;
                kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
                return 0;
@@ -1398,9 +1404,11 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        u16 fs_selector;
        u16 gs_selector;
        u16 ldt_selector;
+       int r;
 
 again:
-       do_interrupt_requests(vcpu, kvm_run);
+       if (!vcpu->mmio_read_completed)
+               do_interrupt_requests(vcpu, kvm_run);
 
        clgi();
 
@@ -1552,6 +1560,13 @@ again:
 
        reload_tss(vcpu);
 
+       /*
+        * Profile KVM exit RIPs:
+        */
+       if (unlikely(prof_on == KVM_PROFILING))
+               profile_hit(KVM_PROFILING,
+                       (void *)(unsigned long)vcpu->svm->vmcb->save.rip);
+
        stgi();
 
        kvm_reput_irq(vcpu);
@@ -1565,7 +1580,8 @@ again:
                return 0;
        }
 
-       if (handle_exit(vcpu, kvm_run)) {
+       r = handle_exit(vcpu, kvm_run);
+       if (r > 0) {
                if (signal_pending(current)) {
                        ++kvm_stat.signal_exits;
                        post_kvm_run_save(vcpu, kvm_run);
@@ -1581,7 +1597,7 @@ again:
                goto again;
        }
        post_kvm_run_save(vcpu, kvm_run);
-       return 0;
+       return r;
 }
 
 static void svm_flush_tlb(struct kvm_vcpu *vcpu)