|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v9 1/2] x86emul: New return code for unimplemented instruction
Enforce the distinction between an instruction not implemented by the
emulator and the failure to emulate that instruction by defining a new
return code, X86EMUL_UNIMPLEMENTED.
This value should only be used by the core emulator if it fails to decode
the current instruction, and not by any of the x86_emulate_ops
callbacks.
Signed-off-by: Petre Pircalabu <ppircalabu@xxxxxxxxxxxxxxx>
Reviewed-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
xen/arch/x86/hvm/emulate.c | 3 +++
xen/arch/x86/hvm/hvm.c | 1 +
xen/arch/x86/hvm/io.c | 1 +
xen/arch/x86/hvm/vmx/realmode.c | 2 +-
xen/arch/x86/mm/shadow/multi.c | 2 +-
xen/arch/x86/x86_emulate/x86_emulate.c | 35 ++++++++++++++++++----------------
xen/arch/x86/x86_emulate/x86_emulate.h | 6 ++++++
7 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index 64454c7..f9f8c25 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -2044,6 +2044,7 @@ int hvm_emulate_one_mmio(unsigned long mfn, unsigned long
gla)
switch ( rc )
{
case X86EMUL_UNHANDLEABLE:
+ case X86EMUL_UNIMPLEMENTED:
hvm_dump_emulation_state(XENLOG_G_WARNING, "MMCFG", &ctxt);
break;
case X86EMUL_EXCEPTION:
@@ -2101,6 +2102,8 @@ void hvm_emulate_one_vm_event(enum emul_kind kind,
unsigned int trapnr,
* consistent with X86EMUL_RETRY.
*/
return;
+ case X86EMUL_UNIMPLEMENTED:
+ /* fall-through */
case X86EMUL_UNHANDLEABLE:
hvm_dump_emulation_state(XENLOG_G_DEBUG, "Mem event", &ctx);
hvm_inject_hw_exception(trapnr, errcode);
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 6cb903d..ea2812c 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3695,6 +3695,7 @@ void hvm_ud_intercept(struct cpu_user_regs *regs)
switch ( hvm_emulate_one(&ctxt) )
{
case X86EMUL_UNHANDLEABLE:
+ case X86EMUL_UNIMPLEMENTED:
hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC);
break;
case X86EMUL_EXCEPTION:
diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
index bf41954..984db21 100644
--- a/xen/arch/x86/hvm/io.c
+++ b/xen/arch/x86/hvm/io.c
@@ -96,6 +96,7 @@ bool hvm_emulate_one_insn(hvm_emulate_validate_t *validate,
const char *descr)
switch ( rc )
{
case X86EMUL_UNHANDLEABLE:
+ case X86EMUL_UNIMPLEMENTED:
hvm_dump_emulation_state(XENLOG_G_WARNING, descr, &ctxt);
return false;
diff --git a/xen/arch/x86/hvm/vmx/realmode.c b/xen/arch/x86/hvm/vmx/realmode.c
index 11bde58..fdbbee2 100644
--- a/xen/arch/x86/hvm/vmx/realmode.c
+++ b/xen/arch/x86/hvm/vmx/realmode.c
@@ -106,7 +106,7 @@ void vmx_realmode_emulate_one(struct hvm_emulate_ctxt
*hvmemul_ctxt)
if ( hvm_vcpu_io_need_completion(vio) || vio->mmio_retry )
vio->io_completion = HVMIO_realmode_completion;
- if ( rc == X86EMUL_UNHANDLEABLE )
+ if ( rc == X86EMUL_UNHANDLEABLE || rc == X86EMUL_UNIMPLEMENTED )
{
gdprintk(XENLOG_ERR, "Failed to emulate insn.\n");
goto fail;
diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c
index c5c0af8..15727a2 100644
--- a/xen/arch/x86/mm/shadow/multi.c
+++ b/xen/arch/x86/mm/shadow/multi.c
@@ -3488,7 +3488,7 @@ static int sh_page_fault(struct vcpu *v,
* would be a good unshadow hint. If we *do* decide to unshadow-on-fault
* then it must be 'failable': we cannot require the unshadow to succeed.
*/
- if ( r == X86EMUL_UNHANDLEABLE )
+ if ( r == X86EMUL_UNHANDLEABLE || r == X86EMUL_UNIMPLEMENTED )
{
perfc_incr(shadow_fault_emulate_failed);
#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
b/xen/arch/x86/x86_emulate/x86_emulate.c
index 2201852..242b0af 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -2577,7 +2577,7 @@ x86_decode(
d = twobyte_table[0x3a].desc;
break;
default:
- rc = X86EMUL_UNHANDLEABLE;
+ rc = X86EMUL_UNIMPLEMENTED;
goto done;
}
}
@@ -2591,7 +2591,7 @@ x86_decode(
}
else
{
- rc = X86EMUL_UNHANDLEABLE;
+ rc = X86EMUL_UNIMPLEMENTED;
goto done;
}
@@ -2871,7 +2871,7 @@ x86_decode(
default:
ASSERT_UNREACHABLE();
- return X86EMUL_UNHANDLEABLE;
+ return X86EMUL_UNIMPLEMENTED;
}
if ( ea.type == OP_MEM )
@@ -4183,7 +4183,7 @@ x86_emulate(
break;
case 4: /* fldenv - TODO */
state->fpu_ctrl = true;
- goto cannot_emulate;
+ goto unimplemented_insn;
case 5: /* fldcw m2byte */
state->fpu_ctrl = true;
if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &src.val,
@@ -4194,7 +4194,7 @@ x86_emulate(
break;
case 6: /* fnstenv - TODO */
state->fpu_ctrl = true;
- goto cannot_emulate;
+ goto unimplemented_insn;
case 7: /* fnstcw m2byte */
state->fpu_ctrl = true;
emulate_fpu_insn_memdst("fnstcw", dst.val);
@@ -4430,7 +4430,7 @@ x86_emulate(
case 4: /* frstor - TODO */
case 6: /* fnsave - TODO */
state->fpu_ctrl = true;
- goto cannot_emulate;
+ goto unimplemented_insn;
case 7: /* fnstsw m2byte */
state->fpu_ctrl = true;
emulate_fpu_insn_memdst("fnstsw", dst.val);
@@ -5177,7 +5177,7 @@ x86_emulate(
goto done;
break;
default:
- goto cannot_emulate;
+ goto unimplemented_insn;
}
break;
}
@@ -6176,7 +6176,7 @@ x86_emulate(
/* vpsll{w,d} $imm8,{x,y}mm,{x,y}mm */
break;
default:
- goto cannot_emulate;
+ goto unimplemented_insn;
}
simd_0f_shift_imm:
generate_exception_if(ea.type != OP_REG, EXC_UD);
@@ -6224,7 +6224,7 @@ x86_emulate(
case 6: /* psllq $imm8,mm */
goto simd_0f_shift_imm;
}
- goto cannot_emulate;
+ goto unimplemented_insn;
case X86EMUL_OPC_66(0x0f, 0x73):
case X86EMUL_OPC_VEX_66(0x0f, 0x73):
@@ -6240,7 +6240,7 @@ x86_emulate(
/* vpslldq $imm8,{x,y}mm,{x,y}mm */
goto simd_0f_shift_imm;
}
- goto cannot_emulate;
+ goto unimplemented_insn;
case X86EMUL_OPC(0x0f, 0x77): /* emms */
case X86EMUL_OPC_VEX(0x0f, 0x77): /* vzero{all,upper} */
@@ -6304,7 +6304,7 @@ x86_emulate(
case 0: /* extrq $imm8,$imm8,xmm */
break;
default:
- goto cannot_emulate;
+ goto unimplemented_insn;
}
/* fall through */
case X86EMUL_OPC_F2(0x0f, 0x78): /* insertq $imm8,$imm8,xmm,xmm */
@@ -6515,7 +6515,7 @@ x86_emulate(
vcpu_must_have(avx);
goto stmxcsr;
}
- goto cannot_emulate;
+ goto unimplemented_insn;
case X86EMUL_OPC_F3(0x0f, 0xae): /* Grp15 */
fail_if(modrm_mod != 3);
@@ -6759,7 +6759,7 @@ x86_emulate(
switch ( modrm_reg & 7 )
{
default:
- goto cannot_emulate;
+ goto unimplemented_insn;
#ifdef HAVE_GAS_RDRAND
case 6: /* rdrand */
@@ -7341,7 +7341,7 @@ x86_emulate(
host_and_vcpu_must_have(bmi1);
break;
default:
- goto cannot_emulate;
+ goto unimplemented_insn;
}
generate_exception_if(vex.l, EXC_UD);
@@ -7650,7 +7650,7 @@ x86_emulate(
host_and_vcpu_must_have(tbm);
break;
default:
- goto cannot_emulate;
+ goto unimplemented_insn;
}
xop_09_rm_rv:
@@ -7684,7 +7684,7 @@ x86_emulate(
host_and_vcpu_must_have(tbm);
goto xop_09_rm_rv;
}
- goto cannot_emulate;
+ goto unimplemented_insn;
case X86EMUL_OPC_XOP(0a, 0x10): /* bextr imm,r/m,r */
{
@@ -7716,6 +7716,9 @@ x86_emulate(
}
default:
+ unimplemented_insn:
+ rc = X86EMUL_UNIMPLEMENTED;
+ goto done;
cannot_emulate:
rc = X86EMUL_UNHANDLEABLE;
goto done;
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h
b/xen/arch/x86/x86_emulate/x86_emulate.h
index 4ddf111..82812ca 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
@@ -133,6 +133,12 @@ struct x86_emul_fpu_aux {
* Undefined behavior when used anywhere else.
*/
#define X86EMUL_DONE 4
+ /*
+ * Current instruction is not implemented by the emulator.
+ * This value should only be returned by the core emulator if decode fails
+ * and not by any of the x86_emulate_ops callbacks.
+ */
+#define X86EMUL_UNIMPLEMENTED 5
/* FPU sub-types which may be requested via ->get_fpu(). */
enum x86_emulate_fpu_type {
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |