aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/emulate.c42
1 files changed, 14 insertions, 28 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 1cdfec5231d0..1f0ff4afa73e 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -75,6 +75,8 @@
75#define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ 75#define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */
76#define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ 76#define GroupDual (1<<15) /* Alternate decoding of mod == 3 */
77#define GroupMask 0xff /* Group number stored in bits 0:7 */ 77#define GroupMask 0xff /* Group number stored in bits 0:7 */
78/* Misc flags */
79#define No64 (1<<28)
78/* Source 2 operand type */ 80/* Source 2 operand type */
79#define Src2None (0<<29) 81#define Src2None (0<<29)
80#define Src2CL (1<<29) 82#define Src2CL (1<<29)
@@ -93,21 +95,21 @@ static u32 opcode_table[256] = {
93 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 95 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
94 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 96 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
95 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 97 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
96 ImplicitOps | Stack, ImplicitOps | Stack, 98 ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
97 /* 0x08 - 0x0F */ 99 /* 0x08 - 0x0F */
98 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 100 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
99 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 101 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
100 0, 0, ImplicitOps | Stack, 0, 102 0, 0, ImplicitOps | Stack | No64, 0,
101 /* 0x10 - 0x17 */ 103 /* 0x10 - 0x17 */
102 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 104 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
103 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 105 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
104 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 106 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
105 ImplicitOps | Stack, ImplicitOps | Stack, 107 ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
106 /* 0x18 - 0x1F */ 108 /* 0x18 - 0x1F */
107 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 109 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
108 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 110 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
109 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 111 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
110 ImplicitOps | Stack, ImplicitOps | Stack, 112 ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
111 /* 0x20 - 0x27 */ 113 /* 0x20 - 0x27 */
112 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 114 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
113 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 115 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
@@ -161,7 +163,7 @@ static u32 opcode_table[256] = {
161 /* 0x90 - 0x97 */ 163 /* 0x90 - 0x97 */
162 DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, 164 DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
163 /* 0x98 - 0x9F */ 165 /* 0x98 - 0x9F */
164 0, 0, SrcImm | Src2Imm16, 0, 166 0, 0, SrcImm | Src2Imm16 | No64, 0,
165 ImplicitOps | Stack, ImplicitOps | Stack, 0, 0, 167 ImplicitOps | Stack, ImplicitOps | Stack, 0, 0,
166 /* 0xA0 - 0xA7 */ 168 /* 0xA0 - 0xA7 */
167 ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs, 169 ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs,
@@ -188,7 +190,7 @@ static u32 opcode_table[256] = {
188 ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov, 190 ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov,
189 /* 0xC8 - 0xCF */ 191 /* 0xC8 - 0xCF */
190 0, 0, 0, ImplicitOps | Stack, 192 0, 0, 0, ImplicitOps | Stack,
191 ImplicitOps, SrcImmByte, ImplicitOps, ImplicitOps, 193 ImplicitOps, SrcImmByte, ImplicitOps | No64, ImplicitOps,
192 /* 0xD0 - 0xD7 */ 194 /* 0xD0 - 0xD7 */
193 ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, 195 ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
194 ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, 196 ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
@@ -201,7 +203,7 @@ static u32 opcode_table[256] = {
201 ByteOp | SrcImmUByte, SrcImmUByte, 203 ByteOp | SrcImmUByte, SrcImmUByte,
202 /* 0xE8 - 0xEF */ 204 /* 0xE8 - 0xEF */
203 SrcImm | Stack, SrcImm | ImplicitOps, 205 SrcImm | Stack, SrcImm | ImplicitOps,
204 SrcImmU | Src2Imm16, SrcImmByte | ImplicitOps, 206 SrcImmU | Src2Imm16 | No64, SrcImmByte | ImplicitOps,
205 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, 207 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
206 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, 208 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
207 /* 0xF0 - 0xF7 */ 209 /* 0xF0 - 0xF7 */
@@ -967,6 +969,11 @@ done_prefixes:
967 } 969 }
968 } 970 }
969 971
972 if (mode == X86EMUL_MODE_PROT64 && (c->d & No64)) {
973 kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction");;
974 return -1;
975 }
976
970 if (c->d & Group) { 977 if (c->d & Group) {
971 group = c->d & GroupMask; 978 group = c->d & GroupMask;
972 c->modrm = insn_fetch(u8, 1, c->eip); 979 c->modrm = insn_fetch(u8, 1, c->eip);
@@ -1739,15 +1746,9 @@ special_insn:
1739 emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags); 1746 emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags);
1740 break; 1747 break;
1741 case 0x06: /* push es */ 1748 case 0x06: /* push es */
1742 if (ctxt->mode == X86EMUL_MODE_PROT64)
1743 goto cannot_emulate;
1744
1745 emulate_push_sreg(ctxt, VCPU_SREG_ES); 1749 emulate_push_sreg(ctxt, VCPU_SREG_ES);
1746 break; 1750 break;
1747 case 0x07: /* pop es */ 1751 case 0x07: /* pop es */
1748 if (ctxt->mode == X86EMUL_MODE_PROT64)
1749 goto cannot_emulate;
1750
1751 rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES); 1752 rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES);
1752 if (rc != 0) 1753 if (rc != 0)
1753 goto done; 1754 goto done;
@@ -1757,9 +1758,6 @@ special_insn:
1757 emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags); 1758 emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
1758 break; 1759 break;
1759 case 0x0e: /* push cs */ 1760 case 0x0e: /* push cs */
1760 if (ctxt->mode == X86EMUL_MODE_PROT64)
1761 goto cannot_emulate;
1762
1763 emulate_push_sreg(ctxt, VCPU_SREG_CS); 1761 emulate_push_sreg(ctxt, VCPU_SREG_CS);
1764 break; 1762 break;
1765 case 0x10 ... 0x15: 1763 case 0x10 ... 0x15:
@@ -1767,15 +1765,9 @@ special_insn:
1767 emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags); 1765 emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags);
1768 break; 1766 break;
1769 case 0x16: /* push ss */ 1767 case 0x16: /* push ss */
1770 if (ctxt->mode == X86EMUL_MODE_PROT64)
1771 goto cannot_emulate;
1772
1773 emulate_push_sreg(ctxt, VCPU_SREG_SS); 1768 emulate_push_sreg(ctxt, VCPU_SREG_SS);
1774 break; 1769 break;
1775 case 0x17: /* pop ss */ 1770 case 0x17: /* pop ss */
1776 if (ctxt->mode == X86EMUL_MODE_PROT64)
1777 goto cannot_emulate;
1778
1779 rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS); 1771 rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS);
1780 if (rc != 0) 1772 if (rc != 0)
1781 goto done; 1773 goto done;
@@ -1785,15 +1777,9 @@ special_insn:
1785 emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags); 1777 emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags);
1786 break; 1778 break;
1787 case 0x1e: /* push ds */ 1779 case 0x1e: /* push ds */
1788 if (ctxt->mode == X86EMUL_MODE_PROT64)
1789 goto cannot_emulate;
1790
1791 emulate_push_sreg(ctxt, VCPU_SREG_DS); 1780 emulate_push_sreg(ctxt, VCPU_SREG_DS);
1792 break; 1781 break;
1793 case 0x1f: /* pop ds */ 1782 case 0x1f: /* pop ds */
1794 if (ctxt->mode == X86EMUL_MODE_PROT64)
1795 goto cannot_emulate;
1796
1797 rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS); 1783 rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS);
1798 if (rc != 0) 1784 if (rc != 0)
1799 goto done; 1785 goto done;