===================================================================
@@ -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;