aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/emulate.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 33ccd757cb11..7552c0ac6e76 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -974,6 +974,12 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
974 op->orig_val = op->val; 974 op->orig_val = op->val;
975} 975}
976 976
977static 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
977static int decode_modrm(struct x86_emulate_ctxt *ctxt, 983static int decode_modrm(struct x86_emulate_ctxt *ctxt,
978 struct operand *op) 984 struct operand *op)
979{ 985{
@@ -1077,15 +1083,20 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
1077 1083
1078 if ((base_reg & 7) == 5 && ctxt->modrm_mod == 0) 1084 if ((base_reg & 7) == 5 && ctxt->modrm_mod == 0)
1079 modrm_ea += insn_fetch(s32, ctxt); 1085 modrm_ea += insn_fetch(s32, ctxt);
1080 else 1086 else {
1081 modrm_ea += ctxt->regs[base_reg]; 1087 modrm_ea += ctxt->regs[base_reg];
1088 adjust_modrm_seg(ctxt, base_reg);
1089 }
1082 if (index_reg != 4) 1090 if (index_reg != 4)
1083 modrm_ea += ctxt->regs[index_reg] << scale; 1091 modrm_ea += ctxt->regs[index_reg] << scale;
1084 } else if ((ctxt->modrm_rm & 7) == 5 && ctxt->modrm_mod == 0) { 1092 } else if ((ctxt->modrm_rm & 7) == 5 && ctxt->modrm_mod == 0) {
1085 if (ctxt->mode == X86EMUL_MODE_PROT64) 1093 if (ctxt->mode == X86EMUL_MODE_PROT64)
1086 ctxt->rip_relative = 1; 1094 ctxt->rip_relative = 1;
1087 } else 1095 } else {
1088 modrm_ea += ctxt->regs[ctxt->modrm_rm]; 1096 base_reg = ctxt->modrm_rm;
1097 modrm_ea += ctxt->regs[base_reg];
1098 adjust_modrm_seg(ctxt, base_reg);
1099 }
1089 switch (ctxt->modrm_mod) { 1100 switch (ctxt->modrm_mod) {
1090 case 0: 1101 case 0:
1091 if (ctxt->modrm_rm == 5) 1102 if (ctxt->modrm_rm == 5)