diff options
author | Gleb Natapov <gleb@redhat.com> | 2013-11-04 08:52:41 -0500 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-11-05 02:11:18 -0500 |
commit | aa9ac1a6323d21065e121902fef4f1b6c07c37c7 (patch) | |
tree | 8d2691f0b1633519595db3b3244b3a84a1bae46a /arch/x86 | |
parent | 95f328d3ad1a8e4e3175a18546fb35c495e31130 (diff) |
KVM: emulator: check rex prefix inside decode_register()
All decode_register() callers check if instruction has rex prefix
to properly decode one byte operand. It make sense to move the check
inside.
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kvm/emulate.c | 18 |
1 files changed, 7 insertions, 11 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 282d28cb9931..0bd372f3c989 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -785,9 +785,10 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, | |||
785 | * @highbyte_regs specifies whether to decode AH,CH,DH,BH. | 785 | * @highbyte_regs specifies whether to decode AH,CH,DH,BH. |
786 | */ | 786 | */ |
787 | static void *decode_register(struct x86_emulate_ctxt *ctxt, u8 modrm_reg, | 787 | static void *decode_register(struct x86_emulate_ctxt *ctxt, u8 modrm_reg, |
788 | int highbyte_regs) | 788 | int byteop) |
789 | { | 789 | { |
790 | void *p; | 790 | void *p; |
791 | int highbyte_regs = (ctxt->rex_prefix == 0) && byteop; | ||
791 | 792 | ||
792 | if (highbyte_regs && modrm_reg >= 4 && modrm_reg < 8) | 793 | if (highbyte_regs && modrm_reg >= 4 && modrm_reg < 8) |
793 | p = (unsigned char *)reg_rmw(ctxt, modrm_reg & 3) + 1; | 794 | p = (unsigned char *)reg_rmw(ctxt, modrm_reg & 3) + 1; |
@@ -1024,7 +1025,6 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt, | |||
1024 | struct operand *op) | 1025 | struct operand *op) |
1025 | { | 1026 | { |
1026 | unsigned reg = ctxt->modrm_reg; | 1027 | unsigned reg = ctxt->modrm_reg; |
1027 | int highbyte_regs = ctxt->rex_prefix == 0; | ||
1028 | 1028 | ||
1029 | if (!(ctxt->d & ModRM)) | 1029 | if (!(ctxt->d & ModRM)) |
1030 | reg = (ctxt->b & 7) | ((ctxt->rex_prefix & 1) << 3); | 1030 | reg = (ctxt->b & 7) | ((ctxt->rex_prefix & 1) << 3); |
@@ -1046,10 +1046,10 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt, | |||
1046 | 1046 | ||
1047 | op->type = OP_REG; | 1047 | op->type = OP_REG; |
1048 | if (ctxt->d & ByteOp) { | 1048 | if (ctxt->d & ByteOp) { |
1049 | op->addr.reg = decode_register(ctxt, reg, highbyte_regs); | 1049 | op->addr.reg = decode_register(ctxt, reg, true); |
1050 | op->bytes = 1; | 1050 | op->bytes = 1; |
1051 | } else { | 1051 | } else { |
1052 | op->addr.reg = decode_register(ctxt, reg, 0); | 1052 | op->addr.reg = decode_register(ctxt, reg, false); |
1053 | op->bytes = ctxt->op_bytes; | 1053 | op->bytes = ctxt->op_bytes; |
1054 | } | 1054 | } |
1055 | fetch_register_operand(op); | 1055 | fetch_register_operand(op); |
@@ -1082,12 +1082,10 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, | |||
1082 | ctxt->modrm_seg = VCPU_SREG_DS; | 1082 | ctxt->modrm_seg = VCPU_SREG_DS; |
1083 | 1083 | ||
1084 | if (ctxt->modrm_mod == 3) { | 1084 | if (ctxt->modrm_mod == 3) { |
1085 | int highbyte_regs = ctxt->rex_prefix == 0; | ||
1086 | |||
1087 | op->type = OP_REG; | 1085 | op->type = OP_REG; |
1088 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; | 1086 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; |
1089 | op->addr.reg = decode_register(ctxt, ctxt->modrm_rm, | 1087 | op->addr.reg = decode_register(ctxt, ctxt->modrm_rm, |
1090 | highbyte_regs && (ctxt->d & ByteOp)); | 1088 | ctxt->d & ByteOp); |
1091 | if (ctxt->d & Sse) { | 1089 | if (ctxt->d & Sse) { |
1092 | op->type = OP_XMM; | 1090 | op->type = OP_XMM; |
1093 | op->bytes = 16; | 1091 | op->bytes = 16; |
@@ -4117,10 +4115,8 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, | |||
4117 | case OpMem8: | 4115 | case OpMem8: |
4118 | ctxt->memop.bytes = 1; | 4116 | ctxt->memop.bytes = 1; |
4119 | if (ctxt->memop.type == OP_REG) { | 4117 | if (ctxt->memop.type == OP_REG) { |
4120 | int highbyte_regs = ctxt->rex_prefix == 0; | 4118 | ctxt->memop.addr.reg = decode_register(ctxt, |
4121 | 4119 | ctxt->modrm_rm, true); | |
4122 | ctxt->memop.addr.reg = decode_register(ctxt, ctxt->modrm_rm, | ||
4123 | highbyte_regs); | ||
4124 | fetch_register_operand(&ctxt->memop); | 4120 | fetch_register_operand(&ctxt->memop); |
4125 | } | 4121 | } |
4126 | goto mem_common; | 4122 | goto mem_common; |