Commit 788abc02 authored by Mohammed Gamal's avatar Mohammed Gamal Committed by Avi Kivity

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.
Signed-off-by: default avatarMohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent ba1d8085
...@@ -139,7 +139,8 @@ static u32 opcode_table[256] = { ...@@ -139,7 +139,8 @@ static u32 opcode_table[256] = {
DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
/* 0x60 - 0x67 */ /* 0x60 - 0x67 */
0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ , ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ ,
0, 0, 0, 0, 0, 0, 0, 0,
/* 0x68 - 0x6F */ /* 0x68 - 0x6F */
SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0, SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0,
...@@ -1225,6 +1226,44 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt, ...@@ -1225,6 +1226,44 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt,
return rc; return rc;
} }
static void emulate_pusha(struct x86_emulate_ctxt *ctxt)
{
struct decode_cache *c = &ctxt->decode;
unsigned long old_esp = c->regs[VCPU_REGS_RSP];
int reg = VCPU_REGS_RAX;
while (reg <= VCPU_REGS_RDI) {
(reg == VCPU_REGS_RSP) ?
(c->src.val = old_esp) : (c->src.val = c->regs[reg]);
emulate_push(ctxt);
++reg;
}
}
static int emulate_popa(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops)
{
struct decode_cache *c = &ctxt->decode;
unsigned long old_esp = c->regs[VCPU_REGS_RSP];
int rc = 0;
int reg = VCPU_REGS_RDI;
while (reg >= VCPU_REGS_RAX) {
if (reg == VCPU_REGS_RSP) {
register_address_increment(c, &c->regs[VCPU_REGS_RSP],
c->op_bytes);
--reg;
}
rc = emulate_pop(ctxt, ops, &c->regs[reg], c->op_bytes);
if (rc != 0)
break;
--reg;
}
return rc;
}
static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops) struct x86_emulate_ops *ops)
{ {
...@@ -1816,6 +1855,14 @@ special_insn: ...@@ -1816,6 +1855,14 @@ special_insn:
if (rc != 0) if (rc != 0)
goto done; goto done;
break; break;
case 0x60: /* pusha */
emulate_pusha(ctxt);
break;
case 0x61: /* popa */
rc = emulate_popa(ctxt, ops);
if (rc != 0)
goto done;
break;
case 0x63: /* movsxd */ case 0x63: /* movsxd */
if (ctxt->mode != X86EMUL_MODE_PROT64) if (ctxt->mode != X86EMUL_MODE_PROT64)
goto cannot_emulate; goto cannot_emulate;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment