ia64/xen-unstable
changeset 7612:03d51c0b0546
fix VMX decoder for MOVZ instruction.
In VMX decoder, we always assume the 2 operands of x86 instructions are
in the same length, however, MOVZ is an exception.
This patch fixes MOVZ instruction handling.
Signed-off-by: Xin Li <xin.b.li@intel.com>
Signed-off-by: Dan Xu <dan.d.xu@intel.com>
In VMX decoder, we always assume the 2 operands of x86 instructions are
in the same length, however, MOVZ is an exception.
This patch fixes MOVZ instruction handling.
Signed-off-by: Xin Li <xin.b.li@intel.com>
Signed-off-by: Dan Xu <dan.d.xu@intel.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Wed Nov 02 11:19:48 2005 +0100 (2005-11-02) |
parents | c31edd72086d |
children | 89030fab2c3f |
files | xen/arch/x86/vmx_platform.c |
line diff
1.1 --- a/xen/arch/x86/vmx_platform.c Wed Nov 02 11:18:51 2005 +0100 1.2 +++ b/xen/arch/x86/vmx_platform.c Wed Nov 02 11:19:48 2005 +0100 1.3 @@ -303,20 +303,20 @@ static void init_instruction(struct inst 1.4 mmio_inst->flags = 0; 1.5 } 1.6 1.7 -#define GET_OP_SIZE_FOR_BYTE(op_size) \ 1.8 - do { \ 1.9 - if (rex) \ 1.10 - op_size = BYTE_64; \ 1.11 - else \ 1.12 - op_size = BYTE; \ 1.13 +#define GET_OP_SIZE_FOR_BYTE(op_size) \ 1.14 + do { \ 1.15 + if (rex) \ 1.16 + op_size = BYTE_64; \ 1.17 + else \ 1.18 + op_size = BYTE; \ 1.19 } while(0) 1.20 1.21 #define GET_OP_SIZE_FOR_NONEBYTE(op_size) \ 1.22 - do { \ 1.23 - if (rex & 0x8) \ 1.24 - op_size = QUAD; \ 1.25 - else if (op_size != WORD) \ 1.26 - op_size = LONG; \ 1.27 + do { \ 1.28 + if (rex & 0x8) \ 1.29 + op_size = QUAD; \ 1.30 + else if (op_size != WORD) \ 1.31 + op_size = LONG; \ 1.32 } while(0) 1.33 1.34 1.35 @@ -398,8 +398,9 @@ static int vmx_decode(unsigned char *opc 1.36 1.37 case 0x20: /* and r8, m8 */ 1.38 instr->instr = INSTR_AND; 1.39 - GET_OP_SIZE_FOR_BYTE(instr->op_size); 1.40 - return reg_mem(instr->op_size, opcode, instr, rex); 1.41 + instr->op_size = BYTE; 1.42 + GET_OP_SIZE_FOR_BYTE(size_reg); 1.43 + return reg_mem(size_reg, opcode, instr, rex); 1.44 1.45 case 0x21: /* and r32/16, m32/16 */ 1.46 instr->instr = INSTR_AND; 1.47 @@ -413,8 +414,9 @@ static int vmx_decode(unsigned char *opc 1.48 1.49 case 0x30: /* xor r8, m8 */ 1.50 instr->instr = INSTR_XOR; 1.51 - GET_OP_SIZE_FOR_BYTE(instr->op_size); 1.52 - return reg_mem(instr->op_size, opcode, instr, rex); 1.53 + instr->op_size = BYTE; 1.54 + GET_OP_SIZE_FOR_BYTE(size_reg); 1.55 + return reg_mem(size_reg, opcode, instr, rex); 1.56 1.57 case 0x31: /* xor r32/16, m32/16 */ 1.58 instr->instr = INSTR_XOR; 1.59 @@ -592,7 +594,7 @@ static int vmx_decode(unsigned char *opc 1.60 instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER); 1.61 return DECODE_success; 1.62 1.63 - case 0xB7: /* movz m16, r32 */ 1.64 + case 0xB7: /* movz m16/m32, r32/r64 */ 1.65 instr->instr = INSTR_MOVZ; 1.66 index = get_index(opcode + 1, rex); 1.67 if (rex & 0x8) { 1.68 @@ -689,9 +691,9 @@ static void mmio_operands(int type, unsi 1.69 struct mmio_op *mmio_opp, struct cpu_user_regs *regs) 1.70 { 1.71 unsigned long value = 0; 1.72 - int index, size; 1.73 + int index, size_reg; 1.74 1.75 - size = operand_size(inst->operand[0]); 1.76 + size_reg = operand_size(inst->operand[0]); 1.77 1.78 mmio_opp->flags = inst->flags; 1.79 mmio_opp->instr = inst->instr; 1.80 @@ -701,14 +703,17 @@ static void mmio_operands(int type, unsi 1.81 1.82 if (inst->operand[0] & REGISTER) { /* dest is memory */ 1.83 index = operand_index(inst->operand[0]); 1.84 - value = get_reg_value(size, index, 0, regs); 1.85 + value = get_reg_value(size_reg, index, 0, regs); 1.86 send_mmio_req(type, gpa, 1, inst->op_size, value, IOREQ_WRITE, 0); 1.87 } else if (inst->operand[0] & IMMEDIATE) { /* dest is memory */ 1.88 value = inst->immediate; 1.89 send_mmio_req(type, gpa, 1, inst->op_size, value, IOREQ_WRITE, 0); 1.90 } else if (inst->operand[0] & MEMORY) { /* dest is register */ 1.91 /* send the request and wait for the value */ 1.92 - send_mmio_req(type, gpa, 1, inst->op_size, 0, IOREQ_READ, 0); 1.93 + if (inst->instr == INSTR_MOVZ) 1.94 + send_mmio_req(type, gpa, 1, size_reg, 0, IOREQ_READ, 0); 1.95 + else 1.96 + send_mmio_req(type, gpa, 1, inst->op_size, 0, IOREQ_READ, 0); 1.97 } else { 1.98 printf("mmio_operands: invalid operand\n"); 1.99 domain_crash_synchronous();