1/* 2 * Fault Injection Test harness (FI) 3 * Copyright (C) Intel Crop. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 18 * USA. 19 * 20 */ 21 22/* Id: pf_in.c,v 1.1.1.1 2002/11/12 05:56:32 brlock Exp 23 * Copyright by Intel Crop., 2002 24 * Louis Zhuang (louis.zhuang@intel.com) 25 * 26 * Bjorn Steinbrink (B.Steinbrink@gmx.de), 2007 27 */ 28 29#include <linux/module.h> 30#include <linux/ptrace.h> /* struct pt_regs */ 31#include "pf_in.h" 32 33#ifdef __i386__ 34/* IA32 Manual 3, 2-1 */ 35static unsigned char prefix_codes[] = { 36 0xF0, 0xF2, 0xF3, 0x2E, 0x36, 0x3E, 0x26, 0x64, 37 0x65, 0x66, 0x67 38}; 39/* IA32 Manual 3, 3-432*/ 40static unsigned int reg_rop[] = { 41 0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F 42}; 43static unsigned int reg_wop[] = { 0x88, 0x89, 0xAA, 0xAB }; 44static unsigned int imm_wop[] = { 0xC6, 0xC7 }; 45/* IA32 Manual 3, 3-432*/ 46static unsigned int rw8[] = { 0x88, 0x8A, 0xC6, 0xAA }; 47static unsigned int rw32[] = { 48 0x89, 0x8B, 0xC7, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F, 0xAB 49}; 50static unsigned int mw8[] = { 0x88, 0x8A, 0xC6, 0xB60F, 0xBE0F, 0xAA }; 51static unsigned int mw16[] = { 0xB70F, 0xBF0F }; 52static unsigned int mw32[] = { 0x89, 0x8B, 0xC7, 0xAB }; 53static unsigned int mw64[] = {}; 54#else /* not __i386__ */ 55static unsigned char prefix_codes[] = { 56 0x66, 0x67, 0x2E, 0x3E, 0x26, 0x64, 0x65, 0x36, 57 0xF0, 0xF3, 0xF2, 58 /* REX Prefixes */ 59 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 60 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f 61}; 62/* AMD64 Manual 3, Appendix A*/ 63static unsigned int reg_rop[] = { 64 0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F 65}; 66static unsigned int reg_wop[] = { 0x88, 0x89, 0xAA, 0xAB }; 67static unsigned int imm_wop[] = { 0xC6, 0xC7 }; 68static unsigned int rw8[] = { 0xC6, 0x88, 0x8A, 0xAA }; 69static unsigned int rw32[] = { 70 0xC7, 0x89, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F, 0xAB 71}; 72/* 8 bit only */ 73static unsigned int mw8[] = { 0xC6, 0x88, 0x8A, 0xB60F, 0xBE0F, 0xAA }; 74/* 16 bit only */ 75static unsigned int mw16[] = { 0xB70F, 0xBF0F }; 76/* 16 or 32 bit */ 77static unsigned int mw32[] = { 0xC7 }; 78/* 16, 32 or 64 bit */ 79static unsigned int mw64[] = { 0x89, 0x8B, 0xAB }; 80#endif /* not __i386__ */ 81 82struct prefix_bits { 83 unsigned shorted:1; 84 unsigned enlarged:1; 85 unsigned rexr:1; 86 unsigned rex:1; 87}; 88 89static int skip_prefix(unsigned char *addr, struct prefix_bits *prf) 90{ 91 int i; 92 unsigned char *p = addr; 93 prf->shorted = 0; 94 prf->enlarged = 0; 95 prf->rexr = 0; 96 prf->rex = 0; 97 98restart: 99 for (i = 0; i < ARRAY_SIZE(prefix_codes); i++) { 100 if (*p == prefix_codes[i]) { 101 if (*p == 0x66) 102 prf->shorted = 1; 103#ifdef __amd64__ 104 if ((*p & 0xf8) == 0x48) 105 prf->enlarged = 1; 106 if ((*p & 0xf4) == 0x44) 107 prf->rexr = 1; 108 if ((*p & 0xf0) == 0x40) 109 prf->rex = 1; 110#endif 111 p++; 112 goto restart; 113 } 114 } 115 116 return (p - addr); 117} 118 119static int get_opcode(unsigned char *addr, unsigned int *opcode) 120{ 121 int len; 122 123 if (*addr == 0x0F) { 124 /* 0x0F is extension instruction */ 125 *opcode = *(unsigned short *)addr; 126 len = 2; 127 } else { 128 *opcode = *addr; 129 len = 1; 130 } 131 132 return len; 133} 134 135#define CHECK_OP_TYPE(opcode, array, type) \ 136 for (i = 0; i < ARRAY_SIZE(array); i++) { \ 137 if (array[i] == opcode) { \ 138 rv = type; \ 139 goto exit; \ 140 } \ 141 } 142 143enum reason_type get_ins_type(unsigned long ins_addr) 144{ 145 unsigned int opcode; 146 unsigned char *p; 147 struct prefix_bits prf; 148 int i; 149 enum reason_type rv = OTHERS; 150 151 p = (unsigned char *)ins_addr; 152 p += skip_prefix(p, &prf); 153 p += get_opcode(p, &opcode); 154 155 CHECK_OP_TYPE(opcode, reg_rop, REG_READ); 156 CHECK_OP_TYPE(opcode, reg_wop, REG_WRITE); 157 CHECK_OP_TYPE(opcode, imm_wop, IMM_WRITE); 158 159exit: 160 return rv; 161} 162#undef CHECK_OP_TYPE 163 164static unsigned int get_ins_reg_width(unsigned long ins_addr) 165{ 166 unsigned int opcode; 167 unsigned char *p; 168 struct prefix_bits prf; 169 int i; 170 171 p = (unsigned char *)ins_addr; 172 p += skip_prefix(p, &prf); 173 p += get_opcode(p, &opcode); 174 175 for (i = 0; i < ARRAY_SIZE(rw8); i++) 176 if (rw8[i] == opcode) 177 return 1; 178 179 for (i = 0; i < ARRAY_SIZE(rw32); i++) 180 if (rw32[i] == opcode) 181 return prf.shorted ? 2 : (prf.enlarged ? 8 : 4); 182 183 printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode); 184 return 0; 185} 186 187unsigned int get_ins_mem_width(unsigned long ins_addr) 188{ 189 unsigned int opcode; 190 unsigned char *p; 191 struct prefix_bits prf; 192 int i; 193 194 p = (unsigned char *)ins_addr; 195 p += skip_prefix(p, &prf); 196 p += get_opcode(p, &opcode); 197 198 for (i = 0; i < ARRAY_SIZE(mw8); i++) 199 if (mw8[i] == opcode) 200 return 1; 201 202 for (i = 0; i < ARRAY_SIZE(mw16); i++) 203 if (mw16[i] == opcode) 204 return 2; 205 206 for (i = 0; i < ARRAY_SIZE(mw32); i++) 207 if (mw32[i] == opcode) 208 return prf.shorted ? 2 : 4; 209 210 for (i = 0; i < ARRAY_SIZE(mw64); i++) 211 if (mw64[i] == opcode) 212 return prf.shorted ? 2 : (prf.enlarged ? 8 : 4); 213 214 printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode); 215 return 0; 216} 217 218/* 219 * Define register ident in mod/rm byte. 220 * Note: these are NOT the same as in ptrace-abi.h. 221 */ 222enum { 223 arg_AL = 0, 224 arg_CL = 1, 225 arg_DL = 2, 226 arg_BL = 3, 227 arg_AH = 4, 228 arg_CH = 5, 229 arg_DH = 6, 230 arg_BH = 7, 231 232 arg_AX = 0, 233 arg_CX = 1, 234 arg_DX = 2, 235 arg_BX = 3, 236 arg_SP = 4, 237 arg_BP = 5, 238 arg_SI = 6, 239 arg_DI = 7, 240#ifdef __amd64__ 241 arg_R8 = 8, 242 arg_R9 = 9, 243 arg_R10 = 10, 244 arg_R11 = 11, 245 arg_R12 = 12, 246 arg_R13 = 13, 247 arg_R14 = 14, 248 arg_R15 = 15 249#endif 250}; 251 252static unsigned char *get_reg_w8(int no, int rex, struct pt_regs *regs) 253{ 254 unsigned char *rv = NULL; 255 256 switch (no) { 257 case arg_AL: 258 rv = (unsigned char *)®s->ax; 259 break; 260 case arg_BL: 261 rv = (unsigned char *)®s->bx; 262 break; 263 case arg_CL: 264 rv = (unsigned char *)®s->cx; 265 break; 266 case arg_DL: 267 rv = (unsigned char *)®s->dx; 268 break; 269#ifdef __amd64__ 270 case arg_R8: 271 rv = (unsigned char *)®s->r8; 272 break; 273 case arg_R9: 274 rv = (unsigned char *)®s->r9; 275 break; 276 case arg_R10: 277 rv = (unsigned char *)®s->r10; 278 break; 279 case arg_R11: 280 rv = (unsigned char *)®s->r11; 281 break; 282 case arg_R12: 283 rv = (unsigned char *)®s->r12; 284 break; 285 case arg_R13: 286 rv = (unsigned char *)®s->r13; 287 break; 288 case arg_R14: 289 rv = (unsigned char *)®s->r14; 290 break; 291 case arg_R15: 292 rv = (unsigned char *)®s->r15; 293 break; 294#endif 295 default: 296 break; 297 } 298 299 if (rv) 300 return rv; 301 302 if (rex) { 303 /* 304 * If REX prefix exists, access low bytes of SI etc. 305 * instead of AH etc. 306 */ 307 switch (no) { 308 case arg_SI: 309 rv = (unsigned char *)®s->si; 310 break; 311 case arg_DI: 312 rv = (unsigned char *)®s->di; 313 break; 314 case arg_BP: 315 rv = (unsigned char *)®s->bp; 316 break; 317 case arg_SP: 318 rv = (unsigned char *)®s->sp; 319 break; 320 default: 321 break; 322 } 323 } else { 324 switch (no) { 325 case arg_AH: 326 rv = 1 + (unsigned char *)®s->ax; 327 break; 328 case arg_BH: 329 rv = 1 + (unsigned char *)®s->bx; 330 break; 331 case arg_CH: 332 rv = 1 + (unsigned char *)®s->cx; 333 break; 334 case arg_DH: 335 rv = 1 + (unsigned char *)®s->dx; 336 break; 337 default: 338 break; 339 } 340 } 341 342 if (!rv) 343 printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no); 344 345 return rv; 346} 347 348static unsigned long *get_reg_w32(int no, struct pt_regs *regs) 349{ 350 unsigned long *rv = NULL; 351 352 switch (no) { 353 case arg_AX: 354 rv = ®s->ax; 355 break; 356 case arg_BX: 357 rv = ®s->bx; 358 break; 359 case arg_CX: 360 rv = ®s->cx; 361 break; 362 case arg_DX: 363 rv = ®s->dx; 364 break; 365 case arg_SP: 366 rv = ®s->sp; 367 break; 368 case arg_BP: 369 rv = ®s->bp; 370 break; 371 case arg_SI: 372 rv = ®s->si; 373 break; 374 case arg_DI: 375 rv = ®s->di; 376 break; 377#ifdef __amd64__ 378 case arg_R8: 379 rv = ®s->r8; 380 break; 381 case arg_R9: 382 rv = ®s->r9; 383 break; 384 case arg_R10: 385 rv = ®s->r10; 386 break; 387 case arg_R11: 388 rv = ®s->r11; 389 break; 390 case arg_R12: 391 rv = ®s->r12; 392 break; 393 case arg_R13: 394 rv = ®s->r13; 395 break; 396 case arg_R14: 397 rv = ®s->r14; 398 break; 399 case arg_R15: 400 rv = ®s->r15; 401 break; 402#endif 403 default: 404 printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no); 405 } 406 407 return rv; 408} 409 410unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs) 411{ 412 unsigned int opcode; 413 int reg; 414 unsigned char *p; 415 struct prefix_bits prf; 416 int i; 417 418 p = (unsigned char *)ins_addr; 419 p += skip_prefix(p, &prf); 420 p += get_opcode(p, &opcode); 421 for (i = 0; i < ARRAY_SIZE(reg_rop); i++) 422 if (reg_rop[i] == opcode) 423 goto do_work; 424 425 for (i = 0; i < ARRAY_SIZE(reg_wop); i++) 426 if (reg_wop[i] == opcode) 427 goto do_work; 428 429 printk(KERN_ERR "mmiotrace: Not a register instruction, opcode " 430 "0x%02x\n", opcode); 431 goto err; 432 433do_work: 434 /* for STOS, source register is fixed */ 435 if (opcode == 0xAA || opcode == 0xAB) { 436 reg = arg_AX; 437 } else { 438 unsigned char mod_rm = *p; 439 reg = ((mod_rm >> 3) & 0x7) | (prf.rexr << 3); 440 } 441 switch (get_ins_reg_width(ins_addr)) { 442 case 1: 443 return *get_reg_w8(reg, prf.rex, regs); 444 445 case 2: 446 return *(unsigned short *)get_reg_w32(reg, regs); 447 448 case 4: 449 return *(unsigned int *)get_reg_w32(reg, regs); 450 451#ifdef __amd64__ 452 case 8: 453 return *(unsigned long *)get_reg_w32(reg, regs); 454#endif 455 456 default: 457 printk(KERN_ERR "mmiotrace: Error width# %d\n", reg); 458 } 459 460err: 461 return 0; 462} 463 464unsigned long get_ins_imm_val(unsigned long ins_addr) 465{ 466 unsigned int opcode; 467 unsigned char mod_rm; 468 unsigned char mod; 469 unsigned char *p; 470 struct prefix_bits prf; 471 int i; 472 473 p = (unsigned char *)ins_addr; 474 p += skip_prefix(p, &prf); 475 p += get_opcode(p, &opcode); 476 for (i = 0; i < ARRAY_SIZE(imm_wop); i++) 477 if (imm_wop[i] == opcode) 478 goto do_work; 479 480 printk(KERN_ERR "mmiotrace: Not an immediate instruction, opcode " 481 "0x%02x\n", opcode); 482 goto err; 483 484do_work: 485 mod_rm = *p; 486 mod = mod_rm >> 6; 487 p++; 488 switch (mod) { 489 case 0: 490 /* if r/m is 5 we have a 32 disp (IA32 Manual 3, Table 2-2) */ 491 /* AMD64: XXX Check for address size prefix? */ 492 if ((mod_rm & 0x7) == 0x5) 493 p += 4; 494 break; 495 496 case 1: 497 p += 1; 498 break; 499 500 case 2: 501 p += 4; 502 break; 503 504 case 3: 505 default: 506 printk(KERN_ERR "mmiotrace: not a memory access instruction " 507 "at 0x%lx, rm_mod=0x%02x\n", 508 ins_addr, mod_rm); 509 } 510 511 switch (get_ins_reg_width(ins_addr)) { 512 case 1: 513 return *(unsigned char *)p; 514 515 case 2: 516 return *(unsigned short *)p; 517 518 case 4: 519 return *(unsigned int *)p; 520 521#ifdef __amd64__ 522 case 8: 523 return *(unsigned long *)p; 524#endif 525 526 default: 527 printk(KERN_ERR "mmiotrace: Error: width.\n"); 528 } 529 530err: 531 return 0; 532} 533