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>
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();