diff --git a/kernel/x86.c b/kernel/x86.c index ef2aba9..a4da0e8 100644 --- a/kernel/x86.c +++ b/kernel/x86.c @@ -144,9 +144,23 @@ void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data) } EXPORT_SYMBOL_GPL(kvm_set_apic_base); +static void handle_multiple_faults(struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.exception.nr != DF_VECTOR) { + printk(KERN_DEBUG "kvm: inject_page_fault:" + " double fault\n"); + vcpu->arch.exception.nr = DF_VECTOR; + vcpu->arch.exception.error_code = 0; + } else + set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests); +} + void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr) { - WARN_ON(vcpu->arch.exception.pending); + if (vcpu->arch.exception.pending) { + handle_multiple_faults(vcpu); + return; + } vcpu->arch.exception.pending = true; vcpu->arch.exception.has_error_code = false; vcpu->arch.exception.nr = nr; @@ -157,25 +171,16 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr, u32 error_code) { ++vcpu->stat.pf_guest; - if (vcpu->arch.exception.pending) { - if (vcpu->arch.exception.nr == PF_VECTOR) { - printk(KERN_DEBUG "kvm: inject_page_fault:" - " double fault 0x%lx\n", addr); - vcpu->arch.exception.nr = DF_VECTOR; - vcpu->arch.exception.error_code = 0; - } else if (vcpu->arch.exception.nr == DF_VECTOR) { - /* triple fault -> shutdown */ - set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests); - } - return; - } vcpu->arch.cr2 = addr; kvm_queue_exception_e(vcpu, PF_VECTOR, error_code); } void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) { - WARN_ON(vcpu->arch.exception.pending); + if (vcpu->arch.exception.pending) { + handle_multiple_faults(vcpu); + return; + } vcpu->arch.exception.pending = true; vcpu->arch.exception.has_error_code = true; vcpu->arch.exception.nr = nr;