diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index e3e15655c5..8aca6e6a34 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2680,7 +2680,11 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) "exitinfo1 = %#"PRIx64", exitinfo2 = %#"PRIx64"\n", exit_reason, (u64)vmcb->exitinfo1, (u64)vmcb->exitinfo2); - domain_crash(v->domain); + if ( vmcb_get_cpl(vmcb) ) + hvm_inject_hw_exception(TRAP_invalid_op, + HVM_DELIVER_NO_ERROR_CODE); + else + domain_crash(v->domain); break; } diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 79a69b1d0c..0bf92b25c2 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -3161,8 +3161,19 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) /* fall through */ default: exit_and_crash: - gdprintk(XENLOG_ERR, "Bad vmexit (reason %#lx)\n", exit_reason); - domain_crash(v->domain); + { + struct segment_register ss; + + gdprintk(XENLOG_WARNING, "Bad vmexit (reason %#lx)\n", + exit_reason); + + vmx_get_segment_register(v, x86_seg_ss, &ss); + if ( ss.attr.fields.dpl ) + hvm_inject_hw_exception(TRAP_invalid_op, + HVM_DELIVER_NO_ERROR_CODE); + else + domain_crash(v->domain); + } break; }