Skip to content

Commit 7e11eec

Browse files
bonzinisean-jc
authored andcommitted
KVM: x86: Share emulator's common register decoding code
Remove all duplicate handling of register operands, including picking the right register class and fetching it, by extracting a new function that can be used for both REG and MODRM operands. Centralize setting op->orig_val = op->val in fetch_register_operand() as well. No functional change intended. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Chang S. Bae <chang.seok.bae@intel.com> Link: https://patch.msgid.link/20251114003633.60689-6-pbonzini@redhat.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 1a84b07 commit 7e11eec

File tree

1 file changed

+17
-32
lines changed

1 file changed

+17
-32
lines changed

arch/x86/kvm/emulate.c

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,7 @@ static void fetch_register_operand(struct operand *op)
10261026
op->val = *(u64 *)op->addr.reg;
10271027
break;
10281028
}
1029+
op->orig_val = op->val;
10291030
}
10301031

10311032
static int em_fninit(struct x86_emulate_ctxt *ctxt)
@@ -1071,16 +1072,9 @@ static int em_fnstsw(struct x86_emulate_ctxt *ctxt)
10711072
return X86EMUL_CONTINUE;
10721073
}
10731074

1074-
static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
1075-
struct operand *op)
1075+
static void __decode_register_operand(struct x86_emulate_ctxt *ctxt,
1076+
struct operand *op, int reg)
10761077
{
1077-
unsigned int reg;
1078-
1079-
if (ctxt->d & ModRM)
1080-
reg = ctxt->modrm_reg;
1081-
else
1082-
reg = (ctxt->b & 7) | ((ctxt->rex_prefix & 1) << 3);
1083-
10841078
if (ctxt->d & Sse) {
10851079
op->type = OP_XMM;
10861080
op->bytes = 16;
@@ -1099,9 +1093,20 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
10991093
op->type = OP_REG;
11001094
op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
11011095
op->addr.reg = decode_register(ctxt, reg, ctxt->d & ByteOp);
1102-
11031096
fetch_register_operand(op);
1104-
op->orig_val = op->val;
1097+
}
1098+
1099+
static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
1100+
struct operand *op)
1101+
{
1102+
unsigned int reg;
1103+
1104+
if (ctxt->d & ModRM)
1105+
reg = ctxt->modrm_reg;
1106+
else
1107+
reg = (ctxt->b & 7) | ((ctxt->rex_prefix & 1) << 3);
1108+
1109+
__decode_register_operand(ctxt, op, reg);
11051110
}
11061111

11071112
static void adjust_modrm_seg(struct x86_emulate_ctxt *ctxt, int base_reg)
@@ -1128,24 +1133,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
11281133
ctxt->modrm_seg = VCPU_SREG_DS;
11291134

11301135
if (ctxt->modrm_mod == 3 || (ctxt->d & NoMod)) {
1131-
op->type = OP_REG;
1132-
op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
1133-
op->addr.reg = decode_register(ctxt, ctxt->modrm_rm,
1134-
ctxt->d & ByteOp);
1135-
if (ctxt->d & Sse) {
1136-
op->type = OP_XMM;
1137-
op->bytes = 16;
1138-
op->addr.xmm = ctxt->modrm_rm;
1139-
kvm_read_sse_reg(ctxt->modrm_rm, &op->vec_val);
1140-
return rc;
1141-
}
1142-
if (ctxt->d & Mmx) {
1143-
op->type = OP_MM;
1144-
op->bytes = 8;
1145-
op->addr.mm = ctxt->modrm_rm & 7;
1146-
return rc;
1147-
}
1148-
fetch_register_operand(op);
1136+
__decode_register_operand(ctxt, op, ctxt->modrm_rm);
11491137
return rc;
11501138
}
11511139

@@ -4619,14 +4607,12 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
46194607
op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
46204608
op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX);
46214609
fetch_register_operand(op);
4622-
op->orig_val = op->val;
46234610
break;
46244611
case OpAccLo:
46254612
op->type = OP_REG;
46264613
op->bytes = (ctxt->d & ByteOp) ? 2 : ctxt->op_bytes;
46274614
op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX);
46284615
fetch_register_operand(op);
4629-
op->orig_val = op->val;
46304616
break;
46314617
case OpAccHi:
46324618
if (ctxt->d & ByteOp) {
@@ -4637,7 +4623,6 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
46374623
op->bytes = ctxt->op_bytes;
46384624
op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RDX);
46394625
fetch_register_operand(op);
4640-
op->orig_val = op->val;
46414626
break;
46424627
case OpDI:
46434628
op->type = OP_MEM;

0 commit comments

Comments
 (0)