aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86_emulate.c
diff options
context:
space:
mode:
authorLaurent Vivier <Laurent.Vivier@bull.net>2007-09-24 05:10:56 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:52:49 -0500
commita01af5ec5163cdc51c00f6dcb22d7766199377cf (patch)
tree36ff10826f39b643736542957a980c37c4ad6fb1 /drivers/kvm/x86_emulate.c
parent05f086f87ef17da70d5f4e9b063e9ea31ab20f28 (diff)
KVM: x86 emulator: Remove no_wb, use dst.type = OP_NONE instead
Remove no_wb, use dst.type = OP_NONE instead, idea stollen from xen-3.1 Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r--drivers/kvm/x86_emulate.c76
1 files changed, 24 insertions, 52 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 76b813b6365c..6161e3f66585 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -1016,8 +1016,7 @@ done:
1016} 1016}
1017 1017
1018static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, 1018static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
1019 struct x86_emulate_ops *ops, 1019 struct x86_emulate_ops *ops)
1020 int *no_wb)
1021{ 1020{
1022 struct decode_cache *c = &ctxt->decode; 1021 struct decode_cache *c = &ctxt->decode;
1023 int rc; 1022 int rc;
@@ -1055,7 +1054,7 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
1055 c->dst.bytes, ctxt->vcpu); 1054 c->dst.bytes, ctxt->vcpu);
1056 if (rc != 0) 1055 if (rc != 0)
1057 return rc; 1056 return rc;
1058 *no_wb = 1; 1057 c->dst.type = OP_NONE;
1059 break; 1058 break;
1060 default: 1059 default:
1061 DPRINTF("Cannot emulate %02x\n", c->b); 1060 DPRINTF("Cannot emulate %02x\n", c->b);
@@ -1137,6 +1136,10 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
1137 ctxt->vcpu); 1136 ctxt->vcpu);
1138 if (rc != 0) 1137 if (rc != 0)
1139 return rc; 1138 return rc;
1139 break;
1140 case OP_NONE:
1141 /* no writeback */
1142 break;
1140 default: 1143 default:
1141 break; 1144 break;
1142 } 1145 }
@@ -1147,7 +1150,6 @@ int
1147x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) 1150x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1148{ 1151{
1149 unsigned long cr2 = ctxt->cr2; 1152 unsigned long cr2 = ctxt->cr2;
1150 int no_wb = 0;
1151 u64 msr_data; 1153 u64 msr_data;
1152 unsigned long saved_eip = 0; 1154 unsigned long saved_eip = 0;
1153 struct decode_cache *c = &ctxt->decode; 1155 struct decode_cache *c = &ctxt->decode;
@@ -1344,18 +1346,16 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1344 goto done; 1346 goto done;
1345 break; 1347 break;
1346 case 0xfe ... 0xff: /* Grp4/Grp5 */ 1348 case 0xfe ... 0xff: /* Grp4/Grp5 */
1347 rc = emulate_grp45(ctxt, ops, &no_wb); 1349 rc = emulate_grp45(ctxt, ops);
1348 if (rc != 0) 1350 if (rc != 0)
1349 goto done; 1351 goto done;
1350 break; 1352 break;
1351 } 1353 }
1352 1354
1353writeback: 1355writeback:
1354 if (!no_wb) { 1356 rc = writeback(ctxt, ops);
1355 rc = writeback(ctxt, ops); 1357 if (rc != 0)
1356 if (rc != 0) 1358 goto done;
1357 goto done;
1358 }
1359 1359
1360 /* Commit shadow register state. */ 1360 /* Commit shadow register state. */
1361 memcpy(ctxt->vcpu->regs, c->regs, sizeof c->regs); 1361 memcpy(ctxt->vcpu->regs, c->regs, sizeof c->regs);
@@ -1395,7 +1395,7 @@ special_insn:
1395 1395
1396 register_address_increment(c->regs[VCPU_REGS_RSP], 1396 register_address_increment(c->regs[VCPU_REGS_RSP],
1397 c->op_bytes); 1397 c->op_bytes);
1398 no_wb = 1; /* Disable writeback. */ 1398 c->dst.type = OP_NONE; /* Disable writeback. */
1399 break; 1399 break;
1400 case 0x6a: /* push imm8 */ 1400 case 0x6a: /* push imm8 */
1401 c->src.val = 0L; 1401 c->src.val = 0L;
@@ -1538,7 +1538,7 @@ special_insn:
1538 case 0xe9: /* jmp rel */ 1538 case 0xe9: /* jmp rel */
1539 case 0xeb: /* jmp rel short */ 1539 case 0xeb: /* jmp rel short */
1540 JMP_REL(c->src.val); 1540 JMP_REL(c->src.val);
1541 no_wb = 1; /* Disable writeback. */ 1541 c->dst.type = OP_NONE; /* Disable writeback. */
1542 break; 1542 break;
1543 1543
1544 1544
@@ -1548,8 +1548,6 @@ special_insn:
1548twobyte_insn: 1548twobyte_insn:
1549 switch (c->b) { 1549 switch (c->b) {
1550 case 0x01: /* lgdt, lidt, lmsw */ 1550 case 0x01: /* lgdt, lidt, lmsw */
1551 /* Disable writeback. */
1552 no_wb = 1;
1553 switch (c->modrm_reg) { 1551 switch (c->modrm_reg) {
1554 u16 size; 1552 u16 size;
1555 unsigned long address; 1553 unsigned long address;
@@ -1604,56 +1602,30 @@ twobyte_insn:
1604 default: 1602 default:
1605 goto cannot_emulate; 1603 goto cannot_emulate;
1606 } 1604 }
1605 /* Disable writeback. */
1606 c->dst.type = OP_NONE;
1607 break; 1607 break;
1608 case 0x21: /* mov from dr to reg */ 1608 case 0x21: /* mov from dr to reg */
1609 no_wb = 1;
1610 if (c->modrm_mod != 3) 1609 if (c->modrm_mod != 3)
1611 goto cannot_emulate; 1610 goto cannot_emulate;
1612 rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]); 1611 rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]);
1612 if (rc)
1613 goto cannot_emulate;
1614 c->dst.type = OP_NONE; /* no writeback */
1613 break; 1615 break;
1614 case 0x23: /* mov from reg to dr */ 1616 case 0x23: /* mov from reg to dr */
1615 no_wb = 1;
1616 if (c->modrm_mod != 3) 1617 if (c->modrm_mod != 3)
1617 goto cannot_emulate; 1618 goto cannot_emulate;
1618 rc = emulator_set_dr(ctxt, c->modrm_reg, 1619 rc = emulator_set_dr(ctxt, c->modrm_reg,
1619 c->regs[c->modrm_rm]); 1620 c->regs[c->modrm_rm]);
1621 if (rc)
1622 goto cannot_emulate;
1623 c->dst.type = OP_NONE; /* no writeback */
1620 break; 1624 break;
1621 case 0x40 ... 0x4f: /* cmov */ 1625 case 0x40 ... 0x4f: /* cmov */
1622 c->dst.val = c->dst.orig_val = c->src.val; 1626 c->dst.val = c->dst.orig_val = c->src.val;
1623 no_wb = 1; 1627 if (!test_cc(c->b, ctxt->eflags))
1624 /* 1628 c->dst.type = OP_NONE; /* no writeback */
1625 * First, assume we're decoding an even cmov opcode
1626 * (lsb == 0).
1627 */
1628 switch ((c->b & 15) >> 1) {
1629 case 0: /* cmovo */
1630 no_wb = (ctxt->eflags & EFLG_OF) ? 0 : 1;
1631 break;
1632 case 1: /* cmovb/cmovc/cmovnae */
1633 no_wb = (ctxt->eflags & EFLG_CF) ? 0 : 1;
1634 break;
1635 case 2: /* cmovz/cmove */
1636 no_wb = (ctxt->eflags & EFLG_ZF) ? 0 : 1;
1637 break;
1638 case 3: /* cmovbe/cmovna */
1639 no_wb = (ctxt->eflags & (EFLG_CF | EFLG_ZF)) ? 0 : 1;
1640 break;
1641 case 4: /* cmovs */
1642 no_wb = (ctxt->eflags & EFLG_SF) ? 0 : 1;
1643 break;
1644 case 5: /* cmovp/cmovpe */
1645 no_wb = (ctxt->eflags & EFLG_PF) ? 0 : 1;
1646 break;
1647 case 7: /* cmovle/cmovng */
1648 no_wb = (ctxt->eflags & EFLG_ZF) ? 0 : 1;
1649 /* fall through */
1650 case 6: /* cmovl/cmovnge */
1651 no_wb &= (!(ctxt->eflags & EFLG_SF) !=
1652 !(ctxt->eflags & EFLG_OF)) ? 0 : 1;
1653 break;
1654 }
1655 /* Odd cmov opcodes (lsb == 1) have inverted sense. */
1656 no_wb ^= c->b & 1;
1657 break; 1629 break;
1658 case 0xa3: 1630 case 0xa3:
1659 bt: /* bt */ 1631 bt: /* bt */
@@ -1727,8 +1699,6 @@ twobyte_insn:
1727 goto writeback; 1699 goto writeback;
1728 1700
1729twobyte_special_insn: 1701twobyte_special_insn:
1730 /* Disable writeback. */
1731 no_wb = 1;
1732 switch (c->b) { 1702 switch (c->b) {
1733 case 0x06: 1703 case 0x06:
1734 emulate_clts(ctxt->vcpu); 1704 emulate_clts(ctxt->vcpu);
@@ -1802,6 +1772,8 @@ twobyte_special_insn:
1802 goto done; 1772 goto done;
1803 break; 1773 break;
1804 } 1774 }
1775 /* Disable writeback. */
1776 c->dst.type = OP_NONE;
1805 goto writeback; 1777 goto writeback;
1806 1778
1807cannot_emulate: 1779cannot_emulate: