mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
x86/HVM: don't crash guest upon problems occurring in user mode
This extends commit 5283b310 ("x86/HVM: only kill guest when unknown VM
exit occurred in guest kernel mode") to a few more cases, including the
failed VM entry one that XSA-110 was needed to be issued for.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Tim Deegan <tim@xen.org>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Release-Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
This commit is contained in:
1 parent
1516b33961
commit
28b4baacd5
2 files changed
+26
-20
No files matched your search
@@ -90,6 +90,15 @@ static bool_t amd_erratum383_found __read_mostly;
|
||||
static uint64_t osvw_length, osvw_status;
|
||||
static DEFINE_SPINLOCK(osvw_lock);
|
||||
|
||||
/* Only crash the guest if the problem originates in kernel mode. */
|
||||
static void svm_crash_or_fault(struct vcpu *v)
|
||||
{
|
||||
if ( vmcb_get_cpl(v->arch.hvm_svm.vmcb) )
|
||||
hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE);
|
||||
else
|
||||
domain_crash(v->domain);
|
||||
}
|
||||
|
||||
void __update_guest_eip(struct cpu_user_regs *regs, unsigned int inst_len)
|
||||
{
|
||||
struct vcpu *curr = current;
|
||||
@@ -100,7 +109,7 @@ void __update_guest_eip(struct cpu_user_regs *regs, unsigned int inst_len)
|
||||
if ( unlikely(inst_len > 15) )
|
||||
{
|
||||
gdprintk(XENLOG_ERR, "Bad instruction length %u\n", inst_len);
|
||||
domain_crash(curr->domain);
|
||||
svm_crash_or_fault(curr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2680,11 +2689,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
|
||||
"exitinfo1 = %#"PRIx64", exitinfo2 = %#"PRIx64"\n",
|
||||
exit_reason,
|
||||
(u64)vmcb->exitinfo1, (u64)vmcb->exitinfo2);
|
||||
if ( vmcb_get_cpl(vmcb) )
|
||||
hvm_inject_hw_exception(TRAP_invalid_op,
|
||||
HVM_DELIVER_NO_ERROR_CODE);
|
||||
else
|
||||
domain_crash(v->domain);
|
||||
svm_crash_or_fault(v);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+15
-14
@@ -134,6 +134,18 @@ static void vmx_vcpu_destroy(struct vcpu *v)
|
||||
passive_domain_destroy(v);
|
||||
}
|
||||
|
||||
/* Only crash the guest if the problem originates in kernel mode. */
|
||||
static void vmx_crash_or_fault(struct vcpu *v)
|
||||
{
|
||||
struct segment_register ss;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static DEFINE_PER_CPU(struct vmx_msr_state, host_msr_state);
|
||||
|
||||
static const u32 msr_index[] =
|
||||
@@ -2508,7 +2520,7 @@ static void vmx_failed_vmentry(unsigned int exit_reason,
|
||||
vmcs_dump_vcpu(curr);
|
||||
printk("**************************************\n");
|
||||
|
||||
domain_crash(curr->domain);
|
||||
vmx_crash_or_fault(curr);
|
||||
}
|
||||
|
||||
void vmx_enter_realmode(struct cpu_user_regs *regs)
|
||||
@@ -3161,19 +3173,8 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
|
||||
/* fall through */
|
||||
default:
|
||||
exit_and_crash:
|
||||
{
|
||||
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);
|
||||
}
|
||||
gdprintk(XENLOG_WARNING, "Bad vmexit (reason %#lx)\n", exit_reason);
|
||||
vmx_crash_or_fault(v);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||