aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/x86_emulate.c56
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) \ 504static inline void
505 do { \ 505register_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) \ 513static 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
522static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, 518static 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 }