[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC V2 1/6] xen: Emulate with no writes
Added support for emulating an instruction with no memory writes. Additionally, introduced hvm_emulate_one_full(), which acts upon all possible return values from the hvm_emulate_one() functions (RETRY, EXCEPTION, UNHANDLEABLE). Changes since V1: - Removed the Linux code that computes the length of an instruction. - Unused function parameters are no longer marked. - Refactored the code to eliminate redundancy. - Made the exception passed on to the guest by hvm_emulate_one_full() configurable. Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx> --- xen/arch/x86/hvm/emulate.c | 73 +++++++++++++++++++++++++++++++++++-- xen/include/asm-x86/hvm/emulate.h | 5 +++ 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c index eac159f..114a77a 100644 --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -688,6 +688,17 @@ static int hvmemul_write( return X86EMUL_OKAY; } +static int hvmemul_write_dummy( + enum x86_segment seg, + unsigned long offset, + void *p_data, + unsigned int bytes, + struct x86_emulate_ctxt *ctxt) +{ + /* discarding the write */ + return X86EMUL_OKAY; +} + static int hvmemul_cmpxchg( enum x86_segment seg, unsigned long offset, @@ -1138,8 +1149,8 @@ static const struct x86_emulate_ops hvm_emulate_ops = { .invlpg = hvmemul_invlpg }; -int hvm_emulate_one( - struct hvm_emulate_ctxt *hvmemul_ctxt) +static int hvm_emulate_one_with_ops(struct hvm_emulate_ctxt *hvmemul_ctxt, + const struct x86_emulate_ops *ops) { struct cpu_user_regs *regs = hvmemul_ctxt->ctxt.regs; struct vcpu *curr = current; @@ -1191,7 +1202,7 @@ int hvm_emulate_one( vio->mmio_retrying = vio->mmio_retry; vio->mmio_retry = 0; - rc = x86_emulate(&hvmemul_ctxt->ctxt, &hvm_emulate_ops); + rc = x86_emulate(&hvmemul_ctxt->ctxt, ops); if ( rc == X86EMUL_OKAY && vio->mmio_retry ) rc = X86EMUL_RETRY; @@ -1239,6 +1250,62 @@ int hvm_emulate_one( return X86EMUL_OKAY; } +int hvm_emulate_one( + struct hvm_emulate_ctxt *hvmemul_ctxt) +{ + return hvm_emulate_one_with_ops(hvmemul_ctxt, &hvm_emulate_ops); +} + +int hvm_emulate_one_no_write( + struct hvm_emulate_ctxt *hvmemul_ctxt) +{ + struct x86_emulate_ops local_ops = hvm_emulate_ops; + local_ops.write = hvmemul_write_dummy; + + return hvm_emulate_one_with_ops(hvmemul_ctxt, &local_ops); +} + +void hvm_emulate_one_full(bool_t nowrite, + unsigned int unhandleable_trapnr, + int unhandleable_errcode) +{ + struct hvm_emulate_ctxt ctx[1] = {}; + int rc = X86EMUL_RETRY; + + hvm_emulate_prepare(ctx, guest_cpu_user_regs()); + + while ( rc == X86EMUL_RETRY ) + { + if ( nowrite ) + rc = hvm_emulate_one_no_write(ctx); + else + rc = hvm_emulate_one(ctx); + } + + switch ( rc ) + { + case X86EMUL_UNHANDLEABLE: + gdprintk(XENLOG_DEBUG, "Emulation failed @ %04x:%lx: " + "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + hvmemul_get_seg_reg(x86_seg_cs, ctx)->sel, + ctx->insn_buf_eip, + ctx->insn_buf[0], ctx->insn_buf[1], + ctx->insn_buf[2], ctx->insn_buf[3], + ctx->insn_buf[4], ctx->insn_buf[5], + ctx->insn_buf[6], ctx->insn_buf[7], + ctx->insn_buf[8], ctx->insn_buf[9]); + hvm_inject_hw_exception(unhandleable_trapnr, unhandleable_errcode); + break; + case X86EMUL_EXCEPTION: + if ( ctx->exn_pending ) + hvm_inject_hw_exception(ctx->exn_vector, ctx->exn_error_code); + /* fall through */ + default: + hvm_emulate_writeback(ctx); + break; + } +} + void hvm_emulate_prepare( struct hvm_emulate_ctxt *hvmemul_ctxt, struct cpu_user_regs *regs) diff --git a/xen/include/asm-x86/hvm/emulate.h b/xen/include/asm-x86/hvm/emulate.h index 00a06cc..d68b485 100644 --- a/xen/include/asm-x86/hvm/emulate.h +++ b/xen/include/asm-x86/hvm/emulate.h @@ -37,6 +37,11 @@ struct hvm_emulate_ctxt { int hvm_emulate_one( struct hvm_emulate_ctxt *hvmemul_ctxt); +int hvm_emulate_one_no_write( + struct hvm_emulate_ctxt *hvmemul_ctxt); +void hvm_emulate_one_full(bool_t nowrite, + unsigned int unhandleable_trapnr, + int unhandleable_errcode); void hvm_emulate_prepare( struct hvm_emulate_ctxt *hvmemul_ctxt, struct cpu_user_regs *regs); -- 1.7.9.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |