Merge tag 'for-5.2-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-2.6-block.git] / arch / powerpc / lib / test_emulate_step.c
1 /*
2  * Simple sanity tests for instruction emulation infrastructure.
3  *
4  * Copyright IBM Corp. 2016
5  *
6  * This program is free software;  you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11
12 #define pr_fmt(fmt) "emulate_step_test: " fmt
13
14 #include <linux/ptrace.h>
15 #include <asm/sstep.h>
16 #include <asm/ppc-opcode.h>
17 #include <asm/code-patching.h>
18
19 #define IMM_L(i)                ((uintptr_t)(i) & 0xffff)
20
21 /*
22  * Defined with TEST_ prefix so it does not conflict with other
23  * definitions.
24  */
25 #define TEST_LD(r, base, i)     (PPC_INST_LD | ___PPC_RT(r) |           \
26                                         ___PPC_RA(base) | IMM_L(i))
27 #define TEST_LWZ(r, base, i)    (PPC_INST_LWZ | ___PPC_RT(r) |          \
28                                         ___PPC_RA(base) | IMM_L(i))
29 #define TEST_LWZX(t, a, b)      (PPC_INST_LWZX | ___PPC_RT(t) |         \
30                                         ___PPC_RA(a) | ___PPC_RB(b))
31 #define TEST_STD(r, base, i)    (PPC_INST_STD | ___PPC_RS(r) |          \
32                                         ___PPC_RA(base) | ((i) & 0xfffc))
33 #define TEST_LDARX(t, a, b, eh) (PPC_INST_LDARX | ___PPC_RT(t) |        \
34                                         ___PPC_RA(a) | ___PPC_RB(b) |   \
35                                         __PPC_EH(eh))
36 #define TEST_STDCX(s, a, b)     (PPC_INST_STDCX | ___PPC_RS(s) |        \
37                                         ___PPC_RA(a) | ___PPC_RB(b))
38 #define TEST_LFSX(t, a, b)      (PPC_INST_LFSX | ___PPC_RT(t) |         \
39                                         ___PPC_RA(a) | ___PPC_RB(b))
40 #define TEST_STFSX(s, a, b)     (PPC_INST_STFSX | ___PPC_RS(s) |        \
41                                         ___PPC_RA(a) | ___PPC_RB(b))
42 #define TEST_LFDX(t, a, b)      (PPC_INST_LFDX | ___PPC_RT(t) |         \
43                                         ___PPC_RA(a) | ___PPC_RB(b))
44 #define TEST_STFDX(s, a, b)     (PPC_INST_STFDX | ___PPC_RS(s) |        \
45                                         ___PPC_RA(a) | ___PPC_RB(b))
46 #define TEST_LVX(t, a, b)       (PPC_INST_LVX | ___PPC_RT(t) |          \
47                                         ___PPC_RA(a) | ___PPC_RB(b))
48 #define TEST_STVX(s, a, b)      (PPC_INST_STVX | ___PPC_RS(s) |         \
49                                         ___PPC_RA(a) | ___PPC_RB(b))
50 #define TEST_LXVD2X(s, a, b)    (PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b))
51 #define TEST_STXVD2X(s, a, b)   (PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b))
52 #define TEST_ADD(t, a, b)       (PPC_INST_ADD | ___PPC_RT(t) |          \
53                                         ___PPC_RA(a) | ___PPC_RB(b))
54 #define TEST_ADD_DOT(t, a, b)   (PPC_INST_ADD | ___PPC_RT(t) |          \
55                                         ___PPC_RA(a) | ___PPC_RB(b) | 0x1)
56 #define TEST_ADDC(t, a, b)      (PPC_INST_ADDC | ___PPC_RT(t) |         \
57                                         ___PPC_RA(a) | ___PPC_RB(b))
58 #define TEST_ADDC_DOT(t, a, b)  (PPC_INST_ADDC | ___PPC_RT(t) |         \
59                                         ___PPC_RA(a) | ___PPC_RB(b) | 0x1)
60
61 #define MAX_SUBTESTS    16
62
63 #define IGNORE_GPR(n)   (0x1UL << (n))
64 #define IGNORE_XER      (0x1UL << 32)
65 #define IGNORE_CCR      (0x1UL << 33)
66
67 static void __init init_pt_regs(struct pt_regs *regs)
68 {
69         static unsigned long msr;
70         static bool msr_cached;
71
72         memset(regs, 0, sizeof(struct pt_regs));
73
74         if (likely(msr_cached)) {
75                 regs->msr = msr;
76                 return;
77         }
78
79         asm volatile("mfmsr %0" : "=r"(regs->msr));
80
81         regs->msr |= MSR_FP;
82         regs->msr |= MSR_VEC;
83         regs->msr |= MSR_VSX;
84
85         msr = regs->msr;
86         msr_cached = true;
87 }
88
89 static void __init show_result(char *mnemonic, char *result)
90 {
91         pr_info("%-14s : %s\n", mnemonic, result);
92 }
93
94 static void __init show_result_with_descr(char *mnemonic, char *descr,
95                                           char *result)
96 {
97         pr_info("%-14s : %-50s %s\n", mnemonic, descr, result);
98 }
99
100 static void __init test_ld(void)
101 {
102         struct pt_regs regs;
103         unsigned long a = 0x23;
104         int stepped = -1;
105
106         init_pt_regs(&regs);
107         regs.gpr[3] = (unsigned long) &a;
108
109         /* ld r5, 0(r3) */
110         stepped = emulate_step(&regs, TEST_LD(5, 3, 0));
111
112         if (stepped == 1 && regs.gpr[5] == a)
113                 show_result("ld", "PASS");
114         else
115                 show_result("ld", "FAIL");
116 }
117
118 static void __init test_lwz(void)
119 {
120         struct pt_regs regs;
121         unsigned int a = 0x4545;
122         int stepped = -1;
123
124         init_pt_regs(&regs);
125         regs.gpr[3] = (unsigned long) &a;
126
127         /* lwz r5, 0(r3) */
128         stepped = emulate_step(&regs, TEST_LWZ(5, 3, 0));
129
130         if (stepped == 1 && regs.gpr[5] == a)
131                 show_result("lwz", "PASS");
132         else
133                 show_result("lwz", "FAIL");
134 }
135
136 static void __init test_lwzx(void)
137 {
138         struct pt_regs regs;
139         unsigned int a[3] = {0x0, 0x0, 0x1234};
140         int stepped = -1;
141
142         init_pt_regs(&regs);
143         regs.gpr[3] = (unsigned long) a;
144         regs.gpr[4] = 8;
145         regs.gpr[5] = 0x8765;
146
147         /* lwzx r5, r3, r4 */
148         stepped = emulate_step(&regs, TEST_LWZX(5, 3, 4));
149         if (stepped == 1 && regs.gpr[5] == a[2])
150                 show_result("lwzx", "PASS");
151         else
152                 show_result("lwzx", "FAIL");
153 }
154
155 static void __init test_std(void)
156 {
157         struct pt_regs regs;
158         unsigned long a = 0x1234;
159         int stepped = -1;
160
161         init_pt_regs(&regs);
162         regs.gpr[3] = (unsigned long) &a;
163         regs.gpr[5] = 0x5678;
164
165         /* std r5, 0(r3) */
166         stepped = emulate_step(&regs, TEST_STD(5, 3, 0));
167         if (stepped == 1 || regs.gpr[5] == a)
168                 show_result("std", "PASS");
169         else
170                 show_result("std", "FAIL");
171 }
172
173 static void __init test_ldarx_stdcx(void)
174 {
175         struct pt_regs regs;
176         unsigned long a = 0x1234;
177         int stepped = -1;
178         unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
179
180         init_pt_regs(&regs);
181         asm volatile("mfcr %0" : "=r"(regs.ccr));
182
183
184         /*** ldarx ***/
185
186         regs.gpr[3] = (unsigned long) &a;
187         regs.gpr[4] = 0;
188         regs.gpr[5] = 0x5678;
189
190         /* ldarx r5, r3, r4, 0 */
191         stepped = emulate_step(&regs, TEST_LDARX(5, 3, 4, 0));
192
193         /*
194          * Don't touch 'a' here. Touching 'a' can do Load/store
195          * of 'a' which result in failure of subsequent stdcx.
196          * Instead, use hardcoded value for comparison.
197          */
198         if (stepped <= 0 || regs.gpr[5] != 0x1234) {
199                 show_result("ldarx / stdcx.", "FAIL (ldarx)");
200                 return;
201         }
202
203
204         /*** stdcx. ***/
205
206         regs.gpr[5] = 0x9ABC;
207
208         /* stdcx. r5, r3, r4 */
209         stepped = emulate_step(&regs, TEST_STDCX(5, 3, 4));
210
211         /*
212          * Two possible scenarios that indicates successful emulation
213          * of stdcx. :
214          *  1. Reservation is active and store is performed. In this
215          *     case cr0.eq bit will be set to 1.
216          *  2. Reservation is not active and store is not performed.
217          *     In this case cr0.eq bit will be set to 0.
218          */
219         if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
220                         || (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
221                 show_result("ldarx / stdcx.", "PASS");
222         else
223                 show_result("ldarx / stdcx.", "FAIL (stdcx.)");
224 }
225
226 #ifdef CONFIG_PPC_FPU
227 static void __init test_lfsx_stfsx(void)
228 {
229         struct pt_regs regs;
230         union {
231                 float a;
232                 int b;
233         } c;
234         int cached_b;
235         int stepped = -1;
236
237         init_pt_regs(&regs);
238
239
240         /*** lfsx ***/
241
242         c.a = 123.45;
243         cached_b = c.b;
244
245         regs.gpr[3] = (unsigned long) &c.a;
246         regs.gpr[4] = 0;
247
248         /* lfsx frt10, r3, r4 */
249         stepped = emulate_step(&regs, TEST_LFSX(10, 3, 4));
250
251         if (stepped == 1)
252                 show_result("lfsx", "PASS");
253         else
254                 show_result("lfsx", "FAIL");
255
256
257         /*** stfsx ***/
258
259         c.a = 678.91;
260
261         /* stfsx frs10, r3, r4 */
262         stepped = emulate_step(&regs, TEST_STFSX(10, 3, 4));
263
264         if (stepped == 1 && c.b == cached_b)
265                 show_result("stfsx", "PASS");
266         else
267                 show_result("stfsx", "FAIL");
268 }
269
270 static void __init test_lfdx_stfdx(void)
271 {
272         struct pt_regs regs;
273         union {
274                 double a;
275                 long b;
276         } c;
277         long cached_b;
278         int stepped = -1;
279
280         init_pt_regs(&regs);
281
282
283         /*** lfdx ***/
284
285         c.a = 123456.78;
286         cached_b = c.b;
287
288         regs.gpr[3] = (unsigned long) &c.a;
289         regs.gpr[4] = 0;
290
291         /* lfdx frt10, r3, r4 */
292         stepped = emulate_step(&regs, TEST_LFDX(10, 3, 4));
293
294         if (stepped == 1)
295                 show_result("lfdx", "PASS");
296         else
297                 show_result("lfdx", "FAIL");
298
299
300         /*** stfdx ***/
301
302         c.a = 987654.32;
303
304         /* stfdx frs10, r3, r4 */
305         stepped = emulate_step(&regs, TEST_STFDX(10, 3, 4));
306
307         if (stepped == 1 && c.b == cached_b)
308                 show_result("stfdx", "PASS");
309         else
310                 show_result("stfdx", "FAIL");
311 }
312 #else
313 static void __init test_lfsx_stfsx(void)
314 {
315         show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
316         show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
317 }
318
319 static void __init test_lfdx_stfdx(void)
320 {
321         show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
322         show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
323 }
324 #endif /* CONFIG_PPC_FPU */
325
326 #ifdef CONFIG_ALTIVEC
327 static void __init test_lvx_stvx(void)
328 {
329         struct pt_regs regs;
330         union {
331                 vector128 a;
332                 u32 b[4];
333         } c;
334         u32 cached_b[4];
335         int stepped = -1;
336
337         init_pt_regs(&regs);
338
339
340         /*** lvx ***/
341
342         cached_b[0] = c.b[0] = 923745;
343         cached_b[1] = c.b[1] = 2139478;
344         cached_b[2] = c.b[2] = 9012;
345         cached_b[3] = c.b[3] = 982134;
346
347         regs.gpr[3] = (unsigned long) &c.a;
348         regs.gpr[4] = 0;
349
350         /* lvx vrt10, r3, r4 */
351         stepped = emulate_step(&regs, TEST_LVX(10, 3, 4));
352
353         if (stepped == 1)
354                 show_result("lvx", "PASS");
355         else
356                 show_result("lvx", "FAIL");
357
358
359         /*** stvx ***/
360
361         c.b[0] = 4987513;
362         c.b[1] = 84313948;
363         c.b[2] = 71;
364         c.b[3] = 498532;
365
366         /* stvx vrs10, r3, r4 */
367         stepped = emulate_step(&regs, TEST_STVX(10, 3, 4));
368
369         if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
370             cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
371                 show_result("stvx", "PASS");
372         else
373                 show_result("stvx", "FAIL");
374 }
375 #else
376 static void __init test_lvx_stvx(void)
377 {
378         show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
379         show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
380 }
381 #endif /* CONFIG_ALTIVEC */
382
383 #ifdef CONFIG_VSX
384 static void __init test_lxvd2x_stxvd2x(void)
385 {
386         struct pt_regs regs;
387         union {
388                 vector128 a;
389                 u32 b[4];
390         } c;
391         u32 cached_b[4];
392         int stepped = -1;
393
394         init_pt_regs(&regs);
395
396
397         /*** lxvd2x ***/
398
399         cached_b[0] = c.b[0] = 18233;
400         cached_b[1] = c.b[1] = 34863571;
401         cached_b[2] = c.b[2] = 834;
402         cached_b[3] = c.b[3] = 6138911;
403
404         regs.gpr[3] = (unsigned long) &c.a;
405         regs.gpr[4] = 0;
406
407         /* lxvd2x vsr39, r3, r4 */
408         stepped = emulate_step(&regs, TEST_LXVD2X(39, 3, 4));
409
410         if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
411                 show_result("lxvd2x", "PASS");
412         } else {
413                 if (!cpu_has_feature(CPU_FTR_VSX))
414                         show_result("lxvd2x", "PASS (!CPU_FTR_VSX)");
415                 else
416                         show_result("lxvd2x", "FAIL");
417         }
418
419
420         /*** stxvd2x ***/
421
422         c.b[0] = 21379463;
423         c.b[1] = 87;
424         c.b[2] = 374234;
425         c.b[3] = 4;
426
427         /* stxvd2x vsr39, r3, r4 */
428         stepped = emulate_step(&regs, TEST_STXVD2X(39, 3, 4));
429
430         if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
431             cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
432             cpu_has_feature(CPU_FTR_VSX)) {
433                 show_result("stxvd2x", "PASS");
434         } else {
435                 if (!cpu_has_feature(CPU_FTR_VSX))
436                         show_result("stxvd2x", "PASS (!CPU_FTR_VSX)");
437                 else
438                         show_result("stxvd2x", "FAIL");
439         }
440 }
441 #else
442 static void __init test_lxvd2x_stxvd2x(void)
443 {
444         show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
445         show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
446 }
447 #endif /* CONFIG_VSX */
448
449 static void __init run_tests_load_store(void)
450 {
451         test_ld();
452         test_lwz();
453         test_lwzx();
454         test_std();
455         test_ldarx_stdcx();
456         test_lfsx_stfsx();
457         test_lfdx_stfdx();
458         test_lvx_stvx();
459         test_lxvd2x_stxvd2x();
460 }
461
462 struct compute_test {
463         char *mnemonic;
464         struct {
465                 char *descr;
466                 unsigned long flags;
467                 unsigned int instr;
468                 struct pt_regs regs;
469         } subtests[MAX_SUBTESTS + 1];
470 };
471
472 static struct compute_test compute_tests[] = {
473         {
474                 .mnemonic = "nop",
475                 .subtests = {
476                         {
477                                 .descr = "R0 = LONG_MAX",
478                                 .instr = PPC_INST_NOP,
479                                 .regs = {
480                                         .gpr[0] = LONG_MAX,
481                                 }
482                         }
483                 }
484         },
485         {
486                 .mnemonic = "add",
487                 .subtests = {
488                         {
489                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
490                                 .instr = TEST_ADD(20, 21, 22),
491                                 .regs = {
492                                         .gpr[21] = LONG_MIN,
493                                         .gpr[22] = LONG_MIN,
494                                 }
495                         },
496                         {
497                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
498                                 .instr = TEST_ADD(20, 21, 22),
499                                 .regs = {
500                                         .gpr[21] = LONG_MIN,
501                                         .gpr[22] = LONG_MAX,
502                                 }
503                         },
504                         {
505                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
506                                 .instr = TEST_ADD(20, 21, 22),
507                                 .regs = {
508                                         .gpr[21] = LONG_MAX,
509                                         .gpr[22] = LONG_MAX,
510                                 }
511                         },
512                         {
513                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
514                                 .instr = TEST_ADD(20, 21, 22),
515                                 .regs = {
516                                         .gpr[21] = ULONG_MAX,
517                                         .gpr[22] = ULONG_MAX,
518                                 }
519                         },
520                         {
521                                 .descr = "RA = ULONG_MAX, RB = 0x1",
522                                 .instr = TEST_ADD(20, 21, 22),
523                                 .regs = {
524                                         .gpr[21] = ULONG_MAX,
525                                         .gpr[22] = 0x1,
526                                 }
527                         },
528                         {
529                                 .descr = "RA = INT_MIN, RB = INT_MIN",
530                                 .instr = TEST_ADD(20, 21, 22),
531                                 .regs = {
532                                         .gpr[21] = INT_MIN,
533                                         .gpr[22] = INT_MIN,
534                                 }
535                         },
536                         {
537                                 .descr = "RA = INT_MIN, RB = INT_MAX",
538                                 .instr = TEST_ADD(20, 21, 22),
539                                 .regs = {
540                                         .gpr[21] = INT_MIN,
541                                         .gpr[22] = INT_MAX,
542                                 }
543                         },
544                         {
545                                 .descr = "RA = INT_MAX, RB = INT_MAX",
546                                 .instr = TEST_ADD(20, 21, 22),
547                                 .regs = {
548                                         .gpr[21] = INT_MAX,
549                                         .gpr[22] = INT_MAX,
550                                 }
551                         },
552                         {
553                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
554                                 .instr = TEST_ADD(20, 21, 22),
555                                 .regs = {
556                                         .gpr[21] = UINT_MAX,
557                                         .gpr[22] = UINT_MAX,
558                                 }
559                         },
560                         {
561                                 .descr = "RA = UINT_MAX, RB = 0x1",
562                                 .instr = TEST_ADD(20, 21, 22),
563                                 .regs = {
564                                         .gpr[21] = UINT_MAX,
565                                         .gpr[22] = 0x1,
566                                 }
567                         }
568                 }
569         },
570         {
571                 .mnemonic = "add.",
572                 .subtests = {
573                         {
574                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
575                                 .flags = IGNORE_CCR,
576                                 .instr = TEST_ADD_DOT(20, 21, 22),
577                                 .regs = {
578                                         .gpr[21] = LONG_MIN,
579                                         .gpr[22] = LONG_MIN,
580                                 }
581                         },
582                         {
583                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
584                                 .instr = TEST_ADD_DOT(20, 21, 22),
585                                 .regs = {
586                                         .gpr[21] = LONG_MIN,
587                                         .gpr[22] = LONG_MAX,
588                                 }
589                         },
590                         {
591                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
592                                 .flags = IGNORE_CCR,
593                                 .instr = TEST_ADD_DOT(20, 21, 22),
594                                 .regs = {
595                                         .gpr[21] = LONG_MAX,
596                                         .gpr[22] = LONG_MAX,
597                                 }
598                         },
599                         {
600                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
601                                 .instr = TEST_ADD_DOT(20, 21, 22),
602                                 .regs = {
603                                         .gpr[21] = ULONG_MAX,
604                                         .gpr[22] = ULONG_MAX,
605                                 }
606                         },
607                         {
608                                 .descr = "RA = ULONG_MAX, RB = 0x1",
609                                 .instr = TEST_ADD_DOT(20, 21, 22),
610                                 .regs = {
611                                         .gpr[21] = ULONG_MAX,
612                                         .gpr[22] = 0x1,
613                                 }
614                         },
615                         {
616                                 .descr = "RA = INT_MIN, RB = INT_MIN",
617                                 .instr = TEST_ADD_DOT(20, 21, 22),
618                                 .regs = {
619                                         .gpr[21] = INT_MIN,
620                                         .gpr[22] = INT_MIN,
621                                 }
622                         },
623                         {
624                                 .descr = "RA = INT_MIN, RB = INT_MAX",
625                                 .instr = TEST_ADD_DOT(20, 21, 22),
626                                 .regs = {
627                                         .gpr[21] = INT_MIN,
628                                         .gpr[22] = INT_MAX,
629                                 }
630                         },
631                         {
632                                 .descr = "RA = INT_MAX, RB = INT_MAX",
633                                 .instr = TEST_ADD_DOT(20, 21, 22),
634                                 .regs = {
635                                         .gpr[21] = INT_MAX,
636                                         .gpr[22] = INT_MAX,
637                                 }
638                         },
639                         {
640                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
641                                 .instr = TEST_ADD_DOT(20, 21, 22),
642                                 .regs = {
643                                         .gpr[21] = UINT_MAX,
644                                         .gpr[22] = UINT_MAX,
645                                 }
646                         },
647                         {
648                                 .descr = "RA = UINT_MAX, RB = 0x1",
649                                 .instr = TEST_ADD_DOT(20, 21, 22),
650                                 .regs = {
651                                         .gpr[21] = UINT_MAX,
652                                         .gpr[22] = 0x1,
653                                 }
654                         }
655                 }
656         },
657         {
658                 .mnemonic = "addc",
659                 .subtests = {
660                         {
661                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
662                                 .instr = TEST_ADDC(20, 21, 22),
663                                 .regs = {
664                                         .gpr[21] = LONG_MIN,
665                                         .gpr[22] = LONG_MIN,
666                                 }
667                         },
668                         {
669                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
670                                 .instr = TEST_ADDC(20, 21, 22),
671                                 .regs = {
672                                         .gpr[21] = LONG_MIN,
673                                         .gpr[22] = LONG_MAX,
674                                 }
675                         },
676                         {
677                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
678                                 .instr = TEST_ADDC(20, 21, 22),
679                                 .regs = {
680                                         .gpr[21] = LONG_MAX,
681                                         .gpr[22] = LONG_MAX,
682                                 }
683                         },
684                         {
685                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
686                                 .instr = TEST_ADDC(20, 21, 22),
687                                 .regs = {
688                                         .gpr[21] = ULONG_MAX,
689                                         .gpr[22] = ULONG_MAX,
690                                 }
691                         },
692                         {
693                                 .descr = "RA = ULONG_MAX, RB = 0x1",
694                                 .instr = TEST_ADDC(20, 21, 22),
695                                 .regs = {
696                                         .gpr[21] = ULONG_MAX,
697                                         .gpr[22] = 0x1,
698                                 }
699                         },
700                         {
701                                 .descr = "RA = INT_MIN, RB = INT_MIN",
702                                 .instr = TEST_ADDC(20, 21, 22),
703                                 .regs = {
704                                         .gpr[21] = INT_MIN,
705                                         .gpr[22] = INT_MIN,
706                                 }
707                         },
708                         {
709                                 .descr = "RA = INT_MIN, RB = INT_MAX",
710                                 .instr = TEST_ADDC(20, 21, 22),
711                                 .regs = {
712                                         .gpr[21] = INT_MIN,
713                                         .gpr[22] = INT_MAX,
714                                 }
715                         },
716                         {
717                                 .descr = "RA = INT_MAX, RB = INT_MAX",
718                                 .instr = TEST_ADDC(20, 21, 22),
719                                 .regs = {
720                                         .gpr[21] = INT_MAX,
721                                         .gpr[22] = INT_MAX,
722                                 }
723                         },
724                         {
725                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
726                                 .instr = TEST_ADDC(20, 21, 22),
727                                 .regs = {
728                                         .gpr[21] = UINT_MAX,
729                                         .gpr[22] = UINT_MAX,
730                                 }
731                         },
732                         {
733                                 .descr = "RA = UINT_MAX, RB = 0x1",
734                                 .instr = TEST_ADDC(20, 21, 22),
735                                 .regs = {
736                                         .gpr[21] = UINT_MAX,
737                                         .gpr[22] = 0x1,
738                                 }
739                         },
740                         {
741                                 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
742                                 .instr = TEST_ADDC(20, 21, 22),
743                                 .regs = {
744                                         .gpr[21] = LONG_MIN | (uint)INT_MIN,
745                                         .gpr[22] = LONG_MIN | (uint)INT_MIN,
746                                 }
747                         }
748                 }
749         },
750         {
751                 .mnemonic = "addc.",
752                 .subtests = {
753                         {
754                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
755                                 .flags = IGNORE_CCR,
756                                 .instr = TEST_ADDC_DOT(20, 21, 22),
757                                 .regs = {
758                                         .gpr[21] = LONG_MIN,
759                                         .gpr[22] = LONG_MIN,
760                                 }
761                         },
762                         {
763                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
764                                 .instr = TEST_ADDC_DOT(20, 21, 22),
765                                 .regs = {
766                                         .gpr[21] = LONG_MIN,
767                                         .gpr[22] = LONG_MAX,
768                                 }
769                         },
770                         {
771                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
772                                 .flags = IGNORE_CCR,
773                                 .instr = TEST_ADDC_DOT(20, 21, 22),
774                                 .regs = {
775                                         .gpr[21] = LONG_MAX,
776                                         .gpr[22] = LONG_MAX,
777                                 }
778                         },
779                         {
780                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
781                                 .instr = TEST_ADDC_DOT(20, 21, 22),
782                                 .regs = {
783                                         .gpr[21] = ULONG_MAX,
784                                         .gpr[22] = ULONG_MAX,
785                                 }
786                         },
787                         {
788                                 .descr = "RA = ULONG_MAX, RB = 0x1",
789                                 .instr = TEST_ADDC_DOT(20, 21, 22),
790                                 .regs = {
791                                         .gpr[21] = ULONG_MAX,
792                                         .gpr[22] = 0x1,
793                                 }
794                         },
795                         {
796                                 .descr = "RA = INT_MIN, RB = INT_MIN",
797                                 .instr = TEST_ADDC_DOT(20, 21, 22),
798                                 .regs = {
799                                         .gpr[21] = INT_MIN,
800                                         .gpr[22] = INT_MIN,
801                                 }
802                         },
803                         {
804                                 .descr = "RA = INT_MIN, RB = INT_MAX",
805                                 .instr = TEST_ADDC_DOT(20, 21, 22),
806                                 .regs = {
807                                         .gpr[21] = INT_MIN,
808                                         .gpr[22] = INT_MAX,
809                                 }
810                         },
811                         {
812                                 .descr = "RA = INT_MAX, RB = INT_MAX",
813                                 .instr = TEST_ADDC_DOT(20, 21, 22),
814                                 .regs = {
815                                         .gpr[21] = INT_MAX,
816                                         .gpr[22] = INT_MAX,
817                                 }
818                         },
819                         {
820                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
821                                 .instr = TEST_ADDC_DOT(20, 21, 22),
822                                 .regs = {
823                                         .gpr[21] = UINT_MAX,
824                                         .gpr[22] = UINT_MAX,
825                                 }
826                         },
827                         {
828                                 .descr = "RA = UINT_MAX, RB = 0x1",
829                                 .instr = TEST_ADDC_DOT(20, 21, 22),
830                                 .regs = {
831                                         .gpr[21] = UINT_MAX,
832                                         .gpr[22] = 0x1,
833                                 }
834                         },
835                         {
836                                 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
837                                 .instr = TEST_ADDC_DOT(20, 21, 22),
838                                 .regs = {
839                                         .gpr[21] = LONG_MIN | (uint)INT_MIN,
840                                         .gpr[22] = LONG_MIN | (uint)INT_MIN,
841                                 }
842                         }
843                 }
844         }
845 };
846
847 static int __init emulate_compute_instr(struct pt_regs *regs,
848                                         unsigned int instr)
849 {
850         struct instruction_op op;
851
852         if (!regs || !instr)
853                 return -EINVAL;
854
855         if (analyse_instr(&op, regs, instr) != 1 ||
856             GETTYPE(op.type) != COMPUTE) {
857                 pr_info("emulation failed, instruction = 0x%08x\n", instr);
858                 return -EFAULT;
859         }
860
861         emulate_update_regs(regs, &op);
862         return 0;
863 }
864
865 static int __init execute_compute_instr(struct pt_regs *regs,
866                                         unsigned int instr)
867 {
868         extern int exec_instr(struct pt_regs *regs);
869         extern s32 patch__exec_instr;
870
871         if (!regs || !instr)
872                 return -EINVAL;
873
874         /* Patch the NOP with the actual instruction */
875         patch_instruction_site(&patch__exec_instr, instr);
876         if (exec_instr(regs)) {
877                 pr_info("execution failed, instruction = 0x%08x\n", instr);
878                 return -EFAULT;
879         }
880
881         return 0;
882 }
883
884 #define gpr_mismatch(gprn, exp, got)    \
885         pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n",     \
886                 gprn, exp, got)
887
888 #define reg_mismatch(name, exp, got)    \
889         pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n",        \
890                 name, exp, got)
891
892 static void __init run_tests_compute(void)
893 {
894         unsigned long flags;
895         struct compute_test *test;
896         struct pt_regs *regs, exp, got;
897         unsigned int i, j, k, instr;
898         bool ignore_gpr, ignore_xer, ignore_ccr, passed;
899
900         for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
901                 test = &compute_tests[i];
902
903                 for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
904                         instr = test->subtests[j].instr;
905                         flags = test->subtests[j].flags;
906                         regs = &test->subtests[j].regs;
907                         ignore_xer = flags & IGNORE_XER;
908                         ignore_ccr = flags & IGNORE_CCR;
909                         passed = true;
910
911                         memcpy(&exp, regs, sizeof(struct pt_regs));
912                         memcpy(&got, regs, sizeof(struct pt_regs));
913
914                         /*
915                          * Set a compatible MSR value explicitly to ensure
916                          * that XER and CR bits are updated appropriately
917                          */
918                         exp.msr = MSR_KERNEL;
919                         got.msr = MSR_KERNEL;
920
921                         if (emulate_compute_instr(&got, instr) ||
922                             execute_compute_instr(&exp, instr)) {
923                                 passed = false;
924                                 goto print;
925                         }
926
927                         /* Verify GPR values */
928                         for (k = 0; k < 32; k++) {
929                                 ignore_gpr = flags & IGNORE_GPR(k);
930                                 if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
931                                         passed = false;
932                                         gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
933                                 }
934                         }
935
936                         /* Verify LR value */
937                         if (exp.link != got.link) {
938                                 passed = false;
939                                 reg_mismatch("LR", exp.link, got.link);
940                         }
941
942                         /* Verify XER value */
943                         if (!ignore_xer && exp.xer != got.xer) {
944                                 passed = false;
945                                 reg_mismatch("XER", exp.xer, got.xer);
946                         }
947
948                         /* Verify CR value */
949                         if (!ignore_ccr && exp.ccr != got.ccr) {
950                                 passed = false;
951                                 reg_mismatch("CR", exp.ccr, got.ccr);
952                         }
953
954 print:
955                         show_result_with_descr(test->mnemonic,
956                                                test->subtests[j].descr,
957                                                passed ? "PASS" : "FAIL");
958                 }
959         }
960 }
961
962 static int __init test_emulate_step(void)
963 {
964         printk(KERN_INFO "Running instruction emulation self-tests ...\n");
965         run_tests_load_store();
966         run_tests_compute();
967
968         return 0;
969 }
970 late_initcall(test_emulate_step);