diff mbox

[1/2] KVM: x86: handle double and triple faults for every exception

Message ID 20091111193837.115825934@localhost.localdomain (mailing list archive)
State New, archived
Headers show

Commit Message

Marcelo Tosatti Nov. 11, 2009, 7:29 p.m. UTC
None
diff mbox

Patch

Index: kvm/arch/x86/kvm/x86.c
===================================================================
--- kvm.orig/arch/x86/kvm/x86.c
+++ kvm/arch/x86/kvm/x86.c
@@ -170,9 +170,21 @@  void kvm_set_apic_base(struct kvm_vcpu *
 }
 EXPORT_SYMBOL_GPL(kvm_set_apic_base);
 
+static void handle_multiple_faults(struct kvm_vcpu *vcpu)
+{
+       if (vcpu->arch.exception.nr != DF_VECTOR) {
+               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;
@@ -184,24 +196,6 @@  void kvm_inject_page_fault(struct kvm_vc
 {
 	++vcpu->stat.pf_guest;
 
-	if (vcpu->arch.exception.pending) {
-		switch(vcpu->arch.exception.nr) {
-		case DF_VECTOR:
-			/* triple fault -> shutdown */
-			set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
-			return;
-		case PF_VECTOR:
-			vcpu->arch.exception.nr = DF_VECTOR;
-			vcpu->arch.exception.error_code = 0;
-			return;
-		default:
-			/* replace previous exception with a new one in a hope
-			   that instruction re-execution will regenerate lost
-			   exception */
-			vcpu->arch.exception.pending = false;
-			break;
-		}
-	}
 	vcpu->arch.cr2 = addr;
 	kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
 }
@@ -214,7 +208,10 @@  EXPORT_SYMBOL_GPL(kvm_inject_nmi);
 
 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;