~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/lib/test_emulate_step.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Simple sanity tests for instruction emulation infrastructure.
  4  *
  5  * Copyright IBM Corp. 2016
  6  */
  7 
  8 #define pr_fmt(fmt) "emulate_step_test: " fmt
  9 
 10 #include <linux/ptrace.h>
 11 #include <asm/cpu_has_feature.h>
 12 #include <asm/sstep.h>
 13 #include <asm/ppc-opcode.h>
 14 #include <asm/code-patching.h>
 15 #include <asm/inst.h>
 16 
 17 #define MAX_SUBTESTS    16
 18 
 19 #define IGNORE_GPR(n)   (0x1UL << (n))
 20 #define IGNORE_XER      (0x1UL << 32)
 21 #define IGNORE_CCR      (0x1UL << 33)
 22 #define NEGATIVE_TEST   (0x1UL << 63)
 23 
 24 #define TEST_PLD(r, base, i, pr) \
 25         ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
 26                         PPC_INST_PLD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
 27 
 28 #define TEST_PLWZ(r, base, i, pr) \
 29         ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
 30                         PPC_RAW_LWZ(r, base, i))
 31 
 32 #define TEST_PSTD(r, base, i, pr) \
 33         ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
 34                         PPC_INST_PSTD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
 35 
 36 #define TEST_PLFS(r, base, i, pr) \
 37         ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
 38                         PPC_INST_LFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
 39 
 40 #define TEST_PSTFS(r, base, i, pr) \
 41         ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
 42                         PPC_INST_STFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
 43 
 44 #define TEST_PLFD(r, base, i, pr) \
 45         ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
 46                         PPC_INST_LFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
 47 
 48 #define TEST_PSTFD(r, base, i, pr) \
 49         ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
 50                         PPC_INST_STFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
 51 
 52 #define TEST_PADDI(t, a, i, pr) \
 53         ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
 54                         PPC_RAW_ADDI(t, a, i))
 55 
 56 static void __init init_pt_regs(struct pt_regs *regs)
 57 {
 58         static unsigned long msr;
 59         static bool msr_cached;
 60 
 61         memset(regs, 0, sizeof(struct pt_regs));
 62 
 63         if (likely(msr_cached)) {
 64                 regs->msr = msr;
 65                 return;
 66         }
 67 
 68         asm volatile("mfmsr %0" : "=r"(regs->msr));
 69 
 70         regs->msr |= MSR_FP;
 71         regs->msr |= MSR_VEC;
 72         regs->msr |= MSR_VSX;
 73 
 74         msr = regs->msr;
 75         msr_cached = true;
 76 }
 77 
 78 static void __init show_result(char *mnemonic, char *result)
 79 {
 80         pr_info("%-14s : %s\n", mnemonic, result);
 81 }
 82 
 83 static void __init show_result_with_descr(char *mnemonic, char *descr,
 84                                           char *result)
 85 {
 86         pr_info("%-14s : %-50s %s\n", mnemonic, descr, result);
 87 }
 88 
 89 static void __init test_ld(void)
 90 {
 91         struct pt_regs regs;
 92         unsigned long a = 0x23;
 93         int stepped = -1;
 94 
 95         init_pt_regs(&regs);
 96         regs.gpr[3] = (unsigned long) &a;
 97 
 98         /* ld r5, 0(r3) */
 99         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LD(5, 3, 0)));
100 
101         if (stepped == 1 && regs.gpr[5] == a)
102                 show_result("ld", "PASS");
103         else
104                 show_result("ld", "FAIL");
105 }
106 
107 static void __init test_pld(void)
108 {
109         struct pt_regs regs;
110         unsigned long a = 0x23;
111         int stepped = -1;
112 
113         if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
114                 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
115                 return;
116         }
117 
118         init_pt_regs(&regs);
119         regs.gpr[3] = (unsigned long)&a;
120 
121         /* pld r5, 0(r3), 0 */
122         stepped = emulate_step(&regs, TEST_PLD(5, 3, 0, 0));
123 
124         if (stepped == 1 && regs.gpr[5] == a)
125                 show_result("pld", "PASS");
126         else
127                 show_result("pld", "FAIL");
128 }
129 
130 static void __init test_lwz(void)
131 {
132         struct pt_regs regs;
133         unsigned int a = 0x4545;
134         int stepped = -1;
135 
136         init_pt_regs(&regs);
137         regs.gpr[3] = (unsigned long) &a;
138 
139         /* lwz r5, 0(r3) */
140         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LWZ(5, 3, 0)));
141 
142         if (stepped == 1 && regs.gpr[5] == a)
143                 show_result("lwz", "PASS");
144         else
145                 show_result("lwz", "FAIL");
146 }
147 
148 static void __init test_plwz(void)
149 {
150         struct pt_regs regs;
151         unsigned int a = 0x4545;
152         int stepped = -1;
153 
154         if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
155                 show_result("plwz", "SKIP (!CPU_FTR_ARCH_31)");
156                 return;
157         }
158 
159         init_pt_regs(&regs);
160         regs.gpr[3] = (unsigned long)&a;
161 
162         /* plwz r5, 0(r3), 0 */
163 
164         stepped = emulate_step(&regs, TEST_PLWZ(5, 3, 0, 0));
165 
166         if (stepped == 1 && regs.gpr[5] == a)
167                 show_result("plwz", "PASS");
168         else
169                 show_result("plwz", "FAIL");
170 }
171 
172 static void __init test_lwzx(void)
173 {
174         struct pt_regs regs;
175         unsigned int a[3] = {0x0, 0x0, 0x1234};
176         int stepped = -1;
177 
178         init_pt_regs(&regs);
179         regs.gpr[3] = (unsigned long) a;
180         regs.gpr[4] = 8;
181         regs.gpr[5] = 0x8765;
182 
183         /* lwzx r5, r3, r4 */
184         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LWZX(5, 3, 4)));
185         if (stepped == 1 && regs.gpr[5] == a[2])
186                 show_result("lwzx", "PASS");
187         else
188                 show_result("lwzx", "FAIL");
189 }
190 
191 static void __init test_std(void)
192 {
193         struct pt_regs regs;
194         unsigned long a = 0x1234;
195         int stepped = -1;
196 
197         init_pt_regs(&regs);
198         regs.gpr[3] = (unsigned long) &a;
199         regs.gpr[5] = 0x5678;
200 
201         /* std r5, 0(r3) */
202         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STD(5, 3, 0)));
203         if (stepped == 1 && regs.gpr[5] == a)
204                 show_result("std", "PASS");
205         else
206                 show_result("std", "FAIL");
207 }
208 
209 static void __init test_pstd(void)
210 {
211         struct pt_regs regs;
212         unsigned long a = 0x1234;
213         int stepped = -1;
214 
215         if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
216                 show_result("pstd", "SKIP (!CPU_FTR_ARCH_31)");
217                 return;
218         }
219 
220         init_pt_regs(&regs);
221         regs.gpr[3] = (unsigned long)&a;
222         regs.gpr[5] = 0x5678;
223 
224         /* pstd r5, 0(r3), 0 */
225         stepped = emulate_step(&regs, TEST_PSTD(5, 3, 0, 0));
226         if (stepped == 1 || regs.gpr[5] == a)
227                 show_result("pstd", "PASS");
228         else
229                 show_result("pstd", "FAIL");
230 }
231 
232 static void __init test_ldarx_stdcx(void)
233 {
234         struct pt_regs regs;
235         unsigned long a = 0x1234;
236         int stepped = -1;
237         unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
238 
239         init_pt_regs(&regs);
240         asm volatile("mfcr %0" : "=r"(regs.ccr));
241 
242 
243         /*** ldarx ***/
244 
245         regs.gpr[3] = (unsigned long) &a;
246         regs.gpr[4] = 0;
247         regs.gpr[5] = 0x5678;
248 
249         /* ldarx r5, r3, r4, 0 */
250         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LDARX(5, 3, 4, 0)));
251 
252         /*
253          * Don't touch 'a' here. Touching 'a' can do Load/store
254          * of 'a' which result in failure of subsequent stdcx.
255          * Instead, use hardcoded value for comparison.
256          */
257         if (stepped <= 0 || regs.gpr[5] != 0x1234) {
258                 show_result("ldarx / stdcx.", "FAIL (ldarx)");
259                 return;
260         }
261 
262 
263         /*** stdcx. ***/
264 
265         regs.gpr[5] = 0x9ABC;
266 
267         /* stdcx. r5, r3, r4 */
268         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STDCX(5, 3, 4)));
269 
270         /*
271          * Two possible scenarios that indicates successful emulation
272          * of stdcx. :
273          *  1. Reservation is active and store is performed. In this
274          *     case cr0.eq bit will be set to 1.
275          *  2. Reservation is not active and store is not performed.
276          *     In this case cr0.eq bit will be set to 0.
277          */
278         if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
279                         || (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
280                 show_result("ldarx / stdcx.", "PASS");
281         else
282                 show_result("ldarx / stdcx.", "FAIL (stdcx.)");
283 }
284 
285 #ifdef CONFIG_PPC_FPU
286 static void __init test_lfsx_stfsx(void)
287 {
288         struct pt_regs regs;
289         union {
290                 float a;
291                 int b;
292         } c;
293         int cached_b;
294         int stepped = -1;
295 
296         init_pt_regs(&regs);
297 
298 
299         /*** lfsx ***/
300 
301         c.a = 123.45;
302         cached_b = c.b;
303 
304         regs.gpr[3] = (unsigned long) &c.a;
305         regs.gpr[4] = 0;
306 
307         /* lfsx frt10, r3, r4 */
308         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LFSX(10, 3, 4)));
309 
310         if (stepped == 1)
311                 show_result("lfsx", "PASS");
312         else
313                 show_result("lfsx", "FAIL");
314 
315 
316         /*** stfsx ***/
317 
318         c.a = 678.91;
319 
320         /* stfsx frs10, r3, r4 */
321         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STFSX(10, 3, 4)));
322 
323         if (stepped == 1 && c.b == cached_b)
324                 show_result("stfsx", "PASS");
325         else
326                 show_result("stfsx", "FAIL");
327 }
328 
329 static void __init test_plfs_pstfs(void)
330 {
331         struct pt_regs regs;
332         union {
333                 float a;
334                 int b;
335         } c;
336         int cached_b;
337         int stepped = -1;
338 
339         if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
340                 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
341                 return;
342         }
343 
344         init_pt_regs(&regs);
345 
346 
347         /*** plfs ***/
348 
349         c.a = 123.45;
350         cached_b = c.b;
351 
352         regs.gpr[3] = (unsigned long)&c.a;
353 
354         /* plfs frt10, 0(r3), 0  */
355         stepped = emulate_step(&regs, TEST_PLFS(10, 3, 0, 0));
356 
357         if (stepped == 1)
358                 show_result("plfs", "PASS");
359         else
360                 show_result("plfs", "FAIL");
361 
362 
363         /*** pstfs ***/
364 
365         c.a = 678.91;
366 
367         /* pstfs frs10, 0(r3), 0 */
368         stepped = emulate_step(&regs, TEST_PSTFS(10, 3, 0, 0));
369 
370         if (stepped == 1 && c.b == cached_b)
371                 show_result("pstfs", "PASS");
372         else
373                 show_result("pstfs", "FAIL");
374 }
375 
376 static void __init test_lfdx_stfdx(void)
377 {
378         struct pt_regs regs;
379         union {
380                 double a;
381                 long b;
382         } c;
383         long cached_b;
384         int stepped = -1;
385 
386         init_pt_regs(&regs);
387 
388 
389         /*** lfdx ***/
390 
391         c.a = 123456.78;
392         cached_b = c.b;
393 
394         regs.gpr[3] = (unsigned long) &c.a;
395         regs.gpr[4] = 0;
396 
397         /* lfdx frt10, r3, r4 */
398         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LFDX(10, 3, 4)));
399 
400         if (stepped == 1)
401                 show_result("lfdx", "PASS");
402         else
403                 show_result("lfdx", "FAIL");
404 
405 
406         /*** stfdx ***/
407 
408         c.a = 987654.32;
409 
410         /* stfdx frs10, r3, r4 */
411         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STFDX(10, 3, 4)));
412 
413         if (stepped == 1 && c.b == cached_b)
414                 show_result("stfdx", "PASS");
415         else
416                 show_result("stfdx", "FAIL");
417 }
418 
419 static void __init test_plfd_pstfd(void)
420 {
421         struct pt_regs regs;
422         union {
423                 double a;
424                 long b;
425         } c;
426         long cached_b;
427         int stepped = -1;
428 
429         if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
430                 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
431                 return;
432         }
433 
434         init_pt_regs(&regs);
435 
436 
437         /*** plfd ***/
438 
439         c.a = 123456.78;
440         cached_b = c.b;
441 
442         regs.gpr[3] = (unsigned long)&c.a;
443 
444         /* plfd frt10, 0(r3), 0 */
445         stepped = emulate_step(&regs, TEST_PLFD(10, 3, 0, 0));
446 
447         if (stepped == 1)
448                 show_result("plfd", "PASS");
449         else
450                 show_result("plfd", "FAIL");
451 
452 
453         /*** pstfd ***/
454 
455         c.a = 987654.32;
456 
457         /* pstfd frs10, 0(r3), 0 */
458         stepped = emulate_step(&regs, TEST_PSTFD(10, 3, 0, 0));
459 
460         if (stepped == 1 && c.b == cached_b)
461                 show_result("pstfd", "PASS");
462         else
463                 show_result("pstfd", "FAIL");
464 }
465 #else
466 static void __init test_lfsx_stfsx(void)
467 {
468         show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
469         show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
470 }
471 
472 static void __init test_plfs_pstfs(void)
473 {
474         show_result("plfs", "SKIP (CONFIG_PPC_FPU is not set)");
475         show_result("pstfs", "SKIP (CONFIG_PPC_FPU is not set)");
476 }
477 
478 static void __init test_lfdx_stfdx(void)
479 {
480         show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
481         show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
482 }
483 
484 static void __init test_plfd_pstfd(void)
485 {
486         show_result("plfd", "SKIP (CONFIG_PPC_FPU is not set)");
487         show_result("pstfd", "SKIP (CONFIG_PPC_FPU is not set)");
488 }
489 #endif /* CONFIG_PPC_FPU */
490 
491 #ifdef CONFIG_ALTIVEC
492 static void __init test_lvx_stvx(void)
493 {
494         struct pt_regs regs;
495         union {
496                 vector128 a;
497                 u32 b[4];
498         } c;
499         u32 cached_b[4];
500         int stepped = -1;
501 
502         init_pt_regs(&regs);
503 
504 
505         /*** lvx ***/
506 
507         cached_b[0] = c.b[0] = 923745;
508         cached_b[1] = c.b[1] = 2139478;
509         cached_b[2] = c.b[2] = 9012;
510         cached_b[3] = c.b[3] = 982134;
511 
512         regs.gpr[3] = (unsigned long) &c.a;
513         regs.gpr[4] = 0;
514 
515         /* lvx vrt10, r3, r4 */
516         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LVX(10, 3, 4)));
517 
518         if (stepped == 1)
519                 show_result("lvx", "PASS");
520         else
521                 show_result("lvx", "FAIL");
522 
523 
524         /*** stvx ***/
525 
526         c.b[0] = 4987513;
527         c.b[1] = 84313948;
528         c.b[2] = 71;
529         c.b[3] = 498532;
530 
531         /* stvx vrs10, r3, r4 */
532         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STVX(10, 3, 4)));
533 
534         if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
535             cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
536                 show_result("stvx", "PASS");
537         else
538                 show_result("stvx", "FAIL");
539 }
540 #else
541 static void __init test_lvx_stvx(void)
542 {
543         show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
544         show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
545 }
546 #endif /* CONFIG_ALTIVEC */
547 
548 #ifdef CONFIG_VSX
549 static void __init test_lxvd2x_stxvd2x(void)
550 {
551         struct pt_regs regs;
552         union {
553                 vector128 a;
554                 u32 b[4];
555         } c;
556         u32 cached_b[4];
557         int stepped = -1;
558 
559         init_pt_regs(&regs);
560 
561 
562         /*** lxvd2x ***/
563 
564         cached_b[0] = c.b[0] = 18233;
565         cached_b[1] = c.b[1] = 34863571;
566         cached_b[2] = c.b[2] = 834;
567         cached_b[3] = c.b[3] = 6138911;
568 
569         regs.gpr[3] = (unsigned long) &c.a;
570         regs.gpr[4] = 0;
571 
572         /* lxvd2x vsr39, r3, r4 */
573         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVD2X(39, R3, R4)));
574 
575         if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
576                 show_result("lxvd2x", "PASS");
577         } else {
578                 if (!cpu_has_feature(CPU_FTR_VSX))
579                         show_result("lxvd2x", "PASS (!CPU_FTR_VSX)");
580                 else
581                         show_result("lxvd2x", "FAIL");
582         }
583 
584 
585         /*** stxvd2x ***/
586 
587         c.b[0] = 21379463;
588         c.b[1] = 87;
589         c.b[2] = 374234;
590         c.b[3] = 4;
591 
592         /* stxvd2x vsr39, r3, r4 */
593         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVD2X(39, R3, R4)));
594 
595         if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
596             cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
597             cpu_has_feature(CPU_FTR_VSX)) {
598                 show_result("stxvd2x", "PASS");
599         } else {
600                 if (!cpu_has_feature(CPU_FTR_VSX))
601                         show_result("stxvd2x", "PASS (!CPU_FTR_VSX)");
602                 else
603                         show_result("stxvd2x", "FAIL");
604         }
605 }
606 #else
607 static void __init test_lxvd2x_stxvd2x(void)
608 {
609         show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
610         show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
611 }
612 #endif /* CONFIG_VSX */
613 
614 #ifdef CONFIG_VSX
615 static void __init test_lxvp_stxvp(void)
616 {
617         struct pt_regs regs;
618         union {
619                 vector128 a;
620                 u32 b[4];
621         } c[2];
622         u32 cached_b[8];
623         int stepped = -1;
624 
625         if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
626                 show_result("lxvp", "SKIP (!CPU_FTR_ARCH_31)");
627                 show_result("stxvp", "SKIP (!CPU_FTR_ARCH_31)");
628                 return;
629         }
630 
631         init_pt_regs(&regs);
632 
633         /*** lxvp ***/
634 
635         cached_b[0] = c[0].b[0] = 18233;
636         cached_b[1] = c[0].b[1] = 34863571;
637         cached_b[2] = c[0].b[2] = 834;
638         cached_b[3] = c[0].b[3] = 6138911;
639         cached_b[4] = c[1].b[0] = 1234;
640         cached_b[5] = c[1].b[1] = 5678;
641         cached_b[6] = c[1].b[2] = 91011;
642         cached_b[7] = c[1].b[3] = 121314;
643 
644         regs.gpr[4] = (unsigned long)&c[0].a;
645 
646         /*
647          * lxvp XTp,DQ(RA)
648          * XTp = 32xTX + 2xTp
649          * let TX=1 Tp=1 RA=4 DQ=0
650          */
651         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVP(34, 4, 0)));
652 
653         if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
654                 show_result("lxvp", "PASS");
655         } else {
656                 if (!cpu_has_feature(CPU_FTR_VSX))
657                         show_result("lxvp", "PASS (!CPU_FTR_VSX)");
658                 else
659                         show_result("lxvp", "FAIL");
660         }
661 
662         /*** stxvp ***/
663 
664         c[0].b[0] = 21379463;
665         c[0].b[1] = 87;
666         c[0].b[2] = 374234;
667         c[0].b[3] = 4;
668         c[1].b[0] = 90;
669         c[1].b[1] = 122;
670         c[1].b[2] = 555;
671         c[1].b[3] = 32144;
672 
673         /*
674          * stxvp XSp,DQ(RA)
675          * XSp = 32xSX + 2xSp
676          * let SX=1 Sp=1 RA=4 DQ=0
677          */
678         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVP(34, 4, 0)));
679 
680         if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
681             cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
682             cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
683             cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
684             cpu_has_feature(CPU_FTR_VSX)) {
685                 show_result("stxvp", "PASS");
686         } else {
687                 if (!cpu_has_feature(CPU_FTR_VSX))
688                         show_result("stxvp", "PASS (!CPU_FTR_VSX)");
689                 else
690                         show_result("stxvp", "FAIL");
691         }
692 }
693 #else
694 static void __init test_lxvp_stxvp(void)
695 {
696         show_result("lxvp", "SKIP (CONFIG_VSX is not set)");
697         show_result("stxvp", "SKIP (CONFIG_VSX is not set)");
698 }
699 #endif /* CONFIG_VSX */
700 
701 #ifdef CONFIG_VSX
702 static void __init test_lxvpx_stxvpx(void)
703 {
704         struct pt_regs regs;
705         union {
706                 vector128 a;
707                 u32 b[4];
708         } c[2];
709         u32 cached_b[8];
710         int stepped = -1;
711 
712         if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
713                 show_result("lxvpx", "SKIP (!CPU_FTR_ARCH_31)");
714                 show_result("stxvpx", "SKIP (!CPU_FTR_ARCH_31)");
715                 return;
716         }
717 
718         init_pt_regs(&regs);
719 
720         /*** lxvpx ***/
721 
722         cached_b[0] = c[0].b[0] = 18233;
723         cached_b[1] = c[0].b[1] = 34863571;
724         cached_b[2] = c[0].b[2] = 834;
725         cached_b[3] = c[0].b[3] = 6138911;
726         cached_b[4] = c[1].b[0] = 1234;
727         cached_b[5] = c[1].b[1] = 5678;
728         cached_b[6] = c[1].b[2] = 91011;
729         cached_b[7] = c[1].b[3] = 121314;
730 
731         regs.gpr[3] = (unsigned long)&c[0].a;
732         regs.gpr[4] = 0;
733 
734         /*
735          * lxvpx XTp,RA,RB
736          * XTp = 32xTX + 2xTp
737          * let TX=1 Tp=1 RA=3 RB=4
738          */
739         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVPX(34, 3, 4)));
740 
741         if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
742                 show_result("lxvpx", "PASS");
743         } else {
744                 if (!cpu_has_feature(CPU_FTR_VSX))
745                         show_result("lxvpx", "PASS (!CPU_FTR_VSX)");
746                 else
747                         show_result("lxvpx", "FAIL");
748         }
749 
750         /*** stxvpx ***/
751 
752         c[0].b[0] = 21379463;
753         c[0].b[1] = 87;
754         c[0].b[2] = 374234;
755         c[0].b[3] = 4;
756         c[1].b[0] = 90;
757         c[1].b[1] = 122;
758         c[1].b[2] = 555;
759         c[1].b[3] = 32144;
760 
761         /*
762          * stxvpx XSp,RA,RB
763          * XSp = 32xSX + 2xSp
764          * let SX=1 Sp=1 RA=3 RB=4
765          */
766         stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVPX(34, 3, 4)));
767 
768         if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
769             cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
770             cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
771             cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
772             cpu_has_feature(CPU_FTR_VSX)) {
773                 show_result("stxvpx", "PASS");
774         } else {
775                 if (!cpu_has_feature(CPU_FTR_VSX))
776                         show_result("stxvpx", "PASS (!CPU_FTR_VSX)");
777                 else
778                         show_result("stxvpx", "FAIL");
779         }
780 }
781 #else
782 static void __init test_lxvpx_stxvpx(void)
783 {
784         show_result("lxvpx", "SKIP (CONFIG_VSX is not set)");
785         show_result("stxvpx", "SKIP (CONFIG_VSX is not set)");
786 }
787 #endif /* CONFIG_VSX */
788 
789 #ifdef CONFIG_VSX
790 static void __init test_plxvp_pstxvp(void)
791 {
792         ppc_inst_t instr;
793         struct pt_regs regs;
794         union {
795                 vector128 a;
796                 u32 b[4];
797         } c[2];
798         u32 cached_b[8];
799         int stepped = -1;
800 
801         if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
802                 show_result("plxvp", "SKIP (!CPU_FTR_ARCH_31)");
803                 show_result("pstxvp", "SKIP (!CPU_FTR_ARCH_31)");
804                 return;
805         }
806 
807         /*** plxvp ***/
808 
809         cached_b[0] = c[0].b[0] = 18233;
810         cached_b[1] = c[0].b[1] = 34863571;
811         cached_b[2] = c[0].b[2] = 834;
812         cached_b[3] = c[0].b[3] = 6138911;
813         cached_b[4] = c[1].b[0] = 1234;
814         cached_b[5] = c[1].b[1] = 5678;
815         cached_b[6] = c[1].b[2] = 91011;
816         cached_b[7] = c[1].b[3] = 121314;
817 
818         init_pt_regs(&regs);
819         regs.gpr[3] = (unsigned long)&c[0].a;
820 
821         /*
822          * plxvp XTp,D(RA),R
823          * XTp = 32xTX + 2xTp
824          * let RA=3 R=0 D=d0||d1=0 R=0 Tp=1 TX=1
825          */
826         instr = ppc_inst_prefix(PPC_RAW_PLXVP_P(34, 0, 3, 0), PPC_RAW_PLXVP_S(34, 0, 3, 0));
827 
828         stepped = emulate_step(&regs, instr);
829         if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
830                 show_result("plxvp", "PASS");
831         } else {
832                 if (!cpu_has_feature(CPU_FTR_VSX))
833                         show_result("plxvp", "PASS (!CPU_FTR_VSX)");
834                 else
835                         show_result("plxvp", "FAIL");
836         }
837 
838         /*** pstxvp ***/
839 
840         c[0].b[0] = 21379463;
841         c[0].b[1] = 87;
842         c[0].b[2] = 374234;
843         c[0].b[3] = 4;
844         c[1].b[0] = 90;
845         c[1].b[1] = 122;
846         c[1].b[2] = 555;
847         c[1].b[3] = 32144;
848 
849         /*
850          * pstxvp XSp,D(RA),R
851          * XSp = 32xSX + 2xSp
852          * let RA=3 D=d0||d1=0 R=0 Sp=1 SX=1
853          */
854         instr = ppc_inst_prefix(PPC_RAW_PSTXVP_P(34, 0, 3, 0), PPC_RAW_PSTXVP_S(34, 0, 3, 0));
855 
856         stepped = emulate_step(&regs, instr);
857 
858         if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
859             cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
860             cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
861             cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
862             cpu_has_feature(CPU_FTR_VSX)) {
863                 show_result("pstxvp", "PASS");
864         } else {
865                 if (!cpu_has_feature(CPU_FTR_VSX))
866                         show_result("pstxvp", "PASS (!CPU_FTR_VSX)");
867                 else
868                         show_result("pstxvp", "FAIL");
869         }
870 }
871 #else
872 static void __init test_plxvp_pstxvp(void)
873 {
874         show_result("plxvp", "SKIP (CONFIG_VSX is not set)");
875         show_result("pstxvp", "SKIP (CONFIG_VSX is not set)");
876 }
877 #endif /* CONFIG_VSX */
878 
879 static void __init run_tests_load_store(void)
880 {
881         test_ld();
882         test_pld();
883         test_lwz();
884         test_plwz();
885         test_lwzx();
886         test_std();
887         test_pstd();
888         test_ldarx_stdcx();
889         test_lfsx_stfsx();
890         test_plfs_pstfs();
891         test_lfdx_stfdx();
892         test_plfd_pstfd();
893         test_lvx_stvx();
894         test_lxvd2x_stxvd2x();
895         test_lxvp_stxvp();
896         test_lxvpx_stxvpx();
897         test_plxvp_pstxvp();
898 }
899 
900 struct compute_test {
901         char *mnemonic;
902         unsigned long cpu_feature;
903         struct {
904                 char *descr;
905                 unsigned long flags;
906                 ppc_inst_t instr;
907                 struct pt_regs regs;
908         } subtests[MAX_SUBTESTS + 1];
909 };
910 
911 /* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
912 #define SI_MIN BIT(33)
913 #define SI_MAX (BIT(33) - 1)
914 #define SI_UMAX (BIT(34) - 1)
915 
916 static struct compute_test compute_tests[] = {
917         {
918                 .mnemonic = "nop",
919                 .subtests = {
920                         {
921                                 .descr = "R0 = LONG_MAX",
922                                 .instr = ppc_inst(PPC_RAW_NOP()),
923                                 .regs = {
924                                         .gpr[0] = LONG_MAX,
925                                 }
926                         }
927                 }
928         },
929         {
930                 .mnemonic = "setb",
931                 .cpu_feature = CPU_FTR_ARCH_300,
932                 .subtests = {
933                         {
934                                 .descr = "BFA = 1, CR = GT",
935                                 .instr = ppc_inst(PPC_RAW_SETB(20, 1)),
936                                 .regs = {
937                                         .ccr = 0x4000000,
938                                 }
939                         },
940                         {
941                                 .descr = "BFA = 4, CR = LT",
942                                 .instr = ppc_inst(PPC_RAW_SETB(20, 4)),
943                                 .regs = {
944                                         .ccr = 0x8000,
945                                 }
946                         },
947                         {
948                                 .descr = "BFA = 5, CR = EQ",
949                                 .instr = ppc_inst(PPC_RAW_SETB(20, 5)),
950                                 .regs = {
951                                         .ccr = 0x200,
952                                 }
953                         }
954                 }
955         },
956         {
957                 .mnemonic = "add",
958                 .subtests = {
959                         {
960                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
961                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
962                                 .regs = {
963                                         .gpr[21] = LONG_MIN,
964                                         .gpr[22] = LONG_MIN,
965                                 }
966                         },
967                         {
968                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
969                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
970                                 .regs = {
971                                         .gpr[21] = LONG_MIN,
972                                         .gpr[22] = LONG_MAX,
973                                 }
974                         },
975                         {
976                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
977                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
978                                 .regs = {
979                                         .gpr[21] = LONG_MAX,
980                                         .gpr[22] = LONG_MAX,
981                                 }
982                         },
983                         {
984                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
985                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
986                                 .regs = {
987                                         .gpr[21] = ULONG_MAX,
988                                         .gpr[22] = ULONG_MAX,
989                                 }
990                         },
991                         {
992                                 .descr = "RA = ULONG_MAX, RB = 0x1",
993                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
994                                 .regs = {
995                                         .gpr[21] = ULONG_MAX,
996                                         .gpr[22] = 0x1,
997                                 }
998                         },
999                         {
1000                                 .descr = "RA = INT_MIN, RB = INT_MIN",
1001                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1002                                 .regs = {
1003                                         .gpr[21] = INT_MIN,
1004                                         .gpr[22] = INT_MIN,
1005                                 }
1006                         },
1007                         {
1008                                 .descr = "RA = INT_MIN, RB = INT_MAX",
1009                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1010                                 .regs = {
1011                                         .gpr[21] = INT_MIN,
1012                                         .gpr[22] = INT_MAX,
1013                                 }
1014                         },
1015                         {
1016                                 .descr = "RA = INT_MAX, RB = INT_MAX",
1017                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1018                                 .regs = {
1019                                         .gpr[21] = INT_MAX,
1020                                         .gpr[22] = INT_MAX,
1021                                 }
1022                         },
1023                         {
1024                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1025                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1026                                 .regs = {
1027                                         .gpr[21] = UINT_MAX,
1028                                         .gpr[22] = UINT_MAX,
1029                                 }
1030                         },
1031                         {
1032                                 .descr = "RA = UINT_MAX, RB = 0x1",
1033                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1034                                 .regs = {
1035                                         .gpr[21] = UINT_MAX,
1036                                         .gpr[22] = 0x1,
1037                                 }
1038                         }
1039                 }
1040         },
1041         {
1042                 .mnemonic = "add.",
1043                 .subtests = {
1044                         {
1045                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1046                                 .flags = IGNORE_CCR,
1047                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1048                                 .regs = {
1049                                         .gpr[21] = LONG_MIN,
1050                                         .gpr[22] = LONG_MIN,
1051                                 }
1052                         },
1053                         {
1054                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1055                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1056                                 .regs = {
1057                                         .gpr[21] = LONG_MIN,
1058                                         .gpr[22] = LONG_MAX,
1059                                 }
1060                         },
1061                         {
1062                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1063                                 .flags = IGNORE_CCR,
1064                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1065                                 .regs = {
1066                                         .gpr[21] = LONG_MAX,
1067                                         .gpr[22] = LONG_MAX,
1068                                 }
1069                         },
1070                         {
1071                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1072                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1073                                 .regs = {
1074                                         .gpr[21] = ULONG_MAX,
1075                                         .gpr[22] = ULONG_MAX,
1076                                 }
1077                         },
1078                         {
1079                                 .descr = "RA = ULONG_MAX, RB = 0x1",
1080                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1081                                 .regs = {
1082                                         .gpr[21] = ULONG_MAX,
1083                                         .gpr[22] = 0x1,
1084                                 }
1085                         },
1086                         {
1087                                 .descr = "RA = INT_MIN, RB = INT_MIN",
1088                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1089                                 .regs = {
1090                                         .gpr[21] = INT_MIN,
1091                                         .gpr[22] = INT_MIN,
1092                                 }
1093                         },
1094                         {
1095                                 .descr = "RA = INT_MIN, RB = INT_MAX",
1096                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1097                                 .regs = {
1098                                         .gpr[21] = INT_MIN,
1099                                         .gpr[22] = INT_MAX,
1100                                 }
1101                         },
1102                         {
1103                                 .descr = "RA = INT_MAX, RB = INT_MAX",
1104                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1105                                 .regs = {
1106                                         .gpr[21] = INT_MAX,
1107                                         .gpr[22] = INT_MAX,
1108                                 }
1109                         },
1110                         {
1111                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1112                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1113                                 .regs = {
1114                                         .gpr[21] = UINT_MAX,
1115                                         .gpr[22] = UINT_MAX,
1116                                 }
1117                         },
1118                         {
1119                                 .descr = "RA = UINT_MAX, RB = 0x1",
1120                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1121                                 .regs = {
1122                                         .gpr[21] = UINT_MAX,
1123                                         .gpr[22] = 0x1,
1124                                 }
1125                         }
1126                 }
1127         },
1128         {
1129                 .mnemonic = "addc",
1130                 .subtests = {
1131                         {
1132                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1133                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1134                                 .regs = {
1135                                         .gpr[21] = LONG_MIN,
1136                                         .gpr[22] = LONG_MIN,
1137                                 }
1138                         },
1139                         {
1140                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1141                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1142                                 .regs = {
1143                                         .gpr[21] = LONG_MIN,
1144                                         .gpr[22] = LONG_MAX,
1145                                 }
1146                         },
1147                         {
1148                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1149                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1150                                 .regs = {
1151                                         .gpr[21] = LONG_MAX,
1152                                         .gpr[22] = LONG_MAX,
1153                                 }
1154                         },
1155                         {
1156                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1157                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1158                                 .regs = {
1159                                         .gpr[21] = ULONG_MAX,
1160                                         .gpr[22] = ULONG_MAX,
1161                                 }
1162                         },
1163                         {
1164                                 .descr = "RA = ULONG_MAX, RB = 0x1",
1165                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1166                                 .regs = {
1167                                         .gpr[21] = ULONG_MAX,
1168                                         .gpr[22] = 0x1,
1169                                 }
1170                         },
1171                         {
1172                                 .descr = "RA = INT_MIN, RB = INT_MIN",
1173                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1174                                 .regs = {
1175                                         .gpr[21] = INT_MIN,
1176                                         .gpr[22] = INT_MIN,
1177                                 }
1178                         },
1179                         {
1180                                 .descr = "RA = INT_MIN, RB = INT_MAX",
1181                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1182                                 .regs = {
1183                                         .gpr[21] = INT_MIN,
1184                                         .gpr[22] = INT_MAX,
1185                                 }
1186                         },
1187                         {
1188                                 .descr = "RA = INT_MAX, RB = INT_MAX",
1189                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1190                                 .regs = {
1191                                         .gpr[21] = INT_MAX,
1192                                         .gpr[22] = INT_MAX,
1193                                 }
1194                         },
1195                         {
1196                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1197                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1198                                 .regs = {
1199                                         .gpr[21] = UINT_MAX,
1200                                         .gpr[22] = UINT_MAX,
1201                                 }
1202                         },
1203                         {
1204                                 .descr = "RA = UINT_MAX, RB = 0x1",
1205                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1206                                 .regs = {
1207                                         .gpr[21] = UINT_MAX,
1208                                         .gpr[22] = 0x1,
1209                                 }
1210                         },
1211                         {
1212                                 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1213                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1214                                 .regs = {
1215                                         .gpr[21] = LONG_MIN | (uint)INT_MIN,
1216                                         .gpr[22] = LONG_MIN | (uint)INT_MIN,
1217                                 }
1218                         }
1219                 }
1220         },
1221         {
1222                 .mnemonic = "addc.",
1223                 .subtests = {
1224                         {
1225                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1226                                 .flags = IGNORE_CCR,
1227                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1228                                 .regs = {
1229                                         .gpr[21] = LONG_MIN,
1230                                         .gpr[22] = LONG_MIN,
1231                                 }
1232                         },
1233                         {
1234                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1235                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1236                                 .regs = {
1237                                         .gpr[21] = LONG_MIN,
1238                                         .gpr[22] = LONG_MAX,
1239                                 }
1240                         },
1241                         {
1242                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1243                                 .flags = IGNORE_CCR,
1244                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1245                                 .regs = {
1246                                         .gpr[21] = LONG_MAX,
1247                                         .gpr[22] = LONG_MAX,
1248                                 }
1249                         },
1250                         {
1251                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1252                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1253                                 .regs = {
1254                                         .gpr[21] = ULONG_MAX,
1255                                         .gpr[22] = ULONG_MAX,
1256                                 }
1257                         },
1258                         {
1259                                 .descr = "RA = ULONG_MAX, RB = 0x1",
1260                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1261                                 .regs = {
1262                                         .gpr[21] = ULONG_MAX,
1263                                         .gpr[22] = 0x1,
1264                                 }
1265                         },
1266                         {
1267                                 .descr = "RA = INT_MIN, RB = INT_MIN",
1268                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1269                                 .regs = {
1270                                         .gpr[21] = INT_MIN,
1271                                         .gpr[22] = INT_MIN,
1272                                 }
1273                         },
1274                         {
1275                                 .descr = "RA = INT_MIN, RB = INT_MAX",
1276                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1277                                 .regs = {
1278                                         .gpr[21] = INT_MIN,
1279                                         .gpr[22] = INT_MAX,
1280                                 }
1281                         },
1282                         {
1283                                 .descr = "RA = INT_MAX, RB = INT_MAX",
1284                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1285                                 .regs = {
1286                                         .gpr[21] = INT_MAX,
1287                                         .gpr[22] = INT_MAX,
1288                                 }
1289                         },
1290                         {
1291                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1292                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1293                                 .regs = {
1294                                         .gpr[21] = UINT_MAX,
1295                                         .gpr[22] = UINT_MAX,
1296                                 }
1297                         },
1298                         {
1299                                 .descr = "RA = UINT_MAX, RB = 0x1",
1300                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1301                                 .regs = {
1302                                         .gpr[21] = UINT_MAX,
1303                                         .gpr[22] = 0x1,
1304                                 }
1305                         },
1306                         {
1307                                 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1308                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1309                                 .regs = {
1310                                         .gpr[21] = LONG_MIN | (uint)INT_MIN,
1311                                         .gpr[22] = LONG_MIN | (uint)INT_MIN,
1312                                 }
1313                         }
1314                 }
1315         },
1316         {
1317                 .mnemonic = "divde",
1318                 .subtests = {
1319                         {
1320                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1321                                 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1322                                 .regs = {
1323                                         .gpr[21] = LONG_MIN,
1324                                         .gpr[22] = LONG_MIN,
1325                                 }
1326                         },
1327                         {
1328                                 .descr = "RA = 1L, RB = 0",
1329                                 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1330                                 .flags = IGNORE_GPR(20),
1331                                 .regs = {
1332                                         .gpr[21] = 1L,
1333                                         .gpr[22] = 0,
1334                                 }
1335                         },
1336                         {
1337                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1338                                 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1339                                 .regs = {
1340                                         .gpr[21] = LONG_MIN,
1341                                         .gpr[22] = LONG_MAX,
1342                                 }
1343                         }
1344                 }
1345         },
1346         {
1347                 .mnemonic = "divde.",
1348                 .subtests = {
1349                         {
1350                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1351                                 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1352                                 .regs = {
1353                                         .gpr[21] = LONG_MIN,
1354                                         .gpr[22] = LONG_MIN,
1355                                 }
1356                         },
1357                         {
1358                                 .descr = "RA = 1L, RB = 0",
1359                                 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1360                                 .flags = IGNORE_GPR(20),
1361                                 .regs = {
1362                                         .gpr[21] = 1L,
1363                                         .gpr[22] = 0,
1364                                 }
1365                         },
1366                         {
1367                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1368                                 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1369                                 .regs = {
1370                                         .gpr[21] = LONG_MIN,
1371                                         .gpr[22] = LONG_MAX,
1372                                 }
1373                         }
1374                 }
1375         },
1376         {
1377                 .mnemonic = "divdeu",
1378                 .subtests = {
1379                         {
1380                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1381                                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1382                                 .flags = IGNORE_GPR(20),
1383                                 .regs = {
1384                                         .gpr[21] = LONG_MIN,
1385                                         .gpr[22] = LONG_MIN,
1386                                 }
1387                         },
1388                         {
1389                                 .descr = "RA = 1L, RB = 0",
1390                                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1391                                 .flags = IGNORE_GPR(20),
1392                                 .regs = {
1393                                         .gpr[21] = 1L,
1394                                         .gpr[22] = 0,
1395                                 }
1396                         },
1397                         {
1398                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1399                                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1400                                 .regs = {
1401                                         .gpr[21] = LONG_MIN,
1402                                         .gpr[22] = LONG_MAX,
1403                                 }
1404                         },
1405                         {
1406                                 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1407                                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1408                                 .regs = {
1409                                         .gpr[21] = LONG_MAX - 1,
1410                                         .gpr[22] = LONG_MAX,
1411                                 }
1412                         },
1413                         {
1414                                 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1415                                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1416                                 .flags = IGNORE_GPR(20),
1417                                 .regs = {
1418                                         .gpr[21] = LONG_MIN + 1,
1419                                         .gpr[22] = LONG_MIN,
1420                                 }
1421                         }
1422                 }
1423         },
1424         {
1425                 .mnemonic = "divdeu.",
1426                 .subtests = {
1427                         {
1428                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1429                                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1430                                 .flags = IGNORE_GPR(20),
1431                                 .regs = {
1432                                         .gpr[21] = LONG_MIN,
1433                                         .gpr[22] = LONG_MIN,
1434                                 }
1435                         },
1436                         {
1437                                 .descr = "RA = 1L, RB = 0",
1438                                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1439                                 .flags = IGNORE_GPR(20),
1440                                 .regs = {
1441                                         .gpr[21] = 1L,
1442                                         .gpr[22] = 0,
1443                                 }
1444                         },
1445                         {
1446                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1447                                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1448                                 .regs = {
1449                                         .gpr[21] = LONG_MIN,
1450                                         .gpr[22] = LONG_MAX,
1451                                 }
1452                         },
1453                         {
1454                                 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1455                                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1456                                 .regs = {
1457                                         .gpr[21] = LONG_MAX - 1,
1458                                         .gpr[22] = LONG_MAX,
1459                                 }
1460                         },
1461                         {
1462                                 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1463                                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1464                                 .flags = IGNORE_GPR(20),
1465                                 .regs = {
1466                                         .gpr[21] = LONG_MIN + 1,
1467                                         .gpr[22] = LONG_MIN,
1468                                 }
1469                         }
1470                 }
1471         },
1472         {
1473                 .mnemonic = "paddi",
1474                 .cpu_feature = CPU_FTR_ARCH_31,
1475                 .subtests = {
1476                         {
1477                                 .descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
1478                                 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1479                                 .regs = {
1480                                         .gpr[21] = 0,
1481                                         .gpr[22] = LONG_MIN,
1482                                 }
1483                         },
1484                         {
1485                                 .descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
1486                                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1487                                 .regs = {
1488                                         .gpr[21] = 0,
1489                                         .gpr[22] = LONG_MIN,
1490                                 }
1491                         },
1492                         {
1493                                 .descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
1494                                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1495                                 .regs = {
1496                                         .gpr[21] = 0,
1497                                         .gpr[22] = LONG_MAX,
1498                                 }
1499                         },
1500                         {
1501                                 .descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
1502                                 .instr = TEST_PADDI(21, 22, SI_UMAX, 0),
1503                                 .regs = {
1504                                         .gpr[21] = 0,
1505                                         .gpr[22] = ULONG_MAX,
1506                                 }
1507                         },
1508                         {
1509                                 .descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
1510                                 .instr = TEST_PADDI(21, 22, 0x1, 0),
1511                                 .regs = {
1512                                         .gpr[21] = 0,
1513                                         .gpr[22] = ULONG_MAX,
1514                                 }
1515                         },
1516                         {
1517                                 .descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
1518                                 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1519                                 .regs = {
1520                                         .gpr[21] = 0,
1521                                         .gpr[22] = INT_MIN,
1522                                 }
1523                         },
1524                         {
1525                                 .descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
1526                                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1527                                 .regs = {
1528                                         .gpr[21] = 0,
1529                                         .gpr[22] = INT_MIN,
1530                                 }
1531                         },
1532                         {
1533                                 .descr = "RA = INT_MAX, SI = SI_MAX, R = 0",
1534                                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1535                                 .regs = {
1536                                         .gpr[21] = 0,
1537                                         .gpr[22] = INT_MAX,
1538                                 }
1539                         },
1540                         {
1541                                 .descr = "RA = UINT_MAX, SI = 0x1, R = 0",
1542                                 .instr = TEST_PADDI(21, 22, 0x1, 0),
1543                                 .regs = {
1544                                         .gpr[21] = 0,
1545                                         .gpr[22] = UINT_MAX,
1546                                 }
1547                         },
1548                         {
1549                                 .descr = "RA = UINT_MAX, SI = SI_MAX, R = 0",
1550                                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1551                                 .regs = {
1552                                         .gpr[21] = 0,
1553                                         .gpr[22] = UINT_MAX,
1554                                 }
1555                         },
1556                         {
1557                                 .descr = "RA is r0, SI = SI_MIN, R = 0",
1558                                 .instr = TEST_PADDI(21, 0, SI_MIN, 0),
1559                                 .regs = {
1560                                         .gpr[21] = 0x0,
1561                                 }
1562                         },
1563                         {
1564                                 .descr = "RA = 0, SI = SI_MIN, R = 0",
1565                                 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1566                                 .regs = {
1567                                         .gpr[21] = 0x0,
1568                                         .gpr[22] = 0x0,
1569                                 }
1570                         },
1571                         {
1572                                 .descr = "RA is r0, SI = 0, R = 1",
1573                                 .instr = TEST_PADDI(21, 0, 0, 1),
1574                                 .regs = {
1575                                         .gpr[21] = 0,
1576                                 }
1577                         },
1578                         {
1579                                 .descr = "RA is r0, SI = SI_MIN, R = 1",
1580                                 .instr = TEST_PADDI(21, 0, SI_MIN, 1),
1581                                 .regs = {
1582                                         .gpr[21] = 0,
1583                                 }
1584                         },
1585                         /* Invalid instruction form with R = 1 and RA != 0 */
1586                         {
1587                                 .descr = "RA = R22(0), SI = 0, R = 1",
1588                                 .instr = TEST_PADDI(21, 22, 0, 1),
1589                                 .flags = NEGATIVE_TEST,
1590                                 .regs = {
1591                                         .gpr[21] = 0,
1592                                         .gpr[22] = 0,
1593                                 }
1594                         }
1595                 }
1596         }
1597 };
1598 
1599 static int __init emulate_compute_instr(struct pt_regs *regs,
1600                                         ppc_inst_t instr,
1601                                         bool negative)
1602 {
1603         int analysed;
1604         struct instruction_op op;
1605 
1606         if (!regs || !ppc_inst_val(instr))
1607                 return -EINVAL;
1608 
1609         /* This is not a return frame regs */
1610         regs->nip = patch_site_addr(&patch__exec_instr);
1611 
1612         analysed = analyse_instr(&op, regs, instr);
1613         if (analysed != 1 || GETTYPE(op.type) != COMPUTE) {
1614                 if (negative)
1615                         return -EFAULT;
1616                 pr_info("emulation failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1617                 return -EFAULT;
1618         }
1619         if (analysed == 1 && negative)
1620                 pr_info("negative test failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1621         if (!negative)
1622                 emulate_update_regs(regs, &op);
1623         return 0;
1624 }
1625 
1626 static int __init execute_compute_instr(struct pt_regs *regs,
1627                                         ppc_inst_t instr)
1628 {
1629         extern int exec_instr(struct pt_regs *regs);
1630 
1631         if (!regs || !ppc_inst_val(instr))
1632                 return -EINVAL;
1633 
1634         /* Patch the NOP with the actual instruction */
1635         patch_instruction_site(&patch__exec_instr, instr);
1636         if (exec_instr(regs)) {
1637                 pr_info("execution failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1638                 return -EFAULT;
1639         }
1640 
1641         return 0;
1642 }
1643 
1644 #define gpr_mismatch(gprn, exp, got)    \
1645         pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n",     \
1646                 gprn, exp, got)
1647 
1648 #define reg_mismatch(name, exp, got)    \
1649         pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n",        \
1650                 name, exp, got)
1651 
1652 static void __init run_tests_compute(void)
1653 {
1654         unsigned long flags;
1655         struct compute_test *test;
1656         struct pt_regs *regs, exp, got;
1657         unsigned int i, j, k;
1658         ppc_inst_t instr;
1659         bool ignore_gpr, ignore_xer, ignore_ccr, passed, rc, negative;
1660 
1661         for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
1662                 test = &compute_tests[i];
1663 
1664                 if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) {
1665                         show_result(test->mnemonic, "SKIP (!CPU_FTR)");
1666                         continue;
1667                 }
1668 
1669                 for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
1670                         instr = test->subtests[j].instr;
1671                         flags = test->subtests[j].flags;
1672                         regs = &test->subtests[j].regs;
1673                         negative = flags & NEGATIVE_TEST;
1674                         ignore_xer = flags & IGNORE_XER;
1675                         ignore_ccr = flags & IGNORE_CCR;
1676                         passed = true;
1677 
1678                         memcpy(&exp, regs, sizeof(struct pt_regs));
1679                         memcpy(&got, regs, sizeof(struct pt_regs));
1680 
1681                         /*
1682                          * Set a compatible MSR value explicitly to ensure
1683                          * that XER and CR bits are updated appropriately
1684                          */
1685                         exp.msr = MSR_KERNEL;
1686                         got.msr = MSR_KERNEL;
1687 
1688                         rc = emulate_compute_instr(&got, instr, negative) != 0;
1689                         if (negative) {
1690                                 /* skip executing instruction */
1691                                 passed = rc;
1692                                 goto print;
1693                         } else if (rc || execute_compute_instr(&exp, instr)) {
1694                                 passed = false;
1695                                 goto print;
1696                         }
1697 
1698                         /* Verify GPR values */
1699                         for (k = 0; k < 32; k++) {
1700                                 ignore_gpr = flags & IGNORE_GPR(k);
1701                                 if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
1702                                         passed = false;
1703                                         gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
1704                                 }
1705                         }
1706 
1707                         /* Verify LR value */
1708                         if (exp.link != got.link) {
1709                                 passed = false;
1710                                 reg_mismatch("LR", exp.link, got.link);
1711                         }
1712 
1713                         /* Verify XER value */
1714                         if (!ignore_xer && exp.xer != got.xer) {
1715                                 passed = false;
1716                                 reg_mismatch("XER", exp.xer, got.xer);
1717                         }
1718 
1719                         /* Verify CR value */
1720                         if (!ignore_ccr && exp.ccr != got.ccr) {
1721                                 passed = false;
1722                                 reg_mismatch("CR", exp.ccr, got.ccr);
1723                         }
1724 
1725 print:
1726                         show_result_with_descr(test->mnemonic,
1727                                                test->subtests[j].descr,
1728                                                passed ? "PASS" : "FAIL");
1729                 }
1730         }
1731 }
1732 
1733 static int __init test_emulate_step(void)
1734 {
1735         printk(KERN_INFO "Running instruction emulation self-tests ...\n");
1736         run_tests_load_store();
1737         run_tests_compute();
1738 
1739         return 0;
1740 }
1741 late_initcall(test_emulate_step);
1742 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php