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>
This commit is contained in:
committed by
Avi Kivity
parent
94677e61fd
commit
abcf14b560
@@ -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,43 @@ 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;
|
||||||
|
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 +1854,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;
|
||||||
|
Reference in New Issue
Block a user