Skip to content

Commit bbe9abb

Browse files
Nitin A Kambleavikivity
authored andcommitted
KVM: x86 emulator: imlpement jump conditional relative
Implement emulation of instruction: jump conditional rel opcodes: 0x0f 0x80 - 0x0f 0x8f Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
1 parent 7de7524 commit bbe9abb

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

drivers/kvm/x86_emulate.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,10 @@ static u16 twobyte_table[256] = {
188188
/* 0x70 - 0x7F */
189189
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190190
/* 0x80 - 0x8F */
191-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
191+
ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
192+
ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
193+
ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
194+
ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
192195
/* 0x90 - 0x9F */
193196
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
194197
/* 0xA0 - 0xA7 */
@@ -479,6 +482,41 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
479482
return rc;
480483
}
481484

485+
static int test_cc(unsigned int condition, unsigned int flags)
486+
{
487+
int rc = 0;
488+
489+
switch ((condition & 15) >> 1) {
490+
case 0: /* o */
491+
rc |= (flags & EFLG_OF);
492+
break;
493+
case 1: /* b/c/nae */
494+
rc |= (flags & EFLG_CF);
495+
break;
496+
case 2: /* z/e */
497+
rc |= (flags & EFLG_ZF);
498+
break;
499+
case 3: /* be/na */
500+
rc |= (flags & (EFLG_CF|EFLG_ZF));
501+
break;
502+
case 4: /* s */
503+
rc |= (flags & EFLG_SF);
504+
break;
505+
case 5: /* p/pe */
506+
rc |= (flags & EFLG_PF);
507+
break;
508+
case 7: /* le/ng */
509+
rc |= (flags & EFLG_ZF);
510+
/* fall through */
511+
case 6: /* l/nge */
512+
rc |= (!(flags & EFLG_SF) != !(flags & EFLG_OF));
513+
break;
514+
}
515+
516+
/* Odd condition identifiers (lsb == 1) have inverted sense. */
517+
return (!!rc ^ (condition & 1));
518+
}
519+
482520
int
483521
x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
484522
{
@@ -1486,6 +1524,27 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
14861524
}
14871525
rc = X86EMUL_CONTINUE;
14881526
break;
1527+
case 0x80 ... 0x8f: /* jnz rel, etc*/ {
1528+
long int rel;
1529+
1530+
switch (op_bytes) {
1531+
case 2:
1532+
rel = insn_fetch(s16, 2, _eip);
1533+
break;
1534+
case 4:
1535+
rel = insn_fetch(s32, 4, _eip);
1536+
break;
1537+
case 8:
1538+
rel = insn_fetch(s64, 8, _eip);
1539+
break;
1540+
default:
1541+
DPRINTF("jnz: Invalid op_bytes\n");
1542+
goto cannot_emulate;
1543+
}
1544+
if (test_cc(b, _eflags))
1545+
JMP_REL(rel);
1546+
break;
1547+
}
14891548
case 0xc7: /* Grp9 (cmpxchg8b) */
14901549
{
14911550
u64 old, new;

0 commit comments

Comments
 (0)