aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorMohammed Gamal <m.gamal005@gmail.com>2009-09-01 09:28:11 -0400
committerAvi Kivity <avi@redhat.com>2009-12-03 02:32:09 -0500
commitabcf14b560a4ba62c659e6f5aafc8f9934d8c130 (patch)
tree8a150ee04c05b09d5429252b5563b2e142d5283d /arch/x86/kvm/emulate.c
parent94677e61fdcf4cdae11a1b7c8974d7034ef9bd1b (diff)
KVM: x86 emulator: Add pusha and popa instructions
This adds pusha and popa instructions (opcodes 0x60-0x61), this enables booting MINIX with invalid guest state emulation on. [marcelo: remove unused variable] Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index db0820dfbffe..d226dff47d77 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -139,7 +139,8 @@ static u32 opcode_table[256] = {
139 DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, 139 DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
140 DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, 140 DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
141 /* 0x60 - 0x67 */ 141 /* 0x60 - 0x67 */
142 0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ , 142 ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
143 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ ,
143 0, 0, 0, 0, 144 0, 0, 0, 0,
144 /* 0x68 - 0x6F */ 145 /* 0x68 - 0x6F */
145 SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0, 146 SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0,
@@ -1225,6 +1226,43 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt,
1225 return rc; 1226 return rc;
1226} 1227}
1227 1228
1229static void emulate_pusha(struct x86_emulate_ctxt *ctxt)
1230{
1231 struct decode_cache *c = &ctxt->decode;
1232 unsigned long old_esp = c->regs[VCPU_REGS_RSP];
1233 int reg = VCPU_REGS_RAX;
1234
1235 while (reg <= VCPU_REGS_RDI) {
1236 (reg == VCPU_REGS_RSP) ?
1237 (c->src.val = old_esp) : (c->src.val = c->regs[reg]);
1238
1239 emulate_push(ctxt);
1240 ++reg;
1241 }
1242}
1243
1244static int emulate_popa(struct x86_emulate_ctxt *ctxt,
1245 struct x86_emulate_ops *ops)
1246{
1247 struct decode_cache *c = &ctxt->decode;
1248 int rc = 0;
1249 int reg = VCPU_REGS_RDI;
1250
1251 while (reg >= VCPU_REGS_RAX) {
1252 if (reg == VCPU_REGS_RSP) {
1253 register_address_increment(c, &c->regs[VCPU_REGS_RSP],
1254 c->op_bytes);
1255 --reg;
1256 }
1257
1258 rc = emulate_pop(ctxt, ops, &c->regs[reg], c->op_bytes);
1259 if (rc != 0)
1260 break;
1261 --reg;
1262 }
1263 return rc;
1264}
1265
1228static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, 1266static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
1229 struct x86_emulate_ops *ops) 1267 struct x86_emulate_ops *ops)
1230{ 1268{
@@ -1816,6 +1854,14 @@ special_insn:
1816 if (rc != 0) 1854 if (rc != 0)
1817 goto done; 1855 goto done;
1818 break; 1856 break;
1857 case 0x60: /* pusha */
1858 emulate_pusha(ctxt);
1859 break;
1860 case 0x61: /* popa */
1861 rc = emulate_popa(ctxt, ops);
1862 if (rc != 0)
1863 goto done;
1864 break;
1819 case 0x63: /* movsxd */ 1865 case 0x63: /* movsxd */
1820 if (ctxt->mode != X86EMUL_MODE_PROT64) 1866 if (ctxt->mode != X86EMUL_MODE_PROT64)
1821 goto cannot_emulate; 1867 goto cannot_emulate;