|
@@ -5670,18 +5670,23 @@ int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(kvm_inject_realmode_interrupt);
|
|
|
|
|
|
-static int handle_emulation_failure(struct kvm_vcpu *vcpu)
|
|
|
+static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
|
|
|
{
|
|
|
int r = EMULATE_DONE;
|
|
|
|
|
|
++vcpu->stat.insn_emulation_fail;
|
|
|
trace_kvm_emulate_insn_failed(vcpu);
|
|
|
+
|
|
|
+ if (emulation_type & EMULTYPE_NO_UD_ON_FAIL)
|
|
|
+ return EMULATE_FAIL;
|
|
|
+
|
|
|
if (!is_guest_mode(vcpu) && kvm_x86_ops->get_cpl(vcpu) == 0) {
|
|
|
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
|
|
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
|
|
|
vcpu->run->internal.ndata = 0;
|
|
|
r = EMULATE_USER_EXIT;
|
|
|
}
|
|
|
+
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
|
|
return r;
|
|
@@ -5977,7 +5982,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
|
|
|
return EMULATE_DONE;
|
|
|
if (emulation_type & EMULTYPE_SKIP)
|
|
|
return EMULATE_FAIL;
|
|
|
- return handle_emulation_failure(vcpu);
|
|
|
+ return handle_emulation_failure(vcpu, emulation_type);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -6012,7 +6017,7 @@ restart:
|
|
|
emulation_type))
|
|
|
return EMULATE_DONE;
|
|
|
|
|
|
- return handle_emulation_failure(vcpu);
|
|
|
+ return handle_emulation_failure(vcpu, emulation_type);
|
|
|
}
|
|
|
|
|
|
if (ctxt->have_exception) {
|