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