debuggers.hg
changeset 13647:21b9416d2215
emulator: Start filling in gaps for privileged instructions.
Signed-off-by: Keir Fraser <keir@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kfraser@localhost.localdomain |
---|---|
date | Thu Jan 25 15:25:06 2007 +0000 (2007-01-25) |
parents | 0843e4261753 |
children | fec1a6975588 |
files | xen/arch/x86/x86_emulate.c |
line diff
1.1 --- a/xen/arch/x86/x86_emulate.c Thu Jan 25 14:52:36 2007 +0000 1.2 +++ b/xen/arch/x86/x86_emulate.c Thu Jan 25 15:25:06 2007 +0000 1.3 @@ -162,22 +162,29 @@ static uint8_t opcode_table[256] = { 1.4 0, 0, 0, 0, 1.5 0, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM, 1.6 /* 0xF8 - 0xFF */ 1.7 - ImplicitOps, ImplicitOps, 0, 0, 1.8 + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 1.9 ImplicitOps, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM 1.10 }; 1.11 1.12 static uint8_t twobyte_table[256] = { 1.13 - /* 0x00 - 0x0F */ 1.14 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 1.15 + /* 0x00 - 0x07 */ 1.16 + 0, 0, 0, 0, 0, ImplicitOps, 0, 0, 1.17 + /* 0x08 - 0x0F */ 1.18 + ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 1.19 /* 0x10 - 0x17 */ 1.20 0, 0, 0, 0, 0, 0, 0, 0, 1.21 /* 0x18 - 0x1F */ 1.22 ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, 1.23 ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, 1.24 - /* 0x20 - 0x2F */ 1.25 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.26 - /* 0x30 - 0x3F */ 1.27 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.28 + /* 0x20 - 0x27 */ 1.29 + ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, 1.30 + 0, 0, 0, 0, 1.31 + /* 0x28 - 0x2F */ 1.32 + 0, 0, 0, 0, 0, 0, 0, 0, 1.33 + /* 0x30 - 0x37 */ 1.34 + ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, 0, 1.35 + /* 0x38 - 0x3F */ 1.36 + 0, 0, 0, 0, 0, 0, 0, 0, 1.37 /* 0x40 - 0x47 */ 1.38 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, 1.39 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, 1.40 @@ -255,6 +262,7 @@ struct operand { 1.41 /* EFLAGS bit definitions. */ 1.42 #define EFLG_OF (1<<11) 1.43 #define EFLG_DF (1<<10) 1.44 +#define EFLG_IF (1<<9) 1.45 #define EFLG_SF (1<<7) 1.46 #define EFLG_ZF (1<<6) 1.47 #define EFLG_AF (1<<4) 1.48 @@ -463,6 +471,10 @@ do { 1.49 /* In future we will be able to generate arbitrary exceptions. */ 1.50 #define generate_exception_if(p, e) fail_if(p) 1.51 1.52 +/* To be done... */ 1.53 +#define mode_ring0() (0) 1.54 +#define mode_iopl() (0) 1.55 + 1.56 /* Given byte has even parity (even number of 1s)? */ 1.57 static int even_parity(uint8_t v) 1.58 { 1.59 @@ -1554,10 +1566,13 @@ x86_emulate( 1.60 dst.type = OP_NONE; 1.61 1.62 /* 1.63 - * The only implicit-operands instruction allowed a LOCK prefix is 1.64 - * CMPXCHG{8,16}B. 1.65 + * The only implicit-operands instructions allowed a LOCK prefix are 1.66 + * CMPXCHG{8,16}B, MOV CRn, MOV DRn. 1.67 */ 1.68 - generate_exception_if(lock_prefix && (b != 0xc7), EXC_GP); 1.69 + generate_exception_if(lock_prefix && 1.70 + ((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */ 1.71 + (b != 0xc7), /* CMPXCHG{8,16}B */ 1.72 + EXC_GP); 1.73 1.74 if ( twobyte ) 1.75 goto twobyte_special_insn; 1.76 @@ -1933,6 +1948,20 @@ x86_emulate( 1.77 _regs.eflags |= EFLG_CF; 1.78 break; 1.79 1.80 + case 0xfa: /* cli */ 1.81 + generate_exception_if(!mode_iopl(), EXC_GP); 1.82 + fail_if(ops->write_rflags == NULL); 1.83 + if ( (rc = ops->write_rflags(_regs.eflags & ~EFLG_IF, ctxt)) != 0 ) 1.84 + goto done; 1.85 + break; 1.86 + 1.87 + case 0xfb: /* sti */ 1.88 + generate_exception_if(!mode_iopl(), EXC_GP); 1.89 + fail_if(ops->write_rflags == NULL); 1.90 + if ( (rc = ops->write_rflags(_regs.eflags | EFLG_IF, ctxt)) != 0 ) 1.91 + goto done; 1.92 + break; 1.93 + 1.94 case 0xfc: /* cld */ 1.95 _regs.eflags &= ~EFLG_DF; 1.96 break; 1.97 @@ -2089,11 +2118,86 @@ x86_emulate( 1.98 twobyte_special_insn: 1.99 switch ( b ) 1.100 { 1.101 + case 0x06: /* clts */ 1.102 + generate_exception_if(!mode_ring0(), EXC_GP); 1.103 + fail_if((ops->read_cr == NULL) || (ops->write_cr == NULL)); 1.104 + if ( (rc = ops->read_cr(0, &dst.val, ctxt)) || 1.105 + (rc = ops->write_cr(0, dst.val|8, ctxt)) ) 1.106 + goto done; 1.107 + break; 1.108 + 1.109 + case 0x08: /* invd */ 1.110 + case 0x09: /* wbinvd */ 1.111 + generate_exception_if(!mode_ring0(), EXC_GP); 1.112 + fail_if(ops->wbinvd == NULL); 1.113 + if ( (rc = ops->wbinvd(ctxt)) != 0 ) 1.114 + goto done; 1.115 + break; 1.116 + 1.117 case 0x0d: /* GrpP (prefetch) */ 1.118 case 0x18: /* Grp16 (prefetch/nop) */ 1.119 case 0x19 ... 0x1f: /* nop (amd-defined) */ 1.120 break; 1.121 1.122 + case 0x20: /* mov cr,reg */ 1.123 + case 0x21: /* mov dr,reg */ 1.124 + case 0x22: /* mov reg,cr */ 1.125 + case 0x23: /* mov reg,dr */ 1.126 + generate_exception_if(!mode_ring0(), EXC_GP); 1.127 + modrm_rm |= (rex_prefix & 1) << 3; 1.128 + modrm_reg |= lock_prefix << 3; 1.129 + if ( b & 2 ) 1.130 + { 1.131 + /* Write to CR/DR. */ 1.132 + src.val = *(unsigned long *)decode_register(modrm_rm, &_regs, 0); 1.133 + if ( !mode_64bit() ) 1.134 + src.val = (uint32_t)src.val; 1.135 + rc = ((b & 1) 1.136 + ? (ops->write_dr 1.137 + ? ops->write_dr(modrm_reg, src.val, ctxt) 1.138 + : X86EMUL_UNHANDLEABLE) 1.139 + : (ops->write_cr 1.140 + ? ops->write_dr(modrm_reg, src.val, ctxt) 1.141 + : X86EMUL_UNHANDLEABLE)); 1.142 + } 1.143 + else 1.144 + { 1.145 + /* Read from CR/DR. */ 1.146 + dst.type = OP_REG; 1.147 + dst.bytes = mode_64bit() ? 8 : 4; 1.148 + dst.reg = decode_register(modrm_rm, &_regs, 0); 1.149 + rc = ((b & 1) 1.150 + ? (ops->read_dr 1.151 + ? ops->read_dr(modrm_reg, &dst.val, ctxt) 1.152 + : X86EMUL_UNHANDLEABLE) 1.153 + : (ops->read_cr 1.154 + ? ops->read_dr(modrm_reg, &dst.val, ctxt) 1.155 + : X86EMUL_UNHANDLEABLE)); 1.156 + } 1.157 + if ( rc != 0 ) 1.158 + goto done; 1.159 + break; 1.160 + 1.161 + case 0x30: /* wrmsr */ { 1.162 + uint64_t val = ((uint64_t)_regs.edx << 32) | (uint32_t)_regs.eax; 1.163 + generate_exception_if(!mode_ring0(), EXC_GP); 1.164 + fail_if(ops->write_msr == NULL); 1.165 + if ( (rc = ops->write_msr((uint32_t)_regs.ecx, val, ctxt)) != 0 ) 1.166 + goto done; 1.167 + break; 1.168 + } 1.169 + 1.170 + case 0x32: /* rdmsr */ { 1.171 + uint64_t val; 1.172 + generate_exception_if(!mode_ring0(), EXC_GP); 1.173 + fail_if(ops->read_msr == NULL); 1.174 + if ( (rc = ops->read_msr((uint32_t)_regs.ecx, &val, ctxt)) != 0 ) 1.175 + goto done; 1.176 + _regs.edx = (uint32_t)(val >> 32); 1.177 + _regs.eax = (uint32_t)(val >> 0); 1.178 + break; 1.179 + } 1.180 + 1.181 case 0x80 ... 0x8f: /* jcc (near) */ { 1.182 int rel = (((op_bytes == 2) && !mode_64bit()) 1.183 ? (int32_t)insn_fetch_type(int16_t)