direct-io.hg

changeset 5555:94893eb31f44

bitkeeper revision 1.1737 (42ba86724fSOFpp6L107qJDWXNKxug)

Attached is the patch with
1. Cleanup of code & correct error handling for MMIO
instructions.
2. Decoding of 64bit instructions for MMIO.


Signed-Off-By: Chengyuan Li <chengyuan.li@intel.com>
Signed-Off-By: Yunhong Jiang <hunhong.jiang@intel.com>
Signed-Off-By: Jun Nakajima <jun.nakajima@intel.com>
Signed-Off-By: Nitin A Kamble <nitin.a.kamble@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Jun 23 09:52:50 2005 +0000 (2005-06-23)
parents 90d851ff9036
children 80b60ef3f553
files tools/ioemu/exec.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_platform.c xen/include/asm-x86/vmx_platform.h
line diff
     1.1 --- a/tools/ioemu/exec.c	Thu Jun 23 09:50:16 2005 +0000
     1.2 +++ b/tools/ioemu/exec.c	Thu Jun 23 09:52:50 2005 +0000
     1.3 @@ -386,6 +386,9 @@ void cpu_physical_memory_rw(target_phys_
     1.4                      io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
     1.5                      l = 2;
     1.6                  } else {
     1.7 +                    if (l!=1){
     1.8 +                        fprintf(logfile, "ERROR 8 bit mmio\n");
     1.9 +                    }
    1.10                      /* 8 bit access */
    1.11                      val = ldub_raw(buf);
    1.12                      io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
     2.1 --- a/xen/arch/x86/vmx_io.c	Thu Jun 23 09:50:16 2005 +0000
     2.2 +++ b/xen/arch/x86/vmx_io.c	Thu Jun 23 09:52:50 2005 +0000
     2.3 @@ -86,7 +86,8 @@ static void set_reg_value (int size, int
     2.4              regs->ebx |= ((value & 0xFF) << 8);
     2.5              break;
     2.6          default:
     2.7 -            printk("size:%x, index:%x are invalid!\n", size, index);
     2.8 +            printk("Error: size:%x, index:%x are invalid!\n", size, index);
     2.9 +            domain_crash_synchronous();
    2.10              break;
    2.11  
    2.12          }
    2.13 @@ -127,7 +128,8 @@ static void set_reg_value (int size, int
    2.14              regs->edi |= (value & 0xFFFF);
    2.15              break;
    2.16          default:
    2.17 -            printk("size:%x, index:%x are invalid!\n", size, index);
    2.18 +            printk("Error: size:%x, index:%x are invalid!\n", size, index);
    2.19 +            domain_crash_synchronous();
    2.20              break;
    2.21          }
    2.22          break;
    2.23 @@ -158,25 +160,150 @@ static void set_reg_value (int size, int
    2.24              regs->edi = value;
    2.25              break;
    2.26          default:
    2.27 -            printk("size:%x, index:%x are invalid!\n", size, index);
    2.28 +            printk("Error: size:%x, index:%x are invalid!\n", size, index);
    2.29 +            domain_crash_synchronous();
    2.30              break;
    2.31          }
    2.32          break;
    2.33      default:
    2.34 -        printk("size:%x, index:%x are invalid!\n", size, index);
    2.35 +        printk("Error: size:%x, index:%x are invalid!\n", size, index);
    2.36 +        domain_crash_synchronous();
    2.37          break;
    2.38      }
    2.39  }
    2.40  #else
    2.41  static void load_cpu_user_regs(struct cpu_user_regs *regs)
    2.42 -{ 
    2.43 -	/* XXX: TBD */
    2.44 -	return;
    2.45 +{
    2.46 +    __vmwrite(GUEST_SS_SELECTOR, regs->ss);
    2.47 +    __vmwrite(GUEST_RSP, regs->rsp);
    2.48 +    __vmwrite(GUEST_RFLAGS, regs->rflags);
    2.49 +    __vmwrite(GUEST_CS_SELECTOR, regs->cs);
    2.50 +    __vmwrite(GUEST_RIP, regs->rip);
    2.51  }
    2.52 +
    2.53 +static inline void __set_reg_value(long *reg, int size, long value)
    2.54 +{
    2.55 +    switch (size) {
    2.56 +        case BYTE_64:
    2.57 +            *reg &= ~0xFF;
    2.58 +            *reg |= (value & 0xFF);
    2.59 +            break;
    2.60 +        case WORD:
    2.61 +            *reg &= ~0xFFFF;
    2.62 +            *reg |= (value & 0xFFFF);
    2.63 +            break;
    2.64 +
    2.65 +        case LONG:
    2.66 +            *reg &= ~0xFFFFFFFF;
    2.67 +            *reg |= (value & 0xFFFFFFFF);
    2.68 +            break;
    2.69 +        case QUAD:
    2.70 +            *reg = value;
    2.71 +            break;
    2.72 +        default:
    2.73 +            printk("Error: <__set_reg_value> : Unknown size for register\n");
    2.74 +            domain_crash_synchronous();
    2.75 +    }
    2.76 +}
    2.77 +
    2.78  static void set_reg_value (int size, int index, int seg, struct cpu_user_regs *regs, long value)
    2.79  {
    2.80 -	/* XXX: TBD */
    2.81 -	return;
    2.82 +    if (size == BYTE) {
    2.83 +        switch (index) {
    2.84 +            case 0:
    2.85 +                regs->rax &= ~0xFF;
    2.86 +                regs->rax |= (value & 0xFF);
    2.87 +                break;
    2.88 +            case 1:
    2.89 +                regs->rcx &= ~0xFF;
    2.90 +                regs->rcx |= (value & 0xFF);
    2.91 +                break;
    2.92 +            case 2:
    2.93 +                regs->rdx &= ~0xFF;
    2.94 +                regs->rdx |= (value & 0xFF);
    2.95 +                break;
    2.96 +            case 3:
    2.97 +                regs->rbx &= ~0xFF;
    2.98 +                regs->rbx |= (value & 0xFF);
    2.99 +                break;
   2.100 +            case 4:
   2.101 +                regs->rax &= 0xFFFFFFFFFFFF00FF;
   2.102 +                regs->rax |= ((value & 0xFF) << 8);
   2.103 +                break;
   2.104 +            case 5:
   2.105 +                regs->rcx &= 0xFFFFFFFFFFFF00FF;
   2.106 +                regs->rcx |= ((value & 0xFF) << 8);
   2.107 +                break;
   2.108 +            case 6:
   2.109 +                regs->rdx &= 0xFFFFFFFFFFFF00FF;
   2.110 +                regs->rdx |= ((value & 0xFF) << 8);
   2.111 +                break;
   2.112 +            case 7:
   2.113 +                regs->rbx &= 0xFFFFFFFFFFFF00FF;
   2.114 +                regs->rbx |= ((value & 0xFF) << 8);
   2.115 +                break;
   2.116 +            default:
   2.117 +                printk("Error: size:%x, index:%x are invalid!\n", size, index);
   2.118 +                domain_crash_synchronous();
   2.119 +                break;
   2.120 +        }
   2.121 +
   2.122 +    }
   2.123 +
   2.124 +    switch (index) {
   2.125 +        case 0: 
   2.126 +            __set_reg_value(&regs->rax, size, value);
   2.127 +            break;
   2.128 +        case 1: 
   2.129 +            __set_reg_value(&regs->rcx, size, value);
   2.130 +            break;
   2.131 +        case 2: 
   2.132 +            __set_reg_value(&regs->rdx, size, value);
   2.133 +            break;
   2.134 +        case 3: 
   2.135 +            __set_reg_value(&regs->rbx, size, value);
   2.136 +            break;
   2.137 +        case 4: 
   2.138 +            __set_reg_value(&regs->rsp, size, value);
   2.139 +            break;
   2.140 +        case 5: 
   2.141 +            __set_reg_value(&regs->rbp, size, value);
   2.142 +            break;
   2.143 +        case 6: 
   2.144 +            __set_reg_value(&regs->rsi, size, value);
   2.145 +            break;
   2.146 +        case 7: 
   2.147 +            __set_reg_value(&regs->rdi, size, value);
   2.148 +            break;
   2.149 +        case 8: 
   2.150 +            __set_reg_value(&regs->r8, size, value);
   2.151 +            break;
   2.152 +        case 9: 
   2.153 +            __set_reg_value(&regs->r9, size, value);
   2.154 +            break;
   2.155 +        case 10: 
   2.156 +            __set_reg_value(&regs->r10, size, value);
   2.157 +            break;
   2.158 +        case 11: 
   2.159 +            __set_reg_value(&regs->r11, size, value);
   2.160 +            break;
   2.161 +        case 12: 
   2.162 +            __set_reg_value(&regs->r12, size, value);
   2.163 +            break;
   2.164 +        case 13: 
   2.165 +            __set_reg_value(&regs->r13, size, value);
   2.166 +            break;
   2.167 +        case 14: 
   2.168 +            __set_reg_value(&regs->r14, size, value);
   2.169 +            break;
   2.170 +        case 15: 
   2.171 +            __set_reg_value(&regs->r15, size, value);
   2.172 +            break;
   2.173 +        default:
   2.174 +            printk("Error: <set_reg_value> Invalid index\n");
   2.175 +            domain_crash_synchronous();
   2.176 +    }
   2.177 +    return;
   2.178  }
   2.179  #endif
   2.180  
   2.181 @@ -269,7 +396,8 @@ void vmx_io_assist(struct vcpu *v)
   2.182          regs->eax = (p->u.data & 0xffffffff);
   2.183          break;
   2.184      default:
   2.185 -        BUG();
   2.186 +        printk("Error: %s unknwon port size\n", __FUNCTION__);
   2.187 +        domain_crash_synchronous();
   2.188      }
   2.189  }
   2.190  
     3.1 --- a/xen/arch/x86/vmx_platform.c	Thu Jun 23 09:50:16 2005 +0000
     3.2 +++ b/xen/arch/x86/vmx_platform.c	Thu Jun 23 09:52:50 2005 +0000
     3.3 @@ -41,12 +41,79 @@
     3.4  #if defined (__x86_64__)
     3.5  void store_cpu_user_regs(struct cpu_user_regs *regs)
     3.6  {
     3.7 +    __vmread(GUEST_SS_SELECTOR, &regs->ss);
     3.8 +    __vmread(GUEST_RSP, &regs->rsp);
     3.9 +    __vmread(GUEST_RFLAGS, &regs->rflags);
    3.10 +    __vmread(GUEST_CS_SELECTOR, &regs->cs);
    3.11 +    __vmread(GUEST_DS_SELECTOR, &regs->ds);
    3.12 +    __vmread(GUEST_ES_SELECTOR, &regs->es);
    3.13 +    __vmread(GUEST_RIP, &regs->rip);
    3.14 +}
    3.15  
    3.16 +static inline long __get_reg_value(unsigned long reg, int size)
    3.17 +{
    3.18 +    switch(size) {
    3.19 +        case BYTE_64:
    3.20 +            return (char)(reg & 0xFF);
    3.21 +        case WORD:
    3.22 +            return (short)(reg & 0xFFFF);
    3.23 +        case LONG:
    3.24 +            return (int)(reg & 0xFFFFFFFF);
    3.25 +        case QUAD:
    3.26 +            return (long)(reg);
    3.27 +        default:
    3.28 +            printk("Error: <__get_reg_value>Invalid reg size\n");
    3.29 +            domain_crash_synchronous();
    3.30 +    }
    3.31  }
    3.32  
    3.33  static long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs) 
    3.34  {
    3.35 -    return 0;
    3.36 +    if (size == BYTE) {
    3.37 +        switch (index) { 
    3.38 +            case 0: //%al
    3.39 +                return (char)(regs->rax & 0xFF);
    3.40 +            case 1: //%cl  
    3.41 +                return (char)(regs->rcx & 0xFF);
    3.42 +            case 2: //%dl
    3.43 +                return (char)(regs->rdx & 0xFF); 
    3.44 +            case 3: //%bl
    3.45 +                return (char)(regs->rbx & 0xFF);
    3.46 +            case 4: //%ah
    3.47 +                return (char)((regs->rax & 0xFF00) >> 8);
    3.48 +            case 5: //%ch 
    3.49 +                return (char)((regs->rcx & 0xFF00) >> 8);
    3.50 +            case 6: //%dh
    3.51 +                return (char)((regs->rdx & 0xFF00) >> 8);
    3.52 +            case 7: //%bh
    3.53 +                return (char)((regs->rbx & 0xFF00) >> 8);
    3.54 +            default:
    3.55 +                printk("Error: (get_reg_value)Invalid index value\n"); 
    3.56 +                domain_crash_synchronous();
    3.57 +        }
    3.58 +
    3.59 +    }
    3.60 +    switch (index) {
    3.61 +        case 0: return __get_reg_value(regs->rax, size);
    3.62 +        case 1: return __get_reg_value(regs->rcx, size);
    3.63 +        case 2: return __get_reg_value(regs->rdx, size);
    3.64 +        case 3: return __get_reg_value(regs->rbx, size);
    3.65 +        case 4: return __get_reg_value(regs->rsp, size);
    3.66 +        case 5: return __get_reg_value(regs->rbp, size);
    3.67 +        case 6: return __get_reg_value(regs->rsi, size);
    3.68 +        case 7: return __get_reg_value(regs->rdi, size);
    3.69 +        case 8: return __get_reg_value(regs->r8, size);
    3.70 +        case 9: return __get_reg_value(regs->r9, size);
    3.71 +        case 10: return __get_reg_value(regs->r10, size);
    3.72 +        case 11: return __get_reg_value(regs->r11, size);
    3.73 +        case 12: return __get_reg_value(regs->r12, size);
    3.74 +        case 13: return __get_reg_value(regs->r13, size);
    3.75 +        case 14: return __get_reg_value(regs->r14, size);
    3.76 +        case 15: return __get_reg_value(regs->r15, size);
    3.77 +        default:
    3.78 +            printk("Error: (get_reg_value)Invalid index value\n"); 
    3.79 +            domain_crash_synchronous();
    3.80 +    }
    3.81  }
    3.82  #elif defined (__i386__)
    3.83  void store_cpu_user_regs(struct cpu_user_regs *regs)
    3.84 @@ -85,8 +152,8 @@ static long get_reg_value(int size, int 
    3.85          case 7: //%bh
    3.86              return (char)((regs->ebx & 0xFF00) >> 8);
    3.87          default:
    3.88 -            printk("(get_reg_value)size case 0 error\n"); 
    3.89 -            return -1; 
    3.90 +            printk("Error: (get_reg_value)size case 0 error\n"); 
    3.91 +            domain_crash_synchronous();
    3.92          }
    3.93      case WORD:
    3.94          switch (index) {
    3.95 @@ -108,8 +175,8 @@ static long get_reg_value(int size, int 
    3.96          case 7: //%di
    3.97              return (short)(regs->edi & 0xFFFF);
    3.98          default:
    3.99 -            printk("(get_reg_value)size case 1 error\n");
   3.100 -            return -1;
   3.101 +            printk("Error: (get_reg_value)size case 1 error\n");
   3.102 +            domain_crash_synchronous();
   3.103          }
   3.104      case LONG:
   3.105          switch (index) {
   3.106 @@ -131,42 +198,47 @@ static long get_reg_value(int size, int 
   3.107          case 7: //%edi
   3.108              return regs->edi;
   3.109          default:
   3.110 -            printk("(get_reg_value)size case 2 error\n");
   3.111 -            return -1;
   3.112 +            printk("Error: (get_reg_value)size case 2 error\n");
   3.113 +            domain_crash_synchronous();
   3.114          }
   3.115      default:
   3.116 -        printk("(get_reg_value)size case error\n");
   3.117 -        return -1;
   3.118 +        printk("Error: (get_reg_value)size case error\n");
   3.119 +        domain_crash_synchronous();
   3.120      }
   3.121  }
   3.122  #endif
   3.123  
   3.124 -static inline unsigned char *check_prefix(unsigned char *inst, struct instruction *thread_inst)
   3.125 +static inline const unsigned char *check_prefix(const unsigned char *inst, struct instruction *thread_inst, unsigned char *rex_p)
   3.126  {
   3.127      while (1) {
   3.128          switch (*inst) {
   3.129 +            /* rex prefix for em64t instructions*/
   3.130 +            case 0x40 ... 0x4e:
   3.131 +                *rex_p = *inst;
   3.132 +                break;
   3.133 +
   3.134              case 0xf3: //REPZ
   3.135 -	    	thread_inst->flags = REPZ;
   3.136 -		break;
   3.137 +    	    	thread_inst->flags = REPZ;
   3.138 +	        	break;
   3.139              case 0xf2: //REPNZ
   3.140 -	    	thread_inst->flags = REPNZ;
   3.141 -		break;
   3.142 +    	    	thread_inst->flags = REPNZ;
   3.143 +	        	break;
   3.144              case 0xf0: //LOCK
   3.145 -	    	break;
   3.146 +    	    	break;
   3.147              case 0x2e: //CS
   3.148              case 0x36: //SS
   3.149              case 0x3e: //DS
   3.150              case 0x26: //ES
   3.151              case 0x64: //FS
   3.152              case 0x65: //GS
   3.153 -		thread_inst->seg_sel = *inst;
   3.154 +		        thread_inst->seg_sel = *inst;
   3.155                  break;
   3.156              case 0x66: //32bit->16bit
   3.157                  thread_inst->op_size = WORD;
   3.158                  break;
   3.159              case 0x67:
   3.160 -		printf("Not handling 0x67 (yet)\n");
   3.161 -		domain_crash_synchronous(); 
   3.162 +	        	printf("Error: Not handling 0x67 (yet)\n");
   3.163 +                domain_crash_synchronous();
   3.164                  break;
   3.165              default:
   3.166                  return inst;
   3.167 @@ -193,9 +265,9 @@ static inline unsigned long get_immediat
   3.168      switch(mod) {
   3.169          case 0:
   3.170              if (rm == 5) {
   3.171 -		if (op16)
   3.172 +                if (op16)
   3.173                      inst = inst + 2; //disp16, skip 2 bytes
   3.174 -		else
   3.175 +                else
   3.176                      inst = inst + 4; //disp32, skip 4 bytes
   3.177              }
   3.178              break;
   3.179 @@ -203,44 +275,81 @@ static inline unsigned long get_immediat
   3.180              inst++; //disp8, skip 1 byte
   3.181              break;
   3.182          case 2:
   3.183 -	    if (op16)
   3.184 +            if (op16)
   3.185                  inst = inst + 2; //disp16, skip 2 bytes
   3.186 -	    else
   3.187 +            else
   3.188                  inst = inst + 4; //disp32, skip 4 bytes
   3.189              break;
   3.190      }
   3.191 +
   3.192 +    if (op_size == QUAD)
   3.193 +        op_size = LONG;
   3.194 +
   3.195      for (i = 0; i < op_size; i++) {
   3.196          val |= (*inst++ & 0xff) << (8 * i);
   3.197      }
   3.198 -    
   3.199 +
   3.200      return val;
   3.201  }
   3.202  
   3.203 -static inline int get_index(const unsigned char *inst)
   3.204 +static inline int get_index(const unsigned char *inst, unsigned char rex)
   3.205  {
   3.206      int mod, reg, rm;
   3.207 +    int rex_r, rex_b;
   3.208  
   3.209      mod = (*inst >> 6) & 3;
   3.210      reg = (*inst >> 3) & 7;
   3.211      rm = *inst & 7;
   3.212  
   3.213 +    rex_r = (rex >> 2) & 1;
   3.214 +    rex_b = rex & 1;
   3.215 +
   3.216      //Only one operand in the instruction is register
   3.217      if (mod == 3) {
   3.218 -        return rm;
   3.219 +        return (rm + (rex_b << 3)); 
   3.220      } else {
   3.221 -        return reg;
   3.222 +        return (reg + (rex_r << 3)); 
   3.223      }
   3.224      return 0;
   3.225  }
   3.226  
   3.227 +static void init_instruction(struct instruction *mmio_inst)
   3.228 +{
   3.229 +    memset(mmio_inst->i_name, '0', I_NAME_LEN);
   3.230 +    mmio_inst->op_size =  0;
   3.231 +    mmio_inst->offset = 0;
   3.232 +    mmio_inst->immediate = 0;
   3.233 +    mmio_inst->seg_sel = 0;
   3.234 +    mmio_inst->op_num = 0;
   3.235 +
   3.236 +    mmio_inst->operand[0] = 0;
   3.237 +    mmio_inst->operand[1] = 0;
   3.238 +    mmio_inst->operand[2] = 0;
   3.239 +        
   3.240 +    mmio_inst->flags = 0;
   3.241 +}
   3.242 +
   3.243 +#define GET_OP_SIZE_FOR_BYTE(op_size)   \
   3.244 +    do {if (rex) op_size = BYTE_64;else op_size = BYTE;} while(0)
   3.245 +
   3.246 +#define GET_OP_SIZE_FOR_NONEBYTE(op_size)   \
   3.247 +    do {if (rex & 0x8) op_size = QUAD; else if (op_size != WORD) op_size = LONG;} while(0)
   3.248 +
   3.249  static int vmx_decode(const unsigned char *inst, struct instruction *thread_inst)
   3.250  {
   3.251      unsigned long eflags;
   3.252      int index, vm86 = 0;
   3.253 +    unsigned char rex = 0;
   3.254 +    unsigned char tmp_size = 0;
   3.255 +
   3.256 +
   3.257 +    init_instruction(thread_inst);
   3.258 +
   3.259 +    inst = check_prefix(inst, thread_inst, &rex);
   3.260  
   3.261      __vmread(GUEST_RFLAGS, &eflags);
   3.262      if (eflags & X86_EFLAGS_VM)
   3.263 -	vm86 = 1;
   3.264 +        vm86 = 1;
   3.265  
   3.266      if (vm86) { /* meaning is reversed */
   3.267         if (thread_inst->op_size == WORD)
   3.268 @@ -255,34 +364,30 @@ static int vmx_decode(const unsigned cha
   3.269          case 0x88:
   3.270              /* mov r8 to m8 */
   3.271              thread_inst->op_size = BYTE;
   3.272 -            index = get_index((inst + 1));
   3.273 -            thread_inst->operand[0] = mk_operand(BYTE, index, 0, REGISTER);
   3.274 +            index = get_index((inst + 1), rex);
   3.275 +            GET_OP_SIZE_FOR_BYTE(tmp_size);
   3.276 +            thread_inst->operand[0] = mk_operand(tmp_size, index, 0, REGISTER);
   3.277 +
   3.278              break;
   3.279          case 0x89:
   3.280              /* mov r32/16 to m32/16 */
   3.281 -            index = get_index((inst + 1));
   3.282 -            if (thread_inst->op_size == WORD) {
   3.283 -                thread_inst->operand[0] = mk_operand(WORD, index, 0, REGISTER);
   3.284 -            } else {
   3.285 -                thread_inst->op_size = LONG;
   3.286 -                thread_inst->operand[0] = mk_operand(LONG, index, 0, REGISTER);
   3.287 -            }
   3.288 +            index = get_index((inst + 1), rex);
   3.289 +            GET_OP_SIZE_FOR_NONEBYTE(thread_inst->op_size);
   3.290 +            thread_inst->operand[0] = mk_operand(thread_inst->op_size, index, 0, REGISTER);
   3.291 +
   3.292              break;
   3.293          case 0x8a:
   3.294              /* mov m8 to r8 */
   3.295              thread_inst->op_size = BYTE;
   3.296 -            index = get_index((inst + 1));
   3.297 -            thread_inst->operand[1] = mk_operand(BYTE, index, 0, REGISTER);
   3.298 +            index = get_index((inst + 1), rex);
   3.299 +            GET_OP_SIZE_FOR_BYTE(tmp_size);
   3.300 +            thread_inst->operand[1] = mk_operand(tmp_size, index, 0, REGISTER);
   3.301              break;
   3.302          case 0x8b:
   3.303              /* mov r32/16 to m32/16 */
   3.304 -            index = get_index((inst + 1));
   3.305 -            if (thread_inst->op_size == WORD) {
   3.306 -                thread_inst->operand[1] = mk_operand(WORD, index, 0, REGISTER);
   3.307 -            } else {
   3.308 -                thread_inst->op_size = LONG;
   3.309 -                thread_inst->operand[1] = mk_operand(LONG, index, 0, REGISTER);
   3.310 -            }
   3.311 +            index = get_index((inst + 1), rex);
   3.312 +            GET_OP_SIZE_FOR_NONEBYTE(thread_inst->op_size);
   3.313 +            thread_inst->operand[1] = mk_operand(thread_inst->op_size, index, 0, REGISTER);
   3.314              break;
   3.315          case 0x8c:
   3.316          case 0x8e:
   3.317 @@ -292,30 +397,25 @@ static int vmx_decode(const unsigned cha
   3.318          case 0xa0:
   3.319              /* mov byte to al */
   3.320              thread_inst->op_size = BYTE;
   3.321 -            thread_inst->operand[1] = mk_operand(BYTE, 0, 0, REGISTER);
   3.322 +            GET_OP_SIZE_FOR_BYTE(tmp_size);
   3.323 +            thread_inst->operand[1] = mk_operand(tmp_size, 0, 0, REGISTER);
   3.324              break;
   3.325          case 0xa1:
   3.326              /* mov word/doubleword to ax/eax */
   3.327 -            if (thread_inst->op_size == WORD) {
   3.328 -                thread_inst->operand[1] = mk_operand(WORD, 0, 0, REGISTER);
   3.329 -            } else {
   3.330 -                thread_inst->op_size = LONG;
   3.331 -                thread_inst->operand[1] = mk_operand(LONG, 0, 0, REGISTER);
   3.332 -            }
   3.333 +	    GET_OP_SIZE_FOR_NONEBYTE(thread_inst->op_size);
   3.334 +	    thread_inst->operand[1] = mk_operand(thread_inst->op_size, 0, 0, REGISTER);
   3.335 +
   3.336              break;
   3.337          case 0xa2:
   3.338              /* mov al to (seg:offset) */
   3.339              thread_inst->op_size = BYTE;
   3.340 -            thread_inst->operand[0] = mk_operand(BYTE, 0, 0, REGISTER);
   3.341 +            GET_OP_SIZE_FOR_BYTE(tmp_size);
   3.342 +            thread_inst->operand[0] = mk_operand(tmp_size, 0, 0, REGISTER);
   3.343              break;
   3.344          case 0xa3:
   3.345              /* mov ax/eax to (seg:offset) */
   3.346 -            if (thread_inst->op_size == WORD) {
   3.347 -                thread_inst->operand[0] = mk_operand(WORD, 0, 0, REGISTER);
   3.348 -            } else {
   3.349 -                thread_inst->op_size = LONG;
   3.350 -                thread_inst->operand[0] = mk_operand(LONG, 0, 0, REGISTER);
   3.351 -            }
   3.352 +            GET_OP_SIZE_FOR_NONEBYTE(thread_inst->op_size);
   3.353 +            thread_inst->operand[0] = mk_operand(thread_inst->op_size, 0, 0, REGISTER);
   3.354              break;
   3.355          case 0xa4:
   3.356              /* movsb */
   3.357 @@ -324,11 +424,8 @@ static int vmx_decode(const unsigned cha
   3.358              return DECODE_success;
   3.359          case 0xa5:
   3.360              /* movsw/movsl */
   3.361 -            if (thread_inst->op_size == WORD) {
   3.362 -            } else {
   3.363 -                thread_inst->op_size = LONG;
   3.364 -            }
   3.365 -            strcpy((char *)thread_inst->i_name, "movs");
   3.366 +            GET_OP_SIZE_FOR_NONEBYTE(thread_inst->op_size);
   3.367 +	    strcpy((char *)thread_inst->i_name, "movs");
   3.368              return DECODE_success;
   3.369          case 0xaa:
   3.370              /* stosb */
   3.371 @@ -353,14 +450,10 @@ static int vmx_decode(const unsigned cha
   3.372              break;
   3.373          case 0xc7:
   3.374              /* mov imm16/32 to m16/32 */
   3.375 -            if (thread_inst->op_size == WORD) {
   3.376 -                thread_inst->operand[0] = mk_operand(WORD, 0, 0, IMMEDIATE);
   3.377 -            } else {
   3.378 -                thread_inst->op_size = LONG;
   3.379 -                thread_inst->operand[0] = mk_operand(LONG, 0, 0, IMMEDIATE);
   3.380 -            }
   3.381 -            thread_inst->immediate = get_immediate(vm86,
   3.382 -					(inst+1), thread_inst->op_size);
   3.383 +            GET_OP_SIZE_FOR_NONEBYTE(thread_inst->op_size);
   3.384 +            thread_inst->operand[0] = mk_operand(thread_inst->op_size, 0, 0, IMMEDIATE);
   3.385 +            thread_inst->immediate = get_immediate(vm86, (inst+1), thread_inst->op_size);
   3.386 +            
   3.387              break;
   3.388          case 0x0f:
   3.389              break;
   3.390 @@ -379,21 +472,23 @@ static int vmx_decode(const unsigned cha
   3.391                      
   3.392          /* movz */
   3.393          case 0xb6:
   3.394 -            index = get_index((inst + 1));
   3.395 -            if (thread_inst->op_size == WORD) {
   3.396 -                thread_inst->operand[1] = mk_operand(WORD, index, 0, REGISTER);
   3.397 -            } else {
   3.398 -                thread_inst->operand[1] = mk_operand(LONG, index, 0, REGISTER);
   3.399 -                
   3.400 -            }
   3.401 +            index = get_index((inst + 1), rex);
   3.402 +            GET_OP_SIZE_FOR_NONEBYTE(thread_inst->op_size);
   3.403 +            thread_inst->operand[1] = mk_operand(thread_inst->op_size, index, 0, REGISTER);
   3.404              thread_inst->op_size = BYTE;
   3.405              strcpy((char *)thread_inst->i_name, "movzb");
   3.406              
   3.407              return DECODE_success;
   3.408          case 0xb7:
   3.409 -            thread_inst->op_size = WORD;
   3.410 -            index = get_index((inst + 1));
   3.411 -            thread_inst->operand[1] = mk_operand(LONG, index, 0, REGISTER);
   3.412 +	    index = get_index((inst + 1), rex);
   3.413 +	    if (rex & 0x8) {
   3.414 +		    thread_inst->op_size = LONG;
   3.415 +		    thread_inst->operand[1] = mk_operand(QUAD, index, 0, REGISTER);
   3.416 +	    } else {
   3.417 +		    thread_inst->op_size = WORD;
   3.418 +		    thread_inst->operand[1] = mk_operand(LONG, index, 0, REGISTER);
   3.419 +	    }
   3.420 +            
   3.421              strcpy((char *)thread_inst->i_name, "movzw");
   3.422              
   3.423              return DECODE_success;
   3.424 @@ -406,8 +501,7 @@ static int vmx_decode(const unsigned cha
   3.425      return DECODE_failure;
   3.426  }
   3.427  
   3.428 -int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
   3.429 -                         int inst_len)
   3.430 +int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, int inst_len)
   3.431  {
   3.432      l1_pgentry_t gpte;
   3.433      unsigned long mfn;
   3.434 @@ -449,22 +543,6 @@ int inst_copy_from_guest(unsigned char *
   3.435      return inst_len+remaining;
   3.436  }
   3.437  
   3.438 -static void init_instruction(struct instruction *mmio_inst)
   3.439 -{
   3.440 -    memset(mmio_inst->i_name, '0', I_NAME_LEN);
   3.441 -    mmio_inst->op_size =  0;
   3.442 -    mmio_inst->offset = 0;
   3.443 -    mmio_inst->immediate = 0;
   3.444 -    mmio_inst->seg_sel = 0;
   3.445 -    mmio_inst->op_num = 0;
   3.446 -
   3.447 -    mmio_inst->operand[0] = 0;
   3.448 -    mmio_inst->operand[1] = 0;
   3.449 -    mmio_inst->operand[2] = 0;
   3.450 -        
   3.451 -    mmio_inst->flags = 0;
   3.452 -}
   3.453 -
   3.454  static int read_from_mmio(struct instruction *inst_p)
   3.455  {
   3.456      // Only for mov instruction now!!!
   3.457 @@ -570,17 +648,10 @@ void handle_mmio(unsigned long va, unsig
   3.458          domain_crash_synchronous();
   3.459      }
   3.460  
   3.461 -#if 0
   3.462 -    printk("handle_mmio: cs:eip 0x%lx:0x%lx(0x%lx): opcode",
   3.463 -        cs, eip, inst_addr, inst_len);
   3.464 -    for (ret = 0; ret < inst_len; ret++)
   3.465 -        printk(" %02x", inst[ret]);
   3.466 -    printk("\n");
   3.467 -#endif
   3.468  
   3.469      init_instruction(&mmio_inst);
   3.470      
   3.471 -    if (vmx_decode(check_prefix(inst, &mmio_inst), &mmio_inst) == DECODE_failure)
   3.472 +    if (vmx_decode(inst, &mmio_inst) == DECODE_failure)
   3.473          domain_crash_synchronous();
   3.474  
   3.475      __vmwrite(GUEST_RIP, eip + inst_len);
   3.476 @@ -654,8 +725,8 @@ void handle_mmio(unsigned long va, unsig
   3.477      }
   3.478  
   3.479      if (!strncmp((char *)mmio_inst.i_name, "stos", 4)) {
   3.480 -	send_mmio_req(gpa, &mmio_inst,
   3.481 -		inst_decoder_regs->eax, IOREQ_WRITE, 0);
   3.482 +        send_mmio_req(gpa, &mmio_inst,
   3.483 +            inst_decoder_regs->eax, IOREQ_WRITE, 0);
   3.484      }
   3.485  
   3.486      domain_crash_synchronous();
     4.1 --- a/xen/include/asm-x86/vmx_platform.h	Thu Jun 23 09:50:16 2005 +0000
     4.2 +++ b/xen/include/asm-x86/vmx_platform.h	Thu Jun 23 09:52:50 2005 +0000
     4.3 @@ -40,6 +40,7 @@
     4.4  #define WORD    2
     4.5  #define LONG    4
     4.6  #define QUAD    8
     4.7 +#define BYTE_64 16
     4.8  
     4.9        //For instruction.operand[].flag
    4.10  #define REGISTER    0x1