[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 01/17] x86emul: split instruction decoding from execution
>>> On 09.09.16 at 20:35, <andrew.cooper3@xxxxxxxxxx> wrote: > On 08/09/16 14:04, Jan Beulich wrote: >> @@ -607,7 +609,7 @@ do{ asm volatile ( >> }) >> #define truncate_ea(ea) truncate_word((ea), ad_bytes) >> >> -#define mode_64bit() (def_ad_bytes == 8) >> +#define mode_64bit() (ctxt->addr_size == 64) >> >> #define fail_if(p) \ >> do { \ >> @@ -1558,32 +1560,63 @@ int x86emul_unhandleable_rw( >> return X86EMUL_UNHANDLEABLE; >> } >> >> -int >> -x86_emulate( >> - struct x86_emulate_ctxt *ctxt, >> - const struct x86_emulate_ops *ops) >> -{ >> - /* Shadow copy of register state. Committed on successful emulation. */ >> - struct cpu_user_regs _regs = *ctxt->regs; >> +struct x86_emulate_state { >> + unsigned int op_bytes, ad_bytes; >> + >> + enum { ext_none, ext_0f, ext_0f38 } ext; >> + uint8_t opcode; >> + uint8_t modrm, modrm_mod, modrm_reg, modrm_rm; >> + uint8_t rex_prefix; >> + bool lock_prefix; >> + opcode_desc_t desc; >> + union vex vex; >> + int override_seg; >> >> - uint8_t b, d, sib, sib_index, sib_base, rex_prefix = 0; >> - uint8_t modrm = 0, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; >> - enum { ext_none, ext_0f, ext_0f38 } ext = ext_none; >> - union vex vex = {}; >> - unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes; >> - bool_t lock_prefix = 0; >> - int override_seg = -1, rc = X86EMUL_OKAY; >> - struct operand src = { .reg = REG_POISON }; >> - struct operand dst = { .reg = REG_POISON }; >> - enum x86_swint_type swint_type; >> - struct x86_emulate_stub stub = {}; >> - DECLARE_ALIGNED(mmval_t, mmval); >> /* >> * Data operand effective address (usually computed from ModRM). >> * Default is a memory operand relative to segment DS. >> */ >> - struct operand ea = { .type = OP_MEM, .reg = REG_POISON }; >> - ea.mem.seg = x86_seg_ds; /* gcc may reject anon union initializer */ >> + struct operand ea; >> + >> + /* Immediate operand values, if any. Use otherwise unused fields. */ >> +#define imm1 ea.val >> +#define imm2 ea.orig_val > > Some instructions (e.g. bextr) have both immediate and memory operands. > Reusing ea like this is unsafe. I disagree: Both fields have never been used for anything, and it was more than once that I had thought about how to eliminate them from ea without eliminating them from src and dst. Until finally I found a use for them here. > Immediate data was previously stashed in src, separately from ea. In > the light of the XSA-123 problems, I think it would be better to just > have "uint64_t imm1, imm2;" here. The XSA-123 problem was completely different, and I specifically took this into consideration. We're not aliasing scalars and pointers here, so there's no risk of causing a new security issue. Just to repeat - these two fields have been completely unused so far. >> + >> + /* Shadow copy of register state. Committed on successful emulation. */ >> + struct cpu_user_regs regs; >> +}; >> + >> +/* Helper definitions. */ >> +#define op_bytes (state->op_bytes) >> +#define ad_bytes (state->ad_bytes) >> +#define ext (state->ext) >> +#define modrm (state->modrm) >> +#define modrm_mod (state->modrm_mod) >> +#define modrm_reg (state->modrm_reg) >> +#define modrm_rm (state->modrm_rm) >> +#define rex_prefix (state->rex_prefix) >> +#define lock_prefix (state->lock_prefix) >> +#define vex (state->vex) >> +#define override_seg (state->override_seg) >> +#define ea (state->ea) >> +#define _regs (state->regs) >> + >> +static int >> +x86_decode( >> + struct x86_emulate_state *state, >> + struct x86_emulate_ctxt *ctxt, >> + const struct x86_emulate_ops *ops) >> +{ >> + uint8_t b, d, sib, sib_index, sib_base; >> + unsigned int def_op_bytes, def_ad_bytes; >> + int rc = X86EMUL_OKAY; >> + >> + memset(state, 0, sizeof(*state)); >> + override_seg = -1; >> + ea.type = OP_MEM; >> + ea.mem.seg = x86_seg_ds; >> + ea.reg = REG_POISON; >> + _regs = *ctxt->regs; > > The helper definitions are fine for the transition period, but I would > like to see them eventually removed to help reduce the quantity of > information hiding in this area. Please don't introduce new uses. I simply can't write e.g. "state->ea.type" here, as that would get macro expanded to "state->(state->ea).type". I've carefully tried to avoid introducing new uses where possible, and I'll be happy to correct cases where I failed to, but here we just can't (and I hope you agree that it would be odd to not use the helpers consistently in a single block of code, i.e. I'd like to not replace _regs (which goes away in patch 3 anyway). >> +int >> +x86_emulate( >> + struct x86_emulate_ctxt *ctxt, >> + const struct x86_emulate_ops *ops) >> +{ >> + struct x86_emulate_state state; >> + int rc; >> + uint8_t b, d; >> + struct operand src = { .reg = REG_POISON }; >> + struct operand dst = { .reg = REG_POISON }; >> + enum x86_swint_type swint_type; >> + struct x86_emulate_stub stub = {}; >> + DECLARE_ALIGNED(mmval_t, mmval); >> + >> + rc = x86_decode(&state, ctxt, ops); >> + if ( rc != X86EMUL_OKAY) > > Space before the bracket (although I guess these lines drop out before > the end of the series anyway?) Oops. And to the question - no, why would they? Emulation obviously requires decoding as the first step. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |