Skip to content

Commit a6e3407

Browse files
committed
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 <[email protected]>
1 parent cbd27ee commit a6e3407

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

arch/x86/kvm/emulate.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,12 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
974974
op->orig_val = op->val;
975975
}
976976

977+
static void adjust_modrm_seg(struct x86_emulate_ctxt *ctxt, int base_reg)
978+
{
979+
if (base_reg == VCPU_REGS_RSP || base_reg == VCPU_REGS_RBP)
980+
ctxt->modrm_seg = VCPU_SREG_SS;
981+
}
982+
977983
static int decode_modrm(struct x86_emulate_ctxt *ctxt,
978984
struct operand *op)
979985
{
@@ -1077,15 +1083,20 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
10771083

10781084
if ((base_reg & 7) == 5 && ctxt->modrm_mod == 0)
10791085
modrm_ea += insn_fetch(s32, ctxt);
1080-
else
1086+
else {
10811087
modrm_ea += ctxt->regs[base_reg];
1088+
adjust_modrm_seg(ctxt, base_reg);
1089+
}
10821090
if (index_reg != 4)
10831091
modrm_ea += ctxt->regs[index_reg] << scale;
10841092
} else if ((ctxt->modrm_rm & 7) == 5 && ctxt->modrm_mod == 0) {
10851093
if (ctxt->mode == X86EMUL_MODE_PROT64)
10861094
ctxt->rip_relative = 1;
1087-
} else
1088-
modrm_ea += ctxt->regs[ctxt->modrm_rm];
1095+
} else {
1096+
base_reg = ctxt->modrm_rm;
1097+
modrm_ea += ctxt->regs[base_reg];
1098+
adjust_modrm_seg(ctxt, base_reg);
1099+
}
10891100
switch (ctxt->modrm_mod) {
10901101
case 0:
10911102
if (ctxt->modrm_rm == 5)

0 commit comments

Comments
 (0)