KVM: Fix SS default ESP/EBP based addressing
We correctly default to SS when BP is used as a base in 16-bit address mode, but we don't do that for 32-bit mode. Fix by adjusting the default to SS when either ESP or EBP is used as the base register. Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
cbd27ee783
commit
a6e3407bb1
1 changed files with 14 additions and 3 deletions
|
@ -974,6 +974,12 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
|
|||
op->orig_val = op->val;
|
||||
}
|
||||
|
||||
static void adjust_modrm_seg(struct x86_emulate_ctxt *ctxt, int base_reg)
|
||||
{
|
||||
if (base_reg == VCPU_REGS_RSP || base_reg == VCPU_REGS_RBP)
|
||||
ctxt->modrm_seg = VCPU_SREG_SS;
|
||||
}
|
||||
|
||||
static int decode_modrm(struct x86_emulate_ctxt *ctxt,
|
||||
struct operand *op)
|
||||
{
|
||||
|
@ -1077,15 +1083,20 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
|
|||
|
||||
if ((base_reg & 7) == 5 && ctxt->modrm_mod == 0)
|
||||
modrm_ea += insn_fetch(s32, ctxt);
|
||||
else
|
||||
else {
|
||||
modrm_ea += ctxt->regs[base_reg];
|
||||
adjust_modrm_seg(ctxt, base_reg);
|
||||
}
|
||||
if (index_reg != 4)
|
||||
modrm_ea += ctxt->regs[index_reg] << scale;
|
||||
} else if ((ctxt->modrm_rm & 7) == 5 && ctxt->modrm_mod == 0) {
|
||||
if (ctxt->mode == X86EMUL_MODE_PROT64)
|
||||
ctxt->rip_relative = 1;
|
||||
} else
|
||||
modrm_ea += ctxt->regs[ctxt->modrm_rm];
|
||||
} else {
|
||||
base_reg = ctxt->modrm_rm;
|
||||
modrm_ea += ctxt->regs[base_reg];
|
||||
adjust_modrm_seg(ctxt, base_reg);
|
||||
}
|
||||
switch (ctxt->modrm_mod) {
|
||||
case 0:
|
||||
if (ctxt->modrm_rm == 5)
|
||||
|
|
Loading…
Reference in a new issue