aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c107
1 files changed, 101 insertions, 6 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 1be5cd640e93..1cdfec5231d0 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -92,19 +92,22 @@ static u32 opcode_table[256] = {
92 /* 0x00 - 0x07 */ 92 /* 0x00 - 0x07 */
93 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 93 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
94 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 94 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
95 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0, 95 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
96 ImplicitOps | Stack, ImplicitOps | Stack,
96 /* 0x08 - 0x0F */ 97 /* 0x08 - 0x0F */
97 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 98 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
98 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 99 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
99 0, 0, 0, 0, 100 0, 0, ImplicitOps | Stack, 0,
100 /* 0x10 - 0x17 */ 101 /* 0x10 - 0x17 */
101 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 102 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
102 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 103 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
103 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0, 104 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
105 ImplicitOps | Stack, ImplicitOps | Stack,
104 /* 0x18 - 0x1F */ 106 /* 0x18 - 0x1F */
105 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 107 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
106 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 108 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
107 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0, 109 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
110 ImplicitOps | Stack, ImplicitOps | Stack,
108 /* 0x20 - 0x27 */ 111 /* 0x20 - 0x27 */
109 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 112 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
110 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 113 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
@@ -244,11 +247,13 @@ static u32 twobyte_table[256] = {
244 /* 0x90 - 0x9F */ 247 /* 0x90 - 0x9F */
245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
246 /* 0xA0 - 0xA7 */ 249 /* 0xA0 - 0xA7 */
247 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 250 ImplicitOps | Stack, ImplicitOps | Stack,
251 0, DstMem | SrcReg | ModRM | BitOp,
248 DstMem | SrcReg | Src2ImmByte | ModRM, 252 DstMem | SrcReg | Src2ImmByte | ModRM,
249 DstMem | SrcReg | Src2CL | ModRM, 0, 0, 253 DstMem | SrcReg | Src2CL | ModRM, 0, 0,
250 /* 0xA8 - 0xAF */ 254 /* 0xA8 - 0xAF */
251 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 255 ImplicitOps | Stack, ImplicitOps | Stack,
256 0, DstMem | SrcReg | ModRM | BitOp,
252 DstMem | SrcReg | Src2ImmByte | ModRM, 257 DstMem | SrcReg | Src2ImmByte | ModRM,
253 DstMem | SrcReg | Src2CL | ModRM, 258 DstMem | SrcReg | Src2CL | ModRM,
254 ModRM, 0, 259 ModRM, 0,
@@ -1186,6 +1191,32 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt,
1186 return rc; 1191 return rc;
1187} 1192}
1188 1193
1194static void emulate_push_sreg(struct x86_emulate_ctxt *ctxt, int seg)
1195{
1196 struct decode_cache *c = &ctxt->decode;
1197 struct kvm_segment segment;
1198
1199 kvm_x86_ops->get_segment(ctxt->vcpu, &segment, seg);
1200
1201 c->src.val = segment.selector;
1202 emulate_push(ctxt);
1203}
1204
1205static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt,
1206 struct x86_emulate_ops *ops, int seg)
1207{
1208 struct decode_cache *c = &ctxt->decode;
1209 unsigned long selector;
1210 int rc;
1211
1212 rc = emulate_pop(ctxt, ops, &selector, c->op_bytes);
1213 if (rc != 0)
1214 return rc;
1215
1216 rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, 1, seg);
1217 return rc;
1218}
1219
1189static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, 1220static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
1190 struct x86_emulate_ops *ops) 1221 struct x86_emulate_ops *ops)
1191{ 1222{
@@ -1707,18 +1738,66 @@ special_insn:
1707 add: /* add */ 1738 add: /* add */
1708 emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags); 1739 emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags);
1709 break; 1740 break;
1741 case 0x06: /* push es */
1742 if (ctxt->mode == X86EMUL_MODE_PROT64)
1743 goto cannot_emulate;
1744
1745 emulate_push_sreg(ctxt, VCPU_SREG_ES);
1746 break;
1747 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 if (rc != 0)
1753 goto done;
1754 break;
1710 case 0x08 ... 0x0d: 1755 case 0x08 ... 0x0d:
1711 or: /* or */ 1756 or: /* or */
1712 emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags); 1757 emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
1713 break; 1758 break;
1759 case 0x0e: /* push cs */
1760 if (ctxt->mode == X86EMUL_MODE_PROT64)
1761 goto cannot_emulate;
1762
1763 emulate_push_sreg(ctxt, VCPU_SREG_CS);
1764 break;
1714 case 0x10 ... 0x15: 1765 case 0x10 ... 0x15:
1715 adc: /* adc */ 1766 adc: /* adc */
1716 emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags); 1767 emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags);
1717 break; 1768 break;
1769 case 0x16: /* push ss */
1770 if (ctxt->mode == X86EMUL_MODE_PROT64)
1771 goto cannot_emulate;
1772
1773 emulate_push_sreg(ctxt, VCPU_SREG_SS);
1774 break;
1775 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);
1780 if (rc != 0)
1781 goto done;
1782 break;
1718 case 0x18 ... 0x1d: 1783 case 0x18 ... 0x1d:
1719 sbb: /* sbb */ 1784 sbb: /* sbb */
1720 emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags); 1785 emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags);
1721 break; 1786 break;
1787 case 0x1e: /* push ds */
1788 if (ctxt->mode == X86EMUL_MODE_PROT64)
1789 goto cannot_emulate;
1790
1791 emulate_push_sreg(ctxt, VCPU_SREG_DS);
1792 break;
1793 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);
1798 if (rc != 0)
1799 goto done;
1800 break;
1722 case 0x20 ... 0x25: 1801 case 0x20 ... 0x25:
1723 and: /* and */ 1802 and: /* and */
1724 emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags); 1803 emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags);
@@ -2297,6 +2376,14 @@ twobyte_insn:
2297 jmp_rel(c, c->src.val); 2376 jmp_rel(c, c->src.val);
2298 c->dst.type = OP_NONE; 2377 c->dst.type = OP_NONE;
2299 break; 2378 break;
2379 case 0xa0: /* push fs */
2380 emulate_push_sreg(ctxt, VCPU_SREG_FS);
2381 break;
2382 case 0xa1: /* pop fs */
2383 rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS);
2384 if (rc != 0)
2385 goto done;
2386 break;
2300 case 0xa3: 2387 case 0xa3:
2301 bt: /* bt */ 2388 bt: /* bt */
2302 c->dst.type = OP_NONE; 2389 c->dst.type = OP_NONE;
@@ -2308,6 +2395,14 @@ twobyte_insn:
2308 case 0xa5: /* shld cl, r, r/m */ 2395 case 0xa5: /* shld cl, r, r/m */
2309 emulate_2op_cl("shld", c->src2, c->src, c->dst, ctxt->eflags); 2396 emulate_2op_cl("shld", c->src2, c->src, c->dst, ctxt->eflags);
2310 break; 2397 break;
2398 case 0xa8: /* push gs */
2399 emulate_push_sreg(ctxt, VCPU_SREG_GS);
2400 break;
2401 case 0xa9: /* pop gs */
2402 rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS);
2403 if (rc != 0)
2404 goto done;
2405 break;
2311 case 0xab: 2406 case 0xab:
2312 bts: /* bts */ 2407 bts: /* bts */
2313 /* only subword offset */ 2408 /* only subword offset */