const struct x86_emulate_ops *ops)
{
uint64_t debugctl;
+ int rc = X86EMUL_UNHANDLEABLE;
- return ops->read_msr &&
- ops->read_msr(MSR_IA32_DEBUGCTLMSR, &debugctl, ctxt) == X86EMUL_OKAY &&
- (debugctl & IA32_DEBUGCTLMSR_BTF);
+ if ( !ops->read_msr ||
+ (rc = ops->read_msr(MSR_IA32_DEBUGCTLMSR, &debugctl,
+ ctxt)) != X86EMUL_OKAY )
+ {
+ if ( rc == X86EMUL_EXCEPTION )
+ x86_emul_reset_event(ctxt);
+ debugctl = 0;
+ }
+
+ return debugctl & IA32_DEBUGCTLMSR_BTF;
}
static bool umip_active(struct x86_emulate_ctxt *ctxt,
if ( !ops->read_xcr || ops->read_xcr(0, &xcr0, ctxt) != X86EMUL_OKAY ||
!(xcr0 & X86_XCR0_BNDREGS) || !(xcr0 & X86_XCR0_BNDCSR) )
+ {
+ ASSERT(!ctxt->event_pending);
return;
+ }
if ( !mode_ring0() )
bndcfg = read_bndcfgu();
else if ( !ops->read_msr ||
- ops->read_msr(MSR_IA32_BNDCFGS, &bndcfg, ctxt) != X86EMUL_OKAY )
+ (rc = ops->read_msr(MSR_IA32_BNDCFGS, &bndcfg,
+ ctxt)) != X86EMUL_OKAY )
+ {
+ if ( rc == X86EMUL_EXCEPTION )
+ x86_emul_reset_event(ctxt);
return;
+ }
if ( (bndcfg & IA32_BNDCFGS_ENABLE) && !(bndcfg & IA32_BNDCFGS_PRESERVE) )
{
/*
if ( (rc = ops->write_segment(x86_seg_gs, &sreg,
ctxt)) != X86EMUL_OKAY )
{
- /* Best effort unwind (i.e. no error checking). */
- ops->write_msr(MSR_SHADOW_GS_BASE, msr_val, ctxt);
+ /* Best effort unwind (i.e. no real error checking). */
+ if ( ops->write_msr(MSR_SHADOW_GS_BASE, msr_val,
+ ctxt) == X86EMUL_EXCEPTION )
+ x86_emul_reset_event(ctxt);
goto done;
}
break;
cr4 = X86_CR4_OSFXSR;
if ( !ops->read_msr ||
ops->read_msr(MSR_EFER, &msr_val, ctxt) != X86EMUL_OKAY )
+ {
+ x86_emul_reset_event(ctxt);
msr_val = 0;
+ }
if ( !(cr4 & X86_CR4_OSFXSR) ||
(mode_64bit() && mode_ring0() && (msr_val & EFER_FFXSE)) )
op_bytes = offsetof(struct x86_fxsr, xmm[0]);
* An event being pending should exactly match returning
* X86EMUL_EXCEPTION. (If this trips, the chances are a codepath has
* called hvm_inject_hw_exception() rather than using
- * x86_emul_hw_exception().)
+ * x86_emul_hw_exception(), or the invocation of a hook has caused an
+ * exception to be raised, while the caller was only checking for
+ * success/failure.)
*/
ASSERT(ctxt->event_pending == (rc == X86EMUL_EXCEPTION));