diff options
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 56 |
1 files changed, 26 insertions, 30 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 008db4dad7b2..cacdcf5f32d7 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -501,23 +501,19 @@ register_address(struct decode_cache *c, unsigned long base, unsigned long reg) | |||
501 | return base + address_mask(c, reg); | 501 | return base + address_mask(c, reg); |
502 | } | 502 | } |
503 | 503 | ||
504 | #define register_address_increment(reg, inc) \ | 504 | static inline void |
505 | do { \ | 505 | register_address_increment(struct decode_cache *c, unsigned long *reg, int inc) |
506 | /* signed type ensures sign extension to long */ \ | 506 | { |
507 | int _inc = (inc); \ | 507 | if (c->ad_bytes == sizeof(unsigned long)) |
508 | if (c->ad_bytes == sizeof(unsigned long)) \ | 508 | *reg += inc; |
509 | (reg) += _inc; \ | 509 | else |
510 | else \ | 510 | *reg = (*reg & ~ad_mask(c)) | ((*reg + inc) & ad_mask(c)); |
511 | (reg) = ((reg) & \ | 511 | } |
512 | ~ad_mask(c)) | \ | ||
513 | (((reg) + _inc) & \ | ||
514 | ad_mask(c)); \ | ||
515 | } while (0) | ||
516 | 512 | ||
517 | #define JMP_REL(rel) \ | 513 | static inline void jmp_rel(struct decode_cache *c, int rel) |
518 | do { \ | 514 | { |
519 | register_address_increment(c->eip, rel); \ | 515 | register_address_increment(c, &c->eip, rel); |
520 | } while (0) | 516 | } |
521 | 517 | ||
522 | static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, | 518 | static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, |
523 | struct x86_emulate_ops *ops, | 519 | struct x86_emulate_ops *ops, |
@@ -1065,7 +1061,7 @@ static inline void emulate_push(struct x86_emulate_ctxt *ctxt) | |||
1065 | c->dst.type = OP_MEM; | 1061 | c->dst.type = OP_MEM; |
1066 | c->dst.bytes = c->op_bytes; | 1062 | c->dst.bytes = c->op_bytes; |
1067 | c->dst.val = c->src.val; | 1063 | c->dst.val = c->src.val; |
1068 | register_address_increment(c->regs[VCPU_REGS_RSP], -c->op_bytes); | 1064 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes); |
1069 | c->dst.ptr = (void *) register_address(c, ctxt->ss_base, | 1065 | c->dst.ptr = (void *) register_address(c, ctxt->ss_base, |
1070 | c->regs[VCPU_REGS_RSP]); | 1066 | c->regs[VCPU_REGS_RSP]); |
1071 | } | 1067 | } |
@@ -1082,7 +1078,7 @@ static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, | |||
1082 | if (rc != 0) | 1078 | if (rc != 0) |
1083 | return rc; | 1079 | return rc; |
1084 | 1080 | ||
1085 | register_address_increment(c->regs[VCPU_REGS_RSP], c->dst.bytes); | 1081 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], c->dst.bytes); |
1086 | 1082 | ||
1087 | return 0; | 1083 | return 0; |
1088 | } | 1084 | } |
@@ -1395,7 +1391,7 @@ special_insn: | |||
1395 | c->dst.type = OP_MEM; | 1391 | c->dst.type = OP_MEM; |
1396 | c->dst.bytes = c->op_bytes; | 1392 | c->dst.bytes = c->op_bytes; |
1397 | c->dst.val = c->src.val; | 1393 | c->dst.val = c->src.val; |
1398 | register_address_increment(c->regs[VCPU_REGS_RSP], | 1394 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], |
1399 | -c->op_bytes); | 1395 | -c->op_bytes); |
1400 | c->dst.ptr = (void *) register_address( | 1396 | c->dst.ptr = (void *) register_address( |
1401 | c, ctxt->ss_base, c->regs[VCPU_REGS_RSP]); | 1397 | c, ctxt->ss_base, c->regs[VCPU_REGS_RSP]); |
@@ -1407,7 +1403,7 @@ special_insn: | |||
1407 | c->op_bytes, ctxt->vcpu)) != 0) | 1403 | c->op_bytes, ctxt->vcpu)) != 0) |
1408 | goto done; | 1404 | goto done; |
1409 | 1405 | ||
1410 | register_address_increment(c->regs[VCPU_REGS_RSP], | 1406 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], |
1411 | c->op_bytes); | 1407 | c->op_bytes); |
1412 | c->dst.type = OP_NONE; /* Disable writeback. */ | 1408 | c->dst.type = OP_NONE; /* Disable writeback. */ |
1413 | break; | 1409 | break; |
@@ -1459,7 +1455,7 @@ special_insn: | |||
1459 | int rel = insn_fetch(s8, 1, c->eip); | 1455 | int rel = insn_fetch(s8, 1, c->eip); |
1460 | 1456 | ||
1461 | if (test_cc(c->b, ctxt->eflags)) | 1457 | if (test_cc(c->b, ctxt->eflags)) |
1462 | JMP_REL(rel); | 1458 | jmp_rel(c, rel); |
1463 | break; | 1459 | break; |
1464 | } | 1460 | } |
1465 | case 0x80 ... 0x83: /* Grp1 */ | 1461 | case 0x80 ... 0x83: /* Grp1 */ |
@@ -1545,10 +1541,10 @@ special_insn: | |||
1545 | &c->dst.val, | 1541 | &c->dst.val, |
1546 | c->dst.bytes, ctxt->vcpu)) != 0) | 1542 | c->dst.bytes, ctxt->vcpu)) != 0) |
1547 | goto done; | 1543 | goto done; |
1548 | register_address_increment(c->regs[VCPU_REGS_RSI], | 1544 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], |
1549 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | 1545 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
1550 | : c->dst.bytes); | 1546 | : c->dst.bytes); |
1551 | register_address_increment(c->regs[VCPU_REGS_RDI], | 1547 | register_address_increment(c, &c->regs[VCPU_REGS_RDI], |
1552 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | 1548 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
1553 | : c->dst.bytes); | 1549 | : c->dst.bytes); |
1554 | break; | 1550 | break; |
@@ -1580,10 +1576,10 @@ special_insn: | |||
1580 | 1576 | ||
1581 | emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags); | 1577 | emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags); |
1582 | 1578 | ||
1583 | register_address_increment(c->regs[VCPU_REGS_RSI], | 1579 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], |
1584 | (ctxt->eflags & EFLG_DF) ? -c->src.bytes | 1580 | (ctxt->eflags & EFLG_DF) ? -c->src.bytes |
1585 | : c->src.bytes); | 1581 | : c->src.bytes); |
1586 | register_address_increment(c->regs[VCPU_REGS_RDI], | 1582 | register_address_increment(c, &c->regs[VCPU_REGS_RDI], |
1587 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | 1583 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
1588 | : c->dst.bytes); | 1584 | : c->dst.bytes); |
1589 | 1585 | ||
@@ -1595,7 +1591,7 @@ special_insn: | |||
1595 | ctxt->es_base, | 1591 | ctxt->es_base, |
1596 | c->regs[VCPU_REGS_RDI]); | 1592 | c->regs[VCPU_REGS_RDI]); |
1597 | c->dst.val = c->regs[VCPU_REGS_RAX]; | 1593 | c->dst.val = c->regs[VCPU_REGS_RAX]; |
1598 | register_address_increment(c->regs[VCPU_REGS_RDI], | 1594 | register_address_increment(c, &c->regs[VCPU_REGS_RDI], |
1599 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | 1595 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
1600 | : c->dst.bytes); | 1596 | : c->dst.bytes); |
1601 | break; | 1597 | break; |
@@ -1611,7 +1607,7 @@ special_insn: | |||
1611 | c->dst.bytes, | 1607 | c->dst.bytes, |
1612 | ctxt->vcpu)) != 0) | 1608 | ctxt->vcpu)) != 0) |
1613 | goto done; | 1609 | goto done; |
1614 | register_address_increment(c->regs[VCPU_REGS_RSI], | 1610 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], |
1615 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | 1611 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
1616 | : c->dst.bytes); | 1612 | : c->dst.bytes); |
1617 | break; | 1613 | break; |
@@ -1650,14 +1646,14 @@ special_insn: | |||
1650 | goto cannot_emulate; | 1646 | goto cannot_emulate; |
1651 | } | 1647 | } |
1652 | c->src.val = (unsigned long) c->eip; | 1648 | c->src.val = (unsigned long) c->eip; |
1653 | JMP_REL(rel); | 1649 | jmp_rel(c, rel); |
1654 | c->op_bytes = c->ad_bytes; | 1650 | c->op_bytes = c->ad_bytes; |
1655 | emulate_push(ctxt); | 1651 | emulate_push(ctxt); |
1656 | break; | 1652 | break; |
1657 | } | 1653 | } |
1658 | case 0xe9: /* jmp rel */ | 1654 | case 0xe9: /* jmp rel */ |
1659 | case 0xeb: /* jmp rel short */ | 1655 | case 0xeb: /* jmp rel short */ |
1660 | JMP_REL(c->src.val); | 1656 | jmp_rel(c, c->src.val); |
1661 | c->dst.type = OP_NONE; /* Disable writeback. */ | 1657 | c->dst.type = OP_NONE; /* Disable writeback. */ |
1662 | break; | 1658 | break; |
1663 | case 0xf4: /* hlt */ | 1659 | case 0xf4: /* hlt */ |
@@ -1857,7 +1853,7 @@ twobyte_insn: | |||
1857 | goto cannot_emulate; | 1853 | goto cannot_emulate; |
1858 | } | 1854 | } |
1859 | if (test_cc(c->b, ctxt->eflags)) | 1855 | if (test_cc(c->b, ctxt->eflags)) |
1860 | JMP_REL(rel); | 1856 | jmp_rel(c, rel); |
1861 | c->dst.type = OP_NONE; | 1857 | c->dst.type = OP_NONE; |
1862 | break; | 1858 | break; |
1863 | } | 1859 | } |