aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm
diff options
context:
space:
mode:
authorNitin A Kamble <nitin.a.kamble@intel.com>2007-09-15 03:23:07 -0400
committerAvi Kivity <avi@qumranet.com>2007-10-13 04:18:28 -0400
commitbbe9abbdaca366510db1f2df25f4c7b48cba38eb (patch)
tree31b2019825d5b1e61916bb132ca4439d147b30dc /drivers/kvm
parent7de752482c71e1ef72ac9650deaeb6d293b8416d (diff)
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>
Diffstat (limited to 'drivers/kvm')
-rw-r--r--drivers/kvm/x86_emulate.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index e4ce34c52ba1..ba53e59f558a 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -188,7 +188,10 @@ static u16 twobyte_table[256] = {
188 /* 0x70 - 0x7F */ 188 /* 0x70 - 0x7F */
189 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190 /* 0x80 - 0x8F */ 190 /* 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,
192 /* 0x90 - 0x9F */ 195 /* 0x90 - 0x9F */
193 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
194 /* 0xA0 - 0xA7 */ 197 /* 0xA0 - 0xA7 */
@@ -479,6 +482,41 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
479 return rc; 482 return rc;
480} 483}
481 484
485static 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
482int 520int
483x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) 521x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
484{ 522{
@@ -1486,6 +1524,27 @@ twobyte_special_insn:
1486 } 1524 }
1487 rc = X86EMUL_CONTINUE; 1525 rc = X86EMUL_CONTINUE;
1488 break; 1526 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 }
1489 case 0xc7: /* Grp9 (cmpxchg8b) */ 1548 case 0xc7: /* Grp9 (cmpxchg8b) */
1490 { 1549 {
1491 u64 old, new; 1550 u64 old, new;