Message ID | 1379861095-628-5-git-send-email-bp@alien8.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Sun, Sep 22, 2013 at 04:44:53PM +0200, Borislav Petkov wrote: > From: Borislav Petkov <bp@suse.de> > > Add initial support for handling three-byte instructions in the > emulator. > > Signed-off-by: Borislav Petkov <bp@suse.de> > --- > arch/x86/kvm/emulate.c | 30 ++++++++++++++++++++++++++++++ > 1 file changed, 30 insertions(+) > > diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c > index 67277bcb377a..72093d76c769 100644 > --- a/arch/x86/kvm/emulate.c > +++ b/arch/x86/kvm/emulate.c > @@ -3880,6 +3880,25 @@ static const struct opcode twobyte_table[256] = { > N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N > }; > > +static const struct gprefix third_opcode_byte_0xf0 = { > + N, N, N, N > +}; > + > +static const struct gprefix third_opcode_byte_0xf1 = { > + N, N, N, N > +}; There are two three opcode tables, so third_opcode_byte is ambiguous. What about pfx_0f_38_f0 and pfx_0f_38_f1? > + > +/* > + * Insns below are selected by the prefix which indexed by the third opcode > + * byte. > + */ > +static const struct opcode opcode_map_0f_38[256] = { > + /* 0x00 - 0x7f */ > + X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), > + /* 0x80 - 0xff */ > + X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N) > +}; > + > #undef D > #undef N > #undef G > @@ -4200,6 +4219,13 @@ done_prefixes: > ctxt->opcode_len = 2; > ctxt->b = insn_fetch(u8, ctxt); > opcode = twobyte_table[ctxt->b]; > + > + /* 0F_38 opcode map */ > + if (ctxt->b == 0x38) { > + ctxt->opcode_len = 3; > + ctxt->b = insn_fetch(u8, ctxt); > + opcode = opcode_map_0f_38[ctxt->b]; > + } > } > ctxt->d = opcode.flags; > > @@ -4531,6 +4557,8 @@ special_insn: > > if (ctxt->opcode_len == 2) > goto twobyte_insn; > + else if (ctxt->opcode_len == 3) > + goto threebyte_insn; > > switch (ctxt->b) { > case 0x63: /* movsxd */ > @@ -4715,6 +4743,8 @@ twobyte_insn: > goto cannot_emulate; > } > > +threebyte_insn: > + > if (rc != X86EMUL_CONTINUE) > goto done; > > -- > 1.8.4 -- Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, Oct 29, 2013 at 11:50:43AM +0200, Gleb Natapov wrote: > There are two three opcode tables, so third_opcode_byte is ambiguous. Actually there's also 0F_3A and there are also other prefixes besides f0 and f1. Oh, and those tables are not completely full so I can imagine more stuff coming in later.... I know what you're thinking by now, btw :-) > What about pfx_0f_38_f0 and pfx_0f_38_f1? Yeah, those make it much more explicit. I wanted to keep the "three_byte" in the name in there somewhere, though, so that it is clear that we're dealing with three byte opcodes instead of requiring the onlooking innocent person to know the opcodes. How about: three_byte_0f_38_f0 three_byte_0f_38_f1 three_byte_0f_3a_50 ... Last one is an example only. Btw, we might want to reconsider that whole tabular representation when more stuff needs to be added...
On Tue, Oct 29, 2013 at 11:04:57AM +0100, Borislav Petkov wrote: > On Tue, Oct 29, 2013 at 11:50:43AM +0200, Gleb Natapov wrote: > > There are two three opcode tables, so third_opcode_byte is ambiguous. > > Actually there's also 0F_3A and there are also other prefixes besides f0 > and f1. Oh, and those tables are not completely full so I can imagine > more stuff coming in later.... > > I know what you're thinking by now, btw :-) > :) > > What about pfx_0f_38_f0 and pfx_0f_38_f1? > > Yeah, those make it much more explicit. > > I wanted to keep the "three_byte" in the name in there somewhere, > though, so that it is clear that we're dealing with three byte opcodes > instead of requiring the onlooking innocent person to know the opcodes. > > How about: > > three_byte_0f_38_f0 > three_byte_0f_38_f1 > three_byte_0f_3a_50 > ... > > Last one is an example only. > Looks OK to me. > Btw, we might want to reconsider that whole tabular representation when > more stuff needs to be added... > Of course. When tables will start to show their limitation we can always change to something else. -- Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 67277bcb377a..72093d76c769 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -3880,6 +3880,25 @@ static const struct opcode twobyte_table[256] = { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N }; +static const struct gprefix third_opcode_byte_0xf0 = { + N, N, N, N +}; + +static const struct gprefix third_opcode_byte_0xf1 = { + N, N, N, N +}; + +/* + * Insns below are selected by the prefix which indexed by the third opcode + * byte. + */ +static const struct opcode opcode_map_0f_38[256] = { + /* 0x00 - 0x7f */ + X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), + /* 0x80 - 0xff */ + X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N) +}; + #undef D #undef N #undef G @@ -4200,6 +4219,13 @@ done_prefixes: ctxt->opcode_len = 2; ctxt->b = insn_fetch(u8, ctxt); opcode = twobyte_table[ctxt->b]; + + /* 0F_38 opcode map */ + if (ctxt->b == 0x38) { + ctxt->opcode_len = 3; + ctxt->b = insn_fetch(u8, ctxt); + opcode = opcode_map_0f_38[ctxt->b]; + } } ctxt->d = opcode.flags; @@ -4531,6 +4557,8 @@ special_insn: if (ctxt->opcode_len == 2) goto twobyte_insn; + else if (ctxt->opcode_len == 3) + goto threebyte_insn; switch (ctxt->b) { case 0x63: /* movsxd */ @@ -4715,6 +4743,8 @@ twobyte_insn: goto cannot_emulate; } +threebyte_insn: + if (rc != X86EMUL_CONTINUE) goto done;