Re: [PATCH] kvm: implement VEX prefix decoder, bextr/andn
From: Paolo Bonzini
Date: Fri Jun 29 2018 - 07:47:14 EST
Thanks, I have some comments on the decoding logic.
On 26/06/2018 14:14, Mason Lee Back wrote:
> + if (ctxt->b == 0xC4 || ctxt->b == 0xC5) {
This should be exactly the condition that you are removing below:
if ((ctxt->b == 0xc5 || ctxt->b == 0xc4) &&
(mode == X86EMUL_MODE_PROT64 || (ctxt->modrm & 0xc0) == 0xc0))
so that you don't need the "reinterpret as LES or LDS" todo. It should also
be moved earlier, right after done_prefixes. The existing code starting
at
/* Opcode byts(s). */
and ending just before
ctxt->d = opcode.flags;
will become the "else" branch.
Otherwise looks at least... sane. :)
Paolo
> + ctxt->vex.prefix = ctxt->b;
> + if (ctxt->b == 0xC4) {
> + ctxt->vex.value = insn_fetch(u16, ctxt);
> + } else {
> + ctxt->vex.value = insn_fetch(u8, ctxt) << 8;
> + ctxt->vex.r = ctxt->vex.w;
> + ctxt->vex.w = 1;
> + ctxt->vex.x = 1;
> + ctxt->vex.b = 1;
> + ctxt->vex.m = 1;
> + }
>
> - /* vex-prefix instructions are not implemented */
> - if (ctxt->opcode_len == 1 && (ctxt->b == 0xc5 || ctxt->b == 0xc4) &&
> - (mode == X86EMUL_MODE_PROT64 || (ctxt->modrm & 0xc0) == 0xc0)) {
> - ctxt->d = NotImpl;
> + if (mode != X86EMUL_MODE_PROT64 && (!ctxt->vex.r || !ctxt->vex.x)) {
> + /* todo: reinterpret as LES (0xC4) or LDS (0xC5) instruction */
> + return EMULATION_FAILED;
> + }
> +
> + ctxt->rex_prefix |= ctxt->vex.r ? 0 : (1 << 2); /* rex.r */
> + ctxt->rex_prefix |= ctxt->vex.x ? 0 : (1 << 1); /* rex.x */
> + ctxt->rex_prefix |= ctxt->vex.b ? 0 : (1 << 0); /* rex.b */
> + if (mode == X86EMUL_MODE_PROT64 && ctxt->vex.w) {
> + ctxt->op_bytes = 8;
> + }
Please set ctxt->rex_prefix too for consistency.
> +
> + ctxt->b = insn_fetch(u8, ctxt);
> + switch (ctxt->vex.m) {
> + case 1:
> + opcode = twobyte_table[ctxt->b];
"ctxt->opcode_len = 2;" missing here.
> + break;
> + case 2:
> + opcode = opcode_map_0f_38[ctxt->b];
"ctxt->opcode_len = 3;" missing here.
> + break;
> + case 3:
> + /* KVM doesn't support this */
> + return EMULATION_FAILED;
> + default:
> + return EMULATION_FAILED;
> + }
> }